HAL 子系统

请求

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

Camera request model

图 1. 相机模型

HAL 和相机子系统

相机子系统包括相机流水线中组件(如 3A 算法和处理控件)的实现。相机 HAL 提供了接口,供您实现这些组件的自定义版本。为了保持多个设备制造商与图像信号处理器(ISP 或相机传感器)供应商之间的跨平台兼容性,相机流水线模型是虚拟的,并不直接对应于任何真实的 ISP。但是,它与真实的处理流水线非常相似,因此您可以将其高效地映射到硬件。此外,它还具有足够的抽象性,允许使用多种不同的算法和操作顺序,而不会影响质量、效率或跨设备兼容性。

相机流水线还支持应用框架可以启动的触发器,以开启自动对焦等功能。它还会向应用框架发回通知,告知应用自动对焦锁定或错误等事件。

Camera hardware abstraction layer

图 2. 相机流水线

请注意,上图中显示的一些图像处理模块在初始版本中未明确定义。相机流水线做出以下假设

  • RAW Bayer 输出在 ISP 内部不进行任何处理。
  • 统计信息基于原始传感器数据生成。
  • 将原始传感器数据转换为 YUV 的各种处理模块的顺序是任意的。
  • 虽然显示了多个缩放和裁剪单元,但所有缩放器单元共享输出区域控件(数码变焦)。但是,每个单元可能具有不同的输出分辨率和像素格式。

API 使用摘要
这是使用 Android Camera API 的步骤的简要摘要。有关这些步骤的详细分解(包括 API 调用),请参阅启动和预期操作序列部分。

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

HAL 操作摘要

  • 来自框架的异步捕获请求。
  • HAL 设备必须按顺序处理请求。并且对于每个请求,生成输出结果元数据以及一个或多个输出图像缓冲区。
  • 请求和结果以及后续请求引用的流均采用先进先出 (FIFO) 方式。
  • 来自给定请求的所有输出的时间戳必须相同,以便框架可以在需要时将它们匹配在一起。
  • 所有捕获配置和状态(3A 例程除外)都封装在请求和结果中。
Camera HAL overview

图 3. 相机 HAL 概述

启动和预期操作序列

本节包含使用 Camera API 时预期步骤的详细说明。有关 HIDL 接口定义,请参阅 platform/hardware/interfaces/camera/

枚举、打开相机设备并创建活动会话

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

使用活动相机会话

  1. 框架使用 HAL 设备的输入/输出流列表调用 ICameraDeviceSession::configureStreams()
  2. 框架通过调用 ICameraDeviceSession::constructDefaultRequestSettings() 来请求某些用例的默认设置。这可以在 ICameraDeviceSessionICameraDevice::open 创建后的任何时间发生。
  3. 框架根据其中一组默认设置构造第一个捕获请求并将其发送到 HAL,并且至少包含一个先前由框架注册的输出流。这通过 ICameraDeviceSession::processCaptureRequest() 发送到 HAL。HAL 必须阻止此调用的返回,直到它准备好发送下一个请求。
  4. 框架继续提交请求并调用 ICameraDeviceSession::constructDefaultRequestSettings() 以根据需要获取其他用例的默认设置缓冲区。
  5. 当请求的捕获开始时(传感器开始为捕获曝光),HAL 调用 ICameraDeviceCallback::notify() 并发送 SHUTTER 消息,其中包括帧号和曝光开始的时间戳。此通知回调不必在请求的第一个 processCaptureResult() 调用之前发生,但在调用该捕获的 notify() 之前,不会向应用传递任何捕获结果。
  6. 经过一些流水线延迟后,HAL 开始使用 ICameraDeviceCallback::processCaptureResult() 将已完成的捕获返回到框架。这些返回的顺序与请求提交的顺序相同。根据相机 HAL 设备的流水线深度,可以同时存在多个正在处理的请求。

一段时间后,将发生以下情况之一

  • 框架可能会停止提交新请求,等待现有捕获完成(所有缓冲区已填充,所有结果已返回),然后再次调用 ICameraDeviceSession::configureStreams()。这将为一组新的输入/输出流重置相机硬件和流水线。某些流可能会从之前的配置中重复使用。如果至少保留一个已注册的输出流,则框架将从到 HAL 的第一个捕获请求继续。(否则,首先需要 ICameraDeviceSession::configureStreams()。)
  • 框架可以调用 ICameraDeviceSession::close() 以结束相机会话。可以在框架没有其他活动调用时随时调用此方法,尽管该调用可能会阻塞,直到所有正在处理的捕获完成(所有结果已返回,所有缓冲区已填充)。在 close() 调用返回后,HAL 不得再调用 ICameraDeviceCallback。一旦 close() 调用正在进行中,框架可能不会调用任何其他 HAL 设备函数。
  • 如果发生错误或其他异步事件,HAL 必须调用 ICameraDeviceCallback::notify() 并发送相应的错误/事件消息。从致命的设备范围错误通知返回后,HAL 应表现得好像已对其调用了 close()。但是,HAL 必须先取消或完成所有未完成的捕获,然后再调用 notify(),以便一旦使用致命错误调用 notify(),框架将不会收到来自设备的进一步回调。在 notify() 方法从致命错误消息返回后,close() 以外的方法应返回 -ENODEV 或 NULL。
