3. HAL层架构解析:Android Camera HAL3架构、Pipeline模型、Stream配置流程
Android Camera HAL3 是 Android 8.0 之后强制要求的相机硬件抽象层架构,它彻底取代了 HAL1 的单一接口模式,引入了 Pipeline(流水线) 和 Stream(流) 的核心概念。理解 HAL3 架构是进行产线校准与驱动调试联合实战的前提,因为校准参数的注入、ISP 调优、以及 sensor 驱动配置都直接与 HAL3 的 Pipeline 模型和 Stream 配置流程绑定。
3.1 HAL3 架构核心组件
HAL3 架构围绕 camera3_device_t 结构体展开,其核心接口函数包括 initialize()、configure_streams()、process_capture_request()、flush() 等。与 HAL1 最大的区别在于:HAL3 不再直接返回 JPEG/YUV,而是通过 Stream Buffer 的流转来实现零拷贝或低拷贝的帧处理。
| 组件 | 角色 | 产线校准关联点 |
|---|---|---|
| Camera HAL3 Interface | 定义 HAL 与 Camera Service 的通信协议 | 校准参数通过 static_metadata 或 request_metadata 传递 |
| Pipeline | 硬件处理流水线,包含 ISP、Sensor、Flash 等模块 | 校准项(如 AWB、AF、AEC)对应 Pipeline 中的具体 Stage |
| Stream | 指定分辨率和格式的数据通道 | 产线测试通常使用 YUV_420_888 或 RAW10 Stream |
| BufferManager | 管理 GraphiBuffer 的分配与释放 | 校准帧的 Buffer 需要保证连续性和时间戳精度 |
| ResultCallback | 将处理完成的帧和 metadata 返回给 Framework | 校准结果(如 AF 位置、AEC 增益)通过 result metadata 上报 |
产线视角提示: 在产线校准中,HAL3 的
configure_streams() 调用次数通常比正常拍照场景少,但每次配置必须保证 Stream 参数(分辨率、format、usage flag)与 sensor 驱动支持的 output mode 严格匹配,否则会导致 Pipeline 初始化失败,校准流程中断。
3.2 Pipeline 模型详解
HAL3 的 Pipeline 模型是一个 有向无环图(DAG),每个节点代表一个硬件或软件处理模块。典型的 Pipeline 包含以下 Stage:
- Sensor Stage:负责曝光、增益、帧率控制,输出 RAW 数据。
- ISP Stage:进行黑电平校正、去噪、颜色校正、Gamma 等处理,输出 YUV 或 RAW。
- Post-Processing Stage:包括缩放、旋转、JPEG 编码等。
- Output Stage:将最终 Buffer 输出到 Framework 指定的 Stream。
在产线校准中,我们通常需要 绕过 部分 ISP 处理(如 AWB、AEC 的自动算法),直接获取 RAW 数据或原始统计信息,以便进行离线校准计算。
驱动调试关键点: 在驱动调试阶段,需要确保 Sensor 驱动能够支持 Binning 和 Cropping 模式切换,因为产线校准通常需要全分辨率 RAW 输出,而正常拍照可能使用 binning 后的 YUV。HAL3 的
configure_streams() 会根据 Stream 的 usage 和 format 自动选择 sensor mode,驱动必须正确实现 enum_frame_sizes 和 set_mode 回调。
3.3 Stream 配置流程
Stream 配置是 HAL3 初始化阶段最关键的步骤,直接决定了 Pipeline 的拓扑结构和 Buffer 分配策略。配置流程如下:
- Framework 发起配置请求:Camera Service 调用
configure_streams(),传入一个camera3_stream_configuration_t结构体,包含 Stream 数组。 - HAL 解析 Stream 参数:HAL 遍历每个 Stream,检查
stream_type(INPUT/OUTPUT)、format、width/height、usage(GRALLOC_USAGE_*)等。 - Pipeline 拓扑决策:HAL 根据 Stream 组合决定 Pipeline 的 Stage 连接方式。例如,同时存在 RAW 和 YUV Stream 时,Pipeline 需要分叉。
- Buffer 分配:HAL 调用 Gralloc 分配 GraphiBuffer,并设置
max_buffers和priv指针。 - 驱动配置:HAL 将最终确定的 sensor mode、ISP 参数下发给底层驱动。
- 返回配置结果:HAL 修改 Stream 结构体中的
priv、max_buffers、usage等字段,并返回 OK。
| 步骤 | HAL 动作 | 产线校准常见问题 |
|---|---|---|
| 1. 解析 Stream 数组 | 检查 Stream 数量(通常 ≤ 3) | 产线测试可能只配置 1 个 RAW Stream,但 Framework 可能额外要求 YUV Stream |
| 2. 匹配 Sensor Mode | 根据最大分辨率选择 sensor output mode | 校准需要全分辨率 RAW,但 sensor 驱动可能不支持该 mode 下的 RAW 输出 |
| 3. 分配 Buffer | 调用 Gralloc 分配 max_buffers 个 Buffer |
Buffer 数量不足会导致 process_capture_request 阻塞,校准超时 |
| 4. 设置 ISP 参数 | 下发 ISP 初始化参数(如黑电平、增益映射) | 校准参数未正确写入 ISP 寄存器,导致 RAW 数据异常 |
| 5. 返回配置 | 修改 Stream 的 priv 指向 HAL 内部结构 |
priv 指针错误会导致后续 request 处理时 crash |
常见踩坑点: 在产线校准场景中,
configure_streams() 可能会被多次调用(例如先配置预览流,再切换为校准流)。HAL 必须正确处理 stream_configuration 的 operation_mode 字段,特别是 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED 模式,避免在切换时导致 Pipeline 重建失败。
3.4 Stream 配置与产线校准的联合实战要点
在产线校准中,Stream 配置需要与驱动调试紧密配合,以下是三个核心要点:
- RAW Stream 的 Format 选择:产线校准通常使用
HAL_PIXEL_FORMAT_RAW10或HAL_PIXEL_FORMAT_RAW16。驱动必须确保 sensor 输出的 RAW 数据位宽与 HAL 配置一致,否则会导致数据错位。 - Stream Usage Flag 设置:校准 Stream 的
usage应设置为GRALLOC_USAGE_SW_READ_OFTEN,以便 CPU 直接读取 RAW 数据。如果错误设置为GRALLOC_USAGE_HW_TEXTURE,可能导致 Buffer 无法被 CPU 映射。 - Pipeline 最大延迟控制:产线校准要求低延迟(通常 < 100ms 每帧)。HAL 在
configure_streams()中应设置request_metadata中的ANDROID_CONTROL_AE_TARGET_FPS_RANGE为固定值,关闭自动帧率调节。
实战建议: 在产线校准的 HAL 实现中,建议在
configure_streams() 内部增加一个 校准模式标志位。当检测到 Stream 配置为 RAW10 + SW_READ_OFTEN 时,自动禁用 ISP 的自动 3A 算法,并将 Pipeline 延迟设置为最低。这样可以避免每次校准都需要修改 HAL 代码,提高产线换型效率。