Camera专题

Camera API2 Overview 01 架构

2020-08-17  本文已影响0人  yzzCool

1引言

1.1编写目的

本篇算是加深理解 Camera 2。

Android 的相机硬件抽象层 (HAL Hardware Abstraction Layer) 可将 Camera 2 中较高层级的相机框架 API 连接到底层的相机驱动程序和硬件。相机子系统包括相机管道组件的实现,而相机 HAL 可提供用于实现您的这些组件版本的接口。

1.2适用范围

Camera API2的使用。

2 主要架构流程

2.1 Android Camera架构

2.1.1 先上图,看图讲故事

图1 Camera 架构

查看源码网站:
https://cs.android.com/
https://www.androidos.net.cn/sourcecode
http://androidxref.com/

实现 HAL
HAL 位于相机驱动程序和更高级别的 Android 框架之间,它定义您必须实现的接口,以便应用可以正确地操作相机硬件。相机 HALHIDL(HAL 接口定义语言 , HAL Interface Definition Language) 接口在 hardware/interfaces/camera 中定义。

典型的绑定式 HAL 必须实现以下 HIDL 接口:
ICameraProvider:用于枚举单个设备并管理其状态。
ICameraDevice:相机设备接口。
ICameraDeviceSession:活跃的相机设备会话接口。

参考 HIDL 实现适用于CameraProvider.cppCameraDevice.cppCameraDeviceSession.cpp。该实现封装了仍使用旧版 API 的旧 HAL。从 Android 8.0 开始,相机 HAL 实现必须使用 HIDL API;不支持使用旧版接口。

2.2 相机 HAL3

Android 的相机硬件抽象层 (HAL) 可将 android.hardware.camera2 中较高级别的相机框架 API 连接到底层的相机驱动程序和硬件。
Android 8.0 引入了 Treble,用于将 CameraHal API 切换到由 HAL 接口描述语言 (HIDL) 定义的稳定接口。

2.2.1 相机 HAL3 功能

重新设计 Android Camera API 的目的::在于大幅提高应用对于 Android 设备上的相机子系统的控制能力,同时重新组织 API,提高其效率和可维护性。借助额外的控制能力,您可以更轻松地在 Android 设备上构建高品质的相机应用,这些应用可在多种产品上稳定运行,同时仍会尽可能使用设备专用算法来最大限度地提升质量和性能。

版本 3 相机子系统将多个运行模式整合为一个统一的视图,您可以使用这种视图实现之前的任何模式以及一些其他模式,例如连拍模式。这样一来,便可以提高用户对聚焦、曝光以及更多后期处理(例如降噪、对比度和锐化)效果的控制能力。此外,这种简化的视图还能够使应用开发者更轻松地使用相机的各种功能。

API 将相机子系统塑造为一个管道,该管道可按照 1:1 的基准将传入的帧捕获请求转化为帧。这些请求包含有关帧的捕获和处理的所有配置信息,其中包括分辨率和像素格式手动传感器镜头和闪光灯控件3A 操作模式RAW 到 YUV 处理控件统计信息生成等等。

简单来说,应用框架从相机子系统请求帧,然后相机子系统将结果返回到输出流。此外,系统还会针对每组结果生成包含色彩空间和镜头遮蔽等信息的元数据。您可以将相机版本 3 看作相机版本 1 的单向流管道。它会将每个捕获请求转化为传感器捕获的一张图像,这张图像将被处理成::

可能的输出 Surface 组经过预配置:

一个请求中包含所需的全部捕获设置,以及要针对该请求将图像缓冲区(从总配置组)推送到其中的输出 Surface 的列表。请求可以只发生一次(使用 capture()),也可以无限重复(使用 setRepeatingRequest())。捕获的优先级高于重复请求的优先级。

图2 相机核心操作模型

2.3 HAL子系统

2.3.1 capture请求

应用框架会针对捕获的结果向相机子系统发出请求。一个请求对应一组结果。请求包含有关捕获和处理这些结果的所有配置信息。其中包括分辨率和像素格式;手动传感器、镜头和闪光灯控件;3A 操作模式;RAW 到 YUV 处理控件;以及统计信息的生成等。这样一来,便可更好地控制结果的输出和处理。一次可发起多个请求,而且提交请求时不会出现阻塞。请求始终按照接收的顺序进行处理。

图3 相机模型

2.3.2 HAL 和相机子系统

相机子系统包括相机管道中组件的实现,例如 3A 算法和处理控件。相机 HAL 为您提供了用于实现您的这些组件版本的接口。为了保持多个设备制造商和图像信号处理器(ISP,也称为相机传感器)供应商之间的跨平台兼容性,相机管道模型是虚拟的,且不直接对应于任何真正的 ISP。不过,它与真正的处理管道足够相似,因此您可以有效地将其映射到硬件。此外,它足够抽象,可支持多种不同的算法和运算顺序,而不会影响质量、效率或跨设备兼容性。

