Camera HAL项目实战:HDR多帧合成流程实现 - 第2节
2.1 HAL3 整体框架:从 HAL1 到 HAL3 的演进
Android Camera HAL 架构经历了从 HAL1 到 HAL3 的重大演进。HAL3(即 Camera3 HAL)是 Android 5.0 引入的新一代相机硬件抽象层,专为现代计算摄影和复杂 ISP 流水线设计。与 HAL1 的“黑盒”模式不同,HAL3 将相机控制权完全交给框架,实现了精细化的逐帧控制。
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 控制模型 | 框架调用一次 capture,HAL 返回 JPEG | 框架下发 request,HAL 返回多个 result buffer |
| 逐帧控制 | 不支持,参数在 capture 间不可变 | 支持,每帧可独立设置 AE/AWB/AF 等参数 |
| Buffer 管理 | HAL 内部管理,框架被动接收 | 框架通过 dequeue/queue 与 HAL 共享 Buffer |
| 多流支持 | 通常只支持预览+拍照两路 | 支持 N 路并行 Stream(YUV/RAW/JPEG/HEIC) |
| HDR 多帧合成 | 无法实现,需在 AP 端后处理 | 原生支持,通过 request 序列和结果回调实现 |
核心要点:HAL3 的本质是“逐帧请求-响应”模型。每一帧的 3A 参数、输出格式、裁剪区域都可以独立指定,这使得多帧 HDR、超级夜景、人像虚化等计算摄影功能成为可能。
2.2 Pipeline 模型:请求流水线
HAL3 的核心是一个 Pipeline(流水线) 模型。框架下发 CaptureRequest,HAL 将其解析为 ISP 硬件可执行的配置序列,经过曝光、RAW 处理、YUV 转换、编码等阶段,最终输出 CaptureResult 和对应的图像 Buffer。
2.2.1 Pipeline 关键阶段
- Request 解析:HAL 从框架接收
CaptureRequest,提取 3A 参数、输出流配置、裁剪区域等。 - Sensor 曝光:根据 AE 参数设置曝光时间、增益、帧间隔,触发 Sensor 输出 RAW 数据。
- ISP 处理:RAW 数据经过黑电平校正、去噪、去马赛克、颜色校正、Gamma 等 ISP 模块。
- 编码输出:YUV 数据可输出到预览 Surface,或经 JPEG/HEIC 编码后输出到拍照 Buffer。
- Result 回调:HAL 将最终 Buffer 和元数据(3A 状态、时间戳、统计信息)封装为
CaptureResult返回框架。
实战提示:在 HDR 多帧合成场景中,Pipeline 需要支持“快速连拍”模式——连续下发 3~5 个不同曝光时间的 Request,HAL 必须保证每帧的曝光参数精确生效,且帧间隔尽可能短(通常 < 33ms)。
2.3 Stream 与 Buffer 管理
Stream 是 HAL3 中描述图像数据流的抽象概念。每个 Stream 对应一个 camera3_stream_t 结构体,包含格式、分辨率、使用场景(预览/拍照/录像)等信息。Buffer 则是 Stream 中实际承载图像数据的内存块。
2.3.1 Stream 配置表
| Stream 类型 | 典型格式 | 分辨率 | 用途 |
|---|---|---|---|
| 预览流 | YUV_420_888 / NV12 | 1920x1080 | ViewFinder 显示 |
| 拍照流 | JPEG / HEIC | 4096x3072 | 最终照片输出 |
| RAW 流 | RAW10 / RAW16 | Sensor 原生 | HDR 多帧合成输入 |
| 深度流 | DEPTH16 / DEPTH_POINT | 640x480 | 人像虚化深度图 |
| YUV 处理流 | YUV_420_888 | 任意 | 算法后处理(如美颜) |
2.3.2 Buffer 管理机制
HAL3 的 Buffer 管理采用 框架-HAL 共享 模式,通过 dequeue_buffer、queue_buffer、cancel_buffer 三个核心接口实现零拷贝传递。
2.3.3 Stream 配置与 Buffer 分配代码示例
// Stream 配置结构体
camera3_stream_t stream;
stream.stream_type = CAMERA3_STREAM_OUTPUT; // 输出流
stream.format = HAL_PIXEL_FORMAT_YUV_420_888;
stream.width = 1920;
stream.height = 1080;
stream.usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_CAMERA_WRITE;
stream.max_buffers = 4; // 建议 4~6 个 Buffer 深度
// 注册 Stream 到 HAL
int ret = camera3_device->ops->configure_streams(camera3_device, &stream_config);
if (ret != 0) {
// 处理配置失败
}
// 在 process_capture_request 中获取 Buffer
camera3_stream_buffer_t *stream_buffer = &request->output_buffers[0];
buffer_handle_t *buffer = stream_buffer->buffer;
// 填充图像数据到 buffer
// ...
// 完成后 queue buffer
stream_buffer->status = CAMERA3_BUFFER_STATUS_OK;
// 框架自动回收 buffer
常见陷阱:
- Buffer 泄漏:HAL 未及时 queue buffer,导致框架 Buffer 池耗尽,预览卡死。
- Stream 配置冲突:多个 Stream 的格式/分辨率不兼容,导致 ISP 无法同时处理。
- Buffer 大小不匹配:Gralloc 分配的 Buffer 尺寸小于 ISP 输出尺寸,导致内存越界。
2.4 本章小结
- HAL3 采用 逐帧请求-响应 模型,每帧可独立控制 3A 参数和输出配置。
- Pipeline 流水线包含 Request 解析、Sensor 曝光、ISP 处理、编码输出、Result 回调五个阶段。
- Stream 是图像数据流的抽象,Buffer 是实际内存载体,通过 dequeue/queue 机制在框架和 HAL 间共享。
- HDR 多帧合成依赖 Pipeline 的快速连拍能力和多 Stream 并行 Buffer 管理。