openCamera的 hal 端流程

本文从流程、代码、log三个方面介绍openCamera 0的hal端流程。

一,流程图

在这里插入图片描述

二,代码逻辑

从SprdCamera3Factory开始

int SprdCamera3Factory::open(const struct hw_module_t *module, const char *id,
                             struct hw_device_t **hw_device) {
    HAL_LOGD("E");
    return gSprdCamera3Factory.open_(module, id, hw_device);
}

继续调用SprdCamera3Factory的 open_ 函数:

  • 1,校验
  • 2,是否支持multicamera,并且为也是cameraId(我们以Camera 0为例说明,暂不考虑这些情况)
  • 3,继续调用 cameraDeviceOpen
int SprdCamera3Factory::open_(const struct hw_module_t *module, const char *id,
                              struct hw_device_t **hw_device) {
    //1,校验
    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);

    if (SPRD_FRONT_HIGH_RES == cameraId ||
        SPRD_BACK_HIGH_RESOLUTION_ID == cameraId) {
        sensor_set_HD_mode(1);
    } else {
        sensor_set_HD_mode(0);
    }

    /* try dynamic ID */
    if (mUseCameraId == DynamicId && cameraId < mNumberOfCameras) {
        int ret = mCameras[cameraId]->openCamera(hw_device);
        if (!ret && mTorchHelper)
            mTorchHelper->lockTorch(cameraId);
        return ret;
    }
    //2,是否支持multicamera,并且为也是cameraId(我们以Camera 0为例说明,暂不考虑这些情况)
#ifdef CONFIG_MULTICAMERA_SUPPORT
    /* try private multi-camera */
    if (cameraId == SPRD_MULTI_CAMERA_ID || cameraId == SPRD_FOV_FUSION_ID ||
        cameraId == SPRD_DUAL_VIEW_VIDEO_ID)
        return SprdCamera3MultiCamera::camera_device_open(module, id,
                                                          hw_device);
#endif

    if(atoi(id) == SPRD_BLUR_ID || atoi(id) == SPRD_PORTRAIT_ID)
        switchTuningParam((int)SENSOR_TUNING_PARAM_BOKEH);
    else
        switchTuningParam((int)SENSOR_TUNING_PARAM_DEFAULT);

    /* try other multi-camera */
    if (mWrapper && is_single_expose(cameraId))
        return mWrapper->cameraDeviceOpen(module, id, hw_device);
    //3,继续调用 cameraDeviceOpen
    /* then try single camera */
    return cameraDeviceOpen(cameraId, hw_device);
}

SprdCamera3Factory 的 cameraDeviceOpen 函数

  • 1,实例化 SprdCamera3HWI,并传入cameraId
  • 2,调用 SprdCamera3HWI 的 openCamera
int SprdCamera3Factory::cameraDeviceOpen(int camera_id,
                                         struct hw_device_t **hw_device) {
    int rc = NO_ERROR;
    int phyId = 0;
    int is_high_res_mode = 0;
    unsigned int on_off = 0;
    struct phySensorInfo *phyPtr = NULL;
    char prop[PROPERTY_VALUE_MAX];

    phyId = multi_id_to_phyid(camera_id);
    if (camera_id < 0 || phyId >= mNumOfCameras)
        return -ENODEV;

    if (phyId < 0)
        phyId = 0;
    phyPtr = sensorGetPhysicalSnsInfo(phyId);
    if (phyPtr->phyId != phyPtr->slotId)
        return -ENODEV;
    //1,实例化 SprdCamera3HWI,并传入cameraId
    SprdCamera3HWI *hw = new SprdCamera3HWI(phyId);

    if (!hw) {
        HAL_LOGE("Allocation of hardware interface failed");
        return NO_MEMORY;
    }

    // Only 3d calibration use this
    // TBD: move 3d calibration to multi camera
    HAL_LOGD("SPRD Camera Hal, camera_id=%d", camera_id);
    if (SPRD_3D_CALIBRATION_ID == camera_id) {
        hw->setMultiCameraMode(MODE_3D_CALIBRATION);
        property_set("vendor.cam.dualmode", "high_mode");
    }
    if (SPRD_BOKEH_CALI_GOLDEN_ID == camera_id) {
        hw->setMultiCameraMode(MODE_BOKEH_CALI_GOLDEN);
        property_set("vendor.cam.dualmode", "high_mode");
    }
    if (SPRD_OPTICSZOOM_W_ID == camera_id) {
        hw->setMultiCameraMode(MODE_OPTICSZOOM_CALIBRATION);
    }
    if (SPRD_OPTICSZOOM_T_ID == camera_id) {
        hw->setMultiCameraMode(MODE_OPTICSZOOM_CALIBRATION);
    }
    //2,调用 SprdCamera3HWI 的 openCamera
    rc = hw->openCamera(hw_device);
    if (rc != 0) {
        delete hw;
    } else {
        if (SPRD_FRONT_HIGH_RES == camera_id ||
            SPRD_BACK_HIGH_RESOLUTION_ID == camera_id) {
            is_high_res_mode = 1;
            hw->camera_ioctrl(CAMERA_TOCTRL_SET_HIGH_RES_MODE,
                              &is_high_res_mode, NULL);
        }

        property_get("persist.vendor.cam.ultrawide.enable", prop, "1");
        if (SPRD_ULTRA_WIDE_ID == camera_id)
            on_off = atoi(prop);
        hw->camera_ioctrl(CAMERA_IOCTRL_ULTRA_WIDE_MODE, &on_off, NULL);
    }

    return rc;
}

