Camera HAL框架:Metadata流转与请求管线调试 - 第1节
1.1 Android Camera HAL 架构演进
Android Camera HAL(硬件抽象层)是连接 Android 框架与底层摄像头硬件的关键中间层。自 Android 诞生以来,Camera HAL 经历了从 HAL1 到 HAL3 的重大架构演进,每一次迭代都旨在解决性能瓶颈、提升灵活性并满足日益复杂的拍照与视频需求。
核心演进驱动力: 从“黑盒式”的固定管线,走向“白盒式”的灵活请求驱动模型,赋予应用层对传感器、ISP 等硬件资源的精细控制能力。
1.1.1 架构演进路线图
下图展示了从 Android 早期到当前主流版本的 Camera HAL 架构演进脉络:
1.1.2 各阶段关键特征
| 版本 | Android 版本 | 驱动模型 | 核心特征 | 局限性 |
|---|---|---|---|---|
| HAL v1 | 2.x ~ 4.x | 固定管线 | 预览、拍照、录像三态切换;简单回调 | 无法并发流;延迟高;扩展性差 |
| HAL v2 | 4.x 过渡期 | 扩展接口 | 增加部分控制接口;支持简单参数传递 | 未解决根本问题;碎片化严重 |
| HAL v3 | 5.0+ | 请求驱动 | 逐帧 capture request/result;metadata 全流程;多流并发 | 实现复杂度高;调试门槛上升 |
开发者视角: 当前所有主流 Android 设备(Android 5.0 及以上)均强制要求 HAL3 实现。HAL1 仅作为兼容层存在于部分低端或老旧设备中。
1.2 HAL3 vs HAL1 核心差异
理解 HAL3 与 HAL1 的差异,是掌握 Camera HAL 框架的基石。两者在架构哲学、数据流模型、控制粒度以及性能表现上存在本质区别。
1.2.1 架构模型对比
1.2.2 关键差异对照表
| 对比维度 | HAL1 | HAL3 |
|---|---|---|
| 数据流模型 | 固定三态(预览/拍照/录像),一次只能处于一种模式 | 请求驱动,可同时提交多个不同配置的 capture request |
| 控制粒度 | 粗粒度,只能设置有限的参数(如白平衡、曝光补偿) | 细粒度,通过 metadata 控制每一帧的传感器、ISP、后处理参数 |
| 并发能力 | 不支持多流并发(如同时预览 + 拍照 + 视频) | 原生支持多路输出流(YUV、RAW、JPEG、HEIC 等) |
| 延迟特性 | 模式切换延迟高(预览→拍照需数百毫秒) | 零延迟拍照(ZSL),预览流中直接提取帧 |
| Metadata 传递 | 无标准 metadata 通道,参数通过扩展接口传递 | 标准化的 android.* metadata 空间,贯穿 request→result 全流程 |
| 实现复杂度 | 较低,约 5~10 个回调函数 | 较高,需实现 process_capture_request、process_capture_result 等核心接口 |
迁移注意事项: 从 HAL1 迁移到 HAL3 不仅仅是接口替换,更是整个相机管线的重构。HAL3 要求 HAL 层具备逐帧处理能力,对 ISP 驱动、sensor driver 的实时性要求显著提升。
1.3 HAL3 接口定义与职责
HAL3 的核心接口定义在 hardware/libhardware/include/hardware/camera3.h 中。整个 HAL3 设备围绕 camera3_device_t 结构体及其回调函数展开。
1.3.1 核心数据结构
HAL3 的接口设计围绕三个核心数据结构:
- camera3_device_t:代表一个打开的相机设备,包含所有操作函数指针。
- camera3_capture_request_t:描述一次捕获请求,包含输出 buffer、metadata、输入 buffer( reprocess 场景)等。
- camera3_capture_result_t:描述一次捕获结果,包含输出 buffer、result metadata、部分结果状态等。
// camera3.h 核心结构体示意
typedef struct camera3_device {
hw_device_t common;
// HAL3 核心操作函数指针
int (*initialize)(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *,
camera3_stream_configuration_t *config);
int (*register_stream_buffers)(const struct camera3_device *,
const camera3_stream_buffer_set_t *buffer_set);
const camera_metadata_t *(*construct_default_request_settings)(
const struct camera3_device *, int type);
int (*process_capture_request)(const struct camera3_device *,
camera3_capture_request_t *request);
void (*dump)(const struct camera3_device *, int fd);
int (*flush)(const struct camera3_device *);
void (*signal_stream_flush)(const struct camera3_device *,
uint32_t num_streams,
const camera3_stream_t *const *streams);
// ... 其他函数
} camera3_device_t;
1.3.2 核心接口职责
| 接口函数 | 调用方 | 职责描述 | 关键约束 |
|---|---|---|---|
initialize |
CameraService | 初始化 HAL 设备,注册回调函数指针 | 必须在其他操作前调用;回调函数必须线程安全 |
configure_streams |
CameraService | 配置输出流集合(分辨率、格式、方向等) | 可多次调用;流配置变更需重置硬件管线 |
construct_default_request_settings |
CameraService | 返回指定类型的默认 metadata 设置 | 类型包括 PREVIEW、STILL_CAPTURE、VIDEO_RECORD 等 |
process_capture_request |
CameraService | 提交一个捕获请求,HAL 开始处理 | 必须异步返回;请求中的 buffer 必须有效 |
flush |
CameraService | 刷新所有待处理的请求,清空管线 | 必须在 1 秒内返回;未完成的请求需返回错误状态 |
dump |
CameraService / dumpsys | 输出 HAL 内部状态用于调试 | 必须线程安全;不应阻塞 |
1.3.3 请求-结果生命周期
1.3.4 HAL3 实现职责清单
作为 HAL 实现者,需要承担以下关键职责:
- 流管理:根据
configure_streams配置,分配和管理所有输出流的 buffer 池。 - 请求调度:维护一个请求队列,按序或按优先级提交给底层硬件处理。
- Metadata 处理:解析 request metadata,将其转换为 sensor/ISP 寄存器配置;收集结果 metadata 并返回。
- 3A 控制:实现自动曝光(AE)、自动对焦(AF)、自动白平衡(AWB)算法,或桥接底层 3A 库。
- 错误处理:当 sensor 故障、buffer 超时、请求无效时,通过
notify回调上报错误。 - 性能保障:确保
process_capture_request非阻塞;flush 操作在 1 秒内完成。
调试切入点: 在 HAL3 开发初期,建议先实现
construct_default_request_settings 和 process_capture_request 的最小路径,确保单帧请求-结果闭环能够正常工作,再逐步添加多流并发、ZSL、reprocess 等高级特性。
1.3.5 回调接口
HAL3 通过 camera3_callback_ops_t 向 CameraService 发送结果和通知:
typedef struct camera3_callback_ops {
// 返回一个捕获结果(包含 metadata 和 buffer)
void (*process_capture_result)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result);
// 发送异步通知(如错误、快门事件等)
void (*notify)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);
// 查询 buffer 是否已由服务端释放(可选)
int (*query_buffer)(const struct camera3_callback_ops *,
uint32_t stream_id,
uint32_t frame_number);
} camera3_callback_ops_t;
这些回调是 HAL 与 Framework 之间的唯一异步通信通道,必须保证线程安全且高效。