4. HAL3 Pipeline 模型:request、result、stream、buffer 管理、pipeline 深度解析
Camera HAL3 的核心设计思想是 Pipeline(流水线) 模型。它将一次拍照或预览抽象为一个由多个阶段组成的、可并行处理的请求-响应循环。理解 Pipeline 模型是掌握 HAL3 适配的关键,它直接决定了相机的吞吐量、延迟和资源利用率。
核心要点: HAL3 Pipeline 是一个基于 异步请求 的框架。应用层下发
capture request,HAL 层处理并返回 capture result,整个过程通过 Stream(流) 和 Buffer(缓冲区) 进行数据传递。
4.1 Pipeline 核心概念与数据流
Pipeline 模型包含四个核心抽象:Request、Result、Stream 和 Buffer。它们之间的关系构成了 HAL3 的数据流动骨架。
4.2 Request 与 Result:请求-响应契约
Capture Request 是 Pipeline 的输入,Capture Result 是输出。它们通过 frame_number 唯一关联,形成一对一的契约关系。
4.2.1 Capture Request 结构
一个 Request 包含以下关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
frame_number |
uint32_t | 帧序号,唯一标识一次捕获请求 |
settings |
metadata | 3A 参数、AE/AF/AWB 模式、效果、裁剪区域等 |
input_buffers |
buffer_handle_t* | 输入缓冲区(用于 reprocessing 场景) |
output_buffers |
buffer_handle_t* | 输出缓冲区列表,每个 buffer 关联一个 stream |
适配提示: 在 Treble 架构下,Request 通过 HIDL 接口从 CameraService 下发到 HAL。HAL 实现必须保证
process_capture_request 是线程安全的,因为多个 Request 可能同时到达。
4.2.2 Capture Result 结构
Result 是 HAL 对 Request 的响应,包含处理后的元数据和填充好的缓冲区:
// HAL3 中 Result 的核心结构
typedef struct camera3_capture_result {
uint32_t frame_number; // 对应 Request 的帧号
const camera3_stream_buffer_t *output_buffers; // 输出缓冲区数组
uint32_t num_output_buffers; // 输出缓冲区数量
const camera3_stream_buffer_t *input_buffers; // 输入缓冲区(reprocessing)
uint32_t num_input_buffers;
const camera_metadata_t *result; // 最终元数据(包含 3A 结果、统计信息等)
uint32_t partial_result; // 部分结果标记(用于分阶段返回)
} camera3_capture_result_t;
4.3 Stream 与 Buffer 管理
Stream 定义了数据的格式和用途,Buffer 是实际的数据载体。HAL3 通过 configure_streams 建立 Stream 配置,然后在运行时通过 Buffer 管理机制进行数据交换。
4.3.1 Stream 配置表
| Stream 类型 | 典型用途 | 格式示例 | Buffer 数量 |
|---|---|---|---|
| CAMERA3_STREAM_OUTPUT | 预览、视频、拍照 | YUV_420_888, JPEG, HEIC | 3~8 |
| CAMERA3_STREAM_INPUT | Reprocessing(如美颜、HDR) | YUV_420_888 | 2~4 |
| CAMERA3_STREAM_BIDIRECTIONAL | ZSL(零快门延迟) | YUV_420_888 | 4~6 |
4.3.2 Buffer 管理流程
Buffer 在 HAL 和 Framework 之间通过 Dequeue → Fill → Enqueue 循环流转:
- Dequeue: HAL 从 Stream 的 Buffer 池中取出一个空闲 Buffer。
- Fill: HAL 将 Sensor 数据或 ISP 处理后的数据写入 Buffer。
- Enqueue: HAL 将填充好的 Buffer 通过
process_capture_result返回给 Framework。 - Release: Framework 消费完数据后,将 Buffer 归还给 HAL 的 Buffer 池。
4.4 Pipeline 深度解析:从 Request 到 Result 的完整路径
一个完整的 Pipeline 周期包含以下阶段:
| 阶段 | 负责方 | 关键操作 | 延迟瓶颈 |
|---|---|---|---|
| 1. Request 构建 | Framework | 填充 metadata,关联 output_buffers | 应用层逻辑 |
| 2. Request 下发 | CameraService | 通过 HIDL 调用 process_capture_request |
IPC 延迟 |
| 3. Sensor 曝光 | HAL | 配置 sensor 参数,触发曝光 | 曝光时间 (通常 10~33ms) |
| 4. ISP 处理 | HAL | RAW→YUV/JPEG 转换,3A 统计 | ISP 时钟频率、算法复杂度 |
| 5. Buffer 填充 | HAL | 将处理后的数据写入 output_buffers | 内存带宽 |
| 6. Result 返回 | HAL | 调用 process_capture_result 回调 |
IPC 延迟 |
常见适配陷阱: 在 Treble 架构下,HAL 实现必须注意 Pipeline 深度(即同时处理的 Request 数量)。深度过小会导致 CPU 空闲等待,深度过大会增加内存压力和延迟。建议根据 Sensor 帧率和 ISP 处理时间动态调整 Pipeline 深度,通常保持在 2~4 之间。
4.5 Pipeline 深度与性能调优
Pipeline 深度(outstanding request count)是 HAL3 性能调优的核心参数。它决定了系统能够同时处理多少个未完成的 Request。
4.6 Treble 架构下的 Pipeline 适配要点
在 Treble 架构中,HAL3 Pipeline 的实现需要额外关注以下方面:
- HIDL 接口封装:
process_capture_request和process_capture_result需要通过ICameraDeviceHIDL 接口进行跨进程调用,注意 IPC 性能开销。 - Buffer 传递: 使用
hidl_memory或native_handle_t传递 Buffer 句柄,避免跨进程拷贝大块数据。 - 同步机制: 利用
camera3_stream_buffer中的acquire_fence和release_fence实现跨进程同步,防止数据竞争。 - Vendor 扩展: 在 Pipeline 中插入 Vendor 特定的处理节点(如 AI 降噪、HDR 融合)时,必须通过
vendor_tag暴露配置接口。
最佳实践: 在 Treble HAL 实现中,建议将 Pipeline 的核心逻辑(Sensor 控制、ISP 处理)放在 Vendor 分区,而将 Buffer 管理和 IPC 通信放在 Framework 分区。这样既能保证性能,又能满足 Treble 的模块化要求。