展锐的hal代码在:vendor\sprd\modules\libcamera下面,主要分为hal、oem、isp三大模块。
本篇我们来看下 hal3_2v6 这个文件夹下代码的流程。
我们知道,在CameraApp的下,有普通的Photo模式,还有类似双摄虚化要打开多颗摄像头,并且跑虚化算法的模式。展锐的hal对这两种类型的Module流程做了区分。
我们先直接把整个流程图给出来,在通过代码去详细跟进。
我们看到,整个流程是从SprdCamera3Factory处做了分支,我们详细来看下这个cpp文件。
1,SprdCamera3Factory的open方法
int SprdCamera3Factory::open_(const struct hw_module_t *module, const char *id,
struct hw_device_t **hw_device) {
2,参数的非空判断,及CameraId的判断
if (module != &HAL_MODULE_INFO_SYM.common) {
HAL_LOGE("invalid param module %p, expect %p", module,
&HAL_MODULE_INFO_SYM.common);
return -EINVAL;
}
if (!id || !hw_device) {
HAL_LOGE("invalid param");
return -EINVAL;
}
int idInt = atoi(id);
if (idInt < 0) {
HAL_LOGE("invalid param camera_id: %s", id);
return -EINVAL;
}
idInt = idCheck(idInt);
int cameraId = overrideCameraIdIfNeeded(idInt);
HAL_LOGI("open camera %d", cameraId);
3,dymamicId的判断
DynamicId 是一个枚举值,在SprdCamera3Factory.h中定义
enum UseCameraId {
PrivateId,
DynamicId,
};
if (mUseCameraId == DynamicId && cameraId < mNumberOfCameras) {
int ret = mCameras[cameraId]->openCamera(hw_device);
if (!ret && mTorchHelper)
mTorchHelper->lockTorch(cameraId);
return ret;
}
log打印 mUseCameraId 的置为 PrivateId,此 if 走不进去
4,判断是否为前摄或者后摄虚化
if(atoi(id) == SPRD_BLUR_ID || atoi(id) == SPRD_PORTRAIT_ID)
switchTuningParam((int)SENSOR_TUNING_PARAM_BOKEH);
else
switchTuningParam((int)SENSOR_TUNING_PARAM_DEFAULT);
5,is_single_expose的判断
/* try other multi-camera */
if (mWrapper && is_single_expose(cameraId)){
return mWrapper->cameraDeviceOpen(module, id, hw_device);
}
/* then try single camera */
return cameraDeviceOpen(cameraId, hw_device);
我们看到,这里通过is_single_expose的值来判断是走mWrapper的cameraDeviceOpen,还是SprdCamera3Factory的cameraDeviceOpen
我们看下 is_single_expose 的逻辑
bool SprdCamera3Factory::is_single_expose(int cameraId) {
HAL_LOGD("mPhysicalSensorNum=%d MAX_ID=%d cameraId=%d", SprdCamera3Setting::mPhysicalSensorNum, SPRD_MULTI_CAMERA_MAX_ID, cameraId);
if ((SprdCamera3Setting::mPhysicalSensorNum > cameraId) ||
(cameraId > SPRD_MULTI_CAMERA_MAX_ID)) {
return false;
}
if ((SPRD_REFOCUS_ID == cameraId) || (SPRD_3D_CALIBRATION_ID == cameraId) ||
(SPRD_BOKEH_CALI_GOLDEN_ID == cameraId) ||
(SPRD_ULTRA_WIDE_ID == cameraId) ||
(SPRD_BACK_HIGH_RESOLUTION_ID == cameraId) ||
(SPRD_FRONT_HIGH_RES == cameraId) ||
(SPRD_OPTICSZOOM_W_ID == cameraId) ||
(SPRD_OPTICSZOOM_T_ID == cameraId)) {
return false;
}
return true;
}
这里有个multi_camera的概念:
- 常规模式,比如 Photo、Video是单纯的打开某一颗摄像头,且不在额外跑算法的module,所以openCamera的时候就是单纯的0、1。
- 像双摄虚化(需打开两个摄像头)、人像模式都要在基于Photo模式下,在额外跑虚化算法的,他们在openCamera的时候就不在是0、1、2这样的Camera id号了
在cmr_common.h中定义了multi_mode 与 multi_cameraId的对应枚举关系
typedef enum {
MODE_SINGLE_CAMERA = 0,
MODE_3D_VIDEO,
MODE_RANGE_FINDER,
MODE_3D_CAPTURE,
MODE_3D_CALIBRATION,
MODE_REFOCUS,
MODE_3D_PREVIEW,
MODE_SOFY_OPTICAL_ZOOM,
MODE_BLUR,
MODE_SELF_SHOT,
MODE_PAGE_TURN,
MODE_BLUR_FRONT,
MODE_BOKEH,
MODE_SBS,
MODE_SINGLE_FACEID_REGISTER,
MODE_SINGLE_FACEID_UNLOCK,
MODE_DUAL_FACEID_REGISTER,
MODE_DUAL_FACEID_UNLOCK,
MODE_TUNING,
MODE_3D_FACE,
MODE_ULTRA_WIDE,
MODE_MULTI_CAMERA,
MODE_PORTRAIT,
MODE_OPTICSZOOM_CALIBRATION,
MODE_PORTRAIT_SINGLE,
MODE_3D_FACEID_REGISTER,
MODE_3D_FACEID_UNLOCK,
MODE_FOV_FUSION,
MODE_DUAL_VIEW_VIDEO,
MODE_PORTRAIT_SCENE,
MODE_BOKEH_CALI_GOLDEN,
MODE_CAMERA_MAX
} multiCameraMode;
typedef enum {
SPRD_MULTI_CAMERA_BASE_ID = 16,
SPRD_3D_FACE_ID,
SPRD_RANGE_FINDER_ID,
SPRD_3D_CAPTURE_ID,
SPRD_3D_CALIBRATION_ID = 20,
SPRD_REFOCUS_ID,
SPRD_3D_PREVIEW_ID,
SPRD_SOFY_OPTICAL_ZOOM_ID,
SPRD_BLUR_ID,
SPRD_SELF_SHOT_ID = 25,
SPRD_PAGE_TURN_ID,
SPRD_BLUR_FRONT_ID,
SPRD_BOKEH_ID,
SPRD_SBS_ID,
SPRD_SINGLE_FACEID_REGISTER_ID = 30,
SPRD_SINGLE_FACEID_UNLOCK_ID,
SPRD_DUAL_FACEID_REGISTER_ID,
SPRD_DUAL_FACEID_UNLOCK_ID,
SPRD_3D_VIDEO_ID,
SPRD_ULTRA_WIDE_ID = 35,
SPRD_MULTI_CAMERA_ID = 36,
SPRD_BACK_HIGH_RESOLUTION_ID = 37,
SPRD_PORTRAIT_ID = 38,
SPRD_FRONT_HIGH_RES = 39,
SPRD_OPTICSZOOM_W_ID = 40,
SPRD_OPTICSZOOM_T_ID = 41,
SPRD_PORTRAIT_SINGLE_ID = 42,
SPRD_3D_FACEID_REGISTER_ID = 46,
SPRD_3D_FACEID_UNLOCK_ID = 47,
SPRD_FOV_FUSION_ID = 48,
SPRD_PORTRAIT_SCENE_FRONT_ID = 52,
SPRD_PORTRAIT_SCENE_REAR_ID = 53,
SPRD_DUAL_VIEW_VIDEO_ID = 54,
SPRD_BOKEH_CALI_GOLDEN_ID = 55,
SPRD_MULTI_CAMERA_MAX_ID
} multiCameraId;
其中前摄人像模式
MODE_PORTRAIT_SINGLE —》SPRD_PORTRAIT_SINGLE_ID
双摄虚化
MODE_BLUR —》 SPRD_BLUR_ID
我们在回到上面 is_single_expose 的判断
bool SprdCamera3Factory::is_single_expose(int cameraId) {
HAL_LOGD("mPhysicalSensorNum=%d MAX_ID=%d cameraId=%d", SprdCamera3Setting::mPhysicalSensorNum, SPRD_MULTI_CAMERA_MAX_ID, cameraId);
if ((SprdCamera3Setting::mPhysicalSensorNum > cameraId) ||
(cameraId > SPRD_MULTI_CAMERA_MAX_ID)) {
return false;
}
if ((SPRD_REFOCUS_ID == cameraId) || (SPRD_3D_CALIBRATION_ID == cameraId) ||
(SPRD_BOKEH_CALI_GOLDEN_ID == cameraId) ||
(SPRD_ULTRA_WIDE_ID == cameraId) ||
(SPRD_BACK_HIGH_RESOLUTION_ID == cameraId) ||
(SPRD_FRONT_HIGH_RES == cameraId) ||
(SPRD_OPTICSZOOM_W_ID == cameraId) ||
(SPRD_OPTICSZOOM_T_ID == cameraId)) {
return false;
}
return true;
}
- 如果是普通的后摄Photo模式,cameraId = 0 ,会进入第一个if,return fase,这样就走到SprdCamera3Factory的cameraOpenDevice流程
- 如果是前摄人像模式,cameraId = 42,两个if都走不进去,return true,这样就走wrapper的cameraOpenDevice流程
这样就去区分了普通 Photo模式 和 人像模式 了。
为了避免篇幅过长,本篇我们就只介绍这个流程分支的关键条件,后面关于普通Photo模式openCamera的流程 和 以人像模式为代表的multiCamera的openCamera流程,我们在下篇文章在做介绍。