2. Camera HAL架构基础:Android Camera HAL3架构、Pipeline模型、关键数据结构
在双摄虚化HAL层适配工作中,深入理解Android Camera HAL3架构是第一步。HAL3相比HAL1最大的变革在于引入了Pipeline(流水线)模型和按需配置的Stream(流)机制,使得多摄像头协同、高帧率、复杂后处理成为可能。本章将拆解HAL3的核心架构、Pipeline数据流以及三个最关键的数据结构。
2.1 Android Camera HAL3架构总览
HAL3架构采用生产者-消费者模型,应用框架(Camera Framework)通过camera3_device_t接口与HAL交互,HAL内部维护一个或多个Capture Pipeline实例。每个Pipeline负责处理一次Capture请求,从Sensor曝光到输出最终图像。
架构要点:HAL3不再像HAL1那样直接操作预览和拍照循环,而是由Framework下发
camera3_capture_request_t,HAL异步返回camera3_capture_result_t。这种设计让HAL拥有更大的调度自由度,便于实现多摄同步、HDR、虚化等复杂场景。
2.2 Pipeline模型:从Request到Result的完整链路
Pipeline是HAL3中最核心的执行单元。一次典型的Capture流程包含以下阶段:
- Request解析:HAL收到
process_capture_request,解析settings、stream buffers。 - Sensor曝光:根据settings中的AE/AWB/AF参数,驱动Sensor曝光。
- ISP处理:RAW数据经过ISP管线(黑电平校正、去马赛克、降噪、色调映射等)。
- Stream输出:处理后的图像写入对应的Stream Buffer(预览、拍照、深度等)。
- Result回调:HAL通过
process_capture_result返回metadata和buffer handles。
双摄虚化Pipeline要点:在双摄场景下,HAL需要同时驱动两个Sensor的Pipeline,并保证主摄和副摄的曝光时间、帧边界严格对齐。通常通过硬件同步信号(如VSYNC)或软件等待机制实现。
2.3 关键数据结构详解
HAL3的适配工作围绕三个核心数据结构展开。理解它们的生命周期和交互关系,是编写稳定HAL的基础。
2.3.1 camera3_device_t
代表一个逻辑Camera设备。在双摄虚化场景中,通常一个camera3_device_t对应一个逻辑摄像头(如“后置主摄”),但内部可能管理多个物理Sensor。
| 字段 | 类型 | 说明 |
|---|---|---|
| ops | camera3_device_ops_t* |
指向操作函数表,包含initialize、configure_streams、process_capture_request等 |
| priv | void* |
HAL私有数据指针,通常指向包含Pipeline状态、Stream信息、双摄同步逻辑的结构体 |
| common | hw_device_t |
硬件设备通用结构,包含close、version等 |
适配注意:在双摄虚化HAL中,
priv字段需要额外存储副摄的Pipeline句柄、同步锁、深度Stream的Buffer队列等信息。切勿将主副摄状态混放在同一个无锁结构体中,否则容易引发竞态条件。
2.3.2 camera3_stream_t
描述一个图像数据流。每个Stream对应一个Buffer队列,Framework通过dequeue/queue机制与HAL交换图像数据。
| 字段 | 说明 | 双摄虚化场景典型值 |
|---|---|---|
| stream_type | 流类型:CAMERA3_STREAM_OUTPUT(输出)、CAMERA3_STREAM_INPUT(输入) |
主摄预览/拍照为OUTPUT;虚化引擎可能使用INPUT接收深度图 |
| width / height | 图像分辨率 | 主摄通常配置最大分辨率(如4000x3000),副摄深度流可配置较低分辨率(如1600x1200) |
| format | 像素格式:HAL_PIXEL_FORMAT_YCbCr_420_888、HAL_PIXEL_FORMAT_BLOB等 |
深度流常用HAL_PIXEL_FORMAT_Y16或HAL_PIXEL_FORMAT_BLOB(包含深度数据) |
| usage | Gralloc使用标志,如GRALLOC_USAGE_HW_CAMERA_WRITE |
双摄场景需确保主副摄Buffer的usage兼容,避免内存拷贝 |
| max_buffers | Stream允许的最大Buffer数 | 预览流通常3~4个,深度流可减少到2个以降低内存占用 |
2.3.3 camera3_capture_request_t 与 camera3_capture_result_t
这两个结构体构成了HAL3的请求-响应循环。
// 请求结构体(简化)
typedef struct camera3_capture_request {
uint32_t frame_number; // 帧序号,用于追踪
const camera3_stream_buffer_t *input_buffers; // 输入Buffer(虚化引擎可能需要)
uint32_t num_input_buffers;
const camera3_stream_buffer_t *output_buffers; // 输出Buffer数组
uint32_t num_output_buffers;
const camera_metadata_t *settings; // 控制参数(AE/AWB/AF/虚化强度等)
// ... 其他字段
} camera3_capture_request_t;
// 结果结构体(简化)
typedef struct camera3_capture_result {
uint32_t frame_number;
const camera3_stream_buffer_t *output_buffers; // 填充好的输出Buffer
uint32_t num_output_buffers;
const camera3_stream_buffer_t *input_buffers; // 已消费的输入Buffer
uint32_t num_input_buffers;
const camera_metadata_t *result; // 结果metadata(包含虚化深度信息等)
// ... 其他字段
} camera3_capture_result_t;
双摄虚化中的关键交互:当Framework下发一个虚化Capture请求时,
settings中会包含ANDROID_CONTROL_AVAILABLE_MODES等tag指示HAL进入双摄模式。HAL需要解析这些tag,同时驱动主摄和副摄Pipeline,将主摄的彩色图和副摄的深度图分别填入对应的output_buffers,并在result中返回虚化相关的metadata(如深度置信度、视差图等)。
2.4 数据结构关系图
下图展示了camera3_device_t、camera3_stream_t、camera3_capture_request_t三者之间的协作关系:
2.5 双摄虚化场景下的HAL适配要点
- 多Stream配置:在
configure_streams中,需要同时配置主摄的彩色Stream和副摄的深度/辅助Stream。注意Stream的format和usage必须与硬件ISP输出能力匹配。 - 帧同步:双摄Pipeline必须保证帧边界对齐。通常通过硬件同步信号(如主摄VSYNC触发副摄)或软件等待(副摄等待主摄完成曝光)实现。
- Buffer管理:副摄的深度Buffer可能不需要输出到Framework,而是直接在HAL内部传递给虚化算法模块。此时需要配置
CAMERA3_STREAM_INPUT类型的Stream。 - Metadata扩展:在
result中需要填充虚化相关的metadata,如ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS、ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST等。
实战建议:在开始双摄虚化HAL适配前,先使用
cam2test或cts测试工具验证单摄Pipeline的稳定性。确保configure_streams、process_capture_request、flush等基础接口在单摄场景下无异常,再逐步加入副摄逻辑。