8056平台中如何实现对aec模块重载chromatix?

过程

第一版本

void search_dynamic_region(char *array, int x, int y,int row,int col) {
int i,j;
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
if (x + i >= 0 && x + i < row &&
y + j >= 0 && y + j < col &&
(x || y == 1) && array[(x + i)*col + y + j] == 1) {
array[(x + i)*col + y + j] = 2;
search_dynamic_region(array, x + i, y + j, row, col);
}
}
}
}

//BRIGHT_REGION_RANGE range:0.1-1.0 值越小,亮区越大
#define BRIGHT_REGION_RANGE 0.6
//DYNAMIC_REGION_THRESHOLD range:>1.0 值越小,越容易判定为动态亮区
#define DYNAMIC_REGION_THRESHOLD 1.2
static boolean keda_backlight_algo(aec_biz_t *aec, const stats_t* stats)
{
//detect input
if (!aec || !stats) {
AEC_ERR("Invalid input: %p,%p",aec, stats);
return FALSE;
}

//define var
char value[PROPERTY_VALUE_MAX];
float aec_ratio = 1;
float aec_dynamic_ratio=1000,aec_static_ratio=1;
chromatix_3a_parms_type *chromatix;
const q3a_bg_stats_t* q3a_bg_stats = stats->bayer_stats.p_q3a_bg_stats;
uint32_t threhold_h = q3a_bg_stats->rMax * q3a_bg_stats->region_pixel_cnt * BRIGHT_REGION_RANGE /4;
chromatix = (chromatix_3a_parms_type*)backlight_set_parameter.u.init_param.chromatix;
if (!chromatix) {
AEC_ERR("Invalid chromatix: %p", chromatix)
return FALSE;
}
int v_step = q3a_bg_stats->bg_region_v_num/NUM_AEC_STATS;
int h_step = q3a_bg_stats->bg_region_h_num/NUM_AEC_STATS;
static uint32_t bg_sum[MAX_BG_STATS_NUM]={0};
char grid_region[MAX_BG_STATS_NUM] ={0};
int grid_v_num, grid_h_num;
int weight_grid_count[NUM_AEC_STATS][NUM_AEC_STATS] = {{0}};
uint32_t bg_count=0;

if (property_get("persist.liqinxing.backlight", value, "") > 0){
aec_static_ratio = atoi(value)/1000.0;
//reduce traverse times and prevent data overflow
int grid_count = q3a_bg_stats->bg_region_h_num * q3a_bg_stats->bg_region_v_num;
//find bright region and dynamic spot
int i,j;
for(i = 0; i < grid_count; i++){
if(q3a_bg_stats->bg_r_sum[i] > threhold_h ||
q3a_bg_stats->bg_gr_sum[i] > threhold_h ||
q3a_bg_stats->bg_b_sum[i] > threhold_h){
bg_count = q3a_bg_stats->bg_r_sum[i]+q3a_bg_stats->bg_gr_sum[i]+
q3a_bg_stats->bg_gb_sum[i]+q3a_bg_stats->bg_b_sum[i];
if(bg_count*10/bg_sum[i] > 12)
grid_region[i] = 2;
else
grid_region[i] = 1;
}
bg_sum[i] = q3a_bg_stats->bg_r_sum[i]+q3a_bg_stats->bg_gr_sum[i]+
q3a_bg_stats->bg_gb_sum[i]+q3a_bg_stats->bg_b_sum[i];
}

//find dynamic bright region
for(i=0; i < grid_count; i++){
if(grid_region[i] == 2){
search_dynamic_region(grid_region, i/q3a_bg_stats->bg_region_h_num,
i%q3a_bg_stats->bg_region_h_num, q3a_bg_stats->bg_region_v_num,
q3a_bg_stats->bg_region_h_num);
}

}

//convert to aec weight grid table
for(i=0; i
if(grid_region[i] != 0){
grid_v_num = i/q3a_bg_stats->bg_region_h_num/v_step;//calculate current position v
grid_h_num = i%q3a_bg_stats->bg_region_h_num/h_step;//calculate current position h
if(grid_region[i] == 2)
weight_grid_count[grid_v_num][grid_h_num] = 2;
else if(weight_grid_count[grid_v_num][grid_h_num] != 2)
weight_grid_count[grid_v_num][grid_h_num] = 1;
}
}

//pthread_rwlock_wrlock(&chromatix->lock);

for(i=0; i < NUM_AEC_STATS; i++){
for(j=0; j < NUM_AEC_STATS; j++){
if(weight_grid_count[i][j] == 2){
chromatix->AEC_algo_data.aec_metering_tables.AEC_weight_center_weighted[i][j] =
keda_exposure_weight[i][j] * aec_dynamic_ratio;
}
else if(weight_grid_count[i][j] == 1)
chromatix->AEC_algo_data.aec_metering_tables.AEC_weight_center_weighted[i][j] =
keda_exposure_weight[i][j] * aec_static_ratio;
else
chromatix->AEC_algo_data.aec_metering_tables.AEC_weight_center_weighted[i][j] =
keda_exposure_weight[i][j];
}
}
//pthread_rwlock_unlock(&chromatix->lock);

if (aec->aec_algo_ops.set_parameters) {
aec->aec_algo_ops.set_parameters(aec->handle, &backlight_set_parameter);
} else {
return FALSE;
}
}
return TRUE;
}

