4. HAL核心数据结构详解

在QCOM平台Camera HAL层开发中,理解核心数据结构是构建稳定、高性能相机系统的基石。本章将深入剖析五个关键数据结构:camera_module_t、camera_device_t、camera3_device_t、camera3_stream_t 和 camera3_capture_request_t,涵盖它们的定义、职责、成员变量以及在HAL层中的典型使用模式。

4.1 数据结构全景图

下图展示了HAL层核心数据结构之间的层次关系与数据流向。从模块加载到设备打开,再到流配置与捕获请求提交,每个结构体都承担着明确的职责。

HAL核心数据结构关系图 HAL核心数据结构关系图 camera_module_t 模块入口:枚举设备、打开设备 camera_device_t HAL1设备:ops回调函数集 camera3_device_t HAL3设备:ops回调函数集 camera3_stream_t 流配置:格式、尺寸、方向 camera3_capture_request_t 捕获请求:buffer、settings 说明:HAL3架构下,camera3_device_t 管理流配置与捕获请求,camera3_stream_t 和 camera3_capture_request_t 是核心数据载体。 camera_device_t 仅在 HAL1 兼容层使用,QCOM 平台主流为 HAL3。

4.2 camera_module_t:模块入口

camera_module_t 是HAL层暴露给Framework的第一个结构体,定义在 hardware/libhardware/include/hardware/camera_common.h 中。它代表整个相机模块,负责枚举物理相机设备并打开它们。

4.2.1 核心成员

成员 类型 说明
common hw_device_t 硬件模块通用结构,包含 tag、version、module_api_version 等
get_number_of_cameras int (*)(void) 返回系统中可用的相机设备数量
get_camera_info int (*)(int id, struct camera_info *info) 获取指定ID相机的静态信息(朝向、支持的分辨率等)
set_callbacks int (*)(const camera_module_callbacks_t *callbacks) 注册Framework回调,用于热插拔通知等
open_legacy int (*)(const struct hw_module_t*, const char*, uint32_t, struct hw_device_t**) 打开HAL1兼容设备(可选)

4.2.2 QCOM平台实现要点

  • 模块初始化:在 camera_module_t 的 common 中设置 module_api_version = CAMERA_MODULE_API_VERSION_3_0,表明支持HAL3。
  • 设备枚举:get_number_of_cameras 返回物理相机数 + 逻辑相机数(如双摄虚化)。
  • 热插拔:通过 set_callbacks 注册的回调,在USB相机插入/拔出时通知Framework。
开发提示:在QCOM平台上,camera_module_t 通常由 mm-camera-impl 库实现,模块加载时通过 HAL_MODULE_INFO_SYM 符号导出。

4.3 camera_device_t 与 camera3_device_t:设备抽象

这两个结构体分别对应HAL1和HAL3的设备抽象。在QCOM平台中,HAL3是主流,camera_device_t 仅用于兼容旧版应用。

4.3.1 camera_device_t(HAL1)

定义在 hardware/libhardware/include/hardware/camera.h,核心是 camera_device_ops_t 函数指针表:

typedef struct camera_device {
    hw_device_t common;
    camera_device_ops_t *ops;  // 操作函数表
    void *priv;                // 私有数据,指向HAL内部实现
} camera_device_t;

camera_device_ops_t 包含 set_preview_window、start_preview、take_picture 等HAL1接口。

4.3.2 camera3_device_t(HAL3)

定义在 hardware/libhardware/include/hardware/camera3.h,是HAL3的核心设备结构体:

typedef struct camera3_device {
    hw_device_t common;
    camera3_device_ops_t *ops;  // HAL3操作函数表
    void *priv;                // 私有数据
} camera3_device_t;

camera3_device_ops_t 包含以下关键回调:

回调函数 说明
initialize 初始化设备,传入Framework回调接口 camera3_callback_ops_t
configure_streams 配置数据流(预览、拍照、录像等),传入 camera3_stream_configuration_t
process_capture_request 处理捕获请求,传入 camera3_capture_request_t
flush 刷新所有未完成的请求,用于快速关闭
dump 导出调试信息

4.3.3 QCOM平台差异

  • HAL3优先:QCOM平台默认使用HAL3,camera3_device_t 的 ops 指向 qcamera3_device_ops 实现。
  • 私有数据:priv 指针指向 qcamera3_device_t 结构体,包含CHI(Camera Hardware Interface)上下文、pipeline句柄等。
  • 兼容层:若Framework请求HAL1,QCOM通过 open_legacy 返回包装后的 camera_device_t。

4.4 camera3_stream_t:流配置

camera3_stream_t 描述一个数据流(如预览流、拍照流、录像流),定义在 camera3.h 中。它是 configure_streams 的核心参数。

4.4.1 结构体定义