流程转到SprdCamera3HWI中

SprdCamera3HWI::openCamera(struct hw_device_t **hw_device) === 》
int SprdCamera3HWI::openCamera()

  • 1,创建SprdCamera3Setting,并传入mCameraId
  • 2,创建SprdCamera3OEMIf,并传入mCameraId
  • 3,调用SprdCamera3OEMIf的openCamera函数
int SprdCamera3HWI::openCamera() {
    ATRACE_CALL();

    int ret = NO_ERROR;

    HAL_LOGI(":hal3: E camId=%d", mCameraId);
    if (mCameraId >= CAMERA_ID_COUNT) {
        HAL_LOGE("hal_err: mCameraId is invalid");
        return UNKNOWN_ERROR;
    }

    if (mOEMIf) {
        HAL_LOGE("Failure: Camera already opened");
        return ALREADY_EXISTS;
    }
    //1,创建SprdCamera3Setting,并传入mCameraId
    mSetting = new SprdCamera3Setting(mCameraId);
    if (mSetting == NULL) {
        HAL_LOGE("alloc setting failed.");
        return NO_MEMORY;
    }
    //2,创建SprdCamera3OEMIf,并传入mCameraId
    mOEMIf = new SprdCamera3OEMIf(mCameraId, mSetting);
    if (!mOEMIf) {
        HAL_LOGE("alloc oemif failed.");
        if (mSetting) {
            delete mSetting;
            mSetting = NULL;
        }
        return NO_MEMORY;
    }

    mOEMIf->camera_ioctrl(CAMERA_IOCTRL_SET_MULTI_CAMERAMODE, &mMultiCameraMode,
                          NULL);
    mOEMIf->camera_ioctrl(CAMERA_IOCTRL_SET_MASTER_ID, &mMasterId, NULL);
    //3,调用SprdCamera3OEMIf的openCamera函数
    ret = mOEMIf->openCamera();
    if (ret) {
        HAL_LOGE("mOEMIf->openCamera failed");
        if (mOEMIf) {
            delete mOEMIf;
            mOEMIf = NULL;
        }
        if (mSetting) {
            delete mSetting;
            mSetting = NULL;
        }
        return ret;
    }
    mCameraOpened = true;

    if (mOEMIf->isIspToolMode()) {
        mOEMIf->ispToolModeInit();
        startispserver(mCameraId);
        ispvideo_RegCameraFunc(1, ispVideoStartPreview);
        ispvideo_RegCameraFunc(2, ispVideoStopPreview);
        ispvideo_RegCameraFunc(3, ispVideoTakePicture);
        ispvideo_RegCameraFunc(4, ispVideoSetParam);
        ispvideo_RegCameraFunc(5, ispVideoSetJpegQuality);
    }

    HAL_LOGI(":hal3: X");
    return NO_ERROR;
}

流程转到SprdCamera3OEMIf中

SprdCamera3OEMIf的openCamera函数很长,其中关键点在 调用oem层的camera_init函数,还有一些与otp相关的内容

ret = mHalOem->ops->camera_init(mCameraId, camera_cb, this, 0,
                                    &mCameraHandle, (void *)Callback_IonMalloc,
                                    (void *)Callback_Free);

三,log

打开主摄Camera的log

