AndroidCamera学习笔记二 基本流程及框架

AndroidCamera的基本流程及框架

在前面简单介绍了一下camera的硬件成像流程,从传感器成像到屏幕显示还要经过Android的多层架构的处理来实现最终显示,一般来说可以分为Kernel、HAL、Framework、APP层。在有部分资料中将Framework又细分为JAVA Framework和native C/C++Libraries及Runtime等多层,其实本质上没有区别,只是在Framework的理解上有不同见解而已。下面简单介绍下各层功能及各版本差异。

AndroidCamera学习笔记二 基本流程及框架_第1张图片

Application

Application层:可以理解为内置在Android系统的app,APP应用层在Android上表现为直接调用SDK API开发的一个Camera 应用APK包。我们可以像调用Java API Framework层一样直接调用系统app。我们也可以自己编写System app,但是要注意系统应用的权限比较特殊,直接写在manifest里面是不行的,需要做特别的处理。一般的第三方APP获取不到多摄权限,手机的多摄功能仅提供给内置相机APP使用(在选择手机时就需要对自己的拍照需求有所衡量,如自拍常用美颜第三方APP就可以对多摄没有太大需求)。我们这里说的AndroidCamera目前仅讨论基本的预览拍照录像,不涉及广角,长焦等内置相机特异性功能。
对于相机APP开发者来说目前有两种APK包供开发调用,即API1和API2。Android5.0之后API1就被弃用了,但是由于很多设备仍然依赖相机 API1,因此之后的版本仍支持该模块。

API1

对于API1来说:因出现较早,Google 给这一版本的定位是:满足“对准 - 拍摄”的需求即可,即一种类似于“傻瓜相机”式的自动调节的拍摄体验。不高的目标加上手机硬件的各种限制,早期的相机 API 设计时“先天不足”、能力有限:
1、有限的照片数据流(拿不到 raw 格式原始数据文件)
2、有限的相机状态信息
3、无法进行手动拍摄控制

API2

而API2就是目前相机主流使用的API版本,重新设计 Android Camera API 的目的在于大幅提高应用对于 Android 设备上的相机子系统的控制能力,同时重新组织 API,提高其效率和可维护性。API2中所有预览、拍照、录像操作均以请求集(Request)形式通过会话(Session)发送到设备来执行不同的操作。API2不仅提供了更多可操作性并且将结构进一步优化使得更加合理。简单来说就是API1的调用就是简单的从头调用到尾,而API2则通过Seesion及Request的封装实现了一个通道,将请求封装通过这个通道发送过去由另一边处理。

Framework

CameraFramework将应用与底层的实现隔离开来,实现了一套Android定义的对上对下接口规范,方便应用及底层硬件的开发和移植。这一层对上以Java类的形式包装出多个类,提供给应用层调用;对下在API1中表现为调用JNI函数而在API2中表现为通过Binder机制与CameraService建立连接。这样做的好处是让Camera的应用框架代码独立,不受底层HAL和驱动层的改变而影响,而保持上层的代码不用变化。确保了程序高内聚,低耦合,使模块的可重用性、移植性大大增强。对于API1来说,Framework层提供给开发者的接口是一个Camera类包括各种方法:

API1中类

AndroidCamera学习笔记二 基本流程及框架_第2张图片

API2中类

API2中提供的方法主要是在camera2中,包括以下类和方法:
1、CameraManager:相机系统服务管理器
getCameraCharacteristics(String cameraId)返回一个Characteristics对象
getCameraIdList()获取cameraID列表 String[]类型
openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)打开相机参数包括id,回调,当前进程
registerAvailabilityCallback(CameraManager.AvailabilityCallback callback, Handler handler)注册一个用于相机设备的回调或无法打开的回调
registerTorchCallback(CameraManager.TorchCallback,Handler handler)
注册一个相机闪光灯torch模式变得不可用的回调
2、CameraDevice:对应一个单一摄像头
close()关闭相机
createCaptureSession(List Surface outputs, CameraCaptureSession.StateCallback callback, Handler handler)创建一个 会话通道(管道)
createCaptureRequest(int templateType)创建一个请求(指令集)
3、CameraDevice.StateCallback 回调,用于接收相机状态
4、CameraCaptureSession()配置捕捉会话,Services和driver之间的通道
5、CaptureRequest.Builder
addTarget()向请求的目录列表添加一个表面
build()使用当前表面和设置构建一个请求
get()获取属性值
removeTarget()从这个请求目标列表删除一个表面
set()设置属性值
setTag()给请求设置一个标记
6、CameraCharacteristics用于描述特定摄像头所支持的各种特性。

HAL

