• 高通Camera驱动(1)--Camx架构介绍


    此文转载自:https://blog.csdn.net/weixin_38328785/article/details/111881221

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

    一、Android分层架构

          

     图片内容来自: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分层架构

     

         图片来源:me

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

        1.2 高通平台camera架构

    二、准备工作

           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

                                vendorqcomproprietarychi-cdkvendor

                                                      驱动文件: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

            

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

          1、CameraServiceframeworksavservicescameralibcameraserviceCameraService.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  (frameworksavservicescameralibcameraserviceapi2CameraDeviceClient.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;
    }

            frameworksavservicescameralibcameraservicecommonCamera2ClientBase.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、Camera3DeviceframeworksavservicescameralibcameraservicedeviceCamera3Device.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、CameraProviderManagerframeworksavservicescameralibcameraservicecommonCameraProviderManager.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架构

               

                    图片内容来自: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结构体

             hardwarelibhardwaremodulescamera3_0Camera.cpp

         

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

            映射到vendorqcomproprietarycamxsrccorehalcamxhal3entry.cpp  的g_Camera3DeviceOps

            Camx的架构入口为Camx包中的camxhal3entry.cpp(vendorqcomproprietarycamxsrccorehalcamxhal3entry.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

                

              camhal3module.cpp 中的构造函数HAL3Module中        

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

            chxextensioninterface.cpp中函数chi_hal_override_entry

            

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

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

          5.5、Chi到 Camx的调用

          

         5.6、Camx 到 kernel的调用

          //TODO

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

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

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

       

    更多内容详见微信公众号:Python测试和开发

    Python测试和开发

  • 相关阅读:
    SLF4J + logback 实现日志输出和记录
    Log4j配置文件
    通过maven的<profile>标签,打包不同配置的变量包
    单点登录(SSO)原理
    MyBatis拦截器(插件)分页
    导航栏pop拦截
    swift 基础小结01 --delegate、Optional、GCD的使用、request请求、网络加载图片并保存到沙箱、闭包以及桥接
    转载-iOS SDK开发
    leaks工具查找内存泄露
    weex stream 之fetch的get、post获取Json数据
  • 原文地址:https://www.cnblogs.com/phyger/p/14277625.html
Copyright © 2020-2023  润新知