高通Camera驱动(2)-- open&initialize

码字不易,多谢支持

前文回顾

简单介绍Camx架构,接下来看下initialize流程

一、open&initialize 流程

    1.1 原文解读


 * 1. Framework calls camera_module_t->common.open(), which returns a
 *    hardware_device_t structure.
 *
 * 2. Framework inspects the hardware_device_t->version field, and instantiates
 *    the appropriate handler for that version of the camera hardware device. In
 *    case the version is CAMERA_DEVICE_API_VERSION_3_0, the device is cast to
 *    a camera3_device_t.
 *
 * 3. Framework calls camera3_device_t->ops->initialize() with the framework
 *    callback function pointers. This will only be called this one time after
 *    open(), before any other functions in the ops structure are called.

1、打开相机:framework这块调用common结构体的方法,camera_module_t-> common.open(),在hw_module_methods_t这块的open你的方法来打开特定 Camera,返回一个的 hardware_device_t结构。
2、检查设备硬件版本,并为之实例化:framework检查hardware_device_t-> version字段,并为该版本的相机硬件设备实例化适当的处理程序。 如果版本为CAMERA_DEVICE_API_VERSION_3_0,则设备将投射到的camera3_device_t。
3、初始化:在open()之后,ops结构中的任何其他函数之前,只调用一次initialize。framework使用framework回调函数指针调用1camera3_device_t-> ops->camera3_device_ops的 initialize()。

    1.2  官网文档

           《80-pc212-1_a_chi_api_specifications_for_qualcomm_spectra_2xx_camera.pdf》简单介绍初始化驱动的过程

      

     1.3 代码分析

               Framework到HAL3的衔接在上一篇文章概述了  Framework和HAL3之间概述,还是简单顺一下framework这块的逻辑。

            hardware/interfaces/camera/provider/2.4/default/CameraProvider_2_4.cpp    中 (1)创建 CameraProvider对象 (2)获取ExternalCameraProviderImpl_2_4实例

            hardware/interfaces/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp 中  (1)创建ExternalCameraDevice 对象

            hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp 中 (1)open  

            hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp  中 (1)initialize

               代码分析这块直接从camxhal3entry.cpp 开始撸代码。

               注意camxhal3entry.cpp这块和Framework的映射关系

              

      1.3.1  open

            vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp

int open(
    const struct hw_module_t*   pHwModuleAPI,
    const char*                 pCameraIdAPI,
    struct hw_device_t**        ppHwDeviceAPI)
{
    /// @todo (CAMX-43) - Reload Jumptable from settings
    JumpTableHAL3* pHAL3 = static_cast<JumpTableHAL3*>(g_dispatchHAL3.GetJumpTable());


    return pHAL3->open(pHwModuleAPI, pCameraIdAPI, ppHwDeviceAPI);
}

           (1)camxhal3entry.cpp这块 ops都是用JumpTable来获取到 camxhal3.cpp 中的JumpTableHAL3的跳转,open也不例外

        vendor/qcom/proprietary/camx/src/core/hal/camxhal3.cpp  

static int open(
    const struct hw_module_t*   pHwModuleAPI,
    const char*                 pCameraIdAPI,
    struct hw_device_t**        ppHwDeviceAPI)
{
    //省略一些断言判断

