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 的异步模型能更好地利用硬件并行能力。
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 处理延迟。
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 而停顿,造成帧率抖动。
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。
3.6 帧率稳定性设计原则
基于 HAL3 架构的特点,帧率稳定性调优应遵循以下设计原则:
- Pipeline 深度匹配:HAL 层设置的 Pipeline 深度应与 V4L2 驱动的 Buffer 队列深度匹配,避免因深度不匹配导致阻塞。
- Stream 配置最小化:在满足业务需求的前提下,尽量减少 Stream 数量和分辨率差异,降低 ISP 处理负载。
- Buffer 数量充足:每个 Stream 的
max_buffers应至少为 Pipeline 深度 + 1,确保 Buffer 供应不成为瓶颈。 - 固定帧率模式:在需要稳定帧率的场景(如录像),使用
ANDROID_CONTROL_AE_TARGET_FPS_RANGE锁定帧率范围,避免 AE 算法动态调整。 - 异步回调优化:Result 回调线程应具有高优先级,避免因线程调度延迟导致帧率抖动。
总结: Camera HAL3 的 Pipeline 模型为帧率稳定性提供了理论框架,Stream 和 Request 的关系决定了 Buffer 管理的复杂度。在实际调优中,需要结合 V4L2 驱动的具体实现,通过调整 Pipeline 深度、Buffer 数量和 Metadata 参数,使整个图像捕获链路达到稳定的帧率输出。