Camera operations flow

图 4. 相机操作流程

硬件级别

相机设备可以根据其功能实现多个硬件级别。有关详细信息,请参阅支持的硬件级别

应用捕获请求、3A 控制和处理流水线之间的交互

根据 3A 控制模块中的设置,相机流水线会忽略应用捕获请求中的某些参数,而改用 3A 控制例程提供的值。例如,当自动曝光处于活动状态时,传感器的曝光时间、帧持续时间和灵敏度参数由平台 3A 算法控制,并且会忽略任何应用指定的值。3A 例程为帧选择的值必须在输出元数据中报告。下表描述了 3A 控制模块的不同模式以及由这些模式控制的属性。有关这些属性的定义,请参阅 platform/system/media/camera/docs/docs.html 文件。

参数 状态 受控属性
android.control.aeMode OFF
ON android.sensor.exposureTime android.sensor.frameDuration android.sensor.sensitivity android.lens.aperture(如果支持)android.lens.filterDensity(如果支持)
ON_AUTO_FLASH 所有内容均为 ON,外加 android.flash.firingPower、android.flash.firingTime 和 android.flash.mode
ON_ALWAYS_FLASH 与 ON_AUTO_FLASH 相同
ON_AUTO_FLASH_RED_EYE 与 ON_AUTO_FLASH 相同
android.control.awbMode OFF
WHITE_BALANCE_* android.colorCorrection.transform。如果 android.colorCorrection.mode 为 FAST 或 HIGH_QUALITY,则进行平台特定的调整。
android.control.afMode OFF
FOCUS_MODE_* android.lens.focusDistance
android.control.videoStabilization OFF
ON 可以调整 android.scaler.cropRegion 以实现视频防抖
android.control.mode OFF AE、AWB 和 AF 均已禁用
AUTO 使用单独的 AE、AWB 和 AF 设置
SCENE_MODE_* 可以覆盖上面列出的所有参数。单独的 3A 控件已禁用。

图 2 中图像处理模块中的控件都以类似的原理运行,并且通常每个模块都有三种模式

  • OFF:此处理模块已禁用。无法禁用去马赛克、色彩校正和色调曲线调整模块。
  • FAST:在此模式下,与 OFF 模式相比,处理模块可能不会降低输出帧率,但应在给定该限制的情况下生成尽可能高质量的输出。通常,这会用于预览或视频录制模式,或用于静止图像的连拍。在某些设备上,这可能等同于 OFF 模式(不降低帧率就无法完成任何处理),而在某些设备上,这可能等同于 HIGH_QUALITY 模式(最佳质量仍然不会降低帧率)。
  • HIGH_QUALITY:在此模式下,处理模块应生成尽可能最佳的质量结果,并根据需要降低输出帧率。通常,这会用于高质量静止图像捕获。某些模块包含手动控件,可以选择性地选择该控件而不是 FAST 或 HIGH_QUALITY。例如,色彩校正模块支持色彩变换矩阵,而色调曲线调整支持任意全局色调映射曲线。

相机子系统可以支持的最大帧率是许多因素的函数

  • 请求的输出图像流的分辨率
  • 图像传感器上 binning/skipping 模式的可用性
  • 图像传感器接口的带宽
  • 各种 ISP 处理模块的带宽

由于这些因素在不同的 ISP 和传感器之间可能差异很大,因此相机 HAL 接口尝试将带宽限制抽象为尽可能简单的模型。所提出的模型具有以下特征

  • 图像传感器始终配置为输出尽可能小的分辨率,具体取决于应用请求的输出流大小。最小分辨率定义为至少与最大请求的输出流大小一样大。
  • 由于任何请求都可以使用任何或所有当前配置的输出流,因此必须将传感器和 ISP 配置为支持将单个捕获同时缩放到所有流。
  • 对于未包含 JPEG 流的请求,JPEG 流的作用类似于已处理的 YUV 流;在直接引用 JPEG 流的请求中,它们充当 JPEG 流。
  • JPEG 处理器可以与相机流水线的其余部分同时运行,但一次不能处理多个捕获。