Android Camera软件框架(一)-Application Framework->Camera Service

Android Camera软件框架(一)-Application Framework->Camera Service

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层承上启下,涉及到图像数据处理和传输,是平台厂商自主设计的部分,不同平台框架差别很大。

android8.0及之后(HIDL)的camera软件架构

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.

api-hal

下面分别分析Camera Api1和Api2对Camera Service的调用。


Camera Api1

Camera.java -> CameraService

camera api1 open camera flow

上图是Camera1接口openCamera操作的调用流程。

其中JNI调用Camera::connect()请求CameraService服务。Camera类继承模板类CameraBase和BnCameraClient。首先调用模板类的connect()函数,在函数中向ServiceManager获取Camera服务信息,并生成CameraService服务代理BpCameraService(/frameworks/av/camera/ICameraService.cpp),然后通过Binder通信发送CONNECT命令,当BnCameraService收到CONNECT命令后调用CameraService的connect()成员函数来做相应的处理。

BpCameraService的connect()成员函数。首先将传递过来的Camera对象转换成IBinder类型,将调用的参数写到Parcel中,通过BpBinder的transact()函数发送消息,然后由BnCameraService去响应该连接,最后就是等待服务端返回,如果成功这里为我们生成一个BpCamera实例。

1
2
3
4
5
6
remote()->transact(BnCameraService::CONNECT, data, &reply); // CONNECT命令
if (readExceptionCode(reply)) return -EPROTO;
status_t status = reply.readInt32();
if (reply.readInt32() != 0) {
device = interface_cast<ICamera>(reply.readStrongBinder()); // client端读出server返回的binder,device为BpCamera(ICamera)
}

camera client and service

BpCameraService是client端的代理接口,通过transact将处理请求传给BnCameraService(BnCameraService)

binder service

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

camnera api2

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,但有可能最后调用的都是同一颗摄像头)。

camnera Device

源码位置:

CameraManager.java:frameworks/base/core/java/android/hardware/camera2

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×