camerad: switch on-sensor binning to BPS downscaling (#37876)

* update blob

* fixed

* didnt catch this

* add back

* needs BLC built in

* for real

* attempt2

* clean up override

* this should keep ox as was

* disable for OX

* update descs

---------

Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
ZwX1616
2026-04-23 16:55:37 -07:00
committed by GitHub
parent 63068481d7
commit ad875632ac
6 changed files with 87 additions and 76 deletions
File diff suppressed because one or more lines are too long
+54 -12
View File
@@ -466,8 +466,11 @@ void SpectraCamera::config_bps(int idx, int request_id) {
* BPS = Bayer Processing Segment
*/
int size = sizeof(struct cam_packet) + sizeof(struct cam_cmd_buf_desc)*2 + sizeof(struct cam_buf_io_cfg)*2;
size += sizeof(struct cam_patch_desc)*12;
bool needs_downscale = sensor->out_scale > 1;
int num_io_cfgs = needs_downscale ? 3 : 2;
int num_patches = needs_downscale ? 14 : 12;
int size = sizeof(struct cam_packet) + sizeof(struct cam_cmd_buf_desc)*2 + sizeof(struct cam_buf_io_cfg)*num_io_cfgs;
size += sizeof(struct cam_patch_desc)*num_patches;
uint32_t cam_packet_handle = 0;
auto pkt = m->mem_mgr.alloc<struct cam_packet>(size, &cam_packet_handle);
@@ -607,7 +610,7 @@ void SpectraCamera::config_bps(int idx, int request_id) {
tmp.header = CAM_ICP_CMD_GENERIC_BLOB_CLK;
tmp.header |= (sizeof(cam_icp_clk_bw_request)) << 8;
tmp.clk.budget_ns = 0x1fca058;
tmp.clk.frame_cycles = 2329024; // comes from the striping lib
tmp.clk.frame_cycles = sensor->frame_width * sensor->frame_height; // matches striping lib pixelCount
tmp.clk.rt_flag = 0x0;
tmp.clk.uncompressed_bw = 0x38512180;
tmp.clk.compressed_bw = 0x38512180;
@@ -622,7 +625,7 @@ void SpectraCamera::config_bps(int idx, int request_id) {
}
// *** io config ***
pkt->num_io_configs = 2;
pkt->num_io_configs = num_io_cfgs;
pkt->io_configs_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf;
struct cam_buf_io_cfg *io_cfg = (struct cam_buf_io_cfg *)((char*)&pkt->payload + pkt->io_configs_offset);
{
@@ -666,11 +669,39 @@ void SpectraCamera::config_bps(int idx, int request_id) {
io_cfg[1].format = CAM_FORMAT_NV12; // TODO: why is this 21 in the dump? should be 12
io_cfg[1].color_space = CAM_COLOR_SPACE_BT601_FULL;
io_cfg[1].resource_type = CAM_ICP_BPS_OUTPUT_IMAGE_FULL;
io_cfg[1].resource_type = needs_downscale ? CAM_ICP_BPS_OUTPUT_IMAGE_REG1 : CAM_ICP_BPS_OUTPUT_IMAGE_FULL;
io_cfg[1].fence = sync_objs_bps[idx];
io_cfg[1].direction = CAM_BUF_OUTPUT;
io_cfg[1].subsample_pattern = 0x1;
io_cfg[1].framedrop_pattern = 0x1;
if (needs_downscale) {
// downscaling needs a full res placeholder
uint32_t full_stride, full_y_h, full_uv_h, full_yuv_size;
std::tie(full_stride, full_y_h, full_uv_h, full_yuv_size) = get_nv12_info(sensor->frame_width, sensor->frame_height);
io_cfg[2].mem_handle[0] = bps_fullres_dummy.handle;
io_cfg[2].mem_handle[1] = bps_fullres_dummy.handle;
io_cfg[2].planes[0] = (struct cam_plane_cfg){
.width = sensor->frame_width,
.height = sensor->frame_height,
.plane_stride = full_stride,
.slice_height = full_y_h,
};
io_cfg[2].planes[1] = (struct cam_plane_cfg){
.width = sensor->frame_width,
.height = sensor->frame_height / 2,
.plane_stride = full_stride,
.slice_height = full_uv_h,
};
io_cfg[2].offsets[1] = ALIGNED_SIZE(full_stride * full_y_h, 0x1000);
io_cfg[2].format = CAM_FORMAT_NV12;
io_cfg[2].color_space = CAM_COLOR_SPACE_BT601_FULL;
io_cfg[2].resource_type = CAM_ICP_BPS_OUTPUT_IMAGE_FULL;
io_cfg[2].fence = sync_objs_bps[idx];
io_cfg[2].direction = CAM_BUF_OUTPUT;
io_cfg[2].subsample_pattern = 0x1;
io_cfg[2].framedrop_pattern = 0x1;
}
}
// *** patches ***
@@ -690,9 +721,17 @@ void SpectraCamera::config_bps(int idx, int request_id) {
// input frame
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[0].ptr[0]), buf_handle_raw[idx], 0);
// output frame
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[0]), buf_handle_yuv[idx], 0);
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[1]), buf_handle_yuv[idx], io_cfg[1].offsets[1]);
if (needs_downscale) {
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[0]), bps_fullres_dummy.handle, 0);
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[1]), bps_fullres_dummy.handle, io_cfg[2].offsets[1]);
// output frame at REG1
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[7].ptr[0]), buf_handle_yuv[idx], 0);
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[7].ptr[1]), buf_handle_yuv[idx], io_cfg[1].offsets[1]);
} else {
// output frame at FULL
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[0]), buf_handle_yuv[idx], 0);
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[1]), buf_handle_yuv[idx], io_cfg[1].offsets[1]);
}
// rest of buffers
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, settings_addr), bps_iq.handle, 0);
@@ -1003,9 +1042,6 @@ bool SpectraCamera::openSensor() {
LOGD("-- Probing sensor %d", cc.camera_num);
auto init_sensor_lambda = [this](SensorInfo *s) {
if (s->image_sensor == cereal::FrameData::ImageSensor::OS04C10 && cc.output_type == ISP_IFE_PROCESSED) {
((OS04C10*)s)->ife_downscale_configure();
}
sensor.reset(s);
return (sensors_init() == 0);
};
@@ -1183,7 +1219,13 @@ void SpectraCamera::configICP() {
// used internally by the BPS, we just allocate it.
// size comes from the BPSStripingLib
bps_cdm_striping_bl.init(m, 0xa100, 0x20, true, m->icp_device_iommu);
bps_cdm_striping_bl.init(m, 0xcfe0, 0x20, true, m->icp_device_iommu);
if (sensor->out_scale > 1) {
uint32_t full_stride, full_y_h, full_uv_h, full_yuv_size;
std::tie(full_stride, full_y_h, full_uv_h, full_yuv_size) = get_nv12_info(sensor->frame_width, sensor->frame_height);
bps_fullres_dummy.init(m, full_yuv_size, 0x1000, true, m->icp_device_iommu);
}
// LUTs
assert(sensor->linearization_lut.size() == 36);
+1
View File
@@ -174,6 +174,7 @@ public:
SpectraBuf bps_striping;
SpectraBuf bps_linearization_lut;
SpectraBuf bps_gamma_lut;
SpectraBuf bps_fullres_dummy;
std::vector<uint32_t> bps_lin_reg;
std::vector<uint32_t> bps_ccm_reg;
+6 -17
View File
@@ -21,27 +21,16 @@ const uint32_t os04c10_analog_gains_reg[] = {
} // namespace
void OS04C10::ife_downscale_configure() {
out_scale = 2;
pixel_size_mm = 0.002;
frame_width = 2688;
frame_height = 1520;
exposure_time_max = 2352;
init_reg_array.insert(init_reg_array.end(), std::begin(ife_downscale_override_array_os04c10), std::end(ife_downscale_override_array_os04c10));
}
OS04C10::OS04C10() {
image_sensor = cereal::FrameData::ImageSensor::OS04C10;
bayer_pattern = CAM_ISP_PATTERN_BAYER_BGBGBG;
pixel_size_mm = 0.004;
pixel_size_mm = 0.002;
data_word = false;
// hdr_offset = 64 * 2 + 8; // stagger
frame_width = 1344;
frame_height = 760; //760 * 2 + hdr_offset;
frame_stride = (frame_width * 12 / 8); // no alignment
out_scale = 2;
frame_width = 2688;
frame_height = 1520;
frame_stride = frame_width * 12 / 8;
extra_height = 0;
frame_offset = 0;
@@ -65,7 +54,7 @@ OS04C10::OS04C10() {
dc_gain_on_grey = 0.9;
dc_gain_off_grey = 1.0;
exposure_time_min = 2;
exposure_time_max = 1684;
exposure_time_max = 2352;
analog_gain_min_idx = 0x0;
analog_gain_rec_idx = 0x0; // 1x
analog_gain_max_idx = 0x28;
+17 -37
View File
@@ -4,7 +4,7 @@ const struct i2c_random_wr_payload start_reg_array_os04c10[] = {{0x100, 1}};
const struct i2c_random_wr_payload stop_reg_array_os04c10[] = {{0x100, 0}};
const struct i2c_random_wr_payload init_array_os04c10[] = {
// baseed on DP_2688X1520_NEWSTG_MIPI0776Mbps_30FPS_10BIT_FOURLANE
// OS04C10_AA_00_02_17_wAO_2688x1524_MIPI728Mbps_Linear12bit_20FPS_4Lane_MCLK24MHz
{0x0103, 0x01}, // software reset
// PLL + clocks
@@ -93,7 +93,7 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x388b, 0x00},
{0x3c80, 0x10},
{0x3c86, 0x00},
{0x3c8c, 0x20},
{0x3c8c, 0x40},
{0x3c9f, 0x01},
{0x3d85, 0x1b},
{0x3d8c, 0x71},
@@ -197,7 +197,7 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x370b, 0x48},
{0x370c, 0x01},
{0x370f, 0x00},
{0x3714, 0x28},
{0x3714, 0x24},
{0x3716, 0x04},
{0x3719, 0x11},
{0x371a, 0x1e},
@@ -229,7 +229,7 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x37bd, 0x01},
{0x37bf, 0x26},
{0x37c0, 0x11},
{0x37c2, 0x14},
{0x37c2, 0x04},
{0x37cd, 0x19},
{0x37e0, 0x08},
{0x37e6, 0x04},
@@ -239,14 +239,14 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x37d8, 0x02},
{0x37e2, 0x10},
{0x3739, 0x10},
{0x3662, 0x08},
{0x3662, 0x10},
{0x37e4, 0x20},
{0x37e3, 0x08},
{0x37d9, 0x04},
{0x37d9, 0x08},
{0x4040, 0x00},
{0x4041, 0x03},
{0x4008, 0x01},
{0x4009, 0x06},
{0x4041, 0x07},
{0x4008, 0x02},
{0x4009, 0x0d},
// FSIN - frame sync
{0x3002, 0x22},
@@ -267,20 +267,20 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x3802, 0x00}, {0x3803, 0x00},
{0x3804, 0x0a}, {0x3805, 0x8f},
{0x3806, 0x05}, {0x3807, 0xff},
{0x3808, 0x05}, {0x3809, 0x40},
{0x380a, 0x02}, {0x380b, 0xf8},
{0x3808, 0x0a}, {0x3809, 0x80},
{0x380a, 0x05}, {0x380b, 0xf0},
{0x3811, 0x08},
{0x3813, 0x08},
{0x3814, 0x03},
{0x3814, 0x01},
{0x3815, 0x01},
{0x3816, 0x03},
{0x3816, 0x01},
{0x3817, 0x01},
{0x380c, 0x0b}, {0x380d, 0xac}, // HTS (line length)
{0x380e, 0x06}, {0x380f, 0x9c}, // VTS (frame length)
{0x380c, 0x08}, {0x380d, 0x5c}, // HTS (line length)
{0x380e, 0x09}, {0x380f, 0x38}, // VTS (frame length)
{0x3820, 0xb3},
{0x3821, 0x01},
{0x3820, 0xb0},
{0x3821, 0x00},
{0x3880, 0x00},
{0x3882, 0x20},
{0x3c91, 0x0b},
@@ -330,23 +330,3 @@ const struct i2c_random_wr_payload init_array_os04c10[] = {
{0x5104, 0x08}, {0x5105, 0xd6},
{0x5144, 0x08}, {0x5145, 0xd6},
};
const struct i2c_random_wr_payload ife_downscale_override_array_os04c10[] = {
// based on OS04C10_AA_00_02_17_wAO_2688x1524_MIPI728Mbps_Linear12bit_20FPS_4Lane_MCLK24MHz
{0x3c8c, 0x40},
{0x3714, 0x24},
{0x37c2, 0x04},
{0x3662, 0x10},
{0x37d9, 0x08},
{0x4041, 0x07},
{0x4008, 0x02},
{0x4009, 0x0d},
{0x3808, 0x0a}, {0x3809, 0x80},
{0x380a, 0x05}, {0x380b, 0xf0},
{0x3814, 0x01},
{0x3816, 0x01},
{0x380c, 0x08}, {0x380d, 0x5c}, // HTS
{0x380e, 0x09}, {0x380f, 0x38}, // VTS
{0x3820, 0xb0},
{0x3821, 0x00},
};
-1
View File
@@ -98,7 +98,6 @@ public:
class OS04C10 : public SensorInfo {
public:
OS04C10();
void ife_downscale_configure();
std::vector<i2c_random_wr_payload> getExposureRegisters(int exposure_time, int new_exp_g, bool dc_gain_enabled) const override;
float getExposureScore(float desired_ev, int exp_t, int exp_g_idx, float exp_gain, int gain_idx) const override;
int getSlaveAddress(int port) const override;