/* * main.cpp - test * * Copyright (c) 2014 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: Wind Yuan <feng.yuan@intel.com> * Author: Yinhang Liu <yinhangx.liu@intel.com> * Author: Wei Zong <wei.zong@intel.com> */ #include "device_manager.h" #include "uvc_device.h" #include "fake_v4l2_device.h" #include "x3a_analyzer_simple.h" #include "analyzer_loader.h" #include "smart_analyzer_loader.h" #if HAVE_IA_AIQ #include "isp/atomisp_device.h" #include "isp/isp_controller.h" #include "isp/isp_image_processor.h" #include "isp/isp_poll_thread.h" #include "isp/x3a_analyzer_aiq.h" #include "x3a_analyze_tuner.h" #include "dynamic_analyzer_loader.h" #include "isp/hybrid_analyzer_loader.h" #endif #if HAVE_LIBCL #include "ocl/cl_3a_image_processor.h" #include "ocl/cl_post_image_processor.h" #include "ocl/cl_csc_image_processor.h" #include "ocl/cl_tnr_handler.h" #endif #if HAVE_LIBDRM #include "drm_display.h" #endif #include "fake_poll_thread.h" #include "image_file_handle.h" #include <base/xcam_3a_types.h> #include <unistd.h> #include <signal.h> #include <stdlib.h> #include <string> #include <getopt.h> #include "test_common.h" using namespace XCam; #define IMX185_WDR_CPF "/etc/atomisp/imx185_wdr.cpf" static Mutex g_mutex; static Cond g_cond; static bool g_stop = false; class MainDeviceManager : public DeviceManager { public: MainDeviceManager () : _save_file (false) , _interval (1) , _frame_width (0) , _frame_height (0) , _frame_count (0) , _frame_save (0) , _enable_display (false) { #if HAVE_LIBDRM _display = DrmDisplay::instance (); #endif XCAM_OBJ_PROFILING_INIT; } ~MainDeviceManager () { _file_handle.close (); } void enable_save_file (bool enable) { _save_file = enable; } void set_interval (uint32_t inteval) { _interval = inteval; } void set_frame_width (uint32_t frame_width) { _frame_width = frame_width; } void set_frame_height (uint32_t frame_height) { _frame_height = frame_height; } void set_frame_save (uint32_t frame_save) { _frame_save = frame_save; } 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 handle_message (const SmartPtr<XCamMessage> &msg); virtual void handle_buffer (const SmartPtr<VideoBuffer> &buf); int display_buf (const SmartPtr<VideoBuffer> &buf); private: void open_file (); private: bool _save_file; uint32_t _interval; uint32_t _frame_width; uint32_t _frame_height; uint32_t _frame_count; uint32_t _frame_save; bool _enable_display; ImageFileHandle _file_handle; #if HAVE_LIBDRM SmartPtr<DrmDisplay> _display; #endif XCAM_OBJ_PROFILING_DEFINES; }; void MainDeviceManager::handle_message (const SmartPtr<XCamMessage> &msg) { XCAM_UNUSED (msg); } void MainDeviceManager::handle_buffer (const SmartPtr<VideoBuffer> &buf) { if (!buf.ptr ()) { XCAM_LOG_WARNING ("video buffer is null, handle buffer failed."); return; } FPS_CALCULATION (fps_buf, 30); XCAM_OBJ_PROFILING_START; if (_enable_display) display_buf (buf); XCAM_OBJ_PROFILING_END("main_dev_manager_display", XCAM_OBJ_DUR_FRAME_NUM); if (!_save_file) return ; if ((_frame_count++ % _interval) != 0) return; if ((_frame_save != 0) && (_frame_count > _frame_save)) { SmartLock locker (g_mutex); g_stop = true; g_cond.broadcast (); return; } open_file (); if (!_file_handle.is_valid ()) { XCAM_LOG_ERROR ("open file failed"); return; } _file_handle.write_buf (buf); } int MainDeviceManager::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->_frame_width, this->_frame_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; } void MainDeviceManager::open_file () { if (_file_handle.is_valid () && (_frame_save == 0)) return; std::string file_name = DEFAULT_SAVE_FILE_NAME; if (_frame_save != 0) { file_name += std::to_string(_frame_count); } file_name += ".raw"; if (_file_handle.open (file_name.c_str (), "wb") != XCAM_RETURN_NO_ERROR) { XCAM_LOG_WARNING ("create file(%s) failed", file_name.c_str ()); } } #define V4L2_CAPTURE_MODE_STILL 0x2000 #define V4L2_CAPTURE_MODE_VIDEO 0x4000 #define V4L2_CAPTURE_MODE_PREVIEW 0x8000 typedef enum { AnalyzerTypeSimple = 0, AnalyzerTypeAiqTuner, AnalyzerTypeDynamic, AnalyzerTypeHybrid, } AnalyzerType; void dev_stop_handler(int sig) { XCAM_UNUSED (sig); SmartLock locker (g_mutex); g_stop = true; g_cond.broadcast (); //exit(0); } void print_help (const char *bin_name) { printf ("Usage: %s [-a analyzer]\n" "Configurations:\n" "\t -a analyzer specify a analyzer\n" "\t select from [simple" #if HAVE_IA_AIQ ", aiq" #if HAVE_LIBCL ", dynamic, hybrid" #endif #endif "], default is [simple]\n" "\t -m mem_type specify video memory type\n" "\t mem_type select from [dma, mmap], default is [mmap]\n" "\t -s save file to %s\n" "\t -n interval save file on every [interval] frame\n" "\t -f pixel_fmt specify output pixel format\n" "\t pixel_fmt select from [NV12, YUYV, BA10, BA12], default is [NV12]\n" "\t -W image_width specify image width, default is [1920]\n" "\t -H image_height specify image height, default is [1080]\n" "\t -d cap_mode specify capture mode\n" "\t cap_mode select from [video, still], default is [video]\n" "\t -i frame_save specify the frame count to save, default is 0 which means endless\n" "\t -p preview on enable local display, need root privilege\n" "\t --usb specify node for usb camera device, enables capture path through USB camera \n" "\t specify [/dev/video4, /dev/video5] depending on which node USB camera is attached\n" "\t -e display_mode preview mode\n" "\t select from [primary, overlay], default is [primary]\n" "\t --sync set analyzer in sync mode\n" "\t -r raw_input specify the path of raw image as fake source instead of live camera\n" "\t -h help\n" #if HAVE_LIBCL "CL features:\n" "\t -c process image with cl kernel\n" #if HAVE_IA_AIQ "\t -b brightness specify brightness level\n" "\t brightness level select from [0, 256], default is [128]\n" #endif "\t --capture specify the capture stage of image\n" "\t capture_stage select from [bayer, tonemapping], default is [tonemapping]\n" "\t --tnr specify temporal noise reduction type, default is tnr off\n" "\t only support [yuv]\n" "\t --tnr-level specify tnr level\n" "\t --wdr-mode specify wdr mode. select from [gaussian, haleq]\n" "\t --enable-bnr enable bayer noise reduction\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 off\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 --pipeline specify pipe mode\n" "\t select from [basic, advance, extreme], default is [basic]\n" "\t --disable-post disable cl post image processor\n" #endif , bin_name , DEFAULT_SAVE_FILE_NAME); } int main (int argc, char *argv[]) { XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr<V4l2Device> device; #if HAVE_IA_AIQ SmartPtr<V4l2SubDevice> event_device; SmartPtr<IspController> isp_controller; SmartPtr<ImageProcessor> isp_processor; #endif SmartPtr<X3aAnalyzer> analyzer; SmartPtr<AnalyzerLoader> loader; AnalyzerType analyzer_type = AnalyzerTypeSimple; #if HAVE_LIBCL bool have_cl_processor = false; SmartPtr<SmartAnalyzer> smart_analyzer; bool have_cl_post_processor = true; SmartPtr<CL3aImageProcessor> cl_processor; SmartPtr<CLPostImageProcessor> cl_post_processor; uint32_t tnr_type = CL_TNR_DISABLE; uint32_t denoise_type = 0; uint8_t tnr_level = 0; CL3aImageProcessor::PipelineProfile pipeline_mode = CL3aImageProcessor::BasicPipelineProfile; CL3aImageProcessor::CaptureStage capture_stage = CL3aImageProcessor::TonemappingStage; CL3aImageProcessor::CLTonemappingMode wdr_mode = CL3aImageProcessor::WDRdisabled; #if HAVE_IA_AIQ int32_t brightness_level = 128; #endif uint32_t defog_type = 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 wireframe_type = false; bool image_warp_type = false; #endif bool need_display = false; #if HAVE_LIBDRM DrmDisplayMode display_mode = DRM_DISPLAY_MODE_PRIMARY; #endif enum v4l2_memory v4l2_mem_type = V4L2_MEMORY_MMAP; const char *bin_name = argv[0]; uint32_t capture_mode = V4L2_CAPTURE_MODE_VIDEO; uint32_t pixel_format = V4L2_PIX_FMT_NV12; bool have_usbcam = 0; std::string usb_device_name; bool sync_mode = false; bool save_file = false; uint32_t interval_frames = 1; uint32_t save_frames = 0; uint32_t frame_rate; uint32_t frame_width = 1920; uint32_t frame_height = 1080; std::string path_to_fake; int opt; const char *short_opts = "sca:n:m:f:W:H:d:b:pi:e:r:h"; const struct option long_opts[] = { {"tnr", required_argument, NULL, 'T'}, {"tnr-level", required_argument, NULL, 'L'}, {"wdr-mode", required_argument, NULL, 'w'}, {"enable-bnr", no_argument, NULL, 'B'}, {"defog-mode", required_argument, NULL, 'X'}, {"wavelet-mode", required_argument, NULL, 'V'}, {"3d-denoise", required_argument, NULL, 'N'}, {"enable-wireframe", no_argument, NULL, 'F'}, {"enable-warp", no_argument, NULL, 'A'}, {"usb", required_argument, NULL, 'U'}, {"sync", no_argument, NULL, 'Y'}, {"capture", required_argument, NULL, 'C'}, {"pipeline", required_argument, NULL, 'P'}, {"disable-post", no_argument, NULL, 'O'}, {0, 0, 0, 0}, }; while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch (opt) { case 'a': { XCAM_ASSERT (optarg); if (!strcmp (optarg, "simple")) analyzer_type = AnalyzerTypeSimple; #if HAVE_IA_AIQ else if (!strcmp (optarg, "aiq")) analyzer_type = AnalyzerTypeAiqTuner; #if HAVE_LIBCL else if (!strcmp (optarg, "dynamic")) analyzer_type = AnalyzerTypeDynamic; else if (!strcmp (optarg, "hybrid")) analyzer_type = AnalyzerTypeHybrid; #endif #endif else { print_help (bin_name); return -1; } break; } case 'm': { XCAM_ASSERT (optarg); if (!strcmp (optarg, "dma")) v4l2_mem_type = V4L2_MEMORY_DMABUF; else if (!strcmp (optarg, "mmap")) v4l2_mem_type = V4L2_MEMORY_MMAP; else print_help (bin_name); break; } case 's': save_file = true; break; case 'n': XCAM_ASSERT (optarg); interval_frames = atoi(optarg); break; case 'i': XCAM_ASSERT (optarg); save_frames = atoi(optarg); break; 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 'd': XCAM_ASSERT (optarg); if (!strcmp (optarg, "still")) capture_mode = V4L2_CAPTURE_MODE_STILL; else if (!strcmp (optarg, "video")) capture_mode = V4L2_CAPTURE_MODE_VIDEO; else { print_help (bin_name); return -1; } break; case 'U': XCAM_ASSERT (optarg); have_usbcam = true; usb_device_name = optarg; XCAM_LOG_DEBUG("using USB camera plugged in at node: %s", XCAM_STR(usb_device_name.c_str())); break; case 'W': XCAM_ASSERT (optarg); frame_width = atoi(optarg); break; case 'H': XCAM_ASSERT (optarg); frame_height = atoi(optarg); break; case 'e': { #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 'Y': sync_mode = true; break; #if HAVE_LIBCL case 'c': have_cl_processor = true; break; #if HAVE_IA_AIQ case 'b': XCAM_ASSERT (optarg); brightness_level = atoi(optarg); if(brightness_level < 0 || brightness_level > 256) { print_help (bin_name); return -1; } break; #endif case 'B': { denoise_type |= XCAM_DENOISE_TYPE_BNR; break; } case 'X': { XCAM_ASSERT (optarg); defog_type = true; if (!strcmp (optarg, "disabled")) defog_type = CLPostImageProcessor::DefogDisabled; else if (!strcmp (optarg, "retinex")) defog_type = CLPostImageProcessor::DefogRetinex; else if (!strcmp (optarg, "dcp")) defog_type = 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); denoise_3d_mode = true; 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 'F': { wireframe_type = true; break; } case 'A': { image_warp_type = true; break; } case 'T': { XCAM_ASSERT (optarg); if (!strcasecmp (optarg, "yuv")) tnr_type = CL_TNR_TYPE_YUV; else { printf ("--tnr only support <yuv>, <%s> is not supported\n", optarg); print_help (bin_name); return -1; } break; } case 'L': { XCAM_ASSERT (optarg); if (atoi(optarg) < 0 || atoi(optarg) > 255) { print_help (bin_name); return -1; } tnr_level = atoi(optarg); break; } case 'w': { XCAM_ASSERT (optarg); if (!strcasecmp (optarg, "gaussian")) wdr_mode = CL3aImageProcessor::Gaussian; else if (!strcasecmp (optarg, "haleq")) wdr_mode = CL3aImageProcessor::Haleq; pixel_format = V4L2_PIX_FMT_SGRBG12; setenv ("AIQ_CPF_PATH", IMX185_WDR_CPF, 1); break; } case 'P': { XCAM_ASSERT (optarg); if (!strcasecmp (optarg, "basic")) pipeline_mode = CL3aImageProcessor::BasicPipelineProfile; else if (!strcasecmp (optarg, "advance")) pipeline_mode = CL3aImageProcessor::AdvancedPipelineProfile; else if (!strcasecmp (optarg, "extreme")) pipeline_mode = CL3aImageProcessor::ExtremePipelineProfile; else { print_help (bin_name); return -1; } break; } case 'C': { XCAM_ASSERT (optarg); if (!strcmp (optarg, "bayer")) capture_stage = CL3aImageProcessor::BasicbayerStage; break; } case 'O': { have_cl_post_processor = false; break; } #endif case 'r': { XCAM_ASSERT (optarg); XCAM_LOG_INFO ("use raw image %s as input source", optarg); path_to_fake = optarg; 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; } } SmartPtr<MainDeviceManager> device_manager = new MainDeviceManager (); device_manager->enable_save_file (save_file); device_manager->set_interval (interval_frames); device_manager->set_frame_save (save_frames); device_manager->set_frame_width (frame_width); device_manager->set_frame_height (frame_height); if (!device.ptr ()) { if (path_to_fake.c_str ()) { device = new FakeV4l2Device (); } else if (have_usbcam) { device = new UVCDevice (usb_device_name.c_str ()); } #if HAVE_IA_AIQ else { if (capture_mode == V4L2_CAPTURE_MODE_STILL) device = new AtomispDevice (CAPTURE_DEVICE_STILL); else if (capture_mode == V4L2_CAPTURE_MODE_VIDEO) device = new AtomispDevice (CAPTURE_DEVICE_VIDEO); else device = new AtomispDevice (DEFAULT_CAPTURE_DEVICE); } #endif } #if HAVE_IA_AIQ if (!isp_controller.ptr ()) isp_controller = new IspController (device); #endif switch (analyzer_type) { case AnalyzerTypeSimple: analyzer = new X3aAnalyzerSimple (); break; #if HAVE_IA_AIQ case AnalyzerTypeAiqTuner: { SmartPtr<X3aAnalyzer> aiq_analyzer = new X3aAnalyzerAiq (isp_controller, DEFAULT_CPF_FILE); SmartPtr<X3aAnalyzeTuner> tuner_analyzer = new X3aAnalyzeTuner (); XCAM_ASSERT (aiq_analyzer.ptr () && tuner_analyzer.ptr ()); tuner_analyzer->set_analyzer (aiq_analyzer); analyzer = tuner_analyzer; break; } #if HAVE_LIBCL case AnalyzerTypeDynamic: { const char *path_of_3a = DEFAULT_DYNAMIC_3A_LIB; SmartPtr<DynamicAnalyzerLoader> dynamic_loader = new DynamicAnalyzerLoader (path_of_3a); loader = dynamic_loader.dynamic_cast_ptr<AnalyzerLoader> (); analyzer = dynamic_loader->load_analyzer (loader); CHECK_EXP (analyzer.ptr (), "load dynamic 3a lib(%s) failed", path_of_3a); break; } case AnalyzerTypeHybrid: { const char *path_of_3a = DEFAULT_HYBRID_3A_LIB; SmartPtr<HybridAnalyzerLoader> hybrid_loader = new HybridAnalyzerLoader (path_of_3a); hybrid_loader->set_cpf_path (DEFAULT_CPF_FILE); hybrid_loader->set_isp_controller (isp_controller); loader = hybrid_loader.dynamic_cast_ptr<AnalyzerLoader> (); analyzer = hybrid_loader->load_analyzer (loader); CHECK_EXP (analyzer.ptr (), "load hybrid 3a lib(%s) failed", path_of_3a); break; } #endif #endif default: print_help (bin_name); return -1; } XCAM_ASSERT (analyzer.ptr ()); analyzer->set_sync_mode (sync_mode); #if HAVE_LIBCL 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_WARNING ("load smart analyzer(%s) failed, please check.", 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 ()); } device_manager->set_smart_analyzer (smart_analyzer); } #endif signal(SIGINT, dev_stop_handler); device->set_sensor_id (0); device->set_capture_mode (capture_mode); //device->set_mem_type (V4L2_MEMORY_DMABUF); device->set_mem_type (v4l2_mem_type); device->set_buffer_count (8); if (pixel_format == V4L2_PIX_FMT_SGRBG12) { frame_rate = 30; device->set_framerate (frame_rate, 1); } #if HAVE_LIBCL else { frame_rate = 25; device->set_framerate (frame_rate, 1); if(wdr_mode != CL3aImageProcessor::WDRdisabled) { XCAM_LOG_WARNING("Tonemapping is only applicable under BA12 format. Disable tonemapping automatically."); wdr_mode = CL3aImageProcessor::WDRdisabled; } } #endif ret = device->open (); CHECK (ret, "device(%s) open failed", device->get_device_name()); ret = device->set_format (frame_width, frame_height, pixel_format, V4L2_FIELD_NONE, frame_width * 2); CHECK (ret, "device(%s) set format failed", device->get_device_name()); #if HAVE_IA_AIQ if (!event_device.ptr ()) event_device = new V4l2SubDevice (DEFAULT_EVENT_DEVICE); ret = event_device->open (); if (ret == XCAM_RETURN_NO_ERROR) { CHECK (ret, "event device(%s) open failed", event_device->get_device_name()); int event = V4L2_EVENT_ATOMISP_3A_STATS_READY; ret = event_device->subscribe_event (event); CHECK_CONTINUE ( ret, "device(%s) subscribe event(%d) failed", event_device->get_device_name(), event); event = V4L2_EVENT_FRAME_SYNC; ret = event_device->subscribe_event (event); CHECK_CONTINUE ( ret, "device(%s) subscribe event(%d) failed", event_device->get_device_name(), event); device_manager->set_event_device (event_device); } #endif device_manager->set_capture_device (device); if (analyzer.ptr()) device_manager->set_3a_analyzer (analyzer); #if HAVE_IA_AIQ #if HAVE_LIBCL if (have_cl_processor) isp_processor = new IspExposureImageProcessor (isp_controller); else #endif isp_processor = new IspImageProcessor (isp_controller); XCAM_ASSERT (isp_processor.ptr ()); device_manager->add_image_processor (isp_processor); #endif #if HAVE_LIBCL if (have_cl_processor) { cl_processor = new CL3aImageProcessor (); cl_processor->set_stats_callback(device_manager); cl_processor->set_denoise (denoise_type); cl_processor->set_capture_stage (capture_stage); cl_processor->set_tonemapping (wdr_mode); if (wdr_mode != CL3aImageProcessor::WDRdisabled) { cl_processor->set_gamma (false); cl_processor->set_3a_stats_bits (12); } cl_processor->set_tnr (tnr_type, tnr_level); cl_processor->set_profile (pipeline_mode); #if HAVE_IA_AIQ analyzer->set_parameter_brightness((brightness_level - 128) / 128.0); #endif device_manager->add_image_processor (cl_processor); } if (have_cl_post_processor) { cl_post_processor = new CLPostImageProcessor (); cl_post_processor->set_stats_callback (device_manager); cl_post_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode)defog_type); 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 (wireframe_type); cl_post_processor->set_image_warp (image_warp_type); if (smart_analyzer.ptr () && (wireframe_type || image_warp_type)) { cl_post_processor->set_scaler (true); cl_post_processor->set_scaler_factor (640.0 / frame_width); } 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)) { device_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 } device_manager->enable_display (need_display); device_manager->add_image_processor (cl_post_processor); } #endif SmartPtr<PollThread> poll_thread; if (have_usbcam) { poll_thread = new PollThread (); } else if (path_to_fake.c_str ()) { poll_thread = new FakePollThread (path_to_fake.c_str ()); } #if HAVE_IA_AIQ else { SmartPtr<IspPollThread> isp_poll_thread = new IspPollThread (); isp_poll_thread->set_isp_controller (isp_controller); poll_thread = isp_poll_thread; } #endif device_manager->set_poll_thread (poll_thread); ret = device_manager->start (); CHECK (ret, "device manager start failed"); #if HAVE_LIBCL // hard code exposure range and max gain for imx185 WDR if (wdr_mode != CL3aImageProcessor::WDRdisabled) { if (frame_rate == 30) analyzer->set_ae_exposure_time_range (80 * 1110 * 1000 / 37125, 1120 * 1110 * 1000 / 37125); else analyzer->set_ae_exposure_time_range (80 * 1320 * 1000 / 37125, 1120 * 1320 * 1000 / 37125); analyzer->set_ae_max_analog_gain (3.98); // 12dB } #endif // wait for interruption { SmartLock locker (g_mutex); while (!g_stop) g_cond.wait (g_mutex); } ret = device_manager->stop(); CHECK_CONTINUE (ret, "device manager stop failed"); device->close (); #if HAVE_IA_AIQ event_device->close (); #endif return 0; }