上篇我们介绍了在openCamera的时候,SprdCamera3Factory会根据CameraId来判断是直接调用SprdCamera3HWI去openCamera , 还是通过SprdCamera3Wrapper去走multiCamera的流程。
本篇我们介绍下通过SprdCamera3HWI去openCamera的流程。multiCamera的openCamera流程其实也是基于普通模式的流程的,只不过在普通模式的流程上添加了额外的算法流程,我们后面会在单独介绍SprdCamera3Wrapper的那套流程。
从SprdCamera3HWI开启的openCamera流程,前半部分比较简单,就是一直单纯的往下调,会从hal3_2v6 调到 oem 。其中cmr_oem.c是oem模块下最上层的统筹接口。
主要逻辑就是集中在cmr_oem.c的 camera_init_internal 方法中。我们贴下该函数的源码
- CONVERED_CAMERA_INIT 的判断是 在blur模式,并且cameraId >=2
- camera_sensor_init
- camera_grab_init
- camera_res_init
- camera_isp_init
- camera_res_init_done
- camera_jpeg_init_async
- 各阶段init失败的处理
cmr_int camera_init_internal(cmr_handle oem_handle, cmr_uint is_autotest) {
ATRACE_BEGIN(__FUNCTION__);
cmr_int ret = CMR_CAMERA_SUCCESS;
cmr_int ret_deinit = CMR_CAMERA_SUCCESS;
char value[PROPERTY_VALUE_MAX];
pthread_mutex_lock(&close_mutex);
while (closing != 0) {
pthread_cond_wait(&close_cond, &close_mutex);
}
pthread_mutex_unlock(&close_mutex);
struct camera_context *cxt = (struct camera_context *)oem_handle;
CMR_LOGD("E");
/* for multicamera mode,when open convered sensor,only need to init sensor
* and res
*/
if (CONVERED_CAMERA_INIT) {
ret = camera_sensor_init(oem_handle, is_autotest);
if (ret) {
CMR_LOGE("failed to init sensor %ld", ret);
goto exit;
}
ret = camera_res_init(oem_handle);
if (ret) {
CMR_LOGE("failed to init res %ld", ret);
goto grab_deinit;
}
ret = camera_res_init_done(oem_handle);
goto exit;
}
ret = camera_sensor_init(oem_handle, is_autotest);
if (ret) {
CMR_LOGE("failed to init sensor %ld", ret);
goto exit;
}
ret = camera_grab_init(oem_handle);
if (ret) {
CMR_LOGE("failed to init grab %ld", ret);
goto sensor_deinit;
}
ret = camera_res_init(oem_handle);
if (ret) {
CMR_LOGE("failed to init res %ld", ret);
goto grab_deinit;
}
ret = camera_isp_init(oem_handle);
if (ret) {
CMR_LOGE("failed to init isp %ld", ret);
goto res_deinit;
}
ret = camera_res_init_done(oem_handle);
if (ret) {
CMR_LOGE("failed to wait res done %ld", ret);
goto isp_deinit;
}
ret = camera_jpeg_init_async(oem_handle);
if (ret) {
CMR_LOGE("failed to init jpeg %ld", ret);
goto isp_deinit;
}
#ifdef CONFIG_CAMERA_MM_DVFS_SUPPORT
pthread_mutex_lock(&mm_dvfs_mutex);
ret = camera_mm_dvfs_init(oem_handle);
pthread_mutex_unlock(&mm_dvfs_mutex);
if (ret)
CMR_LOGE("failed to init mm dvfs %ld", ret);
ret = CMR_CAMERA_SUCCESS;
#endif
camera_front_lcd_enhance_module_init(oem_handle);
property_get("persist.vendor.cam.all_data.mode", value, "0");
if (!strcmp(value, "cap_all")) {
cxt->dbg_cxt.inited = 1;
cxt->dbg_cxt.dump_bits = 1;
}
goto exit;
isp_deinit:
ret_deinit = camera_isp_deinit_notice(oem_handle);
if (ret_deinit) {
CMR_LOGE("failed to camera_isp_deinit_notice %ld", ret_deinit);
}
ret_deinit = camera_isp_deinit(oem_handle);
if (ret_deinit) {
CMR_LOGE("failed to camera_isp_deinit %ld", ret_deinit);
}
res_deinit:
ret_deinit = camera_res_deinit(oem_handle);
if (ret_deinit) {
CMR_LOGE("failed to camera_res_deinit %ld", ret_deinit);
}
grab_deinit:
ret_deinit = camera_grab_deinit(oem_handle);
if (ret_deinit) {
CMR_LOGE("failed to camera_grab_deinit %ld", ret_deinit);
}
sensor_deinit:
ret_deinit = camera_sensor_deinit(oem_handle);
if (ret_deinit) {
CMR_LOGE("failed to camera_sensor_deinit %ld", ret_deinit);
}
exit:
CMR_LOGD("X");
ATRACE_END();
return ret;
}
这其中包含了6个init的函数,每个init在展开又是对应oem下的一个模块,内容非常多,我们还是做了一个图来说明。
我们看到,以cmr_oem.c为入口,openCamera的流程做了非常多的初始化工作,其中 camera_sensor_init 是要跟sensor硬件交互的,其它还有跟preview、setting、snapshot相关的内容。以后有机会我们在展开说明。