Cam3Factory的open
113381:11-16 15:37:51.194   460   985 D Cam3Factory: 171, open: E
113383:11-16 15:37:51.194   460   985 I Cam3Factory: 499, open_: open camera 0
构建SprdCamera3HWI
113391:11-16 15:37:51.195   460   985 I Cam3HWI : 127, SprdCamera3HWI: :hal3: Constructor E camId=0
113392:11-16 15:37:51.195   460   985 D Cam3HWI : 130, SprdCamera3HWI: mCameraId 0,mCameraDevice 0xe2dc1abc
113393:11-16 15:37:51.195   460   985 I Cam3HWI : 167, SprdCamera3HWI: :hal3: Constructor X
Cam3Factory的cameraDeviceOpen
113394:11-16 15:37:51.195   460   985 D Cam3Factory: 584, cameraDeviceOpen: SPRD Camera Hal, camera_id=0
SprdCamera3HWI的openCamera
113395:11-16 15:37:51.195   460   985 D Cam3HWI : 296, openCamera: camera3->open E
113396:11-16 15:37:51.195   460   985 I Cam3HWI : 339, openCamera: :hal3: E camId=0
构建SprdCamera3OEMIf
113397:11-16 15:37:51.195   460   985 I Cam3OEMIf: 607, SprdCamera3OEMIf: :hal3: Constructor E camId=0
113460:11-16 15:37:51.204   460   985 D Cam3OEMIf: 2732, setCameraState: X: camera state = SPRD_INIT, preview state = SPRD_IDLE, capture state = SPRD_IDLE focus state = SPRD_IDLE set param state = SPRD_IDLE
113528:11-16 15:37:51.212   460   985 I Cam3OEMIf: 675, SprdCamera3OEMIf: loaded libcamoem.so mHalOem->dso = 0x6a19bc5b
113529:11-16 15:37:51.212   460   985 I Cam3OEMIf: 812, SprdCamera3OEMIf: :hal3: Constructor X
SprdCamera3OEMIf的openCamera
113534:11-16 15:37:51.212   460   985 I Cam3OEMIf: 6687, openCamera: :hal3: E camId=0
113535:11-16 15:37:51.212   460   985 D Cam3OEMIf: 12188, log_monitor_thread_init: mLogMonitor init, 2
SprdCamera3OEMIf调用OEM端的camera_init
113538:11-16 15:37:51.213   460   985 I Cam3OEMIf: 6774, openCamera: :hal3: camera_init
113539:11-16 15:37:51.213   460  7952 I Cam3OEMIf: 12116, log_monitor_thread_proc: E, 2
114324:11-16 15:37:51.543   460   985 D Cam3OEMIf: 2732, setCameraState: X: camera state = SPRD_IDLE, preview state = SPRD_IDLE, capture state = SPRD_IDLE focus state = SPRD_IDLE set param state = SPRD_IDLE
114352:11-16 15:37:51.543   460   985 D Cam3OEMIf: 6823, openCamera: camera_id 0, mMultiCameraMode 0
114369:11-16 15:37:51.544   460   985 I Cam3OEMIf: 7054, openCamera: sprd_3dcalibration_cap_size w=3264, h=2448
114371:11-16 15:37:51.544   460   985 I Cam3OEMIf: 7065, openCamera: mIommuEnabled=1
114372:11-16 15:37:51.544   460   985 I Cam3OEMIf: 7331, setCamSecurity: multi camera mode = 0
114375:11-16 15:37:51.544   460  8005 D Cam3OEMIf: 11957, ZSLMode_monitor_thread_proc: zsl thread message.msg_type 0x801, sub-type 0x0, ret 0
114376:11-16 15:37:51.544   460  8005 D Cam3OEMIf: 11964, ZSLMode_monitor_thread_proc: zsl thread msg init
SprdCamera3OEMIf的openCamera结束
114377:11-16 15:37:51.544   460   985 I Cam3OEMIf: 7094, openCamera: :hal3: X
SprdCamera3HWI的openCamera结束
114378:11-16 15:37:51.544   460   985 I Cam3HWI : 394, openCamera: :hal3: X
114379:11-16 15:37:51.544   460   985 D Cam3HWI : 330, openCamera: camera3->open X mCameraSessionActive 1

我们看到Camera3Factory中的cametaId这个值,在实例化 SprdCamera3HWI、SprdCamera3Setting、SprdCamera3OEMIf时,均会传入。所以可以得知cameraId是与上述实例一对一绑定的,在closeCamera时,会将其实例销毁

版权声明:本文为CSDN博主「Caroline_cheng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010869159/article/details/121357790

生成海报
点赞 0

Caroline_cheng

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

Android Camera AE和AF的设置

以geekcamera为例,当关闭闪光灯时,flash mode 0,代表flash为off模式; ae mode 1,代表ae为off模式,flash state 2

Camera HIDL接口实现camera preview功能

项目背景 为了在工厂测试中快速启动芯片外设测试项目,而不启动Android系统,使用fastmmi(FFBM: Fast Factory Boot Mode)测试框架。本人负责测试芯片中

支持安卓与iphone13和安卓手机的5W无线充电芯片IC

无线充电系统包括初级和次级线圈,通过电磁场限度地相互耦合一起。两个线圈的铁氧体作为其结构的一部分进一步限度地提高场耦合。初级线圈是从AD-DC适配器供电给发射机以开关波形驱动。次级线圈连接整流能直接电池或电子充电器或二次稳压连接输