void Parser::IncludedFile::WalkThrough::enter_conditional_chain(CondChain *cc) { CListEntry *i, *j; #if SANITY_CHECK unsigned sum = 0; unsigned has_else = 0; #endif if(method == MED_BF && on_conditional_chain_callback) on_conditional_chain_callback(context, cc); for(i = cc->chain.next; i != &cc->chain; i = j) { j = i->next; Cond *c = container_of(i, Cond, link); #if SANITY_CHECK sum += c->value; has_else += (c->type == Cond::CT_ELSE); #endif c->sanity_check(); enter_conditional(c); } #if SANITY_CHECK char emsg[256] = {0x1} ; if(sum > 1) snprintf(emsg, sizeof(emsg), "Has %u true conditionals", sum); if(has_else && sum != 1) snprintf(emsg, sizeof(emsg), "A chain with else has %u true conditionals", sum); if(emsg[0] != '\x1') dump_and_exit(cc, emsg); #endif if(method == MED_DF && on_conditional_chain_callback) on_conditional_chain_callback(context, cc); }
void Cancel() { const ScopeLock lock(mutex); if (!cancel_flag) { cancel_flag = true; cancel_cond.signal(); } }
void PendingChecks::runChecks() { DynMutex::Guard guard = m_mutex.lock(); Checks::iterator it = m_checks.begin(); bool removed = false; while (it != m_checks.end()) { bool cont; try { cont = (**it)(); } catch (...) { Exception::handle(HANDLE_EXCEPTION_FATAL); // keep compiler happy cont = false; } if (!cont) { // Done with this check Checks::iterator next = it; ++next; m_checks.erase(it); it = next; removed = true; } else { ++it; } } // Tell blockOnCheck() calls that they may have completed. if (removed) { m_cond.signal(); } }
VPtr lookup(const K& key) { VPtr val; list<VPtr> to_release; { Mutex::Locker l(lock); ++waiting; bool retry = false; do { retry = false; typename map<K, pair<WeakVPtr, V*>, C>::iterator i = weak_refs.find(key); if (i != weak_refs.end()) { val = i->second.first.lock(); if (val) { lru_add(key, val, &to_release); } else { retry = true; } } if (retry) cond.Wait(lock); } while (retry); --waiting; } return val; }
bool KRT2Device::Send(const uint8_t *msg, unsigned msg_size, OperationEnvironment &env) { //! Number of tries to send a message unsigned retries = NR_RETRIES; assert(msg_size > 0); do { response_mutex.Lock(); response = NO_RSP; response_mutex.Unlock(); // Send the message if (!port.FullWrite(msg, msg_size, env, CMD_TIMEOUT)) return false; // Wait for the response response_mutex.Lock(); rx_cond.timed_wait(response_mutex, CMD_TIMEOUT); auto _response = response; response_mutex.Unlock(); if (_response == ACK) // ACK received, finish return true; // No ACK received, retry retries--; } while (retries); return false; }
VPtr lower_bound(const K& key) { VPtr val; list<VPtr> to_release; { Mutex::Locker l(lock); bool retry = false; do { retry = false; if (weak_refs.empty()) break; typename map<K, WeakVPtr>::iterator i = weak_refs.lower_bound(key); if (i == weak_refs.end()) --i; val = i->second.lock(); if (val) { lru_add(i->first, val, &to_release); } else { retry = true; } if (retry) cond.Wait(lock); } while (retry); } return val; }
VPtr lookup_or_create(const K &key) { VPtr val; list<VPtr> to_release; { Mutex::Locker l(lock); bool retry = false; do { retry = false; typename map<K, pair<WeakVPtr, V*>, C>::iterator i = weak_refs.find(key); if (i != weak_refs.end()) { val = i->second.first.lock(); if (val) { lru_add(key, val, &to_release); return val; } else { retry = true; } } if (retry) cond.Wait(lock); } while (retry); V *new_value = new V(); VPtr new_val(new_value, Cleanup(this, key)); weak_refs.insert(make_pair(key, make_pair(new_val, new_value))); lru_add(key, new_val, &to_release); return new_val; } }
/** * Wakes up the thread to do work, calls tick(). */ void Trigger() { const ScopeLock lock(mutex); if (!trigger_flag) { trigger_flag = true; trigger_cond.signal(); } }
void remove(const K& key, V *valptr) { Mutex::Locker l(lock); typename map<K, pair<WeakVPtr, V*>, C>::iterator i = weak_refs.find(key); if (i != weak_refs.end() && i->second.second == valptr) { weak_refs.erase(i); } cond.Signal(); }
void TriggerDone() { assert(mutex.IsLockedByCurrent()); #ifdef HAVE_POSIX cond.Signal(); #else done_trigger.Signal(); #endif }
void Set(const K &key, const V &value) { auto i = map.insert(std::make_pair(key, Item(value))); Item &item = i.first->second; item.old = false; if (!i.second) item.value = value; cond.broadcast(); }
void TriggerCommand() { assert(mutex.IsLockedByCurrent()); #ifdef HAVE_POSIX cond.Signal(); #else command_trigger.Signal(); #endif }
void dev_stop_handler(int sig) { XCAM_UNUSED (sig); SmartLock locker (g_mutex); g_stop = true; g_cond.broadcast (); //exit(0); }
void leave() const { Lock lock(mutex); assert(refcnt > 0); assert(pthread_equal(holder, pthread_self()) != 0); refcnt--; if (refcnt == 0) { cond.signal(); } }
VPtr lookup(const K &key) { Mutex::Locker l(lock); while (1) { if (contents.count(key)) { VPtr retval = contents[key].lock(); if (retval) return retval; } else { break; } cond.Wait(lock); Mutex::Locker l(lock); } return VPtr(); }
VPtr lookup_or_create(const K &key, const A &arg) { Mutex::Locker l(lock); while (1) { if (contents.count(key)) { VPtr retval = contents[key].lock(); if (retval) return retval; } else { break; } cond.Wait(lock); } VPtr retval(new V(arg), OnRemoval(this, key)); contents[key] = retval; return retval; }
const_iterator Wait(const K &key, OperationEnvironment &env, TimeoutClock timeout) { while (true) { auto i = map.find(key); if (i != map.end() && !i->second.old) return const_iterator(i); if (env.IsCancelled()) return end(); int remaining = timeout.GetRemainingSigned(); if (remaining <= 0) return end(); cond.timed_wait(*this, remaining); } }
const_iterator Wait(std::unique_lock<Mutex> &lock, const K &key, OperationEnvironment &env, TimeoutClock timeout) { while (true) { auto i = map.find(key); if (i != map.end() && !i->second.old) return const_iterator(i); if (env.IsCancelled()) return end(); const auto remaining = timeout.GetRemainingSigned(); if (remaining.count() <= 0) return end(); cond.wait_for(lock, remaining); } }
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()); } }
VPtr lookup(const K &key) { Mutex::Locker l(lock); waiting++; while (1) { typename map<K, pair<WeakVPtr, V*> >::iterator i = contents.find(key); if (i != contents.end()) { VPtr retval = i->second.first.lock(); if (retval) { waiting--; return retval; } } else { break; } cond.Wait(lock); } waiting--; return VPtr(); }
VPtr lookup(K key) { VPtr val; list<VPtr> to_release; { Mutex::Locker l(lock); bool retry = false; do { retry = false; if (weak_refs.count(key)) { val = weak_refs[key].lock(); if (val) { lru_add(key, val, &to_release); } else { retry = true; } } if (retry) cond.Wait(lock); } while (retry); } return val; }
VPtr lookup_or_create(const K &key, const A &arg) { Mutex::Locker l(lock); waiting++; while (1) { typename map<K, pair<WeakVPtr, V*> >::iterator i = contents.find(key); if (i != contents.end()) { VPtr retval = i->second.first.lock(); if (retval) { waiting--; return retval; } } else { break; } cond.Wait(lock); } V *ptr = new V(arg); VPtr retval(ptr, OnRemoval(this, key)); contents.insert(make_pair(key, make_pair(retval, ptr))); waiting--; return retval; }
void remove(const K& key) { Mutex::Locker l(lock); weak_refs.erase(key); cond.Signal(); }
void TriggerCommand() { assert(mutex.IsLockedByCurrent()); cond.signal(); }
void Done() { const ScopeLock protect(mutex); done = true; cond.Broadcast(); }
bool Wait(unsigned timeout_ms=5000) { const ScopeLock protect(mutex); return done || (cond.Wait(mutex, timeout_ms) && done); }
void TriggerDone() { assert(mutex.IsLockedByCurrent()); cond.signal(); }
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; }
void MainDeviceManager::handle_buffer (const SmartPtr<VideoBuffer> &buf) { FPS_CALCULATION (fps_buf, 30); XCAM_OBJ_PROFILING_START; if (_enable_display) display_buf (buf); XCAM_OBJ_PROFILING_END("main_dev_manager_display", 30); 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; } const VideoBufferInfo & frame_info = buf->get_video_info (); uint8_t *frame = buf->map (); if (frame == NULL) return; uint32_t size = 0; switch(frame_info.format) { case V4L2_PIX_FMT_NV12: // 420 case V4L2_PIX_FMT_NV21: size = XCAM_ALIGN_UP(frame_info.width, 2) * XCAM_ALIGN_UP(frame_info.height, 2) * 3 / 2; break; case V4L2_PIX_FMT_YUV422P: // 422 Planar case V4L2_PIX_FMT_YUYV: // 422 case V4L2_PIX_FMT_SBGGR10: case V4L2_PIX_FMT_SGBRG10: case V4L2_PIX_FMT_SGRBG10: case V4L2_PIX_FMT_SRGGB10: case V4L2_PIX_FMT_SBGGR12: case V4L2_PIX_FMT_SGBRG12: case V4L2_PIX_FMT_SGRBG12: case V4L2_PIX_FMT_SRGGB12: size = XCAM_ALIGN_UP(frame_info.width, 2) * XCAM_ALIGN_UP(frame_info.height, 2) * 2; break; case XCAM_PIX_FMT_RGBA64: size = XCAM_ALIGN_UP(frame_info.width, 2) * XCAM_ALIGN_UP(frame_info.height, 2) * 2 * 4; break; default: XCAM_LOG_ERROR ( "unknown v4l2 format(%s) in buffer handle", xcam_fourcc_to_string (frame_info.format)); return; } open_file (); if (!_file) { XCAM_LOG_ERROR ("open file failed"); return; } if (fwrite (frame, size, 1, _file) <= 0) { XCAM_LOG_WARNING ("write frame failed."); } }
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; }