3. HAL3 接口规范详解:camera3_device_ops、camera3_callback_ops、关键数据结构

HAL3 接口是 Android Camera 子系统与硬件抽象层之间的核心契约。当 CameraProvider 枚举设备失败或 HAL3 通信链路中断时,根因往往是对这些接口规范的理解偏差或实现遗漏。本章深入剖析 camera3_device_ops、camera3_callback_ops 以及关键数据结构,为后续的链路调试打下坚实基础。

3.1 接口总览与分层模型

HAL3 接口位于 Camera Framework(CameraService)与 Camera HAL 实现之间。其核心交互模型如下:

核心原则: Framework 通过 camera3_device_ops 向 HAL 下发请求,HAL 通过 camera3_callback_ops 异步返回结果。任何一方的实现不完整或生命周期管理错误,都会导致枚举失败或通信超时。
HAL3 通信分层与接口交互图 HAL3 通信分层与接口交互 CameraService (Framework 端) camera3_callback_ops camera3_device_ops Camera HAL (Provider 端实现) 说明:Framework 通过 device_ops 下发 capture_request,HAL 通过 callback_ops 返回 metadata 和 buffer。 枚举失败常因 HAL 未正确注册 callback_ops 或 device_ops 函数指针为 NULL。

3.2 camera3_device_ops 函数指针表

camera3_device_ops 是 HAL 暴露给 Framework 的操作接口,定义在 hardware/libhardware/include/hardware/camera3.h 中。它是一个包含多个函数指针的结构体,Framework 通过调用这些函数来驱动相机硬件。

函数指针 用途 调试关注点
initialize 初始化设备,注册 callback_ops 必须在此函数中保存 callback_ops 指针;返回 0 表示成功
configure_streams 配置输出/输入流(分辨率、格式、方向) 检查 stream 配置是否被 HAL 拒绝;常见失败原因:不支持的尺寸或格式
construct_default_request_settings 返回默认的 capture request settings 返回的 metadata 必须包含所有必要的 control 字段;返回 NULL 会导致枚举失败
process_capture_request 处理一次 capture 请求 检查 request 中的 settings 和 output_buffers 是否有效
flush 清空所有正在处理的请求 必须在 1000ms 内完成;超时会导致 ANR
dump 输出调试信息到 fd 用于 dumpsys 调试;实现空函数即可
调试技巧: 在 initialize 和 configure_streams 入口处添加 ALOGV 日志,打印传入的参数。枚举失败时,优先检查 construct_default_request_settings 是否返回了非空 metadata。

3.3 camera3_callback_ops 回调接口

camera3_callback_ops 是 Framework 提供给 HAL 的回调接口,HAL 通过它异步通知 Framework 事件和结果。该结构体在 initialize 时由 Framework 传入。

回调函数 触发时机 调试关注点
process_capture_result 一次 capture 完成时 必须为每个 request 调用一次;result 中的 metadata 不能为 NULL
notify 错误、快门事件等发生时 错误类型包括 ERROR_REQUEST、ERROR_RESULT、ERROR_BUFFER 等
常见陷阱: HAL 必须在 initialize 中保存 callback_ops 指针,并在后续所有回调中使用。如果保存的指针被覆盖或释放,Framework 将收到无效回调,导致通信链路断裂。

3.4 关键数据结构详解

HAL3 通信涉及多个核心数据结构,理解它们的生命周期和所有权是调试的基础。

3.4.1 camera3_stream_t

描述一个图像流(输出或输入)。关键字段包括:

  • stream_type:CAMERA3_STREAM_OUTPUT(输出)、CAMERA3_STREAM_INPUT(输入)或 CAMERA3_STREAM_BIDIRECTIONAL(双向)。
  • width / height:图像尺寸。
  • format:像素格式,如 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED。
  • usage:GRALLOC_USAGE_* 标志,指示 buffer 用途。
  • max_buffers:HAL 请求的最大 buffer 数量。

3.4.2 camera3_capture_request_t

描述一次 capture 请求。关键字段包括:

  • frame_number:帧序号,必须唯一且递增。
  • settings:指向 metadata 的指针,包含 3A 参数、AE 模式等。
  • input_buffer:输入 buffer(用于 reprocessing)。
  • num_output_buffers / output_buffers:输出 buffer 数组。

3.4.3 camera3_capture_result_t

描述一次 capture 的结果。关键字段包括:

  • frame_number:对应 request 的帧序号。
  • result:指向 metadata 的指针,包含最终 3A 状态、传感器时间戳等。
  • num_output_buffers / output_buffers:已填充的输出 buffer。
  • partial_result:部分结果计数,用于分阶段返回 metadata。
HAL3 关键数据结构关系图 HAL3 关键数据结构关系图 camera3_capture_request_t frame_number settings (metadata*) output_buffers[] input_buffer camera3_capture_result_t frame_number result (metadata*) output_buffers[] partial_result camera3_stream_t width / height / format usage / max_buffers frame_number 匹配 引用 引用 说明:request 和 result 通过 frame_number 一一对应;stream 在 configure_streams 时分配,生命周期贯穿整个 session。

3.5 枚举失败与通信链路调试要点

当 CameraProvider 枚举失败时,通常与以下 HAL3 接口实现问题相关:

  1. initialize 未正确保存 callback_ops:后续所有回调都将失败,Framework 无法收到通知。
  2. construct_default_request_settings 返回 NULL:Framework 无法获取默认配置,直接判定 HAL 不可用。
  3. configure_streams 返回非 0:流配置被 HAL 拒绝,常见于不支持的尺寸或格式。
  4. process_capture_result 未调用或调用顺序错误:导致 Framework 等待结果超时。
  5. metadata 中缺少必要字段:如 ANDROID_SENSOR_TIMESTAMP、ANDROID_CONTROL_AE_STATE 等。
调试建议: 在 HAL 的 initialize、configure_streams、construct_default_request_settings 和 process_capture_request 入口处添加详细的 ALOGV 日志,打印所有关键参数。使用 adb logcat -s CameraHal 过滤日志,快速定位问题点。

3.6 小结