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层的各个组件:
![](https://i-blog.csdnimg.cn/blog_migrate/112fcce9b35abb839864b6ba73d6b370.png)
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: