3. Camera HAL 架构:Android Camera HAL3 架构、Pipeline 模型、Stream 与 Request 关系

Android Camera HAL3 是 Android 系统从 API 21 开始引入的相机硬件抽象层架构,旨在替代传统的 HAL1 接口,提供更精细的控制能力和更高的帧率稳定性。HAL3 的核心设计围绕 Pipeline 模型 展开,将图像捕获过程抽象为可配置的数据流管道,并通过 Stream 和 Request 机制实现灵活的帧率控制。

3.1 Android Camera HAL3 架构总览

HAL3 架构在 Android 相机系统中位于 Camera Service 与底层 V4L2 驱动之间,承担着将上层抽象的 Capture Request 转换为底层硬件可执行的命令序列的职责。其核心组件包括:

  • Camera Device:代表单个物理或逻辑相机设备,负责处理 Open/Close/ConfigureStreams/ProcessCaptureRequest 等核心操作。
  • Camera Metadata:以键值对形式描述相机能力、当前状态和请求参数,是 HAL3 中控制帧率的关键数据载体。
  • Stream:定义图像数据的输出路径,包括分辨率、格式、使用场景(如 PREVIEW、STILL_CAPTURE、VIDEO_RECORD)等属性。
  • Capture Request:一次完整的图像捕获请求,包含目标 Stream、Metadata 设置以及 Buffer 管理信息。
  • Result:Capture Request 执行完成后返回的 Metadata 和填充了数据的 Buffer。
架构要点: HAL3 采用异步、流水线化的设计,允许同时有多个 Request 在 Pipeline 中处于不同阶段,这是实现高帧率稳定性的基础。与 HAL1 的同步阻塞模型不同,HAL3 的异步模型能更好地利用硬件并行能力。
Android Camera HAL3 架构分层图 Application / Camera2 API Camera Service (CameraProvider) Camera HAL3 Interface CameraDevice · Metadata · Stream · CaptureRequest · Result V4L2 Driver / Sensor Subsystem HAL3 作为中间层,将上层 Request 转换为 V4L2 的 VIDIOC_S_EXT_CTRLS / QBUF / DQBUF 操作序列

3.2 Pipeline 模型:帧率稳定的核心抽象

HAL3 的 Pipeline 模型将图像捕获过程分解为多个可重叠的阶段,每个阶段对应硬件处理单元的一个操作步骤。典型的 Pipeline 包含以下阶段:

阶段 描述 帧率影响因子
Request 解析 解析上层下发的 CaptureRequest,提取 AE/AWB/AF 参数及 Stream 目标 Metadata 解析耗时
Sensor 曝光 配置 sensor 曝光时间、增益,等待帧同步信号(VSYNC) 曝光时间、帧间隔
ISP 处理 RAW 数据经过 ISP 管线:去噪、插值、颜色校正、缩放等 ISP 时钟频率、处理负载
Buffer 填充 将处理后的图像数据写入目标 Stream 对应的 GraphicBuffer 内存带宽、Buffer 数量
Result 返回 将填充好的 Buffer 和 Metadata 结果回调给 Camera Service 回调线程调度延迟
帧率稳定性关键: Pipeline 的深度(同时处理的 Request 数量)直接影响帧率。深度过浅会导致硬件空闲等待,深度过深则引入额外延迟。通常建议 Pipeline 深度为 2~4,具体取决于 sensor 帧率和 ISP 处理延迟。
HAL3 Pipeline 流水线模型(深度=3) t Req1 解析 Req1 曝光 Req1 ISP Req1 Buffer Req1 Result Req2 解析 Req2 曝光 Req2 ISP Req2 Buffer Req2 Result Req3 解析 Req3 曝光 Req3 ISP Req3 Buffer Pipeline 深度=3:同一时刻最多有 3 个 Request 处于不同处理阶段,实现帧率流水线并行 每个阶段的时间片长度取决于硬件特性,帧率 = 1 / max(各阶段耗时)

3.3 Stream 与 Request 关系

Stream 和 Request 是 HAL3 中两个紧密关联的概念,理解它们的关系是调优帧率稳定性的前提。

3.3.1 Stream 配置

Stream 在 configureStreams() 调用中定义,每个 Stream 包含以下关键属性:

  • stream_type:CAMERA_STREAM_TYPE_OUTPUT(输出)或 CAMERA_STREAM_TYPE_INPUT(输入,用于 reprocessing)。
  • width / height:图像分辨率。
  • format:像素格式,如 HAL_PIXEL_FORMAT_YCbCr_420_888、HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED。
  • usage:GRALLOC_USAGE_SW_* 或 GRALLOC_USAGE_HW_* 标志,指示 Buffer 的访问方式。
  • max_buffers:该 Stream 允许的最大 Buffer 数量,直接影响帧率稳定性。
  • data_space:色彩空间,如 HAL_DATASPACE_STANDARD_BT709。
  • rotation:输出旋转角度(0/90/180/270)。

3.3.2 Request 与 Stream 的绑定

每个 CaptureRequest 通过 output_buffers 数组指定要写入哪些 Stream 的 Buffer。一个 Request 可以同时输出到多个 Stream,例如同时输出预览流和拍照流。

帧率陷阱: 当多个 Stream 配置了不同的分辨率或格式时,ISP 可能需要额外的缩放或格式转换操作,这会增加 Pipeline 的处理延迟。如果某个 Stream 的 Buffer 数量不足(max_buffers 过小),会导致 Pipeline 因等待 Buffer 而停顿,造成帧率抖动。
Stream 与 Request 关系图 CaptureRequest Metadata + Buffer 列表 Stream 0: Preview 1920x1080 YCbCr_420_888 Stream 1: Still Capture 4000x3000 JPEG Stream 2: Video Record 1920x1080 IMPLEMENTATION_DEFINED Buffer 池 Stream 0: 4 Buffers Stream 1: 2 Buffers Stream 2: 6 Buffers max_buffers 配置 影响 Pipeline 深度 一个 Request 可以同时输出到多个 Stream,每个 Stream 拥有独立的 Buffer 池 帧率稳定性要求:所有 Stream 的 Buffer 供应必须充足,避免因任一 Stream 的 Buffer 耗尽导致 Pipeline 阻塞

3.4 帧率稳定性相关的关键 Metadata

在 HAL3 中,帧率控制主要通过 Metadata 中的以下字段实现:

Metadata Tag 类型 作用 帧率调优建议
ANDROID_CONTROL_AE_TARGET_FPS_RANGE int32[2] 设置目标帧率范围 [min, max] 固定为 [30,30] 或 [60,60] 可锁定帧率
ANDROID_SENSOR_FRAME_DURATION int64 指定帧周期(纳秒) 设置固定值可避免帧率波动
ANDROID_SENSOR_EXPOSURE_TIME int64 曝光时间(纳秒) 曝光时间不能超过帧周期,否则帧率下降
ANDROID_REQUEST_PIPELINE_DEPTH byte 查询硬件 Pipeline 最大深度 用于决定同时下发的 Request 数量
ANDROID_SYNC_FRAME_NUMBER int32 帧同步编号,用于追踪 Pipeline 中的帧顺序 调试帧率抖动时用于对齐日志
调优实践: 在 Camera HAL 实现中,帧率稳定性调优的第一步是确保 ANDROID_CONTROL_AE_TARGET_FPS_RANGE 的上下限一致(如 [30,30]),避免 AE 算法自动调整帧率范围。第二步是检查 ANDROID_SENSOR_FRAME_DURATION 是否被正确传递到 V4L2 驱动层的 V4L2_CID_EXPOSURE_AUTO_PRIORITY 和帧间隔控制。

3.5 HAL3 与 V4L2 的映射关系

在基于 V4L2 的 Camera HAL 实现中,HAL3 的抽象概念需要映射到具体的 V4L2 操作:

HAL3 概念 V4L2 对应操作 说明
CameraDevice open() / close() 设备节点 对应 /dev/video* 节点
configureStreams() VIDIOC_S_FMT / VIDIOC_REQBUFS 设置格式和分配 Buffer
CaptureRequest VIDIOC_QBUF + VIDIOC_STREAMON 将 Buffer 加入驱动队列
Result VIDIOC_DQBUF + dequeue 回调 从驱动取出填充好的 Buffer
Metadata 控制 VIDIOC_S_EXT_CTRLS 设置曝光、增益、帧率等控制参数
Pipeline 深度 VIDIOC_REQBUFS 的 count 参数 决定驱动内部 Buffer 队列深度
关键映射: HAL3 的 Pipeline 深度直接对应 V4L2 驱动中 VIDIOC_REQBUFS 分配的 Buffer 数量。如果 HAL 层设置的 Pipeline 深度大于 V4L2 驱动的 Buffer 队列深度,会导致 QBUF 阻塞,帧率下降。建议 HAL 层的 Pipeline 深度 ≤ V4L2 驱动的 Buffer 数量 - 1。
HAL3 与 V4L2 映射流程图 HAL3 层 configureStreams() processCaptureRequest() processCaptureResult() V4L2 驱动层 VIDIOC_S_FMT + REQBUFS VIDIOC_QBUF + STREAMON VIDIOC_DQBUF 回调 HAL3 的每个操作最终都映射为 V4L2 的 IOCTL 调用,帧率稳定性取决于这些调用的时序和 Buffer 管理

3.6 帧率稳定性设计原则

基于 HAL3 架构的特点,帧率稳定性调优应遵循以下设计原则:

  1. Pipeline 深度匹配:HAL 层设置的 Pipeline 深度应与 V4L2 驱动的 Buffer 队列深度匹配,避免因深度不匹配导致阻塞。
  2. Stream 配置最小化:在满足业务需求的前提下,尽量减少 Stream 数量和分辨率差异,降低 ISP 处理负载。
  3. Buffer 数量充足:每个 Stream 的 max_buffers 应至少为 Pipeline 深度 + 1,确保 Buffer 供应不成为瓶颈。
  4. 固定帧率模式:在需要稳定帧率的场景(如录像),使用 ANDROID_CONTROL_AE_TARGET_FPS_RANGE 锁定帧率范围,避免 AE 算法动态调整。
  5. 异步回调优化:Result 回调线程应具有高优先级,避免因线程调度延迟导致帧率抖动。
总结: Camera HAL3 的 Pipeline 模型为帧率稳定性提供了理论框架,Stream 和 Request 的关系决定了 Buffer 管理的复杂度。在实际调优中,需要结合 V4L2 驱动的具体实现,通过调整 Pipeline 深度、Buffer 数量和 Metadata 参数,使整个图像捕获链路达到稳定的帧率输出。