3. Camera HAL 关键数据结构详解

Camera HAL 层通过一组标准化的数据结构实现 Framework 与硬件驱动的解耦。理解这些结构体是定位 HAL 层问题的前提。本章逐一拆解 camera_module_t、camera_device_t、camera3_device_t 和 camera3_callback_ops_t 的核心字段、生命周期与常见故障点。

3.1 数据结构总览与层级关系

四个结构体在 HAL 架构中分别承担模块加载、设备抽象、Camera 3 设备接口、回调通知的角色。其调用关系如下:

关键原则: Framework 通过 camera_module_t 枚举设备,通过 camera3_device_t 下发请求,通过 camera3_callback_ops_t 接收结果。任何一层的空指针、未初始化或回调缺失都会导致相机服务崩溃或预览黑屏。
Camera HAL 关键数据结构调用关系 camera_module_t 模块加载 / 设备枚举 camera3_device_t 请求下发 / 流配置 camera3_callback_ops_t 结果回调 / 通知 camera_device_t Camera 1.x 设备接口 调试要点 • camera_module_t 的 get_number_of_cameras() 返回 0 → 驱动未加载 • camera3_callback_ops_t 中 process_capture_result 未实现 → 预览无帧回调

3.2 camera_module_t —— HAL 模块入口

camera_module_t 定义在 hardware/libhardware/include/hardware/camera_common.h 中,是 HAL 模块的顶层接口。Framework 通过 hw_get_module() 获取该结构体指针。

字段类型说明常见问题
commonhw_module_t标准 HAL 模块头,包含 module_api_version版本号不匹配导致加载失败
get_number_of_cameras函数指针返回设备上可用的摄像头数量返回 0 或负值 → 枚举失败
get_camera_info函数指针填充 camera_info 结构体,包含设备方向、静态信息info 字段未初始化 → 空指针崩溃
set_callbacks函数指针注册 HAL 模块级回调(如摄像头热插拔通知)未实现 → 热插拔事件丢失
get_vendor_tag_ops函数指针提供厂商自定义 metadata tag 的查询接口返回空 → 厂商 tag 无法解析
open_legacy函数指针打开 Camera 1.x 兼容设备(可选)未实现时调用返回 -ENOSYS
排查技巧: 当 logcat 中出现 get_number_of_cameras: error -1 或 Failed to open camera HAL 时,优先检查 camera_module_t 的 common.module_api_version 是否与 Framework 期望的 HAL_MODULE_API_VERSION(2,4) 一致。

3.3 camera_device_t —— Camera 1.x 设备接口

camera_device_t 是 Camera 1.x HAL 的设备抽象层,在 Camera 3 HAL 中作为遗留兼容路径存在。其核心字段如下:

typedef struct camera_device {
    hw_device_t common;                    // 标准设备头
    camera_device_ops_t *ops;              // 操作函数表
    void *priv;                            // HAL 私有数据指针
} camera_device_t;

camera_device_ops_t 包含约 30 个函数指针,覆盖预览、拍照、参数设置、内存管理等。调试中重点关注:

  • set_preview_window:绑定 Surface 到 HAL,失败会导致预览黑屏。
  • start_preview / stop_preview:预览启停,未正确实现会导致 ANR。
  • take_picture:拍照触发,返回 JPEG 数据。
  • set_parameters:参数设置入口,格式错误会静默失败。
注意: 在 Camera 3 HAL 实现中,camera_device_t 通常只作为过渡层存在。如果 open_legacy 返回的 ops 表中有空函数指针,调用时直接段错误。

3.4 camera3_device_t —— Camera 3 核心设备接口

camera3_device_t 是 Camera 3.x HAL 的设备抽象,定义在 camera3.h 中。它替代了 camera_device_ops_t 的庞大函数表,采用精简的 ops 结构:

typedef struct camera3_device {
    hw_device_t common;                    // 标准设备头
    camera3_device_ops_t *ops;             // Camera 3 操作函数表
    void *priv;                            // HAL 私有数据
} camera3_device_t;

camera3_device_ops_t 包含以下关键函数:

函数触发时机典型故障
initializeFramework 打开设备后立即调用callback_ops 为空 → 返回 -EINVAL
configure_streams应用设置预览/拍照分辨率时流格式不支持 → 返回 -EINVAL
construct_default_request_settings创建默认 capture request 模板返回 NULL → 相机无法启动
process_capture_request下发拍照/预览请求未及时返回 → 预览卡顿
flush快速关闭所有未完成请求未实现 → 关闭延迟
dumpdumpsys 调用时输出 HAL 状态未实现 → 调试信息缺失
调试黄金法则: 当 Camera 3 HAL 出现 configure_streams 失败时,检查 camera3_stream_t.format 是否在 HAL 的 get_supported_formats() 列表中。常见不支持的格式包括 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 与 YCbCr_420_SP 的混用。

3.5 camera3_callback_ops_t —— 结果回调通道

camera3_callback_ops_t 是 Framework 注册给 HAL 的回调接口,HAL 通过它返回捕获结果和通知事件。定义如下:

typedef struct camera3_callback_ops {
    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);
} camera3_callback_ops_t;

两个回调函数的作用与故障模式:

  • process_capture_result:返回一帧的 metadata 和图像缓冲区。如果 HAL 不调用此回调,Framework 会一直等待,导致预览超时 ANR。
  • notify:发送错误、快门、请求完成等事件。例如 CAMERA3_MSG_ERROR_REQUEST 表示某请求处理失败。
排查案例: 某项目预览黑屏,logcat 无错误。通过加 log 发现 process_capture_result 中 result->output_buffers 的 release_fence 始终为 -1,且 status 为 CAMERA3_BUFFER_STATUS_ERROR。原因是 ISP 驱动未正确填充缓冲区,导致 HAL 跳过回调。

3.6 数据结构对比总结

结构体所属 HAL 版本核心职责初始化时机常见崩溃原因
camera_module_t1.x / 3.x模块加载与设备枚举进程启动时so 加载失败、版本号不匹配
camera_device_t1.x设备操作接口(ops 表)open() 调用时ops 表空指针、set_preview_window 失败
camera3_device_t3.x精简设备接口open() 调用时configure_streams 返回错误
camera3_callback_ops_t3.x结果与事件回调initialize() 时注册未实现回调、回调中空指针解引用

3.7 调试 Checklist

当遇到 Camera HAL 相关问题时,按以下顺序检查数据结构:

  1. camera_module_t:确认 get_number_of_cameras 返回值 > 0,get_camera_info 填充了正确的设备方向。
  2. camera3_device_t:确认 ops 指针非空,initialize 被调用且 callback_ops 已保存。
  3. configure_streams:检查流格式、分辨率、usage 标志是否在 HAL 支持范围内。
  4. process_capture_request:确认 HAL 在收到请求后调用了 process_capture_result。
  5. camera3_callback_ops_t:确认 notify 回调在错误时被正确调用,且 process_capture_result 中的 status 字段为 OK。
常见陷阱: 部分 HAL 实现中 camera3_device_t.priv 指向内部状态结构体。如果 initialize 时未正确初始化 priv,后续所有 ops 调用都会访问野指针。建议在 initialize 入口处加 log 打印 priv 地址。