typedef struct camera3_stream {
    int stream_type;           // CAMERA3_STREAM_OUTPUT / INPUT / BIDIRECTIONAL
    uint32_t width;            // 图像宽度
    uint32_t height;           // 图像高度
    int format;                // 像素格式(HAL_PIXEL_FORMAT_*)
    uint32_t usage;            // 使用标志(GRALLOC_USAGE_*)
    uint32_t max_buffers;      // HAL请求的最大buffer数
    void *priv;                // HAL私有数据
    android_dataspace_t data_space; // 色彩空间
    int rotation;              // 旋转角度
    int stream_set_id;         // 流集合ID(用于同步)
    int physical_camera_id;    // 物理相机ID(逻辑相机使用)
} camera3_stream_t;

4.4.2 关键字段说明

字段 典型值 说明
stream_type CAMERA3_STREAM_OUTPUT 输出流(预览/拍照/录像);输入流用于YUV reprocessing
format HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED QCOM平台常用此格式,由HAL选择最优格式
usage GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE 指示Gralloc分配内存时的用途
max_buffers 3 ~ 8 HAL根据pipeline深度设置,Framework保证不超过此值
data_space HAL_DATASPACE_STANDARD_BT709 色彩空间,影响ISP处理

4.4.3 QCOM平台优化

  • 格式协商:当Framework指定 IMPLEMENTATION_DEFINED 时,QCOM HAL根据流用途选择最优格式(如预览用NV12,拍照用JPEG)。
  • Buffer管理:max_buffers 由CHI pipeline的请求队列深度决定,通常为3~5。
  • 物理相机ID:在逻辑相机(如双摄)中,physical_camera_id 指定该流属于哪个物理相机。

4.5 camera3_capture_request_t:捕获请求

camera3_capture_request_t 是Framework向HAL提交的每一次捕获请求,包含元数据、输出buffer和输入buffer(reprocessing时)。

4.5.1 结构体定义

typedef struct camera3_capture_request {
    uint32_t frame_number;                    // 帧序号,单调递增
    const camera3_stream_buffer_t *input_buffer; // 输入buffer(reprocessing)
    uint32_t num_output_buffers;              // 输出buffer数量
    const camera3_stream_buffer_t *output_buffers; // 输出buffer数组
    const camera_metadata_t *settings;        // 捕获参数(AE/AWB/AF等)
    uint32_t num_physcam_settings;            // 物理相机参数数量
    const camera_metadata_t **physcam_settings; // 物理相机参数数组
} camera3_capture_request_t;

4.5.2 关键字段说明

字段 说明
frame_number 全局递增帧号,用于追踪请求和结果
input_buffer 仅reprocessing时非空,如ZSL拍照的输入YUV buffer
output_buffers 每个元素包含 stream、buffer、status、acquire_fence、release_fence
settings 包含3A参数、AE区域、效果模式等,由Framework填充
physcam_settings 逻辑相机时,每个物理相机可独立设置参数

4.5.3 QCOM平台处理流程

  1. 接收请求:process_capture_request 被调用,HAL将请求加入CHI pipeline的请求队列。
  2. 解析settings:QCOM HAL将 camera_metadata_t 转换为CHI内部的 chi_metadata_t。
  3. Buffer管理:通过 acquire_fence 等待buffer就绪,处理完成后通过 release_fence 通知Framework。
  4. 多帧处理:对于HDR、夜景等场景,一个请求可能触发多个帧的捕获,最终合成一个结果。
性能陷阱:process_capture_request 必须在5ms内返回,否则会导致ANR。QCOM平台通过异步pipeline处理,避免在回调中执行耗时操作。

4.6 数据结构交互流程

下图展示了从 configure_streams 到 process_capture_request 的完整数据流,以及各结构体之间的协作关系。

HAL3数据流交互图 HAL3数据流交互图 Framework configure_streams camera3_stream_t[] process_capture_request camera3_capture_request_t CHI Pipeline process_capture_result 说明:Framework通过 configure_streams 传递 camera3_stream_t 数组,通过 process_capture_request 传递 camera3_capture_request_t。 HAL处理后通过 process_capture_result 回调返回结果。

4.7 数据结构对比总结

结构体 所属层级 核心职责 QCOM平台关键点
camera_module_t 模块层 枚举设备、打开设备 通过 HAL_MODULE_INFO_SYM 导出,支持逻辑相机枚举
camera_device_t HAL1设备层 预览、拍照、录像(旧接口) 仅用于兼容,QCOM通过 open_legacy 包装
camera3_device_t HAL3设备层 流配置、捕获请求处理 priv 指向 qcamera3_device_t,包含CHI上下文
camera3_stream_t 流配置层 描述数据流属性 格式协商、max_buffers 由pipeline深度决定
camera3_capture_request_t 请求层 携带元数据和buffer 异步处理,process_capture_request 需5ms内返回
核心要点:掌握这五个数据结构是理解HAL层工作的基础。在QCOM平台上,camera3_device_t 是中枢,camera3_stream_t 和 camera3_capture_request_t 是数据载体。开发时重点关注 configure_streams 和 process_capture_request 的实现,它们是性能优化的主战场。