void PendingChecks::blockOnCheck(const boost::function<bool ()> &check, bool checkFirst) { DynMutex::Guard guard = m_mutex.lock(); // When we get here, the conditions for returning may already have // been met. Check before sleeping. If we need to continue, then // holding the mutex ensures that the main thread will run the // check on the next iteration. if (!checkFirst || check()) { m_checks.insert(&check); if (!checkFirst) { // Must wake up the main thread from its g_main_context_iteration. g_main_context_wakeup(g_main_context_default()); } do { m_cond.wait(m_mutex); } while (m_checks.find(&check) != m_checks.end()); } }
int main (int argc, char *argv[]) { XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr<MainDeviceManager> device_manager = new MainDeviceManager; SmartPtr<V4l2Device> device; SmartPtr<V4l2SubDevice> event_device; SmartPtr<IspController> isp_controller; SmartPtr<X3aAnalyzer> analyzer; SmartPtr<X3aAnalyzerLoader> loader; const char *path_of_3a; SmartPtr<ImageProcessor> isp_processor; #if HAVE_LIBCL SmartPtr<CLCscImageProcessor> cl_csc_proccessor; #endif AnalyzerType analyzer_type = AnalyzerTypeSimple; DrmDisplayMode display_mode = DRM_DISPLAY_MODE_PRIMARY; #if HAVE_LIBDRM SmartPtr<DrmDisplay> drm_disp = DrmDisplay::instance(); #endif #if HAVE_LIBCL SmartPtr<CL3aImageProcessor> cl_processor; uint32_t hdr_type = CL_HDR_DISABLE; uint32_t tnr_type = CL_TNR_DISABLE; uint32_t denoise_type = 0; uint8_t tnr_level = 0; bool dpc_type = false; CL3aImageProcessor::PipelineProfile pipeline_mode = CL3aImageProcessor::BasicPipelineProfile; CL3aImageProcessor::CaptureStage capture_stage = CL3aImageProcessor::TonemappingStage; #endif bool have_cl_processor = false; bool need_display = false; enum v4l2_memory v4l2_mem_type = V4L2_MEMORY_MMAP; const char *bin_name = argv[0]; int opt; uint32_t capture_mode = V4L2_CAPTURE_MODE_VIDEO; uint32_t pixel_format = V4L2_PIX_FMT_NV12; bool tonemapping_type = false; int32_t brightness_level = 128; bool have_usbcam = 0; char* usb_device_name = NULL; bool sync_mode = false; int frame_rate; const char *short_opts = "sca:n:m:f:d:b:pi:e:h"; const struct option long_opts[] = { {"hdr", required_argument, NULL, 'H'}, {"tnr", required_argument, NULL, 'T'}, {"tnr-level", required_argument, NULL, 'L'}, {"bilateral", no_argument, NULL, 'I'}, {"enable-snr", no_argument, NULL, 'S'}, {"enable-ee", no_argument, NULL, 'E'}, {"enable-bnr", no_argument, NULL, 'B'}, {"enable-dpc", no_argument, NULL, 'D'}, {"enable-tonemapping", no_argument, NULL, 'M'}, {"usb", required_argument, NULL, 'U'}, {"sync", no_argument, NULL, 'Y'}, {"capture", required_argument, NULL, 'C'}, {"pipeline", required_argument, NULL, 'P'}, {0, 0, 0, 0}, }; while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch (opt) { case 'a': { if (!strcmp (optarg, "dynamic")) analyzer_type = AnalyzerTypeDynamic; else if (!strcmp (optarg, "simple")) analyzer_type = AnalyzerTypeSimple; #if HAVE_IA_AIQ else if (!strcmp (optarg, "aiq")) analyzer_type = AnalyzerTypeAiq; else if (!strcmp (optarg, "hybrid")) analyzer_type = AnalyzerTypeHybrid; #endif else { print_help (bin_name); return -1; } break; } case 'm': { 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': device_manager->enable_save_file (true); break; case 'n': device_manager->set_interval (atoi(optarg)); break; #if HAVE_LIBCL case 'c': have_cl_processor = true; break; #endif case 'f': 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': 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 'b': brightness_level = atoi(optarg); if(brightness_level < 0 || brightness_level > 256) { print_help (bin_name); return -1; } break; case 'p': need_display = true; break; case 'U': have_usbcam = true; usb_device_name = strdup(optarg); XCAM_LOG_DEBUG("using USB camera plugged in at node: %s", usb_device_name); break; case 'e': { 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; } break; } case 'i': device_manager->set_frame_save(atoi(optarg)); break; case 'Y': sync_mode = true; break; #if HAVE_LIBCL case 'H': { if (!strcasecmp (optarg, "rgb")) hdr_type = CL_HDR_TYPE_RGB; else if (!strcasecmp (optarg, "lab")) hdr_type = CL_HDR_TYPE_LAB; else { print_help (bin_name); return -1; } break; } case 'I': { denoise_type |= XCAM_DENOISE_TYPE_BILATERAL; denoise_type |= XCAM_DENOISE_TYPE_BIYUV; break; } case 'S': { denoise_type |= XCAM_DENOISE_TYPE_SIMPLE; break; } case 'E': { denoise_type |= XCAM_DENOISE_TYPE_EE; break; } case 'B': { denoise_type |= XCAM_DENOISE_TYPE_BNR; break; } case 'D': { dpc_type = true; break; } case 'T': { if (!strcasecmp (optarg, "yuv")) tnr_type = CL_TNR_TYPE_YUV; else if (!strcasecmp (optarg, "rgb")) tnr_type = CL_TNR_TYPE_RGB; else if (!strcasecmp (optarg, "both")) tnr_type = CL_TNR_TYPE_YUV | CL_TNR_TYPE_RGB; else { print_help (bin_name); return -1; } break; } case 'L': { if (atoi(optarg) < 0 || atoi(optarg) > 255) { print_help (bin_name); return -1; } tnr_level = atoi(optarg); break; } case 'M': { tonemapping_type = true; break; } case 'P': { 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': { if (!strcmp (optarg, "bayer")) capture_stage = CL3aImageProcessor::BasicbayerStage; break; } #endif case 'h': print_help (bin_name); return 0; default: print_help (bin_name); return -1; } } if (need_display) { device_manager->enable_display (true); device_manager->set_display_mode (display_mode); } if (!device.ptr ()) { if (have_usbcam) { device = new UVCDevice (usb_device_name); } 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); } } if (!event_device.ptr ()) event_device = new V4l2SubDevice (DEFAULT_EVENT_DEVICE); if (!isp_controller.ptr ()) isp_controller = new IspController (device); switch (analyzer_type) { case AnalyzerTypeSimple: analyzer = new X3aAnalyzerSimple (); break; #if HAVE_IA_AIQ case AnalyzerTypeAiq: analyzer = new X3aAnalyzerAiq (isp_controller, DEFAULT_CPF_FILE); break; case AnalyzerTypeHybrid: { path_of_3a = DEFAULT_HYBRID_3A_LIB; loader = new X3aAnalyzerLoader (path_of_3a); analyzer = loader->load_hybrid_analyzer (loader, isp_controller, DEFAULT_CPF_FILE); CHECK_EXP (analyzer.ptr (), "load hybrid 3a lib(%s) failed", path_of_3a); break; } #endif case AnalyzerTypeDynamic: { path_of_3a = DEFAULT_DYNAMIC_3A_LIB; loader = new X3aAnalyzerLoader (path_of_3a); analyzer = loader->load_dynamic_analyzer (loader); CHECK_EXP (analyzer.ptr (), "load dynamic 3a lib(%s) failed", path_of_3a); break; } default: print_help (bin_name); return -1; } XCAM_ASSERT (analyzer.ptr ()); analyzer->set_sync_mode (sync_mode); 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); } else { frame_rate = 25; device->set_framerate (frame_rate, 1); } ret = device->open (); CHECK (ret, "device(%s) open failed", device->get_device_name()); ret = device->set_format (1920, 1080, pixel_format, V4L2_FIELD_NONE, 1920 * 2); CHECK (ret, "device(%s) set format failed", device->get_device_name()); 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); } device_manager->set_capture_device (device); device_manager->set_isp_controller (isp_controller); if (analyzer.ptr()) device_manager->set_3a_analyzer (analyzer); if (have_cl_processor) isp_processor = new IspExposureImageProcessor (isp_controller); else isp_processor = new IspImageProcessor (isp_controller); XCAM_ASSERT (isp_processor.ptr ()); device_manager->add_image_processor (isp_processor); #if HAVE_LIBCL if ((display_mode == DRM_DISPLAY_MODE_PRIMARY) && need_display && (!have_cl_processor)) { cl_csc_proccessor = new CLCscImageProcessor(); XCAM_ASSERT (cl_csc_proccessor.ptr ()); device_manager->add_image_processor (cl_csc_proccessor); } if (have_cl_processor) { cl_processor = new CL3aImageProcessor (); cl_processor->set_stats_callback(device_manager); cl_processor->set_dpc(dpc_type); cl_processor->set_hdr (hdr_type); cl_processor->set_denoise (denoise_type); cl_processor->set_tonemapping(tonemapping_type); cl_processor->set_capture_stage (capture_stage); if (need_display) { cl_processor->set_output_format (V4L2_PIX_FMT_XBGR32); } cl_processor->set_tnr (tnr_type, tnr_level); cl_processor->set_profile (pipeline_mode); analyzer->set_parameter_brightness((brightness_level - 128) / 128.0); device_manager->add_image_processor (cl_processor); } #endif ret = device_manager->start (); CHECK (ret, "device manager start failed"); // hard code exposure range and max gain for imx185 WDR if (pixel_format == V4L2_PIX_FMT_SGRBG12) { 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 * 1125 * 1000 / 37125, 1120 * 1125 * 1000 / 37125); analyzer->set_ae_max_analog_gain (3.98); // 12dB } // 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 (); event_device->close (); return 0; }
int main (int argc, const char *argv[]) { (void)argv; (void)argc; // suppress unused variable warning XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr<V4l2Device> device = new AtomispDevice (DEFAULT_CAPTURE_DEVICE); SmartPtr<V4l2SubDevice> event_device = new V4l2SubDevice (DEFAULT_EVENT_DEVICE); SmartPtr<IspController> isp_controller = new IspController (device); SmartPtr<ImageProcessor> processor = new IspImageProcessor (isp_controller); device->set_sensor_id (0); device->set_capture_mode (V4L2_CAPTURE_MODE_VIDEO); //device->set_mem_type (V4L2_MEMORY_MMAP); device->set_mem_type (V4L2_MEMORY_DMABUF); device->set_buffer_count (8); device->set_framerate (25, 1); ret = device->open (); CHECK (ret, "device(%s) open failed", device->get_device_name()); //ret = device->set_format (1920, 1080, V4L2_PIX_FMT_NV12, V4L2_FIELD_NONE, 1920 * 2); ret = device->set_format (1920, 1080, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 1920 * 2); CHECK (ret, "device(%s) set format failed", device->get_device_name()); ret = event_device->open (); 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); ret = event_device->start(); CHECK (ret, "event device start failed"); struct v4l2_format format; device->get_format(format); #if HAVE_LIBDRM AtomispDevice* atom_isp_dev = (AtomispDevice*)device.ptr(); SmartPtr<DrmDisplay> drmdisp = DrmDisplay::instance(); struct v4l2_rect rect = { 0, 0, (int)format.fmt.pix.width, (int)format.fmt.pix.height }; drmdisp->render_init( 0, 0, 1920, 1080, format.fmt.pix.pixelformat, &rect); atom_isp_dev->set_drm_display(drmdisp); ret = device->start(); CHECK (ret, "capture device start failed"); SmartPtr<PollThread> poll_thread = new PollThread(); PollCB* poll_cb = new PollCB(drmdisp, format); #else ret = device->start(); CHECK(ret, "capture device start failed"); SmartPtr<PollThread> poll_thread = new PollThread(); PollCB* poll_cb = new PollCB(format); #endif poll_thread->set_capture_device(device); poll_thread->set_event_device(event_device); poll_thread->set_poll_callback(poll_cb); signal(SIGINT, dev_stop_handler); poll_thread->start(); CHECK (ret, "poll thread start failed"); // wait for interruption { SmartLock locker (g_mutex); while (!g_stop) g_cond.wait (g_mutex); } ret = poll_thread->stop(); CHECK_CONTINUE (ret, "poll thread stop failed"); device->close (); event_device->close (); return 0; }
void WaitUntilNotRunning() { while (running) cond.wait(mutex); }