Hal3_2v6模块介绍---整体流程

展锐的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流程,我们在下篇文章在做介绍。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值