    if ((NULL != pHwModuleAPI) &&
        (NULL != pHwModuleAPI->id) &&
        (NULL != pHwModuleAPI->name) &&
        (NULL != pHwModuleAPI->author) &&
        (NULL != pHwModuleAPI->methods) &&
        (NULL != pCameraIdAPI) &&
        ('\0' != pCameraIdAPI[0]) &&
        (NULL != ppHwDeviceAPI))
    {


        if (CamxResultSuccess == result)
        {
            // Framework camera ID should only be known to these static landing functions, and the remap function
            logicalCameraId = GetCHIAppCallbacks()->chi_remap_camera_id(cameraId, IdRemapCamera);

            // Reserve the Torch resource for camera.
            // If torch already switched on, then turn it off and reserve for camera.
            HAL3Module::GetInstance()->ReserveTorchForCamera(
                GetCHIAppCallbacks()->chi_remap_camera_id(cameraId, IdRemapTorch), cameraId);

            // Sample code to show how the VOID* can be used in ExtendOpen
            ChiOverrideExtendOpen extend                  = { 0 };
            ChiOverrideToken tokenList[NumExtendSettings] = { { 0 } };
            extend.pTokens                                = tokenList;

            GenerateExtendOpenData(NumExtendSettings, &extend);

            // Reserve the camera to detect if it is already open or too many concurrent are open
            CAMX_LOG_CONFIG(CamxLogGroupHAL, "HalOp: Begin OPEN, logicalCameraId: %d, cameraId: %d",
                            logicalCameraId, cameraId);
            result = HAL3Module::GetInstance()->ProcessCameraOpen(logicalCameraId, &extend);
        }

        //省略一些modifySetting的操作

        CAMX_LOG_CONFIG(CamxLogGroupHAL, "HalOp: End OPEN, logicalCameraId: %d, cameraId: %d",
                        logicalCameraId, cameraId);
    }
 

    return Utils::CamxResultToErrno(result);
}

            (1)camxhal3.cpp 这块的open函数,重要的是 调用ProcessCameraOpen

            (2)open函数之前 GetCHIAppCallbacks 会链接HAL3Module,后面的操作可以访问到HAL3Module的函数

         vendor/qcom/proprietary/camx/src/core/hal/camxhal3module.cpp

