高通Camera驅動(1)--Camx架構介紹

之前主要做的是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

                            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/[email protected]

        

        根據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架構

           

                圖片內容來自: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 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

            

          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博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章