Android 的攝像頭硬件抽象層 (HAL) 將攝像頭 2中更高級別的攝像頭框架 API 連接到您的底層攝像頭驅動程序和硬件。相機子系統包括相機管道組件的實現,而相機 HAL 提供用於實現這些組件版本的接口。
建築學
下圖和列表描述了 HAL 組件。
- 應用框架
- 在應用程序框架級別是應用程序的代碼,它使用Camera 2 API 與相機硬件進行交互。在內部,此代碼調用相應的Binder接口來訪問與相機交互的本機代碼。
- AIDL
- 與
CameraService
關聯的 binder 接口可以在frameworks/av/camera/aidl/android/hardware找到。生成的代碼調用較低級別的本機代碼以獲取對物理相機的訪問權,並返回用於在框架級別創建CameraDevice
並最終創建CameraCaptureSession
對象的數據。 - 原生框架
- 此框架位於
frameworks/av/
中,提供與CameraDevice
和CameraCaptureSession
類等效的本機。另請參閱NDK camera2 參考。 - 活頁夾 IPC 接口
- IPC binder 接口有助於跨進程邊界進行通信。
frameworks/av/camera/camera/aidl/android/hardware
目錄中有幾個攝像頭綁定器類調用攝像頭服務。ICameraService
是相機服務的接口;ICameraDeviceUser
是特定打開的相機設備的接口;ICameraServiceListener
和ICameraDeviceCallbacks
分別是應用程序框架的CameraService
和CameraDevice
回調。 - 相機服務
- 位於
frameworks/av/services/camera/libcameraservice/CameraService.cpp
中的攝像頭服務是與 HAL 交互的實際代碼。 - 哈爾
- 硬件抽象層定義了相機服務調用的標準接口,您必須實現該接口才能使相機硬件正常運行。
實施 HAL
HAL 位於相機驅動程序和更高級別的 Android 框架之間,並定義了一個您必須實現的接口,以便應用程序可以正確操作相機硬件。 Camera HAL 的HIDL接口在hardware/interfaces/camera中定義。
典型的綁定 HAL 必須實現以下 HIDL 接口:
-
ICameraProvider
:用於枚舉單個設備並管理它們的狀態。 -
ICameraDevice
:相機設備接口。 -
ICameraDeviceSession
:活動的相機設備會話接口。
參考 HIDL 實現適用於CameraProvider.cpp
、 CameraDevice.cpp
和CameraDeviceSession.cpp
。該實現包裝了仍然使用舊版 API的舊 HAL。從 Android 8.0 開始,Camera HAL 實現必須使用 HIDL API;不支持使用舊接口。
舊版 HAL 組件
本節介紹遺留 HAL 組件的架構以及如何實現 HAL。 Android 8.0 及更高版本上的相機 HAL 實現必須改用 HIDL API,如上所述。
架構(舊版)
下圖和列表描述了舊版相機 HAL 組件。
- 應用框架
- 在應用程序框架級別是應用程序的代碼,它使用
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 綁定代理以獲取對相機服務的訪問權限。 - 活頁夾 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.h
和hardware/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
文件將其複製到適當的位置:
- 創建一個
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
生成文件中添加以下行: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
生成文件中的PRODUCT_PACKAGES
變量中指定它:PRODUCT_PACKAGES := \ Gallery2 \ ...