Camera HAL 架构概述:HAL3 与 HAL1 的区别,Pipeline 模型介绍

Camera HAL(硬件抽象层)是 Android 相机系统中连接 Framework 与底层硬件驱动的关键中间层。HAL 版本直接决定了上层可用的特性集、数据流模型以及性能调优空间。本章聚焦 HAL1 与 HAL3 的核心差异,并深入解析 HAL3 的 Pipeline 模型,为后续场景切换优化奠定架构基础。

2.1 HAL1 与 HAL3 架构对比

HAL1 是 Android 早期版本(API < 21)的标准接口,采用“单线程 + 同步回调”模型;HAL3 自 Android 5.0 引入,基于“请求-响应”异步 Pipeline 设计。下表从关键维度对比两者差异:

对比维度 HAL1 HAL3
数据流模型 单线程同步,预览/拍照/录像串行 异步 Pipeline,多请求并行处理
帧率控制 固定帧率,由驱动决定 动态帧率,应用可指定目标帧率范围
逐帧参数 全局参数,切换需停止流 逐帧参数(per-frame controls),无中断切换
延迟特性 高延迟(~100ms 以上),预热时间长 低延迟(~30-50ms),预热可优化
多流支持 仅支持单输出流 支持多输出流(预览+拍照+视频)
适用场景 低端设备、兼容模式 中高端设备、全特性支持
优化要点: HAL3 的逐帧参数能力是场景切换零停顿的关键。预热延迟和帧率抖动优化必须基于 HAL3 架构设计,HAL1 因缺乏异步 Pipeline 支持,难以实现平滑切换。

2.2 HAL3 Pipeline 模型详解

HAL3 的核心是 Camera3 设备 Pipeline,它将一次图像捕获分解为三个逻辑阶段:

  1. Request 提交阶段: 应用通过 Framework 提交 capture request,包含输出目标(Surface)、3A 参数、帧率控制等。
  2. ISP 处理阶段: HAL 驱动将请求解析为硬件指令,经过传感器曝光、RAW 域处理、YUV 域处理,生成结果帧。
  3. Result 回调阶段: 处理完成的帧通过异步回调返回给 Framework,同时携带元数据(时间戳、3A 状态等)。

以下 SVG 图展示了 HAL3 Pipeline 的核心数据流与阶段划分:

HAL3 Pipeline 核心数据流 Request 提交 capture request 输出目标 + 参数 ISP 处理 RAW → YUV → JPEG 3A 同步 Result 回调 帧数据 + 元数据 异步通知 Pipeline 内部子阶段(ISP 展开) Sensor 曝光 帧同步 RAW 域处理 Bayer → RGB YUV 域处理 降噪/锐化 编码输出 JPEG/H.264 Pipeline 模型支持多请求并行,每个请求独立经过上述三个阶段

2.3 Pipeline 并行性与帧率抖动

HAL3 Pipeline 支持 多请求并行(in-flight requests),即前一个请求仍在 ISP 处理时,新请求可被提交。这种机制降低了帧间隔抖动,但也引入了新的优化挑战:

  • 请求队列深度: 典型值为 2~4 个 in-flight 请求。深度过小导致 Pipeline 饥饿,帧率下降;深度过大增加延迟,切换时产生帧堆积。
  • 帧间隔一致性: 每个请求的处理时间必须稳定。若某个请求因场景切换(如 AE 收敛)耗时突增,后续请求会排队等待,表现为帧率抖动。
  • 预热延迟来源: 首次启动或场景切换时,Pipeline 需要重新配置 sensor 模式、ISP 参数,导致前几帧延迟偏高(cold start latency)。
调试建议: 在场景切换点,通过 dumpstate 或 camera trace 抓取 Pipeline 各阶段耗时。重点关注 sensor_frame_duration 和 pipeline_depth 两个指标,它们直接反映帧率抖动程度。

2.4 HAL3 关键数据结构

理解 Pipeline 模型需要熟悉以下核心数据结构,它们直接参与场景切换参数传递:

数据结构 作用 场景切换相关字段
camera3_capture_request_t 封装单帧捕获请求 settings(逐帧参数)、input_buffer(重处理)
camera3_stream_buffer_t 描述输出 buffer 属性 stream->format、stream->usage(切换时需重新配置)
camera3_capture_result_t 返回处理完成的帧及元数据 result(包含 AE/AWB/AF 状态,用于判断收敛)
camera3_stream_configuration_t 配置所有输出流 operation_mode(NORMAL / CONSTRAINED_HIGH_SPEED)
// HAL3 请求提交示例(简化)
int process_capture_request(camera3_capture_request_t *request) {
    // 1. 解析逐帧参数
    camera_metadata_ro_entry entry;
    find_camera_metadata_ro_entry(request->settings,
                                  ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
                                  &entry);
    int32_t min_fps = entry.data.i32[0];
    int32_t max_fps = entry.data.i32[1];

    // 2. 根据 FPS 范围选择 sensor 模式
    if (max_fps > 30) {
        set_sensor_mode(SENSOR_MODE_HIGH_SPEED);
    } else {
        set_sensor_mode(SENSOR_MODE_NORMAL);
    }

    // 3. 提交到硬件 Pipeline
    return hal_pipeline_submit(request);
}

2.5 HAL1 到 HAL3 迁移的架构影响

从 HAL1 迁移到 HAL3 时,以下架构变化直接影响场景切换优化策略:

  • 流配置时机: HAL1 在 start_preview 时一次性配置;HAL3 在 configure_streams 中配置,且支持运行时动态增减流(需停止 Pipeline)。
  • 参数同步方式: HAL1 通过 set_parameters 全局同步;HAL3 通过 request 的 settings 逐帧同步,切换无停顿。
  • 帧回调路径: HAL1 使用 data_callback 同步回调;HAL3 使用 process_capture_result 异步回调,回调线程模型需独立优化。
常见陷阱: 部分 HAL 实现将 HAL3 的 configure_streams 内部实现为“停止所有流 → 重新配置 → 重启流”,这实际上退化为 HAL1 的同步模型,导致场景切换时出现明显的预热延迟和帧率断崖。务必检查 HAL 实现中是否保留了 Pipeline 的异步特性。