4. HAL3核心数据结构:camera3_device_t、camera3_callback_ops_t、camera3_stream_t详解

在HAL3架构中,camera3_device_t、camera3_callback_ops_t和camera3_stream_t是驱动与框架交互的三大核心数据结构。它们分别定义了设备操作接口、异步回调契约以及数据流配置规范。理解这三者的关系与字段含义,是进行高通平台HAL3适配的首要前提。

学习提示: 本章节将逐一拆解这三个结构体的成员变量与函数指针,并结合高通平台的实际适配场景,说明每个字段在初始化、配置和运行时的作用。

4.1 camera3_device_t:设备操作接口

camera3_device_t 是HAL3中代表单个Camera设备的结构体,它继承自 hw_device_t,并扩展了HAL3特有的操作函数指针。框架通过该结构体调用底层驱动完成初始化、配置流、捕获请求等核心操作。

核心要点: camera3_device_t 是框架与HAL3设备之间的“命令通道”,所有同步操作均通过其函数指针下发。

4.1.1 结构体定义与关键字段

typedef struct camera3_device {
    hw_device_t common;                     // 继承自硬件抽象层基础结构
    camera3_device_ops_t *ops;              // 操作函数指针集合
    void *priv;                             // 私有数据指针,指向高通平台的自定义设备上下文
} camera3_device_t;
字段 类型 说明 高通适配要点
common hw_device_t 包含设备版本号、模块ID、open/close等基础接口 需正确填充 tag 和 version,版本号必须为 HARDWARE_DEVICE_API_VERSION(3, 0)
ops camera3_device_ops_t* 指向所有HAL3操作函数的指针结构体 必须实现所有非NULL函数指针,否则框架拒绝加载
priv void* 私有数据,通常指向高通 qcamera_device_t 扩展结构 用于存储底层驱动句柄、传感器信息、流列表等

4.1.2 camera3_device_ops_t 核心函数指针

camera3_device_ops_t 是实际干活的地方,包含以下关键函数指针:

  • initialize:传入 camera3_callback_ops_t,建立框架到HAL的回调通道。
  • configure_streams:接收 camera3_stream_configuration_t,配置数据流管道。
  • process_capture_request:接收 camera3_capture_request_t,下发拍照/预览请求。
  • flush:清空所有未处理的请求,用于快速停止。
  • dump:导出设备调试信息。
避坑指南: 在高通平台上,configure_streams 的返回值直接影响后续请求能否正常下发。如果返回 BAD_VALUE,框架会认为流配置无效并终止Camera打开流程。务必检查流参数(如宽高、格式)是否在传感器支持范围内。

4.2 camera3_callback_ops_t:异步回调契约

camera3_callback_ops_t 是框架注册给HAL3设备的回调函数集合。HAL3驱动通过这些回调将结果数据、事件和缓冲区异步通知给框架。它是HAL3“异步管道”模型的核心纽带。

核心要点: 回调函数由框架实现,HAL3驱动只能调用不能修改。回调的调用顺序和线程安全由HAL3驱动负责。

4.2.1 结构体定义与回调函数

typedef struct camera3_callback_ops {
    void (*process_capture_result)(const struct camera3_callback_ops *ops,
                                   const camera3_capture_result_t *result);
    void (*notify)(const struct camera3_callback_ops *ops,
                   const camera3_notify_msg_t *msg);
} camera3_callback_ops_t;
回调函数 触发时机 传递数据 高通平台注意事项
process_capture_result 捕获请求完成(部分或全部) camera3_capture_result_t:包含输出缓冲区、元数据、部分结果标记 必须按请求的 frame_number 顺序回调,乱序会导致ANR
notify 错误、快门事件、请求错误等 camera3_notify_msg_t:包含错误码、帧号、事件类型 错误通知必须及时,否则框架会超时强制关闭设备

4.2.2 回调调用流程

以下SVG图展示了从请求下发到回调返回的完整异步流程:

camera3_callback_ops_t 异步回调流程 框架下发请求 HAL3驱动处理 生成结果/事件 回调框架 回调调用规则: 1. process_capture_result 必须按 frame_number 递增顺序调用 2. 支持部分结果(partial_result)提前回调,但最终结果必须包含所有元数据 3. notify 用于错误和快门事件,必须在检测到异常时立即调用 4. 回调函数不能阻塞,否则会导致框架侧帧率下降或ANR

