/* * Copyright (c) 2019 Rockchip 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. * */ #include #include #include "FakeSensorHw.h" #include "fake_v4l2_device.h" namespace RkCam { using namespace std; static uint32_t rk_format_to_media_format(rk_aiq_format_t format) { uint32_t pixelformat = -1; switch (format) { case RK_PIX_FMT_SBGGR8: pixelformat = MEDIA_BUS_FMT_SBGGR8_1X8; break; case RK_PIX_FMT_SRGGB8: pixelformat = MEDIA_BUS_FMT_SRGGB8_1X8; break; case RK_PIX_FMT_SGBRG8: pixelformat = MEDIA_BUS_FMT_SGBRG8_1X8; break; case RK_PIX_FMT_SGRBG8: pixelformat = MEDIA_BUS_FMT_SGRBG8_1X8; break; case RK_PIX_FMT_SBGGR10: pixelformat = MEDIA_BUS_FMT_SBGGR10_1X10; break; case RK_PIX_FMT_SRGGB10: pixelformat = MEDIA_BUS_FMT_SRGGB10_1X10; break; case RK_PIX_FMT_SGBRG10: pixelformat = MEDIA_BUS_FMT_SGBRG10_1X10; break; case RK_PIX_FMT_SGRBG10: pixelformat = MEDIA_BUS_FMT_SGRBG10_1X10; break; case RK_PIX_FMT_SBGGR12: pixelformat = MEDIA_BUS_FMT_SBGGR12_1X12; break; case RK_PIX_FMT_SRGGB12: pixelformat = MEDIA_BUS_FMT_SRGGB12_1X12; break; case RK_PIX_FMT_SGBRG12: pixelformat = MEDIA_BUS_FMT_SGBRG12_1X12; break; case RK_PIX_FMT_SGRBG12: pixelformat = MEDIA_BUS_FMT_SGRBG12_1X12; break; case RK_PIX_FMT_SBGGR14: pixelformat = MEDIA_BUS_FMT_SBGGR14_1X14; break; case RK_PIX_FMT_SRGGB14: pixelformat = MEDIA_BUS_FMT_SRGGB14_1X14; break; case RK_PIX_FMT_SGBRG14: pixelformat = MEDIA_BUS_FMT_SGBRG14_1X14; break; case RK_PIX_FMT_SGRBG14: pixelformat = MEDIA_BUS_FMT_SGRBG14_1X14; break; default: LOGE_CAMHW_SUBM(FAKECAM_SUBM, "%s no support format: %d\n", __func__, format); } return pixelformat; } FakeSensorHw::FakeSensorHw() : SensorHw ("/dev/null") , _sync_cond(false) , _need_sync(false) { ENTER_CAMHW_FUNCTION(); _timer = new CTimer(this); pFunc = NULL; EXIT_CAMHW_FUNCTION(); } FakeSensorHw::~FakeSensorHw() { ENTER_CAMHW_FUNCTION(); delete _timer; EXIT_CAMHW_FUNCTION(); } int FakeSensorHw::get_blank(rk_aiq_exposure_sensor_descriptor* sns_des) { sns_des->pixel_periods_per_line = sns_des->sensor_output_width; sns_des->line_periods_per_field = sns_des->sensor_output_height; return 0; } int FakeSensorHw::get_pixel(rk_aiq_exposure_sensor_descriptor* sns_des) { sns_des->pixel_clock_freq_mhz = 600.0f; return 0; } int FakeSensorHw::get_sensor_fps(float& fps) { fps = 25.0f; return 0; } int FakeSensorHw::get_sensor_desc(rk_aiq_exposure_sensor_descriptor* sns_des) { sns_des->sensor_output_width = _width; sns_des->sensor_output_height = _height; sns_des->sensor_pixelformat = get_v4l2_pixelformat(_fmt_code); return 0; } int FakeSensorHw::get_exposure_range(rk_aiq_exposure_sensor_descriptor* sns_des) { sns_des->coarse_integration_time_min = 1; sns_des->coarse_integration_time_max_margin = 10; return 0; } int FakeSensorHw::get_nr_switch(rk_aiq_sensor_nr_switch_t* nr_switch) { nr_switch->valid = false; nr_switch->direct = 0; nr_switch->up_thres = 0; nr_switch->down_thres = 0; nr_switch->div_coeff = 0; return 0; } XCamReturn FakeSensorHw::get_sensor_descriptor(rk_aiq_exposure_sensor_descriptor *sns_des) { memset(sns_des, 0, sizeof(rk_aiq_exposure_sensor_descriptor)); if (get_sensor_desc(sns_des)) return XCAM_RETURN_ERROR_IOCTL; if (get_blank(sns_des)) return XCAM_RETURN_ERROR_IOCTL; /* * pixel rate is not equal to pclk sometimes * prefer to use pclk = ppl * lpp * fps */ float fps = 0; if (get_sensor_fps(fps) == 0) sns_des->pixel_clock_freq_mhz = (float)(sns_des->pixel_periods_per_line) * sns_des->line_periods_per_field * fps / 1000000.0; else if (get_pixel(sns_des)) return XCAM_RETURN_ERROR_IOCTL; if (get_exposure_range(sns_des)) return XCAM_RETURN_ERROR_IOCTL; if (get_nr_switch(&sns_des->nr_switch)) { // do nothing; } return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::setExposureParams(SmartPtr& expPar) { ENTER_CAMHW_FUNCTION(); if (_first) { RKAiqAecExpInfoWrapper_t* exp = &expPar->data()->result; SmartPtr expParamsProxy = NULL; if (exp->ae_proc_res_rk.exp_set_cnt > 0) { SmartPtr tmp; if (_expParamsPool->has_free_items()) { expParamsProxy = _expParamsPool->get_item(); tmp = expParamsProxy->data(); } else { LOGE_CAMHW_SUBM(SENSOR_SUBM, "%s: no free params buffer!\n", __FUNCTION__); return XCAM_RETURN_ERROR_MEM; } int lastIdx = exp->ae_proc_res_rk.exp_set_cnt - 1; tmp->aecExpInfo.LinearExp = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].LinearExp; tmp->aecExpInfo.HdrExp[0] = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].HdrExp[0]; tmp->aecExpInfo.HdrExp[1] = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].HdrExp[1]; tmp->aecExpInfo.HdrExp[2] = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].HdrExp[2]; tmp->aecExpInfo.frame_length_lines = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].frame_length_lines; tmp->aecExpInfo.line_length_pixels = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].line_length_pixels; tmp->aecExpInfo.pixel_clock_freq_mhz = exp->ae_proc_res_rk.exp_set_tbl[lastIdx].pixel_clock_freq_mhz; } _effecting_exp_map[0] = expParamsProxy; _first = false; LOGD_CAMHW_SUBM(FAKECAM_SUBM, "exp-sync: first set exp, add id[0] to the effected exp map"); } EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::getSensorModeData(const char* sns_ent_name, rk_aiq_exposure_sensor_descriptor& sns_des) { rk_aiq_exposure_sensor_descriptor sensor_desc; get_sensor_descriptor (&sensor_desc); _sns_entity_name = sns_ent_name; sns_des.coarse_integration_time_min = sensor_desc.coarse_integration_time_min; sns_des.coarse_integration_time_max_margin = sensor_desc.coarse_integration_time_max_margin; sns_des.fine_integration_time_min = sensor_desc.fine_integration_time_min; sns_des.fine_integration_time_max_margin = sensor_desc.fine_integration_time_max_margin; sns_des.frame_length_lines = sensor_desc.line_periods_per_field; sns_des.line_length_pck = sensor_desc.pixel_periods_per_line; sns_des.vt_pix_clk_freq_hz = sensor_desc.pixel_clock_freq_mhz/* * 1000000 */; sns_des.pixel_clock_freq_mhz = sensor_desc.pixel_clock_freq_mhz/* * 1000000 */; //add nr_switch sns_des.nr_switch = sensor_desc.nr_switch; sns_des.sensor_output_width = sensor_desc.sensor_output_width; sns_des.sensor_output_height = sensor_desc.sensor_output_height; sns_des.sensor_pixelformat = sensor_desc.sensor_pixelformat; LOGD_CAMHW_SUBM(FAKECAM_SUBM, "vts-hts-pclk: %d-%d-%d-%f, rect: [%dx%d]\n", sns_des.frame_length_lines, sns_des.line_length_pck, sns_des.vt_pix_clk_freq_hz, sns_des.pixel_clock_freq_mhz, sns_des.sensor_output_width, sns_des.sensor_output_height); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::handle_sof(int64_t time, uint32_t frameid) { ENTER_CAMHW_FUNCTION(); EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::set_working_mode(int mode) { __u32 hdr_mode = NO_HDR; if (mode == RK_AIQ_WORKING_MODE_NORMAL) { hdr_mode = NO_HDR; } else if (mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) { hdr_mode = HDR_X2; } else if (mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) { hdr_mode = HDR_X3; } else { LOGE_CAMHW_SUBM(FAKECAM_SUBM, "failed to set hdr mode to %d", mode); return XCAM_RETURN_ERROR_FAILED; } _working_mode = mode; LOGD_CAMHW_SUBM(FAKECAM_SUBM, "%s _working_mode: %d\n", __func__, _working_mode); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::set_mirror_flip(bool mirror, bool flip, int32_t& skip_frame_sequence) { return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::get_mirror_flip(bool& mirror, bool& flip) { return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::set_exp_delay_info(int time_delay, int gain_delay, int hcg_lcg_mode_delay) { return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::start(bool prepared) { ENTER_CAMHW_FUNCTION(); V4l2SubDevice::start(); _timer->SetTimer(0, 100000); _timer->StartTimer(); EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::stop() { ENTER_CAMHW_FUNCTION(); _timer->StopTimer(); _vbuf_list.clear(); SensorHw::stop(); EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::get_selection (int pad, uint32_t target, struct v4l2_subdev_selection &select) { XCAM_ASSERT (is_opened()); return XCAM_RETURN_ERROR_IOCTL; } XCamReturn FakeSensorHw::getFormat(struct v4l2_subdev_format &aFormat) { ENTER_CAMHW_FUNCTION(); aFormat.format.width = _width; aFormat.format.height = _height; aFormat.format.code = _fmt_code; aFormat.format.field = V4L2_FIELD_NONE; aFormat.format.colorspace = V4L2_COLORSPACE_470_SYSTEM_M; LOGD_CAMHW_SUBM(FAKECAM_SUBM, "pad: %d, which: %d, width: %d, " "height: %d, format: 0x%x, field: %d, color space: %d", aFormat.pad, aFormat.which, aFormat.format.width, aFormat.format.height, aFormat.format.code, aFormat.format.field, aFormat.format.colorspace); EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::prepare(rk_aiq_raw_prop_t prop) { ENTER_CAMHW_FUNCTION(); _width = prop.frame_width; _height = prop.frame_height; _fmt_code = rk_format_to_media_format(prop.format); _rawbuf_type = prop.rawbuf_type; EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::enqueue_rawbuffer(struct rk_aiq_vbuf *vbuf, bool sync) { int max_count = 0; SmartPtr fake_v4l2_dev; ENTER_CAMHW_FUNCTION(); if (_working_mode == RK_AIQ_WORKING_MODE_NORMAL) { max_count = 1; } else if (_working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || _working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) { max_count = 2; } else if (_working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || _working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) { max_count = 3; } if (_frame_sequence != uint32_t(-1) && vbuf->buf_info[0].frame_id != _frame_sequence + 1) { LOGW_CAMHW_SUBM(FAKECAM_SUBM, "enqueue frame id(%u) isn't contiguous, change the id to %u", vbuf->buf_info[0].frame_id, _frame_sequence + 1); vbuf->buf_info[0].frame_id = ++_frame_sequence; } else _frame_sequence = vbuf->buf_info[0].frame_id; vbuf->buf_info[1].frame_id = vbuf->buf_info[0].frame_id; vbuf->buf_info[2].frame_id = vbuf->buf_info[0].frame_id; for (int i = 0; i < max_count; i++) { fake_v4l2_dev = _mipi_tx_dev[i].dynamic_cast_ptr(); fake_v4l2_dev->enqueue_rawbuffer(&vbuf->buf_info[i]); } _mutex.lock(); _vbuf_list.push_back(*vbuf); while (_effecting_exp_map.size() > 4) _effecting_exp_map.erase(_effecting_exp_map.begin()); int fid = vbuf->buf_info[0].frame_id; // check valid firstly bool exp_val_valid = true; #if 1 //check float exposure, not reg value if (fabs(vbuf->buf_info[0].exp_time - 0.0f) < FLT_EPSILON || fabs(vbuf->buf_info[0].exp_gain - 0.0f) < FLT_EPSILON) exp_val_valid = false; if (exp_val_valid && (RK_AIQ_HDR_GET_WORKING_MODE(_working_mode) == RK_AIQ_WORKING_MODE_ISP_HDR2)) { if (fabs(vbuf->buf_info[1].exp_time - 0.0f) < FLT_EPSILON || fabs(vbuf->buf_info[1].exp_gain - 0.0f) < FLT_EPSILON) exp_val_valid = false; } if (exp_val_valid && (RK_AIQ_HDR_GET_WORKING_MODE(_working_mode) == RK_AIQ_WORKING_MODE_ISP_HDR3)) { if (fabs(vbuf->buf_info[2].exp_time - 0.0f) < FLT_EPSILON || fabs(vbuf->buf_info[2].exp_gain - 0.0f) < FLT_EPSILON) exp_val_valid = false; } #else if ((vbuf->buf_info[0].exp_gain_reg) == 0) exp_val_valid = false; if (exp_val_valid && (RK_AIQ_HDR_GET_WORKING_MODE(_working_mode) == RK_AIQ_WORKING_MODE_ISP_HDR2)) { if (vbuf->buf_info[1].exp_gain_reg == 0) exp_val_valid = false; } if (exp_val_valid && (RK_AIQ_HDR_GET_WORKING_MODE(_working_mode) == RK_AIQ_WORKING_MODE_ISP_HDR3)) { if (vbuf->buf_info[2].exp_gain_reg == 0) exp_val_valid = false; } #endif if (exp_val_valid) { SmartPtr exp_param_prx = _expParamsPool->get_item(); exp_param_prx->data()->aecExpInfo.LinearExp.exp_sensor_params.analog_gain_code_global = vbuf->buf_info[0].exp_gain_reg; exp_param_prx->data()->aecExpInfo.LinearExp.exp_sensor_params.coarse_integration_time = vbuf->buf_info[0].exp_time_reg; exp_param_prx->data()->aecExpInfo.LinearExp.exp_real_params.analog_gain = vbuf->buf_info[0].exp_gain; exp_param_prx->data()->aecExpInfo.LinearExp.exp_real_params.integration_time = vbuf->buf_info[0].exp_time; exp_param_prx->data()->aecExpInfo.LinearExp.exp_sensor_params.digital_gain_global = 1; exp_param_prx->data()->aecExpInfo.LinearExp.exp_sensor_params.isp_digital_gain = 1; exp_param_prx->data()->aecExpInfo.LinearExp.exp_real_params.digital_gain = 1.0f; exp_param_prx->data()->aecExpInfo.LinearExp.exp_real_params.isp_dgain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_sensor_params.analog_gain_code_global = vbuf->buf_info[2].exp_gain_reg; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_sensor_params.coarse_integration_time = vbuf->buf_info[2].exp_time_reg; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_real_params.analog_gain = vbuf->buf_info[2].exp_gain; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_real_params.integration_time = vbuf->buf_info[2].exp_time; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_sensor_params.digital_gain_global = 1; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_sensor_params.isp_digital_gain = 1; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_real_params.digital_gain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[2].exp_real_params.isp_dgain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_sensor_params.analog_gain_code_global = vbuf->buf_info[1].exp_gain_reg; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_sensor_params.coarse_integration_time = vbuf->buf_info[1].exp_time_reg; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_real_params.analog_gain = vbuf->buf_info[1].exp_gain; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_real_params.integration_time = vbuf->buf_info[1].exp_time; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_sensor_params.digital_gain_global = 1; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_sensor_params.isp_digital_gain = 1; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_real_params.digital_gain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[1].exp_real_params.isp_dgain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_sensor_params.analog_gain_code_global = vbuf->buf_info[0].exp_gain_reg; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_sensor_params.coarse_integration_time = vbuf->buf_info[0].exp_time_reg; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_real_params.analog_gain = vbuf->buf_info[0].exp_gain; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_real_params.integration_time = vbuf->buf_info[0].exp_time; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_sensor_params.digital_gain_global = 1; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_sensor_params.isp_digital_gain = 1; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_real_params.digital_gain = 1.0f; exp_param_prx->data()->aecExpInfo.HdrExp[0].exp_real_params.isp_dgain = 1.0f; _effecting_exp_map[fid] = exp_param_prx; LOGD_CAMHW_SUBM(FAKECAM_SUBM, "add id[%d] to the effected exp map", fid); } else { LOGW_CAMHW_SUBM(FAKECAM_SUBM, "invalid expo info of fid %d", fid); } _mutex.unlock(); if (sync) { _need_sync = sync; if (_sync_cond.timedwait(_sync_mutex, 5000000) != 0) { LOGE_CAMHW_SUBM(FAKECAM_SUBM, "wait raw buffer process done timeout"); return XCAM_RETURN_ERROR_TIMEOUT; } } EXIT_CAMHW_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn FakeSensorHw::register_rawdata_callback(void (*callback)(void *)) { ENTER_XCORE_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; pFunc = callback; EXIT_XCORE_FUNCTION(); return ret; } XCamReturn FakeSensorHw::on_dqueue(int dev_idx, SmartPtr buf_proxy) { ENTER_XCORE_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; std::list::iterator it; SmartLock locker (_mutex); if (!_vbuf_list.empty()) { for(it = _vbuf_list.begin(); it != _vbuf_list.end(); it++) { if (_rawbuf_type == RK_AIQ_RAW_DATA) { uintptr_t ptr = buf_proxy->get_reserved(); LOGD_CAMHW_SUBM(FAKECAM_SUBM, "rawbuf_type(data): %p vs 0x%x",it->buf_info[dev_idx].data_addr,ptr); if (it->buf_info[dev_idx].data_addr == (uint8_t*)ptr) { it->buf_info[dev_idx].valid = false; break; } } else if (_rawbuf_type == RK_AIQ_RAW_ADDR) { uintptr_t ptr = buf_proxy->get_v4l2_userptr(); LOGD_CAMHW_SUBM(FAKECAM_SUBM, "rawbuf_type(addr): %p vs 0x%x",it->buf_info[dev_idx].data_addr,ptr); if (it->buf_info[dev_idx].data_addr == (uint8_t*)ptr) { it->buf_info[dev_idx].valid = false; break; } } else if (_rawbuf_type == RK_AIQ_RAW_FD) { uint32_t buf_fd = buf_proxy->get_expbuf_fd(); LOGD_CAMHW_SUBM(FAKECAM_SUBM, "rawbuf_type(fd): %d vs %d",it->buf_info[dev_idx].data_fd,buf_fd); if (it->buf_info[dev_idx].data_fd == buf_fd) { it->buf_info[dev_idx].valid = false; break; } } else if (_rawbuf_type == RK_AIQ_RAW_FILE) { uintptr_t ptr = buf_proxy->get_v4l2_userptr(); LOGD_CAMHW_SUBM(FAKECAM_SUBM, "rawbuf_type(file): %p vs 0x%x",it->buf_info[dev_idx].data_addr,ptr); if (it->buf_info[dev_idx].data_addr == (uint8_t*)ptr) { it->buf_info[dev_idx].valid = false; break; } } else { LOGE_CAMHW_SUBM(FAKECAM_SUBM, "raw buf type is wrong:0x%x",_rawbuf_type); return XCAM_RETURN_ERROR_FAILED; } } if (it != _vbuf_list.end()) { switch (_working_mode) { case RK_AIQ_WORKING_MODE_NORMAL: if (!it->buf_info[0].valid) { goto out; } break; case RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR: case RK_AIQ_ISP_HDR_MODE_2_LINE_HDR: if (!it->buf_info[0].valid && !it->buf_info[1].valid) { goto out; } break; case RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR: case RK_AIQ_ISP_HDR_MODE_3_LINE_HDR: if (!it->buf_info[0].valid && !it->buf_info[1].valid && !it->buf_info[2].valid) { goto out; } break; } } } EXIT_XCORE_FUNCTION(); return ret; out: _vbuf_list.erase(it); if (_need_sync) { LOGD_CAMHW_SUBM(FAKECAM_SUBM, "give off signal"); _sync_cond.signal(); }else { if (pFunc) pFunc(it->base_addr); } EXIT_XCORE_FUNCTION(); return ret; } XCamReturn FakeSensorHw::set_mipi_tx_devs(SmartPtr mipi_tx_devs[3]) { _mipi_tx_dev[0] = mipi_tx_devs[0]; _mipi_tx_dev[1] = mipi_tx_devs[1]; _mipi_tx_dev[2] = mipi_tx_devs[2]; return XCAM_RETURN_NO_ERROR; } CTimer::CTimer(FakeSensorHw *dev): m_second(0), m_microsecond(0) { _dev = dev; } CTimer::~CTimer() { } void CTimer::SetTimer(long second, long microsecond) { m_second = second; m_microsecond = microsecond; } void CTimer::StartTimer() { pthread_create(&thread_timer, NULL, OnTimer_stub, this); } void CTimer::StopTimer() { #ifndef __ANDROID__ pthread_cancel(thread_timer); #endif pthread_join(thread_timer, NULL); } void CTimer::thread_proc() { while (true) { OnTimer(); #ifndef __ANDROID__ pthread_testcancel(); #endif struct timeval tempval; tempval.tv_sec = m_second; tempval.tv_usec = m_microsecond; select(0, NULL, NULL, NULL, &tempval); } } void CTimer::OnTimer() { SmartPtr fake_v4l2_dev; ENTER_CAMHW_FUNCTION(); if (_dev->_working_mode == RK_AIQ_WORKING_MODE_NORMAL) { fake_v4l2_dev = _dev->_mipi_tx_dev[0].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); } else if (_dev->_working_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR || _dev->_working_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR) { fake_v4l2_dev = _dev->_mipi_tx_dev[0].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); fake_v4l2_dev = _dev->_mipi_tx_dev[1].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); } else if (_dev->_working_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR || _dev->_working_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR) { fake_v4l2_dev = _dev->_mipi_tx_dev[0].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); fake_v4l2_dev = _dev->_mipi_tx_dev[1].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); fake_v4l2_dev = _dev->_mipi_tx_dev[2].dynamic_cast_ptr(); fake_v4l2_dev->on_timer_proc(); } EXIT_XCORE_FUNCTION(); } }; //namespace RkCam