3. Camera HAL 核心数据结构:camera_module_t、camera_device_t、camera3_device_t 结构体详解
Camera HAL 的架构设计围绕三个核心数据结构展开,它们分别对应 HAL 模块的加载、旧版(HAL1)设备接口以及新版(HAL3)设备接口。理解这三个结构体的成员、职责以及生命周期,是掌握 Camera HAL 参数配置与调试的基础。
核心要点: 这三个结构体构成了从“发现设备”到“操作设备”的完整链路。
camera_module_t 负责枚举和创建设备;camera_device_t 是 HAL1 时代的设备抽象;camera3_device_t 是 HAL3 时代支持复杂 pipeline 和 metadata 的设备抽象。
3.1 camera_module_t:HAL 模块的入口
camera_module_t 是 Camera HAL 的顶层结构体,定义在 hardware/libhardware/include/hardware/camera_common.h 中。它是 Android HAL 标准模块结构体 hw_module_t 的扩展,负责向 Camera Service 暴露模块的基本信息和设备工厂方法。
3.1.1 结构体定义与关键成员
typedef struct camera_module {
hw_module_t common; // 标准 HAL 模块头,包含 tag、module_api_version、hal_api_version、id、name、author、methods 等
int (*get_number_of_cameras)(void); // 返回系统中可用的摄像头数量
int (*get_camera_info)(int camera_id, struct camera_info *info); // 获取指定摄像头的静态信息(方向、朝向、是否支持闪光灯等)
int (*set_callbacks)(const camera_module_callbacks_t *callbacks); // 注册回调,用于热插拔通知
void (*get_vendor_tag_ops)(vendor_tag_ops_t *ops); // 获取厂商自定义 metadata tag 的操作接口
int (*open_legacy)(const struct hw_module_t *module, const char *id, uint32_t halVersion, struct hw_device_t **device); // 打开指定 HAL 版本的设备(用于兼容模式)
int (*set_torch_mode)(const char *camera_id, bool enabled); // 设置闪光灯 torch 模式
int (*init)(void); // 模块初始化(可选)
int (*get_physical_camera_info)(int physical_camera_id, struct camera_metadata **static_metadata); // 获取物理摄像头(多摄)的静态 metadata
int (*is_stream_combination_supported)(int camera_id, const struct camera_stream_combination *combination); // 查询流组合是否支持
} camera_module_t;
3.1.2 核心职责与流程
- 设备发现: Camera Service 通过
get_number_of_cameras()和get_camera_info()获取摄像头列表和基本属性。 - 设备创建: 通过
common.methods->open()打开设备,返回hw_device_t,再根据 HAL 版本转换为camera_device_t或camera3_device_t。 - 热插拔与通知: 通过
set_callbacks()注册回调,实现摄像头热插拔事件的传递。 - 厂商扩展: 通过
get_vendor_tag_ops()暴露厂商自定义的 metadata 定义。
调试提示: 在调试初期,应首先确认
get_number_of_cameras() 返回值是否正确,以及 get_camera_info() 返回的 camera_info 中的 device_version 字段是否指向预期的 HAL 版本(HAL1 = 1.0,HAL3 = 3.x)。
3.1.3 模块加载与设备创建流程(SVG)
3.2 camera_device_t:HAL1 时代的设备抽象
camera_device_t 是 Android Camera HAL1 接口的核心结构体,定义在 hardware/libhardware/include/hardware/camera.h 中。它代表一个具体的摄像头设备实例,提供预览、拍照、参数设置等操作接口。
3.2.1 结构体定义与关键成员
typedef struct camera_device {
hw_device_t common; // 标准设备头,包含 tag、version、module、close 等
camera_device_ops_t *ops; // 设备操作函数指针表
void *priv; // 私有数据指针,由 HAL 实现使用
} camera_device_t;
其中 camera_device_ops_t 定义了 HAL1 的所有操作接口,包括:
| 操作接口 | 功能描述 | 调试关注点 |
|---|---|---|
set_preview_window |
设置预览窗口(ANativeWindow) | 确认窗口格式与尺寸匹配 |
start_preview |
启动预览流 | 检查是否返回 0 成功 |
stop_preview |
停止预览流 | 确认无资源泄漏 |
take_picture |
触发拍照 | 检查回调是否正常触发 |
set_parameters |
设置摄像头参数(字符串形式) | 参数解析是否正确 |
get_parameters |
获取当前摄像头参数 | 返回字符串格式是否标准 |
auto_focus |
触发自动对焦 | 对焦回调是否及时 |
cancel_auto_focus |
取消自动对焦 | 避免死锁 |
注意: HAL1 的
set_parameters 和 get_parameters 使用字符串键值对传递参数,解析效率低且容易出错。HAL3 已改用 camera_metadata_t 结构化数据,这是两者重要的架构差异。
3.2.2 HAL1 设备操作流程(SVG)
3.3 camera3_device_t:HAL3 时代的设备抽象
camera3_device_t 是 Android Camera HAL3 接口的核心结构体,定义在 hardware/libhardware/include/hardware/camera3.h 中。它支持复杂的 capture pipeline、metadata 传递以及多流并行操作。
3.3.1 结构体定义与关键成员
typedef struct camera3_device {
hw_device_t common; // 标准设备头
camera3_device_ops_t *ops; // HAL3 设备操作函数指针表
void *priv; // 私有数据指针
} camera3_device_t;
camera3_device_ops_t 是 HAL3 的核心操作接口,与 HAL1 有本质区别:
| 操作接口 | 功能描述 | 与 HAL1 对比 |
|---|---|---|
initialize |
初始化设备,传入框架回调接口 | HAL1 无此接口 |
configure_streams |
配置输出流集合(分辨率、格式、方向) | 替代 HAL1 的 set_preview_window |
register_stream_buffers |
注册流缓冲区(已废弃,但接口保留) | HAL1 无此概念 |
process_capture_request |
提交一次 capture 请求(包含 metadata 和输出 buffer) | 替代 HAL1 的 take_picture + set_parameters |
flush |
刷新所有正在处理的请求,停止 pipeline | HAL1 无此接口 |
dump |
导出调试信息(fd 文件描述符) | HAL1 也有,但 HAL3 更丰富 |
3.3.2 HAL3 核心流程:Capture Request 与 Result
HAL3 的核心工作模式是 Request-Result 异步模型:
- 初始化: Camera Service 调用
initialize()传入camera3_callback_ops_t回调接口。 - 配置流: 调用
configure_streams()定义输出流(如预览流、拍照流、视频流)。 - 提交请求: 通过
process_capture_request()提交camera3_capture_request_t,包含:settings:camera_metadata_t格式的参数。output_buffers:目标 buffer 列表。input_buffer:输入 buffer(用于 reprocessing)。
- 返回结果: HAL 通过回调
process_capture_result()返回camera3_capture_result_t,包含:result:输出 metadata(如 AE/AWB 状态、统计信息)。output_buffers:填充完成的 buffer。partial_result:部分结果序号(用于 partial metadata 更新)。
关键调试点: 在调试 HAL3 时,重点关注
configure_streams() 返回的 CAMERA3_STATUS_OK 或错误码,以及 process_capture_request() 中 metadata 的完整性。常见问题包括:stream 配置不满足硬件限制、metadata 中缺少必要 tag、buffer 格式不匹配。
3.3.3 HAL3 Request-Result 异步模型(SVG)
3.4 三个核心结构体的对比总结
| 特性 | camera_module_t |
camera_device_t (HAL1) |
camera3_device_t (HAL3) |
|---|---|---|---|
| 角色 | 模块入口,设备工厂 | HAL1 设备实例 | HAL3 设备实例 |
| 参数传递方式 | N/A | 字符串键值对 | camera_metadata_t 结构化数据 |
| 操作模型 | 同步查询 | 顺序调用 | 异步 Request-Result |
| 多流支持 | N/A | 有限(单预览+单拍照) | 原生支持多流并行 |
| 热插拔 | 通过回调支持 | 不支持 | 通过模块回调支持 |
| 调试复杂度 | 低 | 中 | 高(需理解 metadata 和 pipeline) |
学习建议: 对于初学者,建议先掌握
camera_module_t 的加载流程,然后对比 HAL1 和 HAL3 的设备操作差异。在实际调试中,大部分问题出现在 configure_streams() 和 process_capture_request() 的参数配置上,建议结合 dumpsys 和 logcat 进行验证。