HAL层(Hardware Abstraction Layer)硬件抽象层,是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚。思路是把控制硬件的动作都放到了Android HAL中,由于Android底层是Linux核心,Linux规定必须要开源,如果厂商把摄像头的成像处理算法放到Kernel中就要把算法开源,这是厂商绝对不答应的,因此Android就在Kernel上又加了一层叫做HAL,将算法及图像处理放入HAL,Android不规定必须开源,所以就保护了厂商的利益。主要用于把底层camera driver与硬件和位于android.hardware中的framework API连接起来。camera HAL起着承上启下的作用。在camera HAL层实现中,芯片厂商一般将camera HAL层的实现分为两层:interface层和OEM层。OEM层为下层,它用于屏蔽不同的camera硬件。不同的camera硬件必须支持OEM层提供的对外接口。Interface层为上层,它调用OEM层的对外接口来实现camera HAL所定义的接口。对于Interface层,它并不知道底层camera硬件到底是哪一个版本。同时,interface层完成了屏蔽camera HAL版本的作用。对于OEM层,它也不知道上层是哪一个camera HAL版本,及android版本。两层分离架构,可以很容易地实现不同芯片支持同一个android版本和同一款芯片支持不同android版本(前提条件是该款芯片能够支持这些android版本的各个需求)。在HAL的发展过程中出现了多个HAL版本,主要的大版本为HAL1和HAL3:

HAL1

HAL1被设计为具有高级控件和预览、视频录制、静态拍摄三种运行模式的黑盒子。三种模式具有略有不同而又互相重叠的功能,这样就难以实现介于其中两种运行模式之间的新功能,例如连拍模式。虽然相机 HAL1 已弃用,但是 由于很多设备仍然依赖相机 HAL1,因此 Android 7.0 之后继续支持该模块。此外,Android 相机服务还支持同时实现两种 HAL(1和3)。 下图是HAL1(qcom)的一个简要结构,层层下调,层层返回结果。
AndroidCamera学习笔记二 基本流程及框架_第3张图片

HAL3

HAL3将多个运行模式整合为一个统一的视图,您可以使用这种视图实现之前的任何模式以及一些其他模式,例如连拍模式。这样一来,便可以提高用户对聚焦、曝光以及更多后期处理(例如降噪、对比度和锐化)效果的控制能力。此外,这种简化的视图还能够使应用开发者更轻松地使用相机的各种功能。HAL3对相机的各个参数精细化控制并提供给上层接口,使得可以实现更加多元化的功能。HAL1到HAL3也不仅仅是功能的细化,更是在结构和流程上进行了优化,这部分在Android8.0后加入Trable机制后更加明显,独立于上层,与上层的联系为Request,通过请求来决定处理。AndroidCamera学习笔记二 基本流程及框架_第4张图片

API和HAL的各版本搭配

AndroidCamera学习笔记二 基本流程及框架_第5张图片
简单来说,在4种调用组合里面, 有3种是通过在CameraService中创建不同的Client来实现的,使用了不同的Client(Client泛指CameraService和HAL层之间的接口, 有三个版本), 在makeClient函数中完成。HAL层默认使用HAL1,则创建 CameraClient, 如果HAL层默认使用HAL3, 根据使用API进行判断, 使用API1则创建 Camera2Client, 使用API2则创建 CameraDeviceClient.如果指定了一个特殊的HAL版本, 并且不是默认的HAL版本, 此时只会创建CameraClient。只有API2调用HAL1是在API层面实现的,即把Camera API2的API调用转为Camera API1。Camera API2调用HAL1其实是在Framework层将API2接口转为了API1, 对CameraService来说, 就是使用API1来调用.

Kernel层

Android是在Linux内核的基础上构建的,Android的内核属于Linux内核的一个分支。Android核心系统服务依赖于Linux2.6内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型。Linux内核也是作为硬件与软件栈的抽象层。Linux内核层提供了几乎所有手机、平板电脑相关设备的驱动程序,实现系统与各种硬件的通信,如显示屏、摄像头、内存、键盘、无线网络、音频设备、电源等组件。对Camera来说,一般是按V4l2规范将Camera原子功能以ioctl的形式暴露出来供HAL层调用的实现。

总结

在这部分简单介绍下AndroidCamera的层级架构,其实就是Android的分层架构,不同的模块在各层的实现有差异,大部分差异集中在各模块的HAL上。不同的模块HAL层有各自的实现及版本更迭。文中图片基本都来自于社区的各位前辈及同行的各位大佬,整文也仅是基于网络资料加个人理解记录下学习过程,引用过多图片,未标明出处,望各位大佬勿怪,仅用以学习记录及交流探讨。

你可能感兴趣的:(AndroidCamera学习笔记二 基本流程及框架)