Camera根据Android架构从上至下可分为:
1.Applications: 最上层的应用;
2.Application Framework: 主要为Applications提供API;
3.JNI: 使Application Framework和Libraries可交互
4.Libraries: 包括Camera Framework和Camera Service(camera service和camera client);
5.HAL: 硬件抽象层, 用来链接driver和 Camera Service;
6.Kernel: image sensor driver的实现.
其中2-4的部分属于Android系统原生架构,平台厂商一般不改动或做少许拓展。而HAL层承上启下,涉及到图像数据处理和传输,是平台厂商自主设计的部分,不同平台框架差别很大。
Camera Api分Api1和Api2,5.0后支持Api2。Api2支持的功能更多,更适合用来定制Camera类应用。
目前Android Camera hal版本主要有v1和v3,v3将更多的工作集中在了Framework去完成,,从而与HAL的交互的数据信息更少,也进一步减轻了一些在旧版本中HAL层所需要做的事情,也更加模块化。
这里就几个组合,Api1->Hal1,Api1->Hal3,Api2->Hal3,Android P版本的新项目Api1都强制使用Hal3,但从老项目比如O版本升级上来的继续使用Hal1.
下面分别分析Camera Api1和Api2对Camera Service的调用。
Camera Api1
Camera.java -> CameraService
上图是Camera1接口openCamera操作的调用流程。
其中JNI调用Camera::connect()请求CameraService服务。Camera类继承模板类CameraBase
BpCameraService的connect()成员函数。首先将传递过来的Camera对象转换成IBinder类型,将调用的参数写到Parcel中,通过BpBinder的transact()函数发送消息,然后由BnCameraService去响应该连接,最后就是等待服务端返回,如果成功这里为我们生成一个BpCamera实例。
1 |
|
BpCameraService是client端的代理接口,通过transact将处理请求传给BnCameraService(BnCameraService)
IXXXService为client端的代理接口BpXXXService和server端的BnXXXService的共同接口类,这个共同接口类的目的就是保证service方法在C/S两端的一致性。
CameraService -> HAL
CameraService在hal1老版本的实现里,是通过hw_get_module(CAMERA_HARDWARE_MODULE_ID)打开对应Camera hal层动态库,老版本Hal层调用的原理是dlopen()。
新版hal3则是通过HIDL连接Hal层。HIDL又分直通式和绑定式,直通式的原理还是dlopen(只是用HIDL的方式封装了),所以直通式HIDL下hal层还是跟service在同一个进程,而绑定式HIDL使用Binder方式进行IPC,所以service和hal层运行在不同进程。
源码位置:
frameworks/base/core/java/android/hardware/Camera.java
Camera.java为App直接调用的接口
frameworks/base/core/jni/android_hardware_Camera.cpp
此部分为Java调用的JNI native部分代码
frameworks/av/camera/Camera.cpp
frameworks/av/camera/CameraBase.cpp
App连接到CameraService部分的Client
frameworks/av/services/camera/libcameraservice/CameraService.cpp
frameworks/av/services/camera/libcameraservice/CameraService.h
这部分是CameraService的代码, App通过Binder来连接
frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
这部分是CameraService端的Client, 用于调用HAL层的接口
frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
Google定义的HAL接口, 由芯片厂商去实现, 以上代码是Google写的Android系统代码, HAL层及以下则是芯片厂商写的代码,
Camera Api2
CameraManager.java -> CameraService
Camera2接口和Camera1接口差别很大。
- CameraCharacteristics:描述摄像头的各种特性,我们可以通过CameraManager的getCameraCharacteristics(@NonNull String cameraId)方法来获取。
- CameraDevice:描述系统摄像头,类似于早期的Camera。
- CameraCaptureSession:Session类,当需要拍照、预览等功能时,需要先创建该类的实例,然后通过该实例里的方法进行控制(例如:拍照 capture())。
- CaptureRequest:描述了一次操作请求,拍照、预览等操作都需要先传入CaptureRequest参数,具体的参数控制也是通过CameraRequest的成员变量来设置。
Camera2直接通过binder连接CameraService,不像camera1还要经过jni。
- ICameraService 是相机服务的接口。用于请求连接、添加监听等。
- ICameraDeviceUser 是已打开的特定相机设备的接口。应用框架可通过它访问具体设备。
- ICameraServiceListener 和 ICameraDeviceCallbacks 分别是从 CameraService 和 CameraDevice 到应用框架的回调
- ICameraProvider 是CameraProvider的接口。
CameraProvider也是一个注册到ServiceManager的服务,它属于Camera HAL层服务的一部分。
Cameraservice通过 CameraProviderManager 来管理对 CameraProvider的操作。
CameraService-(持有)->CameraProviderManager-(Binder)->CameraProvider-(持有)->ICameraDeviceManager->ICameraDevice/ICameraDeviceSession
CameraService可以通过CameraProvider获取ICameraDevice,CameraProver起到一个适配的功能,可以返回不同版本的Camera Device如Device HAL1,Device HAL3(在framework层,hal1和hal3的设备是分开枚举的,如device@1.0/device@3.2,但有可能最后调用的都是同一颗摄像头)。
源码位置:
CameraManager.java:frameworks/base/core/java/android/hardware/camera2