相机管道还支持应用框架可以启动来开启自动对焦等功能的触发器。它还会将通知发送回应用框架,以通知应用自动对焦锁定或错误等事件。

图4 相机管道

请注意,上图所示的一些图像处理块在初始版本中没有明确定义。
相机管道做出以下假设:

API 用途摘要
下面简要介绍了使用 Android Camera API 的步骤。有关这些步骤(包括 API 调用)的详细说明,请参阅“启动和预期操作顺序”部分。

  1. 监听和枚举相机设备。
  2. 打开设备并连接监听器。
  3. 配置目标使用情形的输出(如静态捕获、录制等)。
  4. 为目标使用情形创建请求。
  5. 捕获/重复请求和连拍。
  6. 接收结果元数据和图片数据。
  7. 切换使用情形时,返回到第 3 步。

HAL 操作摘要
捕获的异步请求来自于框架。

图5 相机 HAL 概览

2.3.3 启动和预期操作顺序

本部分详细说明了使用 Camera API 时应遵循的步骤。有关 HIDL 接口的定义,请参阅 platform/hardware/interfaces/camera/

枚举、打开相机设备并创建有效会话

  1. 初始化后,框架开始监听实现 ICameraProvider 接口的任何现有相机提供程序。如果存在一个或多个此类提供程序,框架将尝试建立连接。
  2. 框架通过 ICameraProvider::getCameraIdList() 枚举相机设备。
  3. 框架通过调用相应的 ICameraProvider::getCameraDeviceInterface_VX_X() 来实例化一个新的 ICameraDevice
  4. 框架调用 ICameraDevice::open() 来创建一个新的有效捕获会话 ICameraDeviceSession

使用有效相机会话

  1. 框架调用 ICameraDeviceSession::configureStreams() 并传入到 HAL 设备的输入/输出流列表。
  2. 框架通过调用 ICameraDeviceSession::constructDefaultRequestSettings() 来为某些使用情形请求默认设置。这可能会在 ICameraDevice::open 创建 ICameraDeviceSession 之后的任何时间发生。
  3. 框架通过基于某一组默认设置的设置以及框架之前注册的至少一个输出流来构建第一个捕获请求并将其发送到 HAL。此请求通过 ICameraDeviceSession::processCaptureRequest() 发送到 HAL。HAL 必须阻止此调用返回,直到准备好发送下一个请求为止。
  4. 框架继续提交请求并根据需要调用 ICameraDeviceSession::constructDefaultRequestSettings() 以获取其他使用情形的默认设置缓冲区。
  5. 当请求捕获开始(传感器开始曝光以进行捕获)时,HAL 会调用 ICameraDeviceCallback::notify() 并显示 SHUTTER 消息,包括帧号和开始曝光的时间戳。此通知回调不必在对请求第一次调用 processCaptureResult() 之前发生,但直到针对相应的捕获调用 notify() 之后,才会向应用提供有关该捕获的结果。
  6. 经过一定的管道延迟后,HAL 开始使用 ICameraDeviceCallback::processCaptureResult() 将完成的捕获返回到框架。这些捕获按照与提交请求相同的顺序返回。一次可发起多个请求,具体取决于相机 HAL 设备的管道深度。

一段时间后,会出现以下某种情况:

图6 相机操作流程

2.3.4 应用捕获请求、3A 控件和处理管道之间的交互

根据 3A 控件块中的设置,相机管道会忽略应用捕获请求中的某些参数,而改用 3A 控件例程提供的值。例如,启用自动曝光后,传感器的曝光时间、帧时长和感光度参数由平台 3A 算法控制,所有应用指定的值都会被忽略。必须在输出元数据中报告由 3A 例程为帧选择的值。
下表描述了 3A 控件块的不同模式以及由这些模式控制的属性。有关这些属性的定义,请参阅 platform/system/media/camera/docs/docs.html 文件。

图7 3A 控件块

图4 相机管道 中,图像处理块中的控件都以类似的原理操作,并且每个块一般都具有 3 种模式:

相机子系统可以支持的最大帧速率受到多种因素的影响:

由于这些因素在不同的 ISP 和传感器之间可能有很大差异,因此相机 HAL 接口会设法将带宽限制抽象为尽可能简单的模型。
显示的模型具有以下特性:

3 进程间通信类总结

我们直达camera模块的代码根据层次可以分为下面几层,开发者直接接触的是Camera api的部分,Camera api会通过Binder IPC方式调用到Camera服务部分,但是这部分代码实在繁杂,需要将这部分IPC联系的方式总结一些,方便后来人方便的学习这一块的内容。

加深两个路径:
1,首先大家关注一下这个代码路径:frameworks/av/camera/aidl/ 这里是和cameraservice端交互的桥梁。

图8 aidl

2, cameraservice端的代码在frameworks/av/services/camera/libcameraservice/下面。

图9 cameraservice

参考文章

  1. 官方介绍,搬运工
  2. Android Camera架构
上一篇下一篇

猜你喜欢

热点阅读