camx框架-Camera初始化

1. camera provider

目录:hardware/interfaces/camera/

service.cpp->cameraprovider_2_4.cpp(HIDL_FETCH_ICameraProvider)->HIDL_FETCH_ICameraProvider->new CameraProvider()->LegacyCameraProviderImpl_2_4.cpp(LegacyCameraProviderImpl_2_4::initialize)->hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&rawModule); -> new CameraModule(rawModule) -> CameraModule.cpp(通过CAMERA_HARDWARE_MODULE_ID寻找到camx的hal3)

2. camx hal3

A. init:先调用mModule->init (CameraModule.cpp),通过ID 进入camxhal3entry.cpp入口,在init通过static_cast(g_dispatchHAL3.GetJumpTable()) ,进入到camxhal3.cpp的init方法。同时也调用了getNumberOfCameras, 在camxhal3.cpp中HAL3Module::GetInstance,通过HAL3Module::GetInstance()静态方法实例化了HAL3Module对象,
在其构造方法里面通过HwEnvironment::GetInstance()静态方法又实例化了HwEnvironment对象,
在其构造方法中,实例化了SettingsManager对象,然后又在它构造方法中通过OverrideSettingsFile对象获取了位于/vendor/etc/camera/camoverridesettings.txt文件中的平台相关的配置信息(通过这种Override机制方便平台厂商加入自定义配置),该配置文件中,可以加入平台特定的配置项,比如可以通过设置multiCameraEnable的值来表示当前平台是否支持多摄,或者通过设置overrideLogLevels设置项来配置CamX-CHI部分的Log输出等级等等。

camx/src/core/hal/camxhal3entry.cpp

CAMX_VISIBILITY_PUBLIC camera_module_t HAL_MODULE_INFO_SYM =
{
    .common =
    {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = CAMERA_MODULE_API_VERSION_CURRENT,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = CAMERA_HARDWARE_MODULE_ID,
        .name               = "QTI Camera HAL",
        .author             = "Qualcomm Technologies, Inc.",
        .methods            = &CamX::g_hwModuleMethods
    },
    .get_number_of_cameras  = CamX::get_number_of_cameras,
    .get_camera_info        = CamX::get_camera_info,
    .set_callbacks          = CamX::set_callbacks,
    .get_vendor_tag_ops     = CamX::get_vendor_tag_ops,
    .open_legacy            = CamX::open_legacy,
    .set_torch_mode         = CamX::set_torch_mode,
    .init                   = CamX::init
};
static camera3_device_ops_t g_camera3DeviceOps =
{
    .initialize                         = CamX::initialize,
    .configure_streams                  = CamX::configure_streams,
    .construct_default_request_settings = CamX::construct_default_request_settings,
    .process_capture_request            = CamX::process_capture_request,
    .dump                               = CamX::dump,
    .flush                              = CamX::flush,
};

int init()
{
    JumpTableHAL3* pHAL3 = static_cast(g_dispatchHAL3.GetJumpTable());

    CAMX_ASSERT(pHAL3);
    CAMX_ASSERT(pHAL3->init);

    return pHAL3->init();
}

 camx/src/core/hal/camxhal3.cpp

static int get_number_of_cameras(void)
{
    CAMX_ENTRYEXIT_SCOPE(CamxLogGroupHAL, SCOPEEventHAL3GetNumberOfCameras);

    return static_cast(HAL3Module::GetInstance()->GetNumCameras());
}

B.  同时在HwEnvironment构造方法中会调用其Initialize方法,其中mode为CSLHwEnabled, 在该方法中实例化了CSLModeManager对象,并通过CSLModeManager提供的接口,获取了所有底层支持的硬件设备信息,其中包括了Camera Request Manager、CAPS模块(该驱动模块主要用于CSL获取Camera平台驱动信息,以及IPE/BPS模块的电源控制)以及Sensor/IPE/Flash等硬件模块,还加载了chi-cdk的so库,并且通过调用CSLHwInternalProbeSensorHW方法获取了当前设备安装的Sensor模组信息,并且将获取的信息暂存起来,等待后续阶段使用,总得来说在HwEnvironment初始化的过程中,通过探测方法获取了所有底层的硬件驱动模块,并将其信息存储下来供后续阶段使用。其中用到event事件的用法。

camx\src\core\camxhwenvironment.cpp

CamxResult HwEnvironment::Initialize()
{
    result = CSLInitialize(¶ms); //open subdev等等设备
    result = ProbeChiComponents(pExternalComponent, &m_numExternalComponent); //加载chi-cdk库
    
}

HwEnvironment* HwEnvironment::GetInstance()
{
    static HwEnvironment s_HwEnvironmentSingleton;


    if (InitCapsInitialize == s_HwEnvironmentSingleton.m_initCapsStatus)
    {
        s_HwEnvironmentSingleton.InitCaps();  
    }

    return &s_HwEnvironmentSingleton;
}

VOID HwEnvironment::InitCaps()
{
        EnumerateDevices();
        ProbeImageSensorModules();  //读取com.qti.sensormodule.*.bin
        EnumerateSensorDevices();  //CSLEnumerateDevices->CSLHwInternalProbeSensorHW,下发                
                                   //CAM_SENSOR_PROBE_CMD,match硬件是否成功;
        InitializeSensorSubModules(); //check VIDIOC_SUBSCRIBE_EVENT(V4L_EVENT_CAM_REQ_MGR_SENSOR_LOCK) CAM_HANDLE_USER_POINTER 
        InitializeSensorStaticCaps();

    result = m_staticEntryMethods.GetStaticCaps(&m_platformCaps[0]); //camxtitan17xcontext.cpp 
}

