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)

camera_module_t 模块加载与设备创建流程 camera_module_t 模块加载与设备创建流程 Camera Service hw_get_module() camera_module_t get_number_of_cameras() get_camera_info() open() → hw_device_t 说明:Camera Service 通过 hw_get_module() 加载 camera_module_t,然后依次调用 get_number_of_cameras()、get_camera_info() 获取设备信息,最后通过 open() 创建设备实例。

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)

camera_device_t (HAL1) 设备操作流程 camera_device_t (HAL1) 设备操作流程 open() set_preview_window start_preview set_parameters take_picture auto_focus 说明:HAL1 设备操作是顺序调用模式,先设置预览窗口,启动预览,然后可设置参数、触发对焦和拍照。

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 异步模型:

  1. 初始化: Camera Service 调用 initialize() 传入 camera3_callback_ops_t 回调接口。
  2. 配置流: 调用 configure_streams() 定义输出流(如预览流、拍照流、视频流)。
  3. 提交请求: 通过 process_capture_request() 提交 camera3_capture_request_t,包含:
    • settings:camera_metadata_t 格式的参数。
    • output_buffers:目标 buffer 列表。
    • input_buffer:输入 buffer(用于 reprocessing)。
  4. 返回结果: 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)

camera3_device_t HAL3 Request-Result 异步模型 camera3_device_t HAL3 Request-Result 异步模型 Camera Service initialize() configure_streams() process_capture_request() HAL Pipeline process_capture_result() flush() 说明:HAL3 采用异步 Request-Result 模型,Service 提交请求,HAL 处理完成后通过回调返回结果。flush() 用于中断正在处理的请求。

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 进行验证。