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); } } } } #define BRIGHT_REGION_RANGE 0.6 #define DYNAMIC_REGION_THRESHOLD 1.2 static boolean keda_backlight_algo (aec_biz_t *aec, const stats_t * stats) { if (!aec || !stats) { AEC_ERR("Invalid input: %p,%p" ,aec, stats); return FALSE; } 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 ; int grid_count = q3a_bg_stats->bg_region_h_num * q3a_bg_stats->bg_region_v_num; 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]; } 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); } } for (i=0 ; i<grid_count; i++){ if (grid_region[i] != 0 ){ grid_v_num = i/q3a_bg_stats->bg_region_h_num/v_step; grid_h_num = i%q3a_bg_stats->bg_region_h_num/h_step; 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 ; } } 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]; } } 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_weight和backlight_set_parameter,其中backlight_set_parameter中有数组指针,很可能是指针的访问越界了。
指针有两个属性:指向变量/对象的地址和长度,但是指针只存储地址,长度则取决于指针的类型
void指针赋值给其他类型的指针时都要进行转换,void指针不能参与指针运算,除非进行转换
这是他们初始化的地方,直接对backlight_set_parameter进行memcpy,值得注意的是其中有一个void*指针,由于指针只是一个8个或者4个字节的类型,因此这样赋值是没有问题的,而指针的类型只是和指针的运算有关系,在后面的运算中进行强制类型转换就可以了。
这里还需要注意两个问题:
相比较来说,第二种情况更有可能,因此进行分析,从初始化的地方搜寻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]这里的数据是没有问题的。