Android 的相機硬件抽象層 (HAL) 可將 Camera 2 中較高級別的相機框架 API 連接到底層的相機驅動程序和硬件。相機子系統包括相機管道組件的實現,而相機 HAL 則可提供用於實現您的這些組件版本的接口。
注意:如果您要在搭載 Android 8.0 或更高版本的設備上實現相機 HAL,則必須使用 HIDL 接口。要了解舊版組件,請參閱舊版 HAL 組件。
架構
下列圖表和列表說明了 HAL 組件:
圖 1. 相機架構
應用框架
應用代碼位於應用框架級別,它使用 Camera 2 API 與相機硬件進行交互。在內部,這些代碼會調用相應的 Binder 接口,以訪問與相機互動的原生代碼。
AIDL
與 CameraService 關聯的 Binder 接口可在 frameworks/av/camera/aidl/android/hardware 中找到。 生成的代碼會調用較低級別的原生代碼以獲取對實體相機的訪問權限,並返回用於在框架級別創建 CameraDevice並最終創建 CameraCaptureSession 對象的數據。
原生框架
此框架位於 frameworks/av/
中,並提供相當於 CameraDevice 和 CameraCaptureSession 類的原生類。另請參閱 NDK camera2 參考。
Binder IPC 接口
IPC binder 接口用於實現跨越進程邊界的通信。調用相機服務的若干個相機 Binder 類位於 frameworks/av/camera/camera/aidl/android/hardware
目錄中。 ICameraService 是相機服務的接口;ICameraDeviceUser 是已打開的特定相機設備的接口;ICameraServiceListener 和 ICameraDeviceCallbacks分別是對應用框架的 CameraService 和 CameraDevice 回調。
相機服務
位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp
下的相機服務是與 HAL 進行互動的實際代碼。
HAL
硬件抽象層定義了由相機服務調用、且您必須實現以確保相機硬件正常運行的標準接口。
實現 HAL
HAL 位於相機驅動程序和更高級別的 Android 框架之間,它定義您必須實現的接口,以便應用可以正確地操作相機硬件。從 Android 8.0 開始,相機 HAL 接口是 Project Treble 的一部分,相應的 HIDL 接口在 hardware/interfaces/camera 中定義。
典型的綁定式 HAL 必須實現以下 HIDL 接口:
- ICameraProvider:用於枚舉單個設備並管理其狀態。
- ICameraDevice:相機設備接口。
- ICameraDeviceSession:活躍的相機設備會話接口。
參考 HIDL 實現適用於 CameraProvider.cpp、CameraDevice.cpp 和 CameraDeviceSession.cpp。該實現封裝了仍在使用舊版 API 的舊 HAL。從 Android 8.0 開始,相機 HAL 實現必須使用 HIDL API;不支持使用舊版接口。
要詳細瞭解 Treble 和 HAL 開發,請參閱 Treble 資源。
舊版 HAL 組件
此部分介紹了舊版 HAL 組件的架構以及如何實現 HAL。搭載 Android 8.0 或更高版本的設備上的相機 HAL 實現必須改用 HIDL API(如上所述)。
架構(舊版)
下列圖表和列表說明了舊版相機 HAL 組件:
圖 1. 相機架構
應用框架
應用代碼位於應用框架級別,它利用 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 代理,以獲取對相機服務的訪問權限。
Binder IPC 代理
IPC binder 代理用於促進跨越進程邊界的通信。調用相機服務的 3 個相機 binder 類位於 frameworks/av/camera
目錄中。ICameraService 是相機服務的接口,ICamera 是已打開的特定相機設備的接口,ICameraClient 是指回應用框架的設備接口。
相機服務
位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp
下的相機服務是與 HAL 進行互動的實際代碼。
HAL
硬件抽象層定義了由相機服務調用、且您必須實現以確保相機硬件正常運行的標準接口。
內核驅動程序
相機的驅動程序可與實際相機硬件以及您的 HAL 實現進行互動。相機和驅動程序必須支持 YV12 和 NV21 圖像格式,以便在顯示和視頻錄製時支持預覽相機圖像。
實現 HAL(舊版)
HAL 位於相機驅動程序和更高級別的 Android 框架之間,它定義您必須實現的接口,以便應用可以正確地操作相機硬件。HAL 接口在 hardware/libhardware/include/hardware/camera.h
和 hardware/libhardware/include/hardware/camera_common.h
標頭文件中定義。
camera_common.h
定義 camera_module
;這是一個標準結構,可用於獲取有關相機的一般信息,例如相機 ID 和所有相機通用的屬性(例如,攝像頭是前置還是後置)。
camera.h
包含對應於 android.hardware.Camera 的代碼。此標頭文件會聲明一個 camera_device
結構,該結構又反過來包含一個帶函數指針(可實現 HAL 接口)的 camera_device_ops
結構。有關開發者可以設置的相機參數的文檔,請參閱 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
文件將其複製到相應位置:
- 創建一個
device/<company_name>/<device_name>/camera
目錄以包含您庫的源文件。 - 創建一個
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。 - 使用您設備的 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
。 - 在
device/<company_name>/<device_name>/media_profiles.xml
和device/<company_name>/<device_name>/media_codecs.xml
XML 文件中聲明您相機的媒體編解碼器、格式和分辨率功能。如需瞭解詳情,請參閱將編解碼器展示給框架。 - 在您設備的
device/<company_name>/<device_name>/device.mk
Makefile 中添加以下行,以將media_profiles.xml
和media_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
- 要將相機應用包含在設備的系統映像中,請在設備的
device/<company>/<device>/device.mk
Makefile 中的PRODUCT_PACKAGES
變量中指定該應用:PRODUCT_PACKAGES := \ Gallery2 \ ...