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。

HAL3 Pipeline 模型 CaptureRequest Sensor 曝光 ISP RAW 处理 YUV/JPEG 编码 CaptureResult Pipeline 深度:Request → Sensor → ISP → Encoder → Result,每帧独立流水 HAL 必须保证 Pipeline 的实时性,否则会导致预览卡顿或拍照延迟

2.2.1 Pipeline 关键阶段

  1. Request 解析:HAL 从框架接收 CaptureRequest,提取 3A 参数、输出流配置、裁剪区域等。
  2. Sensor 曝光:根据 AE 参数设置曝光时间、增益、帧间隔,触发 Sensor 输出 RAW 数据。
  3. ISP 处理:RAW 数据经过黑电平校正、去噪、去马赛克、颜色校正、Gamma 等 ISP 模块。
  4. 编码输出:YUV 数据可输出到预览 Surface,或经 JPEG/HEIC 编码后输出到拍照 Buffer。
  5. 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 三个核心接口实现零拷贝传递。

Stream-Buffer 管理流程 Camera Framework Camera HAL Gralloc Buffer 池 ① 注册 Stream ② dequeue_buffer ③ 填充图像数据 Buffer 生命周期:dequeue(HAL 获取空 Buffer)→ fill(ISP 写入数据)→ queue(HAL 返回给框架) HAL 必须及时 queue Buffer,否则框架会因 Buffer 耗尽而丢帧 HDR 多帧场景下,HAL 需要同时管理多个 Stream 的 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 管理。