CamxResult HAL3Module::ProcessCameraOpen(
    UINT32  logicalCameraId,
    VOID*   pPriv)
{
    CamxResult result   = CamxResultSuccess;

    //省略无效camera id、已经被使用camera id、CameraOpen个数大于最大值 判断
    {
        result = m_ChiAppCallbacks.chi_extend_open(logicalCameraId, pPriv);

        if (CamxResultSuccess == result)
        {
            m_perCameraInfo[logicalCameraId].isCameraOpened = TRUE;
            m_numCamerasOpened++;
            CAMX_LOG_CONFIG(CamxLogGroupHAL, "number of Camera Opened %d", m_numCamerasOpened);
        }

    }

    return result;
}

             (1)camxhal3module.cpp这块的ProcessCameraOpen函数,重要的是 调用chi_extend_open

             (2) m_ChiAppCallbacks 这块是由 HAL3Module函数中

                    CHIHALOverrideEntry funcCHIHALOverrideEntry =
                    reinterpret_cast<CHIHALOverrideEntry>(
                        CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry"));

                     if (NULL != funcCHIHALOverrideEntry)
                    {
                           funcCHIHALOverrideEntry(&m_ChiAppCallbacks);

     

        vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensioninterface.cpp

static CDKResult chi_extend_open(
    uint32_t    cameraId,
    void*       priv)
{
    ExtensionModule* pExtensionModule = ExtensionModule::GetInstance();

    return pExtensionModule->ExtendOpen(cameraId, priv);
}

               (1)chxextensioninterface.cpp这块的chi_extend_open函数,重要的是 调用ExtendOpen

               (2)是通过加头文件#include "chioverride.h" ,从camxhal3module.cpp 调到 chxextensioninterface.cpp

   

        vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp 

               (1)配置参数,没有多少实际意义

CDKResult ExtensionModule::ExtendOpen(
    uint32_t  logicalCameraId,
    VOID*     pPriv)
{
    // The ExtensionModule has been initialized, and if there is any work needed to be done during HAL open, this is where
    // to add that code

    // sample code...this uses the input to create a data structure used to hold configuration settings
    ChiOverrideExtendOpen* pExtend = static_cast<ChiOverrideExtendOpen*>(pPriv);
    UINT32     openCameraCost      = m_singleISPResourceCost;
    CDKResult  result              = CDKResultSuccess;

    if ((NULL == m_pConfigSettings) || (pExtend->numTokens > MaxConfigSettings))
    {
        CHX_LOG_ERROR("ExtendOpen failed! m_pConfigSettings=%p, numTokens=%d MaxConfigSettings=%d",
                      m_pConfigSettings, pExtend->numTokens, MaxConfigSettings);
        result = CDKResultEInvalidArg;
    }

    if (m_logicalCameraInfo[logicalCameraId].numPhysicalCameras > 1)
    {
        openCameraCost = m_singleISPResourceCost * 2; // dual/multi
    }

    if ((CDKResultSuccess == result) && (openCameraCost + CostOfAnyCurrentlyOpenLogicalCameras()) > m_totalResourceBudget)
    {
        CHX_LOG_ERROR("ExtendOpen failed! HW resource insufficient! openCameraCost=%d"
                    "CostOfAnyCurrentlyOpenLogicalCameras =%d, m_totalResourceBudget = %d",
                    openCameraCost, CostOfAnyCurrentlyOpenLogicalCameras(), m_totalResourceBudget);
        result = CamxResultETooManyUsers; // over capacity
    }
    if (CDKResultSuccess == result)
    {
        if (NULL == m_pPerfLockManager[logicalCameraId])
        {
            m_pPerfLockManager[logicalCameraId] = PerfLockManager::Create();
            if (NULL == m_pPerfLockManager[logicalCameraId])
            {
                CHX_LOG_ERROR("Failed to create perflock manager %d", logicalCameraId);
            }
        }

        if (NULL != m_pPerfLockManager[logicalCameraId])
        {
            m_pPerfLockManager[logicalCameraId]->AcquirePerfLock(PERF_LOCK_OPEN_CAMERA, 1000);
        }

        MappingConfigSettings(pExtend->numTokens, static_cast<VOID*>(pExtend->pTokens));

        // Update camera open and close status in static settings
        for (UINT8 index = 0; index < m_logicalCameraInfo[logicalCameraId].numPhysicalCameras; index++)
        {
            UINT32 cameraId = m_logicalCameraInfo[logicalCameraId].ppDeviceInfo[index]->cameraId;
            *m_pOverrideCameraOpen     |=  (1 << cameraId);
            *m_pOverrideCameraClose    &= ~(1 << cameraId);
        }
        CHX_LOG_INFO("Open Logical cameraId: %d  numPhysicalCameras: %d"
                    "CameraOpen Mask = 0x%x CameraClose Mask 0x%x",
                    logicalCameraId, m_logicalCameraInfo[logicalCameraId].numPhysicalCameras,
                    *m_pOverrideCameraOpen, *m_pOverrideCameraClose);

        m_TeardownInProgress = FALSE;
        m_RecoveryInProgress = FALSE;
    }

    return result;
}

       1.3.2 initialize

       vendor/qcom/proprietary/camx/src/core/hal/camxhal3entry.cpp

int initialize(
    const struct camera3_device*    pCamera3DeviceAPI,
    const camera3_callback_ops_t*   pCamera3CbOpsAPI)
{
    JumpTableHAL3* pHAL3 = static_cast<JumpTableHAL3*>(g_dispatchHAL3.GetJumpTable());

    //省略一部分判断赋值的操作
    return pHAL3->initialize(pCamera3DeviceAPI, pCamera3CbOpsAPI);
}

     

       vendor/qcom/proprietary/camx/src/core/hal/camxhal3.cpp  

static int initialize(
    const struct camera3_device*    pCamera3DeviceAPI,
    const camera3_callback_ops_t*   pCamera3CbOpsAPI)
{
    CAMX_ENTRYEXIT_SCOPE(CamxLogGroupHAL, SCOPEEventHAL3Initialize);

    CamxResult result = CamxResultSuccess;

    CAMX_ASSERT(NULL != pCamera3DeviceAPI);
    CAMX_ASSERT(NULL != pCamera3DeviceAPI->priv);

    CAMX_LOG_INFO(CamxLogGroupHAL, "initialize(): %p, %p", pCamera3DeviceAPI, pCamera3CbOpsAPI);

    if ((NULL != pCamera3DeviceAPI) &&
        (NULL != pCamera3DeviceAPI->priv))
    {
        HALDevice* pHALDevice = GetHALDevice(pCamera3DeviceAPI);
        pHALDevice->SetCallbackOps(pCamera3CbOpsAPI);
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupHAL, "Invalid argument(s) for initialize()");
        // HAL interface requires -ENODEV (EFailed) if initialization fails for any reason, including invalid arguments.
        result = CamxResultEFailed;
    }

    return Utils::CamxResultToErrno(result);
}

               (1) GetHALDevice 获取当前HAL的device

             (2)  SetCallbackOps 设置回调

            vendor/qcom/proprietary/camx/src/core/hal/camxhaldevice.cpp

CamxResult HALDevice::Initialize(
    const HwModule* pHwModule,
    UINT32          cameraId)
{
    CamxResult result = CamxResultSuccess;

    m_cameraId = cameraId;

    if (CamxResultSuccess == result)
    {
        m_camera3Device.hwDevice.tag     = HARDWARE_DEVICE_TAG; /// @todo (CAMX-351) Get from local macro

#if ((CAMX_ANDROID_API) && (CAMX_ANDROID_API >= 28)) // Android-P or better
        m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_5;
#else
        m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_3;
#endif // ((CAMX_ANDROID_API) && (CAMX_ANDROID_API >= 28))

        m_camera3Device.hwDevice.close   = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());
        m_camera3Device.pDeviceOps       = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());
        m_camera3Device.pPrivateData     = this;
        // NOWHINE CP036a: Need exception here
        m_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);

        m_HALCallbacks.process_capture_result = ProcessCaptureResult;
        m_HALCallbacks.notify_result          = Notify;
    }

    m_pHALSession = NULL;
    Utils::Memset(m_flushRequest, 0, sizeof(m_flushRequest));

    SIZE_T                entryCapacity;
    SIZE_T                dataSize;
    HAL3MetadataUtil::CalculateSizeAllMeta(&entryCapacity, &dataSize, TagSectionVisibleToFramework);

    m_pResultMetadata = HAL3MetadataUtil::CreateMetadata(
            entryCapacity,
            dataSize);

    for (UINT i = RequestTemplatePreview; i < RequestTemplateCount; i++)
    {
        if (NULL == m_pDefaultRequestMetadata[i])
        {
            ConstructDefaultRequestSettings(static_cast<Camera3RequestTemplate>(i));
        }
    }

    const StaticSettings* pStaticSettings = HwEnvironment::GetInstance()->GetStaticSettings();

    m_numPartialResult = pStaticSettings->numMetadataResults;

    /* We will increment the Partial result count by 1 if CHI also has its own implementation */
    if (CHIPartialDataSeparate == pStaticSettings->enableCHIPartialData)
    {
        m_numPartialResult++;
    }

    if (TRUE == pStaticSettings->enableThermalMitigation)
    {
        ThermalManager* pThermalManager = HAL3Module::GetInstance()->GetThermalManager();
        if (NULL != pThermalManager)
        {
            CamxResult resultThermalReg = pThermalManager->RegisterHALDevice(this);
            if (CamxResultEResource == resultThermalReg)
            {
                result = resultThermalReg;
            }
            // else Ignore result even if it fails. We don't want camera to fail due to any issues with initializing the
            // thermal engine
        }
    }

    return result;
}

            (1)设置m_HALCallbacks( <--HAL callbacks provided to the CHI override)的 Resutl和 Notify的回调

            (2)计算所有meta的size,生成metadata

            (3)构建默认请求配置、获取静态配置

            (4)注册HAL Device

二、LOG

      01-24 13:29:53.274   779   779 I CamX    : [CONFIG][HAL    ] camxhal3.cpp:406 open() HalOp: Begin OPEN, logicalCameraId: 0, cameraId: 0

      01-24 13:29:53.276   779   779 I CHIUSECASE: [INFO   ] chxextensionmodule.cpp:553 ExtendOpen() Open Logical cameraId: 0  numPhysicalCameras: 1CameraOpen Mask = 0x1 CameraClose Mask 0x0
      01-24 13:29:53.276   779   779 I CamX    : [CONFIG][HAL    ] camxhal3module.cpp:598 ProcessCameraOpen() number of Camera Opened 1

      01-24 13:29:53.276   779   779 I CamX    : [CONFIG][HAL    ] camxhal3.cpp:466 open() HalOp: End OPEN, logicalCameraId: 0, cameraId: 0

三、常见问题

         //TODO:回家吃饭,小伙子明天再搞

猜你喜欢

转载自blog.csdn.net/weixin_38328785/article/details/112847229