aboutsummaryrefslogtreecommitdiff
path: root/tests/test-pipe-manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-pipe-manager.cpp')
-rw-r--r--tests/test-pipe-manager.cpp467
1 files changed, 467 insertions, 0 deletions
diff --git a/tests/test-pipe-manager.cpp b/tests/test-pipe-manager.cpp
new file mode 100644
index 0000000..280bfdc
--- /dev/null
+++ b/tests/test-pipe-manager.cpp
@@ -0,0 +1,467 @@
+/*
+ * test-pipe-manager.cpp -test pipe manager
+ *
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include <pipe_manager.h>
+#include <smart_analyzer_loader.h>
+#include <ocl/cl_post_image_processor.h>
+#if HAVE_LIBDRM
+#include <drm_display.h>
+#endif
+#include <getopt.h>
+#include <test_common.h>
+#include <signal.h>
+#include <stdio.h>
+
+#define DEFAULT_FPT_BUF_COUNT 32
+
+using namespace XCam;
+
+static bool is_stop = false;
+
+struct FileFP {
+ FILE *fp;
+ FileFP ()
+ : fp (NULL)
+ {}
+ ~FileFP ()
+ {
+ if (fp)
+ fclose (fp);
+ fp = NULL;
+ }
+};
+
+class MainPipeManager
+ : public PipeManager
+{
+public:
+ MainPipeManager ()
+ : _image_width (0)
+ , _image_height (0)
+ , _enable_display (false)
+ {
+#if HAVE_LIBDRM
+ _display = DrmDisplay::instance ();
+#endif
+ XCAM_OBJ_PROFILING_INIT;
+ }
+
+ void set_image_width (uint32_t image_width) {
+ _image_width = image_width;
+ }
+
+ void set_image_height (uint32_t image_height) {
+ _image_height = image_height;
+ }
+
+ void enable_display (bool value) {
+ _enable_display = value;
+ }
+
+#if HAVE_LIBDRM
+ void set_display_mode (DrmDisplayMode mode) {
+ _display->set_display_mode (mode);
+ }
+#endif
+
+protected:
+ virtual void post_buffer (const SmartPtr<VideoBuffer> &buf);
+ int display_buf (const SmartPtr<VideoBuffer> &buf);
+
+private:
+ uint32_t _image_width;
+ uint32_t _image_height;
+ bool _enable_display;
+#if HAVE_LIBDRM
+ SmartPtr<DrmDisplay> _display;
+#endif
+ XCAM_OBJ_PROFILING_DEFINES;
+};
+
+void
+MainPipeManager::post_buffer (const SmartPtr<VideoBuffer> &buf)
+{
+ FPS_CALCULATION (fps_buf, XCAM_OBJ_DUR_FRAME_NUM);
+
+ XCAM_OBJ_PROFILING_START;
+
+ if (_enable_display)
+ display_buf (buf);
+
+ XCAM_OBJ_PROFILING_END("main_pipe_manager_display", XCAM_OBJ_DUR_FRAME_NUM);
+}
+
+int
+MainPipeManager::display_buf (const SmartPtr<VideoBuffer> &data)
+{
+#if HAVE_LIBDRM
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ SmartPtr<VideoBuffer> buf = data;
+ const VideoBufferInfo & frame_info = buf->get_video_info ();
+ struct v4l2_rect rect = { 0, 0, frame_info.width, frame_info.height};
+
+ if (!_display->is_render_inited ()) {
+ ret = _display->render_init (0, 0, this->_image_width, this->_image_height,
+ frame_info.format, &rect);
+ CHECK (ret, "display failed on render_init");
+ }
+ ret = _display->render_setup_frame_buffer (buf);
+ CHECK (ret, "display failed on framebuf set");
+ ret = _display->render_buffer (buf);
+ CHECK (ret, "display failed on rendering");
+#else
+ XCAM_UNUSED (data);
+#endif
+
+ return 0;
+}
+
+XCamReturn
+read_buf (SmartPtr<VideoBuffer> &buf, FileFP &file)
+{
+ const VideoBufferInfo info = buf->get_video_info ();
+ VideoBufferPlanarInfo planar;
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+ uint8_t *memory = buf->map ();
+ for (uint32_t index = 0; index < info.components; index++) {
+ info.get_planar_info (planar, index);
+ uint32_t line_bytes = planar.width * planar.pixel_bytes;
+
+ for (uint32_t i = 0; i < planar.height; i++) {
+ if (fread (memory + info.offsets [index] + i * info.strides [index], 1, line_bytes, file.fp) != line_bytes) {
+ if (feof (file.fp)) {
+ fseek (file.fp, 0, SEEK_SET);
+ ret = XCAM_RETURN_BYPASS;
+ } else {
+ XCAM_LOG_ERROR ("read file failed, size doesn't match");
+ ret = XCAM_RETURN_ERROR_FILE;
+ }
+ goto done;
+ }
+ }
+ }
+done:
+ buf->unmap ();
+ return ret;
+}
+
+void pipe_stop_handler(int sig)
+{
+ XCAM_UNUSED (sig);
+ is_stop = true;
+}
+
+void print_help (const char *bin_name)
+{
+ printf ("Usage: %s [--format=NV12] [--width=1920] ...\n"
+ "\t --format specify output pixel format, default is NV12\n"
+ "\t --width specify input image width, default is 1920\n"
+ "\t --height specify input image height, default is 1080\n"
+ "\t --fake-input specify the path of image as fake source\n"
+ "\t --defog-mode specify defog mode\n"
+ "\t select from [disabled, retinex, dcp], default is [disabled]\n"
+ "\t --wavelet-mode specify wavelet denoise mode, default is disable\n"
+ "\t select from [0:disable, 1:Hat Y, 2:Hat UV, 3:Haar Y, 4:Haar UV, 5:Haar YUV, 6:Haar Bayes Shrink]\n"
+ "\t --3d-denoise specify 3D Denoise mode\n"
+ "\t select from [disabled, yuv, uv], default is [disabled]\n"
+ "\t --enable-wireframe enable wire frame\n"
+ "\t --enable-warp enable image warp\n"
+ "\t --display-mode display mode\n"
+ "\t select from [primary, overlay], default is [primary]\n"
+ "\t -p enable local display, need root privilege\n"
+ "\t -h help\n"
+ , bin_name);
+}
+
+int main (int argc, char *argv[])
+{
+ const char *bin_name = argv[0];
+
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ VideoBufferInfo buf_info;
+ SmartPtr<VideoBuffer> video_buf;
+ SmartPtr<SmartAnalyzer> smart_analyzer;
+ SmartPtr<CLPostImageProcessor> cl_post_processor;
+ SmartPtr<BufferPool> buf_pool;
+
+ uint32_t pixel_format = V4L2_PIX_FMT_NV12;
+ uint32_t image_width = 1920;
+ uint32_t image_height = 1080;
+ bool need_display = false;
+#if HAVE_LIBDRM
+ DrmDisplayMode display_mode = DRM_DISPLAY_MODE_PRIMARY;
+#endif
+ const char *input_path = NULL;
+ FileFP input_fp;
+
+ uint32_t defog_mode = 0;
+ CLWaveletBasis wavelet_mode = CL_WAVELET_DISABLED;
+ uint32_t wavelet_channel = CL_IMAGE_CHANNEL_UV;
+ bool wavelet_bayes_shrink = false;
+ uint32_t denoise_3d_mode = 0;
+ uint8_t denoise_3d_ref_count = 3;
+ bool enable_wireframe = false;
+ bool enable_image_warp = false;
+
+ int opt;
+ const char *short_opts = "ph";
+ const struct option long_opts [] = {
+ {"format", required_argument, NULL, 'F'},
+ {"width", required_argument, NULL, 'W'},
+ {"height", required_argument, NULL, 'H'},
+ {"fake-input", required_argument, NULL, 'A'},
+ {"defog-mode", required_argument, NULL, 'D'},
+ {"wavelet-mode", required_argument, NULL, 'V'},
+ {"3d-denoise", required_argument, NULL, 'N'},
+ {"enable-wireframe", no_argument, NULL, 'I'},
+ {"enable-warp", no_argument, NULL, 'S'},
+ {"display-mode", required_argument, NULL, 'P'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while ((opt = getopt_long (argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 'F': {
+ XCAM_ASSERT (optarg);
+ CHECK_EXP ((strlen (optarg) == 4), "invalid pixel format\n");
+ pixel_format = v4l2_fourcc ((unsigned) optarg[0],
+ (unsigned) optarg[1],
+ (unsigned) optarg[2],
+ (unsigned) optarg[3]);
+ break;
+ }
+ case 'W': {
+ XCAM_ASSERT (optarg);
+ image_width = atoi (optarg);
+ break;
+ }
+ case 'H': {
+ XCAM_ASSERT (optarg);
+ image_height = atoi (optarg);
+ break;
+ }
+ case 'A': {
+ XCAM_ASSERT (optarg);
+ XCAM_LOG_INFO ("use image %s as input source", optarg);
+ input_path = optarg;
+ break;
+ }
+ case 'D': {
+ XCAM_ASSERT (optarg);
+ if (!strcmp (optarg, "disabled"))
+ defog_mode = CLPostImageProcessor::DefogDisabled;
+ else if (!strcmp (optarg, "retinex"))
+ defog_mode = CLPostImageProcessor::DefogRetinex;
+ else if (!strcmp (optarg, "dcp"))
+ defog_mode = CLPostImageProcessor::DefogDarkChannelPrior;
+ else {
+ print_help (bin_name);
+ return -1;
+ }
+ break;
+ }
+ case 'V': {
+ XCAM_ASSERT (optarg);
+ if (atoi(optarg) < 0 || atoi(optarg) > 255) {
+ print_help (bin_name);
+ return -1;
+ }
+ if (atoi(optarg) == 1) {
+ wavelet_mode = CL_WAVELET_HAT;
+ wavelet_channel = CL_IMAGE_CHANNEL_Y;
+ } else if (atoi(optarg) == 2) {
+ wavelet_mode = CL_WAVELET_HAT;
+ wavelet_channel = CL_IMAGE_CHANNEL_UV;
+ } else if (atoi(optarg) == 3) {
+ wavelet_mode = CL_WAVELET_HAAR;
+ wavelet_channel = CL_IMAGE_CHANNEL_Y;
+ } else if (atoi(optarg) == 4) {
+ wavelet_mode = CL_WAVELET_HAAR;
+ wavelet_channel = CL_IMAGE_CHANNEL_UV;
+ } else if (atoi(optarg) == 5) {
+ wavelet_mode = CL_WAVELET_HAAR;
+ wavelet_channel = CL_IMAGE_CHANNEL_UV | CL_IMAGE_CHANNEL_Y;
+ } else if (atoi(optarg) == 6) {
+ wavelet_mode = CL_WAVELET_HAAR;
+ wavelet_channel = CL_IMAGE_CHANNEL_UV | CL_IMAGE_CHANNEL_Y;
+ wavelet_bayes_shrink = true;
+ } else {
+ wavelet_mode = CL_WAVELET_DISABLED;
+ }
+ break;
+ }
+ case 'N': {
+ XCAM_ASSERT (optarg);
+ if (!strcmp (optarg, "disabled"))
+ denoise_3d_mode = CLPostImageProcessor::Denoise3DDisabled;
+ else if (!strcmp (optarg, "yuv"))
+ denoise_3d_mode = CLPostImageProcessor::Denoise3DYuv;
+ else if (!strcmp (optarg, "uv"))
+ denoise_3d_mode = CLPostImageProcessor::Denoise3DUV;
+ else {
+ print_help (bin_name);
+ return -1;
+ }
+ break;
+ }
+ case 'I': {
+ enable_wireframe = true;
+ break;
+ }
+ case 'S': {
+ enable_image_warp = true;
+ break;
+ }
+ case 'P': {
+#if HAVE_LIBDRM
+ XCAM_ASSERT (optarg);
+ if (!strcmp (optarg, "primary"))
+ display_mode = DRM_DISPLAY_MODE_PRIMARY;
+ else if (!strcmp (optarg, "overlay"))
+ display_mode = DRM_DISPLAY_MODE_OVERLAY;
+ else {
+ print_help (bin_name);
+ return -1;
+ }
+#else
+ XCAM_LOG_WARNING ("preview is not supported");
+#endif
+ break;
+ }
+ case 'p': {
+#if HAVE_LIBDRM
+ need_display = true;
+#else
+ XCAM_LOG_WARNING ("preview is not supported, disable preview now");
+ need_display = false;
+#endif
+ break;
+ }
+ case 'h':
+ print_help (bin_name);
+ return 0;
+ default:
+ print_help (bin_name);
+ return -1;
+ }
+ }
+
+ signal (SIGINT, pipe_stop_handler);
+
+ if (!input_path) {
+ XCAM_LOG_ERROR ("path of image is NULL");
+ return -1;
+ }
+ input_fp.fp = fopen (input_path, "rb");
+ if (!input_fp.fp) {
+ XCAM_LOG_ERROR ("failed to open file: %s", XCAM_STR (input_path));
+ return -1;
+ }
+
+ SmartPtr<MainPipeManager> pipe_manager = new MainPipeManager ();
+ pipe_manager->set_image_width (image_width);
+ pipe_manager->set_image_height (image_height);
+
+ SmartHandlerList smart_handlers = SmartAnalyzerLoader::load_smart_handlers (DEFAULT_SMART_ANALYSIS_LIB_DIR);
+ if (!smart_handlers.empty () ) {
+ smart_analyzer = new SmartAnalyzer ();
+ if (smart_analyzer.ptr ()) {
+ SmartHandlerList::iterator i_handler = smart_handlers.begin ();
+ for (; i_handler != smart_handlers.end (); ++i_handler) {
+ XCAM_ASSERT ((*i_handler).ptr ());
+ smart_analyzer->add_handler (*i_handler);
+ }
+ } else {
+ XCAM_LOG_INFO ("load smart analyzer(%s) failed", DEFAULT_SMART_ANALYSIS_LIB_DIR);
+ }
+ }
+ if (smart_analyzer.ptr ()) {
+ if (smart_analyzer->prepare_handlers () != XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_WARNING ("analyzer(%s) prepare handlers failed", smart_analyzer->get_name ());
+ }
+ pipe_manager->set_smart_analyzer (smart_analyzer);
+ }
+
+ cl_post_processor = new CLPostImageProcessor ();
+ cl_post_processor->set_stats_callback (pipe_manager);
+ cl_post_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode) defog_mode);
+ cl_post_processor->set_wavelet (wavelet_mode, wavelet_channel, wavelet_bayes_shrink);
+ cl_post_processor->set_3ddenoise_mode ((CLPostImageProcessor::CL3DDenoiseMode) denoise_3d_mode, denoise_3d_ref_count);
+
+ cl_post_processor->set_wireframe (enable_wireframe);
+ cl_post_processor->set_image_warp (enable_image_warp);
+ if (smart_analyzer.ptr () && (enable_wireframe || enable_image_warp)) {
+ cl_post_processor->set_scaler (true);
+ cl_post_processor->set_scaler_factor (640.0 / image_width);
+ }
+
+ pipe_manager->add_image_processor (cl_post_processor);
+
+ buf_info.init (pixel_format, image_width, image_height);
+ buf_pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (buf_pool.ptr ());
+ if (!buf_pool->set_video_info (buf_info) || !buf_pool->reserve (DEFAULT_FPT_BUF_COUNT)) {
+ XCAM_LOG_ERROR ("init buffer pool failed");
+ return -1;
+ }
+
+ if (need_display) {
+ need_display = false;
+ XCAM_LOG_WARNING ("CLVideoBuffer doesn't support local preview, disable local preview now");
+ }
+
+ if (need_display) {
+#if HAVE_LIBDRM
+ if (DrmDisplay::set_preview (need_display)) {
+ pipe_manager->set_display_mode (display_mode);
+ cl_post_processor->set_output_format (V4L2_PIX_FMT_XBGR32);
+ } else {
+ need_display = false;
+ XCAM_LOG_WARNING ("set preview failed, disable local preview now");
+ }
+#else
+ XCAM_LOG_WARNING ("preview is not supported, disable preview now");
+ need_display = false;
+#endif
+ }
+ pipe_manager->enable_display (need_display);
+
+ ret = pipe_manager->start ();
+ CHECK (ret, "pipe manager start failed");
+
+ while (!is_stop) {
+ video_buf = buf_pool->get_buffer (buf_pool);
+ XCAM_ASSERT (video_buf.ptr ());
+
+ ret = read_buf (video_buf, input_fp);
+ if (ret == XCAM_RETURN_BYPASS) {
+ ret = read_buf (video_buf, input_fp);
+ }
+
+ if (ret == XCAM_RETURN_NO_ERROR)
+ pipe_manager->push_buffer (video_buf);
+ }
+
+ ret = pipe_manager->stop();
+ CHECK (ret, "pipe manager stop failed");
+
+ return 0;
+}