Android Camera2+HAL3架构

本文转载于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<span class="token punctuation">.</span>hardware<span class="token punctuation">.</span>camera2<span class="token punctuation">.</span>impl<span class="token punctuation">.</span>CameraDeviceImpl deviceImpl <span class="token operator">=</span>      <span class="token comment">// CameraDeviceImp继承自CameraDevice</span>
    	<span class="token keyword">new</span> <span class="token class-name">android<span class="token punctuation">.</span>hardware<span class="token punctuation">.</span>camera2<span class="token punctuation">.</span>impl<span class="token punctuation">.</span>CameraDeviceImpl</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    ICameraDeviceCallbacks callbacks <span class="token operator">=</span> deviceImpl<span class="token punctuation">.</span><span class="token function">getCallbacks</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 获取CameraDevice的回调函数</span>
    ICameraService cameraService <span class="token operator">=</span> CameraManagerGlobal<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getCameraService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    cameraUser <span class="token operator">=</span> cameraService<span class="token punctuation">.</span><span class="token function">connectDevice</span><span class="token punctuation">(</span>callbacks<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// connect到camera service,并将camera device callback注册进去</span>
    <span class="token comment">// 返回的ICameraDeviceUser就是CameraDeviceClient的本地接口</span>
    deviceImpl<span class="token punctuation">.</span><span class="token function">setRemoteDevice</span><span class="token punctuation">(</span>cameraUser<span class="token punctuation">)</span><span class="token punctuation">;</span>
    device <span class="token operator">=</span> deviceImpl<span class="token punctuation">;</span>
    
    <span class="token keyword">return</span> device<span class="token punctuation">;</span>
    

    }

      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。
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值