VOID HwEnvironment::ProbeImageSensorModules()
{
    result = ImageSensorModuleDataManager::Create(&pSensorManager, this); //获取驱动module数据
    cam_map |= set_cam_map(pSensorName); // 比对驱动sensor_name 和hal定义是否一致。
    result = pData->Probe(&detected, &deviceIndex); //ImageSensorModuleData::Probe 
}

 camx\src\csl\hw\camxcslhw.cpp

CamxResult CSLInitializeHW()
{
  // 查找并获取/dev/videoX 设备,该节点对应着Kernel部分的Request Manager
  CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideodevice, CAM_VNODE_DEVICE_TYPE);
  // 查找并获取/dev/v4l-subdevX cpas设备
  CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideoSubdevice, CAM_CPAS_DEVICE_TYPE);
  // 查找并获取/dev/v4l-subdevX其它设备,诸如Sensor/IFE/IPE/Flash等
  CSLHwEnumerateAndAddCSLHwDevice(CSLInternalHwVideoSubdeviceAll, 0);
  // g_pCSLModeManager 为CSLModeManager
	g_pCSLModeManager = CAMX_NEW CSLModeManager(pInitializeParams);
}



CamxResult CSLImageSensorProbeHW(
    CSLMemHandle                hPacket,
    SIZE_T                      offset,
    CSLImageSensorProbeResult*  pProbeResult)
{

    CamxResult result = CamxResultEFailed;

    if ((NULL != pProbeResult) && (CSLInvalidHandle != hPacket))
    {
        if (TRUE == CSLHwInstanceGetRefCount())
        {
            INT32   deviceIndex;

            result = CSLHwInternalProbeSensorHW(hPacket, offset, &deviceIndex);
            if (CamxResultSuccess == result)
            {
                pProbeResult->detected    = TRUE;
                pProbeResult->deviceIndex = deviceIndex;
            }
            CSLHwInstancePutRefCount();
        }
    }
    else
    {
        result = CamxResultEInvalidArg;
    }

    return result;
}

camx\src\core\camximagesensormoduledata.cpp 

camximagesensormoduledata.cpp
CamxResult ImageSensorModuleData::Probe(
    BOOL*   pDetected,
    INT32*  pDeviceIndex){
    result = CSLImageSensorProbe(pProbePacket->GetMemHandle(), pProbePacket->GetOffset(), &probeResult);
    result = GetSensorDataObject()->LoadSensorLibrary(); //加载/vendor/lib64/camera/com.qti.sensor.*.so 
}

 camx\src\csl\hw\camxcslhwinternalsensor.cpp

CamxResult CSLHwInternalProbeSensorHW(
    CSLMemHandle hPacket,
    SIZE_T       offset,
    INT32*       pDeviceIndex)
{
                    ioctlCmd.op_code     = CAM_SENSOR_PROBE_CMD;
                    ioctlCmd.size        = sizeof(ioctlCmd.handle);
                    ioctlCmd.handle_type = CAM_HANDLE_MEM_HANDLE;
                    ioctlCmd.reserved    = 0;
                    ioctlCmd.handle      = hPacket;

                    result = pLoophw->deviceOp.Ioctl(pLoophw, VIDIOC_CAM_CONTROL, &ioctlCmd);

        result = CSLHwInternalDefaultSubscribeEvents(&g_CSLHwInstance.CSLHwSensorSlotDevices[hIndex],
                                                    V4L_EVENT_CAM_REQ_MGR_SENSOR_LOCK,
                                                    CAM_SENSOR_EVENT_TYPE); // 使用event handle

        ioctlCmd.op_code     = CAM_SENSOR_INTR_INIT;
        ioctlCmd.size        = sizeof(cam_sensor_gpio_intr_config);
        ioctlCmd.handle_type = CAM_HANDLE_USER_POINTER;
        ioctlCmd.reserved    = 0;
        ioctlCmd.handle      = (uint64_t)pIntrInfo;
        result =  ioctl(deviceFd, VIDIOC_CAM_CONTROL, &ioctlCmd);

}

3. 之后通过调用HwEnvironment对象中的ProbeChiComponents方法在/vendor/lib64/camera/components路径下找寻各个Node生成的So库,并获取Node提供的标准对外接口,这些Node不但包括CHI部分用户自定义的模块,还包括了CamX部分实现的硬件模块,并最后都将其都存入ExternalComponentInfo对象中,等待后续阶段使用。 (camxhal3module.cpp ->camxchicomponent.cpp(Initialize)-> camxchicomponent.cpp(ProbeChiComponents));

camx框架-Camera初始化_第1张图片

从上图不难看出,在HAL3Module构造方法中会去通过dlopen方法加载com.qti.chi.override.so库,并通过dlsym映射出CHI部分的入口方法chi_hal_override_entry,并调用该方法将HAL3Module对像中的成员变量m_ChiAppCallbacks(CHIAppCallbacks)传入CHI中,其中包含了很多函数指针,这些函数指针分别对应着CHI部分的操作方法集中的方法,一旦进入到CHI中,就会将CHI本地的操作方法集合中的函数地址依次赋值给m_ChiAppCallbacks,这样CamX后续就可以通过这个成员变量调用到CHI中方法,从而保持了与CHI的通讯。

同样地,CHI中的ExtensionModule在初始化的时候,其构造方法中也会通过调用dlopen方法加载camera.qcom.so库,并将其入口方法ChiEntry通过dlsym映射出来,之后调用该方法,将g_chiContextOps(ChiContextOps,该结构体中定义了很多指针函数)作为参数传入CamX中,一旦进入CamX中,便会将本地的操作方法地址依次赋值给g_chiContextOps中的每一个函数指针,这样CHI之后就可以通过g_chiContextOps访问到CamX方法。

Camx 基本组件及其结构关系_yaoming168的博客-CSDN博客

你可能感兴趣的:(gnu,p2p)