欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

高通Camera驱动--Camx架构介绍

程序员文章站 2022-05-01 19:53:43
参考文档:Android Camera简单整理(二)-Qcom HAL3 Camx架构学习 - 简书 (jianshu.com)一、Android分层架构 图片内容来自:https://source.android.google.cn/setup Android分层架构: APP层:每一个应用程序由一个或多个活动组成,都是java写的 Framework层:用java编写一些规范化的模块封装框架。用Java Native Interface(JNI 是......

之前主要做的是MTK平台camera驱动,高通平台这块只是简单了解架构。为了做成一个系列,简单梳理下高通camx架构

一、Android分层架构

      高通Camera驱动--Camx架构介绍

 图片内容来自:https://source.android.google.cn/setup

     Android分层架构:

    APP:每一个应用程序由一个或多个活动组成,都是java写的

    Framework:用java编写一些规范化的模块封装框架。用Java Native Interface(JNI java调用native语言的一种特性,通过JNI可以使java可以调用C/C++的代码)

    Libraries系统库:核心库,主要包含基本的C库等。和我们相关主要是Bionic系统C

    Android运行时库:提供Java编程语言核心库的大多数功能。每一个Android应用程序都在它自己的进程中运行,都有一个独立的Dalvik虚拟机实例。

    HAL:硬件抽象层,Android frameworksJNI调用hardware.c中定义hw_get_module函数来获取硬件模块。然后调用硬件模块中的方法,硬件模块中的方法直接调用内核接口完成相应功能。

    Linux核心层Android的核心系统服务依赖于Linux内核。如安全性、内存管理、进程管理、网络协议栈、和驱动模型。

   SELinux:是Linux内核模块,也是Linux的一个安全子系统。主要作用最大限度地减少系统中服务进程可访问的的资源(最小权限原则)

     1.1、Camera分层架构

 高通Camera驱动--Camx架构介绍

     图片来源:me

    高通平台《80-pc212-1_a_chi_api_specifications_for_qualcomm_spectra_2xx_camera.pdf》所示,对高通平台对Camxhal3有个初步的认识。

    1.2 高通平台camera架构

高通Camera驱动--Camx架构介绍

图片内容来自:80-pc212-1_a_chi_api_specifications_for_qualcomm_spectra_2xx_camera.pdf

二、准备工作

       camera驱动开发需要在source insight 中需要加入的文件

       system仓下:   camera_metadata_tags.h、camera_metadata_tag.c、camera_metadata.c、camera_metadata.h

       kernel仓下: arch/arm/boot/dts

       hardware仓下:camera3.h、CameraDevice.cpp、CameraDeviceSession.cpp

       framework/av仓下:framework层camera文件, camerametadata.cpp、camerametadata.h、CameraService.cpp

       vendor仓下:vendor/qcom/proprietary/camx

                            vendor\qcom\proprietary\chi-cdk\vendor\

                                                  驱动文件:actuator    eeprom  fd  flash    ois  sensor   

                                                  usecase:topology 

 

         //TODO,完善细节

