相機

Android 相機 HAL 圖標

Android 的相機硬體抽象層 (HAL) 將Camera 2中的更高階相機框架 API 連接到底層相機驅動程式和硬體。相機子系統包括相機管道組件的實現,而相機 HAL 提供用於實現您的這些組件版本的介面。

建築學

下圖和列表描述了 HAL 組件。

Android相機架構

圖 1.相機架構

應用程式框架
應用程式框架層級是應用程式的程式碼,它使用Camera 2 API 與相機硬體進行互動。在內部,程式碼會呼叫對應的Binder介面來存取與相機互動的本機程式碼。
人工智慧DL
CameraService相關的 Binder 介面可以在Frameworks/av/camera/aidl/android/hardware中找到。產生的程式碼會呼叫較低層級的本機程式碼來取得對實體相機的存取權限,並傳回用於在框架層級建立CameraDevice和最終CameraCaptureSession物件的資料。
原生框架
此框架位於frameworks/av/中,提供了與CameraDeviceCameraCaptureSession類別相同的本機等效項。另請參閱NDKcamera2 參考
綁定器工控機介面
IPC 綁定器介面有利於跨進程邊界的通訊。 frameworks/av/camera/camera/aidl/android/hardware目錄中有幾個相機綁定器類別可以呼叫相機服務。 ICameraService是相機服務的介面; ICameraDeviceUser是具體開啟的相機設備的介面; ICameraServiceListenerICameraDeviceCallbacks分別是應用程式框架的CameraServiceCameraDevice回呼。
網路網路服務
相機服務位於frameworks/av/services/camera/libcameraservice/CameraService.cpp中,是與 HAL 互動的實際程式碼。
哈爾
硬體抽象層定義了相機服務呼叫的標準接口,您必須實作該接口才能使相機硬體正常運作。

實施 HAL

HAL 位於相機驅動程式和更高層級的 Android 框架之間,定義了一個必須實現的接口,以便應用程式可以正確操作相機硬體。相機 HAL 的HIDL介面在hardware/interfaces/camera中定義。

典型的綁定化 HAL 必須實作以下 HIDL 介面:

參考 HIDL 實作可用於CameraProvider.cppCameraDevice.cppCameraDeviceSession.cpp 。此實作包裝了仍使用舊版 API 的舊 HAL。從 Android 8.0 開始,Camera HAL 實作必須使用 HIDL API;不支援使用舊版介面。

輸入驗證

由於 HAL 可以存取與相機服務不同的資源,因此兩者之間的邊界被視為安全邊界。這意味著從相機服務傳遞的參數被認為是不可信和未經消毒的。為了防止安全漏洞允許攻擊者升級權限或存取他們不打算存取的數據,攝影機 HAL 必須驗證從攝影機服務傳遞到 HAL 的參數。這包括檢查緩衝區長度值是否在允許的範圍內,以及在使用之前以及將參數傳遞給硬體或核心驅動程式之前清理參數。

舊版 HAL 組件

本節介紹舊版 HAL 元件的架構以及如何實作 HAL。 Android 8.0 及更高版本上的相機 HAL 實作必須改用 HIDL API,如上所述。

架構(遺留)

下圖和列表描述了舊版相機 HAL 組件。

Android相機架構

圖 2.傳統相機架構

