1. Camera 标准启动流程
在进行整体架构的介绍前我们需要先知道Android Camera在使用时最最重要的三个步骤。
- 打开相机(CameraManager.openCamera):获取一个相机设备
- 建立连接(CameraDevice.createCaptureSessiong): 连接设备,相当于创建了一条对应于一个相机设备的通路。
- 发送请求(CameraCaptureSession.set***Request):在建立了于相机连接的通路后,通过向这条通路发送各类请求(CaptureRequest)获取对应设置的图片或视频。
2. 整体框架简介
关于对Android camera整体框架的简介,我按照详细程度,进行了三次归纳。在理解了稍微简单一些的流程后,
再逐步添加详细的介绍会更清晰一些。
2.1 整体框架分层结构
2.1.1 基础分层
如下图所示,可以将Android Camera分为五个层次:
- Camera App:应用层处于整个框架的顶端,承担着于用户直接进行交互的责任,承接来自用户直接或者间接的比如预览/拍照/录像等一系列具体需求,一旦接收到用户相关UI操作,便会通过Camera Api2标准接口将需求发送至Camera Framework部分,并且等待Camera Framework回传处理结果。
- Camera2 Api:该层主要位于Camera App与Camera Service之间,以jar包的形式运行在App进程中,它封装了Camera Api2接口的实现细节,暴露接口给App进行调用,进而接收来自App的请求,同时维护着请求在内部流转的业务逻辑,最终通过调用Camera AIDL跨进程接口将请求发送至Camera Service中进行处理,紧接着,等待Camera Service结果的回传,进而将最终结果发送至App。
- CaemraService:该层位于Camera Framework与Camera Provider之间,作为一个独立进程存在于Android系统中,在系统启动初期会运行起来,它封装了Camera AIDL跨进程接口,提供给Framework进行调用,进而接收来自Framework的图像请求,同时内部维护着关于请求在该层的处理逻辑,最终通过调用Camera HIDL跨进程接口将请求再次下发到Camera Provider中,并且等待结果的回传,进而将结果上传至Framework中。
- CameraHAL(CameraProvider):该层位于Camera Service与Camera Driver之间,CameraProvider作为一个独立的进程存在于Android系统中,同时在系统启动初期被运行,提供Camera HIDL跨进程接口供Camera Service进行调用,封装了该接口的实现细节,接收来自Service的图像请求,并且内部加载了Camera HAL Module,该Module由OEM/ODM实现,遵循谷歌制定的标准Camera HAL3接口,进而通过该接口控制Camera HAL部分,最后等待Camera HAL的结果回传,紧接着Provider通过Camera HIDL接口将结果发送至Camera Service。
- CameraHardWare:相机硬件处在整个相机体系的最底层,是相机系统的物理实现部分,该部分一般包括镜头、感光器、ISP三个最重要的模块,还有对焦马达、闪光灯、滤光片、光圈等辅助模块。
2.1.2 详细分层
下图可以作为2.1.1的补充版本,添加了各个分层中比较重要的类(不太完善,重要的类太多了,之间的相互关联也比较多。需要对应具体的函数调用具体分析,这里主要是为了理解整体分层)。
在这里我们可以将整个相机的使用流程按照上述的三个重要步骤分为两条主线和一条连接主线支线的分线(下图红圈内1,2,3分别代表两条主线和一条支线)。
主线一: 获取相机设备
主线二: 获取服务
支线三: 提供服务的实体是相机设备,而服务只是作为中间人来传递上层对设备的请求,以及返回设备的结果给上层。
2.2 详细流程
绿色框中是应用开发者需要做的操作,蓝色为AOSP提供的API,黄色为Native Framework Service,紫色为HAL层Service.
描述一下步骤:
- App一般在MainActivity中使用SurfaceView或者SurfaceTexture+TextureView或者GLSurfaceView等控件作为显示预览界面的控件,共同点都是包含了一个单独的Surface作为取相机数据的容器.
- 当我们需要打开相机时调用API (openCamera)去通知Framework Native Service CameraServer去connect HAL继而打开Camera硬件sensor.
- openCamera成功会有回调从CameraServer通知到App,在onOpenedCamera或类似回调中去调用类似startPreview的操作.此时会创建CameraCaptureSession,创建过程中会向CameraServer调用ConfigureStream的操作,ConfigureStream的参数中包含了第一步中空间中的Surface的引用,相当于App将Surface容器给到了CameraServer,CameraServer包装了下该Surface容器为stream,通过HIDL传递给HAL,继而HAL也做configureStream操作
- ConfigureStream成功后CameraServer会给App回调通知ConfigStream成功,接下来App便会调用AOSP setRepeatingRequest接口发送请求到CameraServer,CameraServer初始化时便起来了一个死循环线程等待来接收Request.
- CameraServer将request交到Hal层去处理,得到HAL处理结果后取出该Request的处理Result中的Buffer填到App给到的容器中,SetRepeatingRequest为了预览,则交给Preview的Surface容器,如果是Capture Request则将收到的Buffer交给ImageReader的Surface容器.
- Surface本质上是BufferQueue的使用者和封装者,当CameraServer中App设置来的Surface容器被填满了BufferQueue机制将会通知到应用,此时App中控件取出各自容器中的内容消费掉,Preview控件中的Surface中的内容将通过View提供到SurfaceFlinger中进行合成最终显示出来,即预览;而ImageReader中的Surface被填了,则App将会取出保存成图片文件消费掉。
总结
通过本文,我们可以大致了解到Android Camera的整体框架设计,但是,理解整体框架只能算是Android Camera学习中
最最基础的一件事情。了解了这些,当设备底层都比较完善的情况下,我们可以顺畅的使用api进行相机app的开发。
但是往往作为一名Camera工程师,只是能够调用Api来进行开发的话,是远远远远不够的。而本系列文章的究极目的,
就是能够让读者学会如何成为一名真正Camera 工程师(当然其中也有许多细小的分类,例如:tuning、camera frame
work、camera Driver.......)。需要逐步地去学习。而在真正了解完这些之后,希望能够脱离android 平台,去接触
更加广阔的camera世界。