问题一:一运行就崩溃

访问了禁止访问的区域?

chromatix_3a_parms_type *chromatix = (chromatix_3a_parms_type*)param->u.init_param.chromatix;
backlight_set_parameter.type = AEC_SET_INIT_CHROMATIX_SENSOR;
memcpy(&backlight_set_parameter.u.init_param, ¶m->u.init_param,
sizeof(aec_set_parameter_init_t));
int i,j;
for(i=0;i < NUM_AEC_STATS; i++)
for(j=0;j < NUM_AEC_STATS; j++)
keda_exposure_weight[i][j] =
chromatix->AEC_algo_data.aec_metering_tables.AEC_weight_center_weighted[i][j];

这里主要定义了二维数组keda_exposure_weightbacklight_set_parameter,其中backlight_set_parameter中有数组指针,很可能是指针的访问越界了。

指针有两个属性:指向变量/对象的地址和长度,但是指针只存储地址,长度则取决于指针的类型

void指针赋值给其他类型的指针时都要进行转换,void指针不能参与指针运算,除非进行转换

这是他们初始化的地方,直接对backlight_set_parameter进行memcpy,值得注意的是其中有一个void*指针,由于指针只是一个8个或者4个字节的类型,因此这样赋值是没有问题的,而指针的类型只是和指针的运算有关系,在后面的运算中进行强制类型转换就可以了。

这里还需要注意两个问题:

  • 这个初始化函数是否运行,因为没有运行意味着没有对void*指针进行初始化

  • 对void*指向的内容进行读取或者修改,也就是说对chromatix参数进行修改,是否这个参数只是一个函数的局部变量或者形参。运行完函数就会丢弃。

相比较来说,第二种情况更有可能,因此进行分析,从初始化的地方搜寻chromatix指针的来源。在aec_port中我们可以发现:此处init_param.chromatix的数据,指向的是event->u.module_event->module_event_data->chromatix3APtr

modulesChromatix_t *mod_chrom =
(modulesChromatix_t *)mod_evt->module_event_data;
q3a_thread_aecawb_msg_t *aec_msg = aec_port_malloc_msg(MSG_AEC_SET,
AEC_SET_PARAM_INIT_CHROMATIX_SENSOR);
aec_msg->u.aec_set_parm.u.init_param.chromatix = mod_chrom->chromatix3APtr;
rc = q3a_aecawb_thread_en_q_msg(private->thread_data, aec_msg);

在sensor模块中的sensor_util_post_chromatix_event_downstream函数中我们可以看到

module_chromatix.chromatix3APtr =
s_bundle->chromatix_metadata.a3_chromatix_ptr =
chromatix_params->chromatix_ptr[SENSOR_CHROMATIX_3A];
new_event.u.module_event.module_event_data =
(void *)&module_chromatix;

module_event中就可以获取到chromatix数据的地址,我们只需要将chromatix数据的地址保存下来,就算之后module_event的数据发生了改变,但是chromatix的数据还没进行改变就行了。

不过此时需要注意memcpy的地方,因为这个地方就不是传递地址了,是对值进行传递,后来的变量可能会被回收。

可以看到eztune获取chromatix数据时就是将chromatix_params.chromatix_ptr[SENSOR_CHROMATIX_3A]复制到eztune的结构体中,而设置chromatix参数时是将extune结构体中的chromatix参数复制到chromatix_params.chromatix_ptr[SENSOR_CHROMATIX_3A]中,由此我们也可以进行对chromatix的重载。

重载chromatix的新想法

是否可以对chromatix数据进行实时加载?通过设置persist,告诉chromatix修改了哪些地方的值,一个type对应一组数据,这个type可以用ADD_ENTRY的方式去定义数组字符串的方式去查找。而数据的话如果比较多就写入文件,这样就不需要全文读取。

memcpy(chromatix->aaa_chromatixData, chromatix_params.chromatix_ptr[SENSOR_CHROMATIX_3A], sizeof(chromatix_3a_parms_type));

回归正题,可以既然extune是可以对chromatix数据进行修改,且能够生效,我们就可以确定chromatix_params.chromatix_ptr[SENSOR_CHROMATIX_3A]这里的数据是没有问题的。