Android Camera2+HAL3架构

版权声明:本文为博主原创文章,转载请注明出处 http://blog.csdn.net/u013961718 https://blog.csdn.net/u013961718/article/details/87302254

整体架构概述

Android Camera整体框架主要包括三个进程:app进程、camera server进程、hal进程。进程之间的通信都是通过binder实现,其中app和camera server通信使用aidl,camera server和hal通信使用hidl。Android Camera2整体架构如下图:

Camera architecture
大致分为这几个部分:

  1. Application framework
    这一层是用于给APP提供访问hardware的Camera API2,通过binder来访问camera service。有两个主要的类:
  • CameraManager,CameraManager是一个独一无二地用于检测、连接和描述相机设备的系统服务,负责管理所有的CameraDevice相机设备。通过ICameraService调用到CameraService。
// CameraManager.java
private void connectCameraServiceLocked() {  // CameraManager是一个系统服务,应该是开机就会被创建起来
	IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
	ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);  // 返回Stub.Proxy对象,也就是ICameraServiceProxy
	CameraStatus[] cameraStatuses = cameraService.addListener(this);                      // 注册 ICameraServiceListener                
	mCameraService = cameraService;
}
  • CameraDevice:CameraDevice是连接在安卓设备上的单个相机的抽象表示。通过ICameraDeviceUser调用到CameraDeviceClient。
private CameraDevice openCameraDeviceUserAsync() {
	CameraDevice device = null;
	ICameraDeviceUser cameraUser = null;

	android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =      // CameraDeviceImp继承自CameraDevice
		new android.hardware.camera2.impl.CameraDeviceImpl(cameraId, ...);
	ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();    // 获取CameraDevice的回调函数
	ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
	cameraUser = cameraService.connectDevice(callbacks, cameraId, ...);  // connect到camera service,并将camera device callback注册进去
    // 返回的ICameraDeviceUser就是CameraDeviceClient的本地接口
	deviceImpl.setRemoteDevice(cameraUser);
	device = deviceImpl;

	return device;
}
  1. AIDL
    基于Binder实现的一个用于让App fw代码访问natice fw代码的接口。其实现存在于下述路径:frameworks/av/camera/aidl/android/hardware。其中:
    (1) ICameraService 是相机服务的接口。用于请求连接、添加监听等。
    (2) ICameraDeviceUser 是已打开的特定相机设备的接口。应用框架可通过它访问具体设备。
    (3) ICameraServiceListener 和 ICameraDeviceCallbacks 分别是从 CameraService 和 CameraDevice 到应用框架的回调。
  2. Natice framework
    代码路径位于:frameworks/av/。提供了ICameraService、ICameraDeviceUser、ICameraDeviceCallbacks、ICameraServiceListener等aidl接口的实现。以及camera server的main函数。
  3. Binder IPC interface
    提供进程间通信的接口,APP和CameraService的通信、CameraService和HAL的通信。其中,AIDL、HIDL都是基于Binder实现的。
  4. Camera Service
    代码路径:frameworks/av/services/camera/。同APP、HAL交互的服务,起到了承上启下的作用。
  5. HAL
    Google的HAL定义了可以让Camera Service访问的标准接口。对于供应商而言,必须要实现这些接口。

核心概念:Request

request是贯穿camera2数据处理流程最为重要的概念,应用框架是通过向camera子系统发送request来获取其想要的result。request有下述几个重要特征:

  1. 一个request可以对应一系列的result。
  2. request应当包含所有必要的配置信息,存放于metadata中。如:分辨率和像素格式;sensor、镜头、闪光等的控制信息;3A 操作模式;RAW 到 YUV 处理控件;以及统计信息的生成等。
  3. request需要携带对应的surface(也就是框架里面的stream),用于接收返回的图像。
  4. 多个request可以同时处于in-flight状态,并且submit request是non-blocking方式的。也就是说,上一个request没有处理完,也可以submit新的request。
  5. 队列中request的处理总是按照FIFO的形式。
  6. snapshot的request的preview的request拥有更高的优先级。

request的整体处理流程如下图:
request processing

  • open 流程(黑色箭头线条)
    • CameraManager注册AvailabilityCallback回调,用于接收相机设备的可用性状态变更的通知。
    • CameraManager通过调用getCameraIdList()获取到当前可用的camera id,通过getCameraCharacteristcs()函数获取到指定相机设备的特性。
    • CameraManager调用openCamera()打开指定相机设备,并返回一个CameraDevice对象,后续通过该CameraDevice对象操控具体的相机设备。
    • 使用CameraDevice对象的createCaptureSession()创建一个session,数据请求(预览、拍照等)都是通过session进行。在创建session时,需要提供Surface作为参数,用于接收返回的图像。
  • configure stream流程(蓝色箭头线条)
    • 申请Surface,如上图的OUTPUT STREAMS DESTINATIONS框,用于在创建session时作为参数,接收session返回的图像。
    • 创建session后,surface会被配置成框架的stream。在框架中,stream定义了图像的size及format。
    • 每个request都需要携带target surface用于指定返回的图像是归属到哪个被configure的stream的。
  • request处理流程(橙色箭头线条)
    • CameraDevice对象通过createCaptureRequest()来创建request,每个reqeust都需要有surface和settings(settings就是metadata,request包含的所有配置信息都是放在metadata中的)。
    • 使用session的capture()、captureBurst()、setStreamingRequest()、setStreamingBurst()等api可以将request发送到框架。
    • 预览的request,通过setStreamingRequest()、setStreamingBurst()发送,仅调用一次。将request set到repeating request list里面。只要pending request queue里面没有request,就将repeating list里面的request copy到pending queue里面。
    • 拍照的request,通过capture()、captureBurst()发送,每次需要拍照都会调用。每次触发,都会直接将request入到pending request queue里面,所以拍照的request比预览的request的优先级更高。
    • in-progress queue代表当前正在处理的request的queue,每处理完一个,都会从pending queue里面拿出来一个新的request放到这里。
  • 数据返回流程(紫色箭头线条)
    • 硬件层面返回的数据会放到result里面返回,会通过session的capture callback回调响应。

request在HAL的处理方式

  1. framework发送异步的request到hal。
  2. hal必须顺序处理request,对于每一个request都要返回timestamp(shutter,也就是帧的生成时间)、metadata、image buffers。
  3. 对于request引用的每一类steam,必须按FIFO的方式返回result。比如:对于预览的stream,result id 9必须要先于result id 10返回。但是拍照的stream,当前可以只返回到result id 7,因为拍照和预览用的stream不一样。
  4. hal需要的信息都通过request携带的metadata接收,hal需要返回的信息都通过result携带的metadata返回。

HAL处理request的整体流程如下图。
Camera HAL Process Request

  • request处理流程(黑色箭头线条)
    • framework异步地submit request到hal,hal依次处理,并返回result。
    • 每个被submit到hal的request都必须携带stream。stream分为input stream和output stream:input stream对应的buffer是已有图像数据的buffer,hal对这些buffer进行reprocess;output stream对应的buffer是empty buffer,hal将生成的图像数据填充的这些buffer里面。
  • input stream处理流程(图像的INPUT STREAM 1)
    • request携带input stream及input buffer到hal。
    • hal进行reprocess,然后新的图像数据重新填充到buffer里面,返回到framework。
  • output stream处理流程(图像的OUTPUT STREAM 1…N)
    • request携带output stream及output buffer到hal。
    • hal经过一系列模块的的处理,将图像数据写到buffer中,返回到frameowork。

猜你喜欢

转载自blog.csdn.net/u013961718/article/details/87302254