三、名词解释

       Usecase :摄像机管道的特定配置,实现了已经定义良好的功能。例如,20万像素的ZSL快照和2k显示的预览是单一的用途的情况。Chi API被设计为在一定范围内指定任何可想象的用户定义用例底层硬件,不需要修改驱动程序。

       Session:单个会话是摄像机管道配置完成,从随时准备处理图像,直到摄像机管道被破坏,而另一个管道可能在它的位置配置。支持多个并行会话。

       Request:使摄像机管道处理数据的动作。这可以是请求处理从图像传感器中提取的一帧数据,或处理从存储器中提取的一帧数据。结果必须从驱动程序返回到相机应用程序。

       Sub-Request:将单个请求分解为多个内部请求的操作。驱动处理完的子请求的结果不会直接返回,而是合并成为单个结果对应原始请求。子请求用于启用诸如HDR,其中多次曝光变化的传感器需要产生单一的图像,或

                                多帧后处理,其中多个图像合并创建一个单一的输出图像。

       Steam:用于处理的具有相同大小和格式的缓冲区序列图像数据。可以指定多个不同类型的流作为相机的输入和输出管道。这组流是定义用例的关键组件。

       Per-session setting:影响相机处理管道的设置。这些设置不在会话开始时更改。例如,允许图像稳定处理。

       Per-request setting:影响单个请求的设置。例如,手动曝光值。

       拓扑结构 :表示单个用例的有向无环图(DAG)。划好了道格一系列处理节点和一组链接,它们描述正在处理的缓冲区通过这些节点。拓扑是通过XML文件指定的。

       Engine:可以用来处理数据的硬件。光谱ISP,骁龙CPU,Adreno,和DSP是Chi API可用引擎的例子。

       Node:camera管道中的一个逻辑功能块,它在单个引擎节点连接在一起形成拓扑结构。在Chi API的初始版本中,所有ISP外部的节点通过CPU代码调用,CPU代码调用本机API。本机API驱动OpenCL和FastCV等引擎。Chi API可以在未来扩                    展到允许缓存和重用硬件命令,而不需要重用本地api。

       Pipeline:支持数据操作的惟一上下文。每个管道都可以维护自己的状态跨多个请求,而不受其他管道的影响。管道利用拓扑来定义使用的引擎和数据处理流程。

       Statistics:算法包括3A,这是用来自动控制图像传感器和相机ISP,以达到更好的图像质量。这些领域特定的算法是作为Chi API的专用部分处理。

       Live Stream:处理从图像传感器接收数据的任何配置,并且不能修改以前请求中的任何数据。实时流处理速度不适合的处理传感器数据速率可以移动到offline stream去处理。

       Offline Stream:离线流处理过程不接收来自图像传感器的数据的任何配置。在Chi API中,离线流可以与实时流配对,而无需额外添加延迟。离线流的结果可以返回给相机应用程序。

