diff options
Diffstat (limited to 'tests/test-pipe-manager.cpp')
-rw-r--r-- | tests/test-pipe-manager.cpp | 467 |
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; +} |