1.Camera
Android的camera硬件抽象層(HAL)將更高層次的android.hardware中的camera框架層API與底層的camera驅動和camera硬件模塊連接了起來。Camera子系統包括camera流水線上各個組件的實現,而camera HAL提供了這些組件的使用接口。
注:camera HAL起着承上啓下的作用。在camera HAL層實現中,芯片廠商一般將camera HAL層的實現分爲兩層:interface層和OEM層。OEM層爲下層,它用於屏蔽不同的camera硬件。不同的camera硬件必須支持OEM層提供的對外接口。Interface層爲上層,它調用OEM層的對外接口來實現camera HAL所定義的接口。對於Interface層,它並不知道底層camera硬件到底是哪一個版本。同時,interface層完成了屏蔽camera HAL版本的作用。對於OEM層,它也不知道上層是哪一個camera HAL版本,及android版本。兩層分離架構,可以很容易地實現不同芯片支持同一個android版本和同一款芯片支持不同android版本(前提條件是該款芯片能夠支持這些android版本的各個需求)。
2. Architecture
下面的圖片和列表描述camera HAL層的各個組件:
Application framework
應用框架層是app代碼,它調用android.hardware.Camera API與底層的camera硬件進行交互。在android.hardware.Camera API內部,調用相應的JNI類來訪問native層的代碼,與camera硬件進行交互。
JNI
JNI代碼位於frameworks/base/core/jni/android_hardware_Camera.cpp
中,它與
android.hardware.Camera有一定的關係。JNI代碼調用native層代碼獲得底層camera硬件的訪問入口,通過該入口,可以獲取到framework層用於創建android.hardware.Camera對象的相關數據。
注:JNI =java native interface,該層使用C++語言實現。有些app軟件通過直接調用JNI層對外的接口來訪問底層camera硬件,這樣使用效率會高一些,但實現複雜度相對也高一些。
Native framework
Native framework層的定義位於frameworks/av/camera/Camera.cpp
,
該層提供了與android.hardware.Camera類對等的一個實現。這個類通過調用IPC
binder代理來獲取camera service的訪問接口。
Binder IPC proxies
IPC binder代理可以現實進程間通信。在frameworks/av/camera
目錄下有三個camera binder類的定義。ICameraService是cameraservice的接口,ICamera是被打開的camera設備的接口,ICameraClient是camera設備返回給application
framework層的接口。
Camera service
Camera service層的定義位於frameworks/av/services/camera/libcameraservice/CameraService.cpp
中。它是與camera HAL交互的實際代碼。
HAL
硬件抽象層定義了可供cameraservice層調用的標準接口,該接口必須被你的camera硬件功能正確地實現。
Kernel driver
Camera驅動與真實的camera硬件和所實現的camera HAL層進行交互。Camera硬件和驅動必須能夠提供YV12和NV21格式的圖像數據,以支持camera圖像數據在顯示屏上的預覽和視頻錄製。
注:YV12是YUV420P,三個plane,即Y,V,U三個plane依次存儲,如:YYYYYYYY VV UU;NV21是YUV420SP,兩plane,即Y,VU作爲兩個plane存儲,且VU交織,即一個V,一個U,依次存儲,如:YYYYYYYY VUVU。具體見:
http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html
3. Implementing the HAL
Camera HAL層位於camera驅動和更高層次的android framework之間,它定義了你必須實現的接口,該接口方便app能夠正確地操作camera硬件。CameraHAL層的接口被定義在頭文件hardware/libhardware/include/hardware/camera.h
和hardware/libhardware/include/hardware/camera_common.h
中。
camera_common.h
定義了一個重要的結構體camera_module
,這個結構體定義了一個標準結構,可以獲取camera基本信息,比如ID和所有camera所共有的屬性,比如是否是前置或者後置camera。
camera.h
包含的code基本上與
android.hardware.Camera一致。這個頭文件中聲明瞭一個結構體camera_device
,它包含了結構體camera_device_ops,該結構體中有指向實現camera
HAL接口的函數的函數指針。關於開發者可以設置的camera參數的各中類型,可以參考文件frameworks/av/include/camera/CameraParameters.h
。在camera HAL層,使用int (*set_parameters)(struct camera_device *, const char *parms)來設置這些參數。
一個camera HAL層實現的實例,可以參考hardware/ti/omap4xxx/camera
下面的關於
Galaxy
Nexus HAL的實現。
4. Configuring the Shared Library
你需要建立android編譯環境,正確地將camera 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
,看看
GalaxyNexus
camera的Makefile文件。
3> 通過從目錄frameworks/native/data/etc
下拷貝必要功能
XML文件,在你的設備的Makefile文件中明確指出你的設備有哪些功能。例如,明確指出你的設備有閃光燈,而且能自動聚焦,那就需要在你的設備所對應的<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.xml和device/<company_name>/<device_name>/media_codecs.xml兩個
XML文件中,聲明你的camera設備支持的多媒體編解碼器,格式和分辨率。爲了獲取更多相關信息,可以參考ExposingCodecs
and Profiles to the Framework。
注:這個信息很重要,上層app如果要使用相關功能,需要先查詢底層硬件支持哪些編解碼器及其性能,然後選擇與自己需求最匹配的特性,設置給底層硬件。如果該信息設置錯誤,底層硬件將無法工作,或者出現工作異常。
5> 將下面的信息加入你的device/<company_name>/<device_name>/device.mk
Makefile文件,將拷貝media_profiles.xml
和media_codecs.xml
到相應的位置。
# media config xml file
PRODUCT_COPY_FILES +=\
<device>/<company_name>/<device_name>/media_profiles.xml:system/etc/media_profiles.xml
# media codec config xml file
PRODUCT_COPY_FILES +=\
<device>/<company_name>/<device_name>/media_codecs.xml:system/etc/media_codecs.xml
6> 通過在你的設備device/<company_name>/<device_name>/device.mk
Makefile中的PRODUCT_PACKAGES
變量裏添加app名稱,聲明你想將哪些cameraapp添加到你的設備的系統image中:
PRODUCT_PACKAGES :=\
Gallery2 \
...
Website:
https://source.android.com/devices/camera/index.html