4.3 camera3_stream_t:数据流配置

camera3_stream_t 描述单个数据流的属性,包括图像格式、分辨率、使用方向等。在 configure_streams 调用中,框架会传入一个 camera3_stream_t 数组,HAL3驱动需要根据这些配置分配内部缓冲区并设置ISP管道。

核心要点: camera3_stream_t 是HAL3“流配置”的最小单元,每个流对应一个输出目标(如预览Surface、拍照ImageReader、录像MediaCodec)。

4.3.1 结构体定义与关键字段

typedef struct camera3_stream {
    int stream_type;                        // CAMERA3_STREAM_OUTPUT / INPUT / BIDIRECTIONAL
    uint32_t width;                         // 图像宽度(像素)
    uint32_t height;                        // 图像高度(像素)
    int format;                             // 像素格式(HAL_PIXEL_FORMAT_xxx)
    uint32_t usage;                         // 使用标志(GRALLOC_USAGE_xxx)
    uint32_t max_buffers;                   // HAL3驱动请求的最大缓冲区数
    const char *physical_camera_id;         // 物理Camera ID(多摄场景)
    void *priv;                             // 私有数据,高通用于存储stream句柄
    uint64_t reserved[7];                   // 保留字段
} camera3_stream_t;
字段 说明 高通适配典型值/注意事项
stream_type 流方向:输出、输入或双向 预览/拍照通常为 CAMERA3_STREAM_OUTPUT
width / height 图像分辨率 必须匹配传感器输出尺寸,否则 configure_streams 返回错误
format 像素格式 常用 HAL_PIXEL_FORMAT_YCbCr_420_888(预览)和 HAL_PIXEL_FORMAT_BLOB(JPEG)
usage Gralloc缓冲区使用标志 预览通常为 GRALLOC_USAGE_SW_READ_OFTEN,录像为 GRALLOC_USAGE_HW_VIDEO_ENCODER
max_buffers HAL请求的缓冲区数量 高通平台通常请求3~4个缓冲区用于双缓冲或三缓冲

4.3.2 流配置与管道关系

以下SVG图展示了一个典型预览+拍照场景下的流配置结构:

典型双流配置:预览 + 拍照 Camera Sensor ISP Pipeline Stream 0: 预览 1920x1080 YCbCr_420 Stream 1: 拍照 4000x3000 BLOB (JPEG) 配置要点: 每个流独立配置 width/height/format,ISP根据所有流的最大分辨率分配内部处理资源。

4.4 三者协作关系

在HAL3运行时,camera3_device_t、camera3_callback_ops_t和camera3_stream_t通过以下方式协作:

  1. 初始化阶段:框架调用 camera3_device_t->ops->initialize(),传入 camera3_callback_ops_t 指针,HAL3驱动保存该指针用于后续回调。
  2. 配置阶段:框架调用 configure_streams(),传入 camera3_stream_configuration_t(包含 camera3_stream_t 数组),HAL3驱动解析流参数并配置ISP。
  3. 运行阶段:框架下发 process_capture_request,HAL3驱动填充输出缓冲区,通过 process_capture_result 回调返回结果。
高通平台经验: 在 configure_streams 中,高通HAL会检查所有流的 format 和 usage 是否匹配硬件能力。如果预览流和拍照流的分辨率差异过大,可能需要启用“双ISP”模式,此时 max_buffers 需要相应增加。

4.5 常见适配问题与排查

问题现象 可能原因 排查方向
Camera打开失败 camera3_device_t 的 common.version 不匹配 检查版本号是否为 HARDWARE_DEVICE_API_VERSION(3, 0)
预览黑屏 camera3_stream_t 的 format 或 usage 与Gralloc分配不匹配 确认 HAL_PIXEL_FORMAT_YCbCr_420_888 对应的usage包含 GRALLOC_USAGE_SW_READ_OFTEN
拍照卡死 process_capture_result 回调未按帧号顺序调用 检查驱动侧结果队列是否按 frame_number 排序
ANR超时 notify 回调未及时上报错误事件 在驱动检测到硬件错误时立即调用 notify(CAMERA3_MSG_ERROR_DEVICE)
关键提醒: 在高通SDM平台(如SM8250)上,camera3_stream_t 的 priv 字段被用于存储 cpp_stream_t 指针,用于连接ISP输出和JPEG编码器。切勿在框架侧修改该字段,否则会导致内存损坏。