四、Framework层

       MTK和高通用的都是Android的架构,在framework层的都是一样的代码。但是为了读者有更好的阅读体验,我还这里写一下这部分的代码(Android Q 之MTK代码分析(一)--Camera Hal3 Service_Cam_韦的博客-CSDN博客

       CameraService服务启动是通过LoadBootScripts() 函数加载cameraserver.rc

       camera provider进程和cameraserver进程和底层的驱动交互,camera provider进程非常重要,camera HAL层几乎全部运行在camera provider进程中完成。

         首先看下camera provider所在源码中的位置:hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service.rc

        高通Camera驱动--Camx架构介绍

        根据Android Camera分层架构可以看出来,framework有四个组件。(CameraService、CameraDeviceClient、Camera3Device、CameraProviderManager

      1、CameraServiceframeworks\av\services\camera\libcameraservice\CameraService.cpp

CameraService::CameraService() {
    ALOGI("CameraService started (pid=%d)", getpid());   
}

 

void CameraService::onFirstRef()
{
    ALOGI("CameraService process starting");
    res = enumerateProviders();
}
status_t CameraService::enumerateProviders() {
    status_t res;

    //创建对象,要判断Provider对象为0才能创建
    mCameraProviderManager = new CameraProviderManager(); 
    res = mCameraProviderManager->initialize(this);
 
    deviceIds = mCameraProviderManager->getCameraDeviceIds();

    return OK;
}

          从camera分层架构来看,CameraService要创建CameraProviderMangaer

          cameraservice.cpp中 enumerateProviders枚举Provider开始创建CameraProviderManager对象并初始化

       2、CameraDeviceClient  (frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp

CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
{

    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}

status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {

    res = Camera2ClientBase::initialize(providerPtr, monitorTags);

    return OK;
}

        frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp      

Camera2ClientBase<TClientBase>::Camera2ClientBase(
        mDevice(new Camera3Device(cameraId)),     
{
    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),String8(clientPackageName).string(), clientPid, clientUid);
}

       从这块CameraDeviceClient就创建Camera3Device对象

template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {

    res = mDevice->initialize(providerPtr, monitorTags);

    return OK;
}

      3、Camera3Deviceframeworks\av\services\camera\libcameraservice\device\Camera3Device.cpp

          ICameraDeviceSession 这块让framework和HAL又联系在一起

status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {

    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());

    sp<ICameraDeviceSession> session;
}

       4、CameraProviderManagerframeworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp

            #include <android/hardware/camera/device/3.5/ICameraDevice.h>

           这样通过头文件的形式ICameraDevice.h,framework就和HAL的联系上

status_t CameraProviderManager::ProviderInfo::initialize(
        sp<provider::V2_4::ICameraProvider>& interface,
        hardware::hidl_bitfield<provider::V2_5::DeviceState> currentDeviceState) {
 
    ALOGI("Connecting to new camera provider: %s, isRemote? %d",
            mProviderName.c_str(), interface->isRemote());

    Status status;
    // Get initial list of camera devices, if any
    std::vector<std::string> devices;
    hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](

    hardware::Return<Status> st = interface->setCallback(this); //这块用ICameraProvider 接口连接上HAL
    ALOGI("Camera provider %s ready with %zu camera devices",
            mProviderName.c_str(), mDevices.size());

    mInitialized = true;
    return OK;
}

     ICameraProvider ,interface->setCallback(this)让framework连上HAL之后。  

    以上就是framework的四个组件,以及framework和HAL的联系

五、高通平台HAL3 camx

   5.1、这边附上一个架构图,简单直接了解camx架构

           高通Camera驱动--Camx架构介绍

                图片内容来自:Android Camera简单整理(二)-Qcom HAL3 Camx架构学习 - 简书 (jianshu.com)

    5.2、CameraServer 到Provider的调用关系

     在CameraService中,主要接口在CameraService.cpp 和 Camera3Device.cpp中

     在CameraProvider中, 主要接口在CameraDevice.cpp 和CameraDeviceSession.cpp

    5.3、Provider 到 hal3的调用关系

        在provider中,mDevice->ops即为Camera3.h中的camera3_device_ops结构体

         hardware\libhardware\modules\camera\3_0\Camera.cpp

     高通Camera驱动--Camx架构介绍

         这样就找到Camera hal层的函数指针的映射关系。

        映射到vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp  的g_Camera3DeviceOps

        Camx的架构入口为Camx包中的camxhal3entry.cpp(\vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp)      

/// Array containing hw_module_methods_t methods
static hw_module_methods_t g_hwModuleMethods =
{
    CamX::open
};

/// Array containing camera3_device_ops_t methods
#if defined (_LINUX)
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,
};
#else // _LINUX
static camera3_device_ops_t g_camera3DeviceOps =
{
    CamX::initialize,
    CamX::configure_streams,
    NULL,
    CamX::construct_default_request_settings,
    CamX::process_capture_request,
    NULL,
    CamX::dump,
    CamX::flush,
    NULL,
    {0},
};
#endif // _LINUX

/// Array of HwDeviceCloseOps to hold the close method
static HwDeviceCloseOps g_hwDeviceCloseOps =
{
    close
};

       5.4、Camx到Chi的映射

           在camhal3.cpp中,定义了g_jumpTableHAL3

            camxchitypes.h定义了CHIAppCallback结构体

            camxhal3module.h中定义了 chi_hal_callback_ops_t

            高通Camera驱动--Camx架构介绍

          camhal3module.cpp 中的构造函数HAL3Module中        

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

        chxextensioninterface.cpp中函数chi_hal_override_entry

        高通Camera驱动--Camx架构介绍

      chi这块代码有点生疏了,看个博客快速回忆下。感谢xiaozi63大佬的博客

高通Camera驱动--Camx架构介绍

图片内容来自:深入理解Android相机体系结构之六_u012596975的博客-CSDN博客

      5.5、Chi到 Camx的调用

      高通Camera驱动--Camx架构介绍

     5.6、Camx 到 kernel的调用

      //TODO

     以上将介绍高通平台的camx架构,后面会对这块补充细节。

 

参考文档:Android Camera简单整理(二)-Qcom HAL3 Camx架构学习 - 简书 (jianshu.com)

推荐文档:深入理解Android相机体系结构之六_u012596975的博客-CSDN博客

本文地址:https://blog.csdn.net/weixin_38328785/article/details/111881221