AndroidCamera的基本流程及框架

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

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中类

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)的一个简要结构,层层下调,层层返回结果。

HAL3

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

API和HAL的各版本搭配


简单来说,在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学习笔记二 基本流程及框架相关推荐

  1. RobotFramework学习笔记二:遇到Frame框架

    当元素存在frame/iframe框架内部时,RF会报找不到该元素,这时需要使用Select Frame 和Unselect Frame 关键字进行操作了. Select Frame 可以通过id n ...

  2. Colly 学习笔记(二)——爬虫框架,抓取下载数据(上证A股数据下载)

    Colly 学习笔记(二)--爬虫框架,抓取下载数据(上证A股数据下载) Colly 学习笔记(一)--爬虫框架,抓取中金公司行业市盈率数据 Colly 学习笔记(二)--爬虫框架,抓取下载数据(上证 ...

  3. Spring Boot 框架学习笔记(二)(配置文件与数据注入 yaml基本语法 JSR303数据验证 多环境切换 )

    Spring Boot 框架学习笔记(二) 六.appliaction.properties配置与数据注入 6.1 `@Value`注解 测试注入数据 读取输入流 6.2 读取配置文件数据注入 单文件 ...

  4. pythonsze_python学习笔记二 数据类型(基础篇)

    Python基础 对于Python,一切事物都是对象,对象基于类创建 不同类型的类可以创造出字符串,数字,列表这样的对象,比如"koka".24.['北京', '上海', '深圳' ...

  5. Unity3D 学习笔记4 —— UGUI+uLua游戏框架

    Unity3D 学习笔记4 -- UGUI+uLua游戏框架 使用到的资料下载地址以及基础知识 框架讲解 拓展热更过程 在这里我们使用的是uLua/cstolua技术空间所以提供的UGUI+uLua的 ...

  6. AndroidCamera学习笔记一 硬件

    AndroidCamera学习笔记一 硬件 题记 硬件部分 镜头 传感器 ISP.DSP 闪光灯.滤光片等其他部件 摄像头重要参数 分辨率.像素 光圈数 景深 焦距 硬件成像流程![成像流程](htt ...

  7. 爬虫学习笔记(十)—— Scrapy框架(五):下载中间件、用户/IP代理池、settings文件

    一.下载中间件 下载中间件是一个用来hooks进Scrapy的request/response处理过程的框架. 它是一个轻量级的底层系统,用来全局修改scrapy的request和response. ...

  8. 项目管理学习笔记二:信息系统服务管理

    项目管理学习笔记二:信息系统服务管理 2010-10-22 09:56:33 标签:信息系统 笔记 项目管理 服务 学习 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文 ...

  9. html 流程控制,HTML5独家分享:原生JS学习笔记2——程序流程控制

    当当当当 .....楼主又来了!新一期的js学习笔记2--程序流程控制更新了! 想一键获取全部js学习笔记的可以给楼主留言哦! js中的程序控制语句 常见的程序有三种执行结构: 1.顺序结构 2.分支 ...

  10. LIteOS学习笔记-7LiteOS启动流程与编译流程

    LIteOS学习笔记-7LiteOS启动流程与编译流程 LiteOS启动流程 1. 启动方式 2. 启动流程 硬件初始化 内核初始化 调试串口初始化 尝试进行网络连接 启动任务调度 LiteOS编译流 ...

最新文章

  1. 2021全球数字经济大会“北京数字经济体验周”清华数为大数据开发工具DWF体验培训工作圆满结束...
  2. 软件测试nextdata程序,Nextdata测试用例及源程序.doc
  3. CRM WebClient UI里标准configuration和custom configuration区别
  4. linux php自动执行_linux下实现定时执行php脚本
  5. nyoj91 阶乘之和
  6. linux环境对xml的影响,Linux下XPath对xml解析
  7. python中自定义超时异常的几种方法
  8. 【操作系统/OS笔记02】操作系统的历史、操作系统结构
  9. Android so文件进阶 一
  10. Java抓取淘宝/天猫商品详情 1
  11. Vczh Library++ 语法分析器开发指南(转载)
  12. 比特大陆将任命新任首席执行官
  13. linux下iso镜像的制作工具,ISO镜像文件制作转换工具(AnyToISO)
  14. 使用Sugar制作数据可视化大屏的操作过程
  15. 金山词霸2009牛津with SP3完全破解版(含全部本地词库和语音包)
  16. CSUOJ 1256 天朝的单行道(最短路)
  17. 中国阀门驱动装置行业运行状况与前景趋势研究报告2022-2028年
  18. Policy Gradient连续动作 tf.distributions.Normal log_prob = self.normal_dist.log_prob(self.a) 的解释
  19. 5_echo命令的作用
  20. [ CTF ] WriteUp- 20221003 CTFShow新(脑洞)手(套路)杯

热门文章

  1. python随机出100道加法题_python3 随机生成10以内的加法算术题
  2. C语言 十进制转换为二进制
  3. 如何在windows中配置自动生成崩溃文件(.dmp)
  4. 如何使用Navicat将psc备份导入到MySQL
  5. xyz坐标转换ybc_经纬度转换XYZ
  6. 中关村-DIY之笔记本做wifi热点供手机无线上网
  7. 立创开源丨无刷电机驱动FOC驱动板
  8. Linux服务器监控性能测试
  9. Processing 入门教程(二十一) 利用数组产生雪花坠落效果
  10. Java通过代理服务器上网