高通capability获取流程以及预览拍照如何判断走驱动的哪个res设置

一capacity的获取流程:

Qcamera2HWI.cpp

int QCamera2HardwareInterface::openCamera()

{

if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {

LOGE("initCapabilities failed.");

rc = UNKNOWN_ERROR;

goto error_exit3;

}

}

int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,

mm_camera_vtbl_t *cameraHandle)

{

cameraHandle->ops->map_bufs(cameraHandle->camera_handle,

&bufMapList);

cameraHandle->ops->query_capability(cameraHandle->camera_handle);

}

cameraHandle是Mm_camera_interface.c中的g_cam_ctrl.cam_obj[camera_idx]->vtbl; cam_obj->vtbl.ops = &mm_camera_ops;

所以会调用static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)

{

rc = mm_camera_query_capability(my_obj);

}

Mm_camera.c中的int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)

{

ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);

}

通过一些复杂的调用,会跑到mct_pipeline.c中的

static boolean mct_pipeline_process_get(struct msm_v4l2_event_data *data,

mct_pipeline_t *pipeline)

{

case MSM_CAMERA_PRIV_QUERY_CAP: {

/* for queryBuf */

ret &= mct_list_traverse(pipeline->modules, mct_pipeline_query_modules,

pipeline);//各个module去获取capability

if (!pipeline->query_buf || !pipeline->modules) {

CLOGE(CAM_MCT_MODULE,

"NULL ptr detected! query_buf = [%p] module list = [%p]",

pipeline->query_buf, pipeline->modules);

ret = FALSE;

} else {

/* fill up HAL's query buffer with query_data

extracted during start_session */

ret = mct_pipeline_populate_query_cap_buffer(pipeline);//填充capability

}

}

}

static boolean mct_pipeline_query_modules(void *data, void *user_data)

{

boolean ret = TRUE;

mct_pipeline_t *pipeline = (mct_pipeline_t *)user_data;

mct_module_t *module   = (mct_module_t *)data;

if (!pipeline || !module)

return FALSE;

if (module->query_mod) {

ret = module->query_mod(module, &pipeline->query_data, pipeline->session);

if(FALSE == ret)

CLOGE(CAM_MCT_MODULE, "Query mod failed on %s",

MCT_MODULE_NAME(module));

}

return ret;

}

调用各个module的query_mod来查询capacity,具体在sensor这块,是调用

static boolean module_sensor_query_mod(mct_module_t *module,

void *buf, uint32_t sessionid)

二预览拍照如何判断走驱动的哪个res设置:

Sensor_pick_res.c中的int32_t sensor_pick_resolution(void *sctrl,

sensor_set_res_cfg_t *res_cfg, int32_t *pick_res)函数,res_cfg上层需要的尺寸,会从sensor驱动提供的最小的分辨率开始做各种检测,找到合适的res配置。

for(i = 0; i<SEN_COND_MAX; i++){

((*sensor_pick->pick)[i][sensor_pick->usecase])

}

const check_func_t check_v1 = {

[SEN_COND_FPS] = sensor_pick_check_fps,

[SEN_COND_BOUNDED_FPS] = sensor_pick_check_bounded_fps,

[SEN_COND_ASPR] = sensor_pick_check_aspect_ratio,

[SEN_COND_W] = sensor_pick_check_width,

[SEN_COND_H] = sensor_pick_check_height,

[SEN_COND_CLK] = sensor_pick_check_pixclk,

[SEN_COND_MODE_QUADRA] = sensor_pick_check_mode,

[SEN_COND_MODE_HFR] = sensor_pick_check_mode,

[SEN_COND_MODE_DEF] = sensor_pick_check_mode,

[SEN_COND_MODE_IHDR] = sensor_pick_check_mode,

[SEN_COND_MODE_RHDR] = sensor_pick_check_mode,

[SEN_COND_MODE_MPIX] = sensor_pick_check_mpix,

[SEN_COND_MODE_BEST_RES] = sensor_pick_check_best_res

};

其中res_cfg是需要输出的分辨率,这个分辨率是从哪里来的呢?从hardware层开始描述:

