From 65aad94f0dcfb8bcfc5b4a29e4cdf2a661a8d1f4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Dec 2023 16:21:16 -0800 Subject: [PATCH] Revert "camerad: refactor sensor parameters to struct (#30639)" This reverts commit 166fdc950c23ccff7c6223b769dc916b6fbbc06a. old-commit-hash: 0586f86ad01323bc213c125e8584df277555456d --- system/camerad/cameras/camera_common.cc | 6 +- system/camerad/cameras/camera_common.h | 22 +--- system/camerad/cameras/camera_qcom2.cc | 135 ++++++++++++------------ system/camerad/cameras/camera_qcom2.h | 23 +++- system/camerad/sensors/ar0231.cc | 6 +- 5 files changed, 94 insertions(+), 98 deletions(-) diff --git a/system/camerad/cameras/camera_common.cc b/system/camerad/cameras/camera_common.cc index 703378b104..987ccf23da 100644 --- a/system/camerad/cameras/camera_common.cc +++ b/system/camerad/cameras/camera_common.cc @@ -28,7 +28,7 @@ class Debayer { public: Debayer(cl_device_id device_id, cl_context context, const CameraBuf *b, const CameraState *s, int buf_width, int uv_offset) { char args[4096]; - const CameraInfo *ci = s->ci.get(); + const CameraInfo *ci = &s->ci; snprintf(args, sizeof(args), "-cl-fast-relaxed-math -cl-denorms-are-zero " "-DFRAME_WIDTH=%d -DFRAME_HEIGHT=%d -DFRAME_STRIDE=%d -DFRAME_OFFSET=%d " @@ -66,7 +66,7 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, this->yuv_type = init_yuv_type; frame_buf_count = frame_cnt; - const CameraInfo *ci = s->ci.get(); + const CameraInfo *ci = &s->ci; // RAW frame const int frame_size = (ci->frame_height + ci->extra_height) * ci->frame_stride; camera_bufs = std::make_unique(frame_buf_count); @@ -152,7 +152,7 @@ void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &fr framed.setProcessingTime(frame_data.processing_time); const float ev = c->cur_ev[frame_data.frame_id % 3]; - const float perc = util::map_val(ev, c->ci->min_ev, c->ci->max_ev, 0.0f, 100.0f); + const float perc = util::map_val(ev, c->min_ev, c->max_ev, 0.0f, 100.0f); framed.setExposureValPercent(perc); if (c->camera_id == CAMERA_ID_AR0231) { diff --git a/system/camerad/cameras/camera_common.h b/system/camerad/cameras/camera_common.h index 8022fa844e..9d9e42a5ed 100644 --- a/system/camerad/cameras/camera_common.h +++ b/system/camerad/cameras/camera_common.h @@ -16,8 +16,8 @@ #define CAMERA_ID_AR0231 0 #define CAMERA_ID_OX03C10 1 +#define CAMERA_ID_MAX 2 -#define ANALOG_GAIN_MAX_CNT 55 const int YUV_BUFFER_COUNT = 20; enum CameraType { @@ -41,26 +41,6 @@ typedef struct CameraInfo { uint32_t extra_height = 0; int registers_offset = -1; int stats_offset = -1; - - int exposure_time_min; - int exposure_time_max; - - float dc_gain_factor; - int dc_gain_min_weight; - int dc_gain_max_weight; - float dc_gain_on_grey; - float dc_gain_off_grey; - - float sensor_analog_gains[ANALOG_GAIN_MAX_CNT]; - int analog_gain_min_idx; - int analog_gain_max_idx; - int analog_gain_rec_idx; - int analog_gain_cost_delta; - float analog_gain_cost_low; - float analog_gain_cost_high; - float target_grey_factor; - float min_ev; - float max_ev; } CameraInfo; typedef struct FrameMetadata { diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 5aa95bd63d..e6ca0fff94 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -40,6 +40,27 @@ const size_t AR0231_REGISTERS_HEIGHT = 2; const size_t AR0231_STATS_HEIGHT = 2+8; const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py + +CameraInfo cameras_supported[CAMERA_ID_MAX] = { + [CAMERA_ID_AR0231] = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .frame_stride = FRAME_STRIDE, + .extra_height = AR0231_REGISTERS_HEIGHT + AR0231_STATS_HEIGHT, + + .registers_offset = 0, + .frame_offset = AR0231_REGISTERS_HEIGHT, + .stats_offset = AR0231_REGISTERS_HEIGHT + FRAME_HEIGHT, + }, + [CAMERA_ID_OX03C10] = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .frame_stride = FRAME_STRIDE, // (0xa80*12//8) + .extra_height = 16, // top 2 + bot 14 + .frame_offset = 2, + }, +}; + const float DC_GAIN_AR0231 = 2.5; const float DC_GAIN_OX03C10 = 7.32; @@ -403,10 +424,10 @@ void CameraState::config_isp(int io_mem_handle, int fence, int request_id, int b if (io_mem_handle != 0) { io_cfg[0].mem_handle[0] = io_mem_handle; io_cfg[0].planes[0] = (struct cam_plane_cfg){ - .width = ci->frame_width, - .height = ci->frame_height + ci->extra_height, - .plane_stride = ci->frame_stride, - .slice_height = ci->frame_height + ci->extra_height, + .width = ci.frame_width, + .height = ci.frame_height + ci.extra_height, + .plane_stride = ci.frame_stride, + .slice_height = ci.frame_height + ci.extra_height, .meta_stride = 0x0, // YUV has meta(stride=0x400, size=0x5000) .meta_size = 0x0, .meta_offset = 0x0, @@ -496,17 +517,8 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) { // ******************* camera ******************* -struct CameraAR0231 : public CameraInfo { - CameraAR0231() { - frame_width = FRAME_WIDTH, - frame_height = FRAME_HEIGHT, - frame_stride = FRAME_STRIDE, - extra_height = AR0231_REGISTERS_HEIGHT + AR0231_STATS_HEIGHT, - - registers_offset = 0, - frame_offset = AR0231_REGISTERS_HEIGHT, - stats_offset = AR0231_REGISTERS_HEIGHT + FRAME_HEIGHT, - +void CameraState::camera_set_parameters() { + if (camera_id == CAMERA_ID_AR0231) { dc_gain_factor = DC_GAIN_AR0231; dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_AR0231; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231; @@ -520,23 +532,12 @@ struct CameraAR0231 : public CameraInfo { analog_gain_cost_delta = ANALOG_GAIN_COST_DELTA_AR0231; analog_gain_cost_low = ANALOG_GAIN_COST_LOW_AR0231; analog_gain_cost_high = ANALOG_GAIN_COST_HIGH_AR0231; - for (int i = 0; i <= analog_gain_max_idx; i++) { + for (int i=0; i<=analog_gain_max_idx; i++) { sensor_analog_gains[i] = sensor_analog_gains_AR0231[i]; } min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx]; - max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx]; target_grey_factor = TARGET_GREY_FACTOR_AR0231; - } -}; - -struct CameraOx0310 : public CameraInfo { - CameraOx0310() { - frame_width = FRAME_WIDTH, - frame_height = FRAME_HEIGHT, - frame_stride = FRAME_STRIDE, // (0xa80*12//8) - extra_height = 16, // top 2 + bot 14 - frame_offset = 2, - + } else if (camera_id == CAMERA_ID_OX03C10) { dc_gain_factor = DC_GAIN_OX03C10; dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_OX03C10; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10; @@ -554,27 +555,19 @@ struct CameraOx0310 : public CameraInfo { sensor_analog_gains[i] = sensor_analog_gains_OX03C10[i]; } min_ev = (exposure_time_min + VS_TIME_MIN_OX03C10) * sensor_analog_gains[analog_gain_min_idx]; - max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx]; target_grey_factor = TARGET_GREY_FACTOR_OX03C10; - } -}; - -void CameraState::camera_set_parameters() { - if (camera_id == CAMERA_ID_AR0231) { - ci = std::make_unique(); - } else if (camera_id == CAMERA_ID_OX03C10) { - ci = std::make_unique(); } else { assert(false); } + max_ev = exposure_time_max * dc_gain_factor * sensor_analog_gains[analog_gain_max_idx]; target_grey_fraction = 0.3; dc_gain_enabled = false; - dc_gain_weight = ci->dc_gain_min_weight; - gain_idx = ci->analog_gain_rec_idx; + dc_gain_weight = dc_gain_min_weight; + gain_idx = analog_gain_rec_idx; exposure_time = 5; - cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight) * ci->sensor_analog_gains[gain_idx] * exposure_time; + cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight) * sensor_analog_gains[gain_idx] * exposure_time; } void CameraState::camera_map_bufs(MultiCameraState *s) { @@ -597,6 +590,10 @@ void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, int came camera_id = camera_id_; LOGD("camera init %d", camera_num); + assert(camera_id < std::size(cameras_supported)); + ci = cameras_supported[camera_id]; + assert(ci.frame_width != 0); + request_id_last = 0; skipped = true; @@ -683,16 +680,16 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num .usage_type = 0x0, .left_start = 0, - .left_stop = ci->frame_width - 1, - .left_width = ci->frame_width, + .left_stop = ci.frame_width - 1, + .left_width = ci.frame_width, .right_start = 0, - .right_stop = ci->frame_width - 1, - .right_width = ci->frame_width, + .right_stop = ci.frame_width - 1, + .right_width = ci.frame_width, .line_start = 0, - .line_stop = ci->frame_height + ci->extra_height - 1, - .height = ci->frame_height + ci->extra_height, + .line_stop = ci.frame_height + ci.extra_height - 1, + .height = ci.frame_height + ci.extra_height, .pixel_clk = 0x0, .batch_size = 0x0, @@ -704,8 +701,8 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num .data[0] = (struct cam_isp_out_port_info){ .res_type = CAM_ISP_IFE_OUT_RES_RDI_0, .format = CAM_FORMAT_MIPI_RAW_12, - .width = ci->frame_width, - .height = ci->frame_height + ci->extra_height, + .width = ci.frame_width, + .height = ci.frame_height + ci.extra_height, .comp_grp_id = 0x0, .split_point = 0x0, .secure_mode = 0x0, }, }; @@ -949,7 +946,7 @@ void CameraState::handle_camera_event(void *evdat) { meta_data.frame_id = main_id - idx_offset; meta_data.timestamp_sof = timestamp; exp_lock.lock(); - meta_data.gain = analog_gain_frac * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); + meta_data.gain = analog_gain_frac * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); meta_data.high_conversion_gain = dc_gain_enabled; meta_data.integ_lines = exposure_time; meta_data.measured_grey_fraction = measured_grey_fraction; @@ -975,15 +972,15 @@ void CameraState::update_exposure_score(float desired_ev, int exp_t, int exp_g_i // Cost of ev diff score = std::abs(desired_ev - (exp_t * exp_gain)) * 10; // Cost of absolute gain - float m = exp_g_idx > ci->analog_gain_rec_idx ? ci->analog_gain_cost_high : ci->analog_gain_cost_low; - score += std::abs(exp_g_idx - (int)ci->analog_gain_rec_idx) * m; + float m = exp_g_idx > analog_gain_rec_idx ? analog_gain_cost_high : analog_gain_cost_low; + score += std::abs(exp_g_idx - (int)analog_gain_rec_idx) * m; // Cost of changing gain score += std::abs(exp_g_idx - gain_idx) * (score + 1.0) / 10.0; } else if (camera_id == CAMERA_ID_OX03C10) { score = std::abs(desired_ev - (exp_t * exp_gain)); - float m = exp_g_idx > ci->analog_gain_rec_idx ? ci->analog_gain_cost_high : ci->analog_gain_cost_low; - score += std::abs(exp_g_idx - (int)ci->analog_gain_rec_idx) * m; - score += ((1 - ci->analog_gain_cost_delta) + ci->analog_gain_cost_delta * (exp_g_idx - ci->analog_gain_min_idx) / (ci->analog_gain_max_idx - ci->analog_gain_min_idx)) * std::abs(exp_g_idx - gain_idx) * 5.0; + float m = exp_g_idx > analog_gain_rec_idx ? analog_gain_cost_high : analog_gain_cost_low; + score += std::abs(exp_g_idx - (int)analog_gain_rec_idx) * m; + score += ((1 - analog_gain_cost_delta) + analog_gain_cost_delta * (exp_g_idx - analog_gain_min_idx) / (analog_gain_max_idx - analog_gain_min_idx)) * std::abs(exp_g_idx - gain_idx) * 5.0; } if (score < best_ev_score) { @@ -1011,10 +1008,10 @@ void CameraState::set_camera_exposure(float grey_frac) { const float cur_ev_ = cur_ev[buf.cur_frame_data.frame_id % 3]; // Scale target grey between 0.1 and 0.4 depending on lighting conditions - float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + ci->target_grey_factor*cur_ev_) / log2(6000.0), 0.1, 0.4); + float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + target_grey_factor*cur_ev_) / log2(6000.0), 0.1, 0.4); float target_grey = (1.0 - k_grey) * target_grey_fraction + k_grey * new_target_grey; - float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, ci->min_ev, ci->max_ev); + float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, min_ev, max_ev); float k = (1.0 - k_ev) / 3.0; desired_ev = (k * cur_ev[0]) + (k * cur_ev[1]) + (k * cur_ev[2]) + (k_ev * desired_ev); @@ -1025,16 +1022,16 @@ void CameraState::set_camera_exposure(float grey_frac) { // Hysteresis around high conversion gain // We usually want this on since it results in lower noise, but turn off in very bright day scenes bool enable_dc_gain = dc_gain_enabled; - if (!enable_dc_gain && target_grey < ci->dc_gain_on_grey) { + if (!enable_dc_gain && target_grey < dc_gain_on_grey) { enable_dc_gain = true; - dc_gain_weight = ci->dc_gain_min_weight; - } else if (enable_dc_gain && target_grey > ci->dc_gain_off_grey) { + dc_gain_weight = dc_gain_min_weight; + } else if (enable_dc_gain && target_grey > dc_gain_off_grey) { enable_dc_gain = false; - dc_gain_weight = ci->dc_gain_max_weight; + dc_gain_weight = dc_gain_max_weight; } - if (enable_dc_gain && dc_gain_weight < ci->dc_gain_max_weight) {dc_gain_weight += 1;} - if (!enable_dc_gain && dc_gain_weight > ci->dc_gain_min_weight) {dc_gain_weight -= 1;} + if (enable_dc_gain && dc_gain_weight < dc_gain_max_weight) {dc_gain_weight += 1;} + if (!enable_dc_gain && dc_gain_weight > dc_gain_min_weight) {dc_gain_weight -= 1;} std::string gain_bytes, time_bytes; if (env_ctrl_exp_from_params) { @@ -1053,14 +1050,14 @@ void CameraState::set_camera_exposure(float grey_frac) { } else { // Simple brute force optimizer to choose sensor parameters // to reach desired EV - for (int g = std::max((int)ci->analog_gain_min_idx, gain_idx - 1); g <= std::min((int)ci->analog_gain_max_idx, gain_idx + 1); g++) { - float gain = ci->sensor_analog_gains[g] * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); + for (int g = std::max((int)analog_gain_min_idx, gain_idx - 1); g <= std::min((int)analog_gain_max_idx, gain_idx + 1); g++) { + float gain = sensor_analog_gains[g] * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); // Compute optimal time for given gain - int t = std::clamp(int(std::round(desired_ev / gain)), ci->exposure_time_min, ci->exposure_time_max); + int t = std::clamp(int(std::round(desired_ev / gain)), exposure_time_min, exposure_time_max); // Only go below recommended gain when absolutely necessary to not overexpose - if (g < ci->analog_gain_rec_idx && t > 20 && g < gain_idx) { + if (g < analog_gain_rec_idx && t > 20 && g < gain_idx) { continue; } @@ -1073,12 +1070,12 @@ void CameraState::set_camera_exposure(float grey_frac) { measured_grey_fraction = grey_frac; target_grey_fraction = target_grey; - analog_gain_frac = ci->sensor_analog_gains[new_exp_g]; + analog_gain_frac = sensor_analog_gains[new_exp_g]; gain_idx = new_exp_g; exposure_time = new_exp_t; dc_gain_enabled = enable_dc_gain; - float gain = analog_gain_frac * (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight); + float gain = analog_gain_frac * (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight); cur_ev[buf.cur_frame_data.frame_id % 3] = exposure_time * gain; exp_lock.unlock(); @@ -1103,7 +1100,7 @@ void CameraState::set_camera_exposure(float grey_frac) { // t_HCG&t_LCG + t_VS on LPD, t_SPD on SPD uint32_t hcg_time = exposure_time; uint32_t lcg_time = hcg_time; - uint32_t spd_time = std::min(std::max((uint32_t)exposure_time, (ci->exposure_time_max + VS_TIME_MAX_OX03C10) / 3), ci->exposure_time_max + VS_TIME_MAX_OX03C10); + uint32_t spd_time = std::min(std::max((uint32_t)exposure_time, (exposure_time_max + VS_TIME_MAX_OX03C10) / 3), exposure_time_max + VS_TIME_MAX_OX03C10); uint32_t vs_time = std::min(std::max((uint32_t)exposure_time / 40, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); uint32_t real_gain = ox03c10_analog_gains_reg[new_exp_g]; diff --git a/system/camerad/cameras/camera_qcom2.h b/system/camerad/cameras/camera_qcom2.h index b1765aa582..87cdd091f6 100644 --- a/system/camerad/cameras/camera_qcom2.h +++ b/system/camerad/cameras/camera_qcom2.h @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -13,11 +12,12 @@ #include "common/util.h" #define FRAME_BUF_COUNT 4 +#define ANALOG_GAIN_MAX_CNT 55 class CameraState { public: MultiCameraState *multi_cam_state; - std::unique_ptr ci; + CameraInfo ci; bool enabled; std::mutex exp_lock; @@ -28,13 +28,32 @@ public: int gain_idx; float analog_gain_frac; + int exposure_time_min; + int exposure_time_max; + + float dc_gain_factor; + int dc_gain_min_weight; + int dc_gain_max_weight; + float dc_gain_on_grey; + float dc_gain_off_grey; + + float sensor_analog_gains[ANALOG_GAIN_MAX_CNT]; + int analog_gain_min_idx; + int analog_gain_max_idx; + int analog_gain_rec_idx; + int analog_gain_cost_delta; + float analog_gain_cost_low; + float analog_gain_cost_high; + float cur_ev[3]; + float min_ev, max_ev; float best_ev_score; int new_exp_g; int new_exp_t; float measured_grey_fraction; float target_grey_fraction; + float target_grey_factor; unique_fd sensor_fd; unique_fd csiphy_fd; diff --git a/system/camerad/sensors/ar0231.cc b/system/camerad/sensors/ar0231.cc index 10034a7c3c..7d7a454f7e 100644 --- a/system/camerad/sensors/ar0231.cc +++ b/system/camerad/sensors/ar0231.cc @@ -21,7 +21,7 @@ std::map> ar0231_build_register_lut(CameraState *c std::map> registers; for (int register_row = 0; register_row < 2; register_row++) { - uint8_t *registers_raw = data + c->ci->frame_stride * register_row; + uint8_t *registers_raw = data + c->ci.frame_stride * register_row; assert(registers_raw[0] == 0x0a); // Start of line int value_tag_count = 0; @@ -46,7 +46,7 @@ std::map> ar0231_build_register_lut(CameraState *c cur_addr += 2; first_val_idx = val_idx; } else { - registers[cur_addr] = std::make_pair(first_val_idx + c->ci->frame_stride * register_row, val_idx + c->ci->frame_stride * register_row); + registers[cur_addr] = std::make_pair(first_val_idx + c->ci.frame_stride * register_row, val_idx + c->ci.frame_stride * register_row); } value_tag_count++; @@ -80,7 +80,7 @@ float ar0231_parse_temp_sensor(uint16_t calib1, uint16_t calib2, uint16_t data_r void ar0231_process_registers(MultiCameraState *s, CameraState *c, cereal::FrameData::Builder &framed) { const uint8_t expected_preamble[] = {0x0a, 0xaa, 0x55, 0x20, 0xa5, 0x55}; - uint8_t *data = (uint8_t *)c->buf.cur_camera_buf->addr + c->ci->registers_offset; + uint8_t *data = (uint8_t *)c->buf.cur_camera_buf->addr + c->ci.registers_offset; if (memcmp(data, expected_preamble, std::size(expected_preamble)) != 0) { LOGE("unexpected register data found");