應用程式框架
應用程式框架層級是應用程式的程式碼,它使用android.hardware.Camera API 與相機硬體進行互動。在內部,此程式碼會呼叫對應的 JNI 黏合類別來存取與相機互動的本機程式碼。
JNI
android.hardware.Camera相關的 JNI 程式碼位於frameworks/base/core/jni/android_hardware_Camera.cpp 。此程式碼會呼叫較低層級的本機程式碼來取得對實體相機的存取權限,並傳回用於在框架層級建立android.hardware.Camera物件的資料。
原生框架
frameworks/av/camera/Camera.cpp中定義的本機框架提供了與android.hardware.Camera類別等效的本機框架。此類別呼叫 IPC 綁定器代理程式可取得相機服務的存取權限。
Binder IPC 代理
IPC 綁定器代理程式有助於跨進程邊界的通訊。位於frameworks/av/camera目錄中的三個相機綁定器類別可呼叫相機服務。 ICameraService是相機服務的接口, ICamera是特定打開的相機設備的接口, ICameraClient是設備返回到應用程式框架的接口。
網路網路服務
相機服務位於frameworks/av/services/camera/libcameraservice/CameraService.cpp中,是與 HAL 互動的實際程式碼。
哈爾
硬體抽象層定義了相機服務呼叫的標準接口,您必須實作該接口才能使相機硬體正常運作。
核心驅動程式
相機的驅動程式與實際的相機硬體和 HAL 的實現進行互動。攝影機和驅動程式必須支援 YV12 和 NV21 影像格式,以提供在顯示器上預覽攝影機影像和視訊錄製的支援。

實施 HAL(舊版)

HAL 位於相機驅動程式和更高層級的 Android 框架之間,定義了一個必須實現的接口,以便應用程式可以正確操作相機硬體。 HAL 介面在hardware/libhardware/include/hardware/camera.hhardware/libhardware/include/hardware/camera_common.h頭檔中定義。

camera_common.h定義了camera_module ,這是一個標準結構體,用於獲取有關相機的一般信息,例如相機 ID 和所有相機共有的屬性(即,無論是前置攝像頭還是後置攝像頭)。

camera.h包含與android.hardware.Camera對應的程式碼。此頭檔宣告了一個camera_device結構體,該結構體又包含一個camera_device_ops結構體,其中包含指向實作HAL介面的函數的指標。有關開發人員可以設定的相機參數的文檔,請參閱frameworks/av/include/camera/CameraParameters.h 。這些參數是透過 HAL 中int (*set_parameters)(struct camera_device *, const char *parms)指向的函數來設定的。

有關 HAL 實作的範例,請參閱hardware/ti/omap4xxx/camera中 Galaxy Nexus HAL 的實作。

配置共享庫

設定 Android 建置系統以將 HAL 實作正確打包到共用庫中,並透過建立Android.mk檔案將其複製到適當的位置:

  1. 建立device/<company_name>/<device_name>/camera目錄以包含庫的來源檔案。
  2. 建立Android.mk檔案來建立共享庫。確保 makefile 包含以下行:
    LOCAL_MODULE := camera.<device_name>
    LOCAL_MODULE_RELATIVE_PATH := hw
    

    您的庫必須命名為camera.<device_name>.so會自動附加),以便Android可以正確載入該庫。有關範例,請參閱位於hardware/ti/omap4xxx/Android.mk中的 Galaxy Nexus 相機的 makefile。

  3. 透過使用裝置的 makefile 複製frameworks/native/data/etc目錄中必要的功能 XML 檔案來指定您的裝置具有相機功能。例如,要指定您的裝置具有相機閃光燈並且可以自動對焦,請在裝置的<device>/<company_name>/<device_name>/device.mk makefile 中新增下列行:
    PRODUCT_COPY_FILES := \ ...
    
    PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
    

    有關裝置 makefile 的範例,請參閱device/samsung/tuna/device.mk

  4. device/<company_name>/<device_name>/media_profiles.xmldevice/<company_name>/<device_name>/media_codecs.xml XML 檔案中宣告相機的媒體編解碼器、格式和解析度功能。有關詳細信息,請參閱向框架公開編解碼器
  5. 在裝置的device/<company_name>/<device_name>/device.mk makefile 中加入以下行,以將media_profiles.xmlmedia_codecs.xml檔案複製到適當的位置:
    # media config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_profiles.xml:system/etc/media_profiles.xml
    
    # media codec config xml file
    PRODUCT_COPY_FILES += \
        <device>/<company>/<device>/media_codecs.xml:system/etc/media_codecs.xml
    
  6. 若要將相機應用程式包含在裝置的系統映像中,請在裝置的device/<company>/<device>/device.mk makefile 中的PRODUCT_PACKAGES變數中指定它:
    PRODUCT_PACKAGES := \
    Gallery2 \
    ...