Qcamera2HWI.CPP中streamInfo->dim这个记录了一个stream需要的分辨率,这个分辨率是apk通过setpreviewsize/setpicutresize等设置下来的。

Port_sensor.c中的函数static boolean port_sensor_caps_reserve(mct_port_t *port,

void __attribute__((unused))*peer_caps, void *info)

{

if (stream_info->pp_config.rotation == ROTATE_90 ||

stream_info->pp_config.rotation == ROTATE_270) {

if (bundle_info.s_bundle->max_width< (uint32_t)stream_info->dim.height)

bundle_info.s_bundle->max_width =

(uint32_t)stream_info->dim.height;

if (bundle_info.s_bundle->max_height< (uint32_t)stream_info->dim.width)

bundle_info.s_bundle->max_height =

(uint32_t)stream_info->dim.width;

} else {

if (bundle_info.s_bundle->max_width < (uint32_t)stream_info->dim.width)

bundle_info.s_bundle->max_width =

(uint32_t)stream_info->dim.width;

if (bundle_info.s_bundle->max_height < (uint32_t)stream_info->dim.height)

bundle_info.s_bundle->max_height =

(uint32_t)stream_info->dim.height;

}

}

这个函数非常关键,根据stream传下来的width和height,如果大于bundle的设置,则赋值给bundle。Bundle指向的就是某一颗sensor,可以通过s_bundle->sensor_info->session_id标记。也就是说这个port或者说sensor上有多少个stream(一般拍照预览有CAM_STREAM_TYPE_PREVIEW、CAM_STREAM_TYPE_SNAPSHOT、CAM_STREAM_TYPE_ANALYSIS三个stream),这颗sensor使用的max_width就是这三个stream的最大值

Module_sensor.c

static boolean module_sensor_is_ready_for_stream_on(mct_port_t *port,

mct_event_t *event, sensor_set_res_cfg_t *res_cfg,

module_sensor_bundle_info_t *s_bundle, int32_t bundle_id)

{

res_cfg->width       = s_bundle->max_width;

res_cfg->height      = s_bundle->max_height;

res_cfg->stream_mask = s_bundle->stream_mask;

}//需要设置的分辨率获取,在下面的函数中使用

boolean module_sensor_stream_on(mct_module_t *module,

mct_event_t *event, module_sensor_bundle_info_t *s_bundle)

{

stream_on_flag = module_sensor_is_ready_for_stream_on(port, event,

&stream_on_cfg, s_bundle, bundle_id);

ret = module_sensor_set_new_resolution_stream_on(module, event, s_bundle,

module_sensor_params, &stream_on_cfg, stream_info);

}

boolean module_sensor_set_new_resolution_stream_on(mct_module_t *module,

mct_event_t *event, module_sensor_bundle_info_t *s_bundle,

module_sensor_params_t* module_sensor_params,

sensor_set_res_cfg_t *stream_on_cfg, mct_stream_info_t* stream_info)

{

retVal = modules_sensor_set_new_resolution(module, event, s_bundle,

module_sensor_params, stream_on_cfg, &is_retry, stream_info);

}

boolean modules_sensor_set_new_resolution(mct_module_t *module,

mct_event_t *event,

module_sensor_bundle_info_t *s_bundle,

module_sensor_params_t *module_sensor_params,

sensor_set_res_cfg_t *stream_on_cfg,

boolean *is_retry,

mct_stream_info_t *stream_info)

{

rc = module_sensor_get_pick_data(s_bundle, &s_bundle->stream_size_info,

stream_on_cfg);//这边更新stream_on_cfg的其他设置

rc = module_sensor_params->func_tbl.process(

module_sensor_params->sub_module_private,

SENSOR_SET_RESOLUTION, &set_res);

}

static int32_t sensor_set_resolution(void *sctrl, void *data)

{

rc = sensor_pick_resolution(sctrl, res_cfg, &res);

}//这个位置就是去获取sensor驱动提供的哪一组res配置

另外preview size会在获取capacity的时候做lcd显示尺寸的限制。

四fps_ranges_tbl获取:

typedef struct {

float min_fps;

float max_fps;

float video_min_fps;

float video_max_fps;

} cam_fps_range_t;

(0)

相关推荐