4. Camera HAL 核心数据结构详解

Camera HAL 的架构围绕一组核心数据结构展开,它们定义了 HAL 模块的加载方式、设备生命周期、以及数据流的传输协议。理解这些结构体是进行 HAL 移植、调试和性能优化的基础。本章将深入剖析 camera_module_t、camera_device_t、camera3_device_t 和 camera3_stream_t 等关键结构体。

4.1 模块入口:camera_module_t

camera_module_t 是 HAL 层与 Android 框架交互的起点。它定义在 hardware/libhardware/include/hardware/camera_common.h 中,是 HAL 模块的标准接口。

字段 类型 说明
common hw_module_t 标准 HAL 模块头,包含模块 ID、版本、作者等信息。
get_number_of_cameras int (*)(void) 返回系统中可用的摄像头数量。
get_camera_info int (*)(int camera_id, struct camera_info *info) 获取指定摄像头的静态信息,如朝向、设备类型(前置/后置/外接)。
set_callbacks int (*)(const camera_module_callbacks_t *callbacks) 注册框架回调,用于通知 HAL 模块热插拔事件或设备状态变化。
get_vendor_tag_ops void (*)(vendor_tag_ops_t* ops) (可选)提供厂商自定义 metadata tag 的操作接口。
open_legacy int (*)(const struct hw_module_t* module, const char* id, uint32_t halVersion, struct hw_device_t** device) (可选)打开指定 HAL 版本的设备,用于兼容旧版 Camera HAL。
set_torch_mode int (*)(const char* camera_id, bool enabled) (可选)独立控制闪光灯 torch 模式,无需打开 camera device。
init int (*)(void) (可选)模块级初始化,在 hw_get_module 之后调用。
实战要点: 在移植过程中,get_number_of_cameras 和 get_camera_info 是必须实现的基础接口。如果设备支持热插拔 USB 摄像头,务必正确实现 set_callbacks 以通知框架设备状态变化。

4.2 设备抽象:camera_device_t 与 camera3_device_t

这两个结构体分别对应 Camera HAL v1 和 v3 的设备抽象。v1 是旧版接口,v3 是当前主流接口,支持更复杂的 pipeline 和 metadata 控制。

4.2.1 camera_device_t (HAL v1)

定义在 hardware/libhardware/include/hardware/camera.h,是 v1 接口的设备句柄。

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

其中 camera_device_ops_t 包含了 start_preview、stop_preview、take_picture 等传统操作函数。

4.2.2 camera3_device_t (HAL v3)

定义在 hardware/libhardware/include/hardware/camera3.h,是 v3 接口的核心设备结构体。

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

camera3_device_ops_t 是 v3 接口的灵魂,包含以下关键函数:

  • initialize:初始化设备,传入框架回调 camera3_callback_ops_t。
  • configure_streams:配置数据流,是 pipeline 建立的核心入口。
  • register_stream_buffers:注册 stream 的 buffer 句柄(Android N 后已废弃)。
  • process_capture_request:提交一次 capture 请求,包含 metadata 和 buffer 信息。
  • flush:异步刷新所有正在处理的请求。
  • dump:导出设备调试信息。
版本对比: v1 接口基于同步操作,适合简单功能机;v3 接口基于异步 request/result 模型,支持多路 stream、高帧率、ZSL 等高级特性,是当前 Android 系统的主流选择。

4.3 数据流核心:camera3_stream_t

camera3_stream_t 定义了单个数据流的属性,是 configure_streams 中传递的基本单元。它描述了框架期望 HAL 输出的图像格式、分辨率、使用场景等。

字段 类型 说明
stream_type int 流类型:CAMERA3_STREAM_OUTPUT (输出)、CAMERA3_STREAM_INPUT (输入)、CAMERA3_STREAM_BIDIRECTIONAL (双向)。
width uint32_t 图像宽度(像素)。
height uint32_t 图像高度(像素)。
format int 像素格式,如 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED、HAL_PIXEL_FORMAT_YCbCr_420_888、HAL_PIXEL_FORMAT_BLOB。
usage uint32_t Gralloc buffer 使用标志,如 GRALLOC_USAGE_SW_READ_OFTEN、GRALLOC_USAGE_HW_TEXTURE。
max_buffers uint32_t HAL 请求的最大 buffer 数量,由 HAL 在 configure_streams 中设置。
priv void * HAL 私有数据指针,用于关联 stream 对应的硬件 pipeline 上下文。
data_space android_dataspace_t 色彩空间,如 HAL_DATASPACE_STANDARD_BT709。
rotation int 输出旋转角度:0、90、180、270。
physical_camera_id const char * (Android 9+)物理摄像头 ID,用于多摄场景。
常见陷阱: 在 configure_streams 中,HAL 必须根据硬件能力调整 max_buffers 和 usage 字段。如果 HAL 无法支持框架请求的格式或分辨率组合,必须返回 -EINVAL 并重新协商。忽略此规则会导致预览黑屏或拍照失败。

4.4 结构体关系总览

下图展示了 Camera HAL v3 中核心结构体的层次关系与数据流向:

Camera HAL v3 核心结构体关系图 camera_module_t camera3_device_t camera3_device_ops_t camera3_stream_t[] camera3_stream_t camera3_stream_buffer_t 数据流说明 1. 框架通过 hw_get_module 加载 camera_module_t 2. 调用 open() 创建 camera3_device_t 3. 通过 ops 调用 configure_streams() 4. 框架传入 stream 数组 5. HAL 填充 stream 属性 6. process_capture_request 携带 stream_buffer 7. HAL 填充 buffer 并 回调通知框架

4.5 实战:从结构体到代码实现

在 HAL 实现中,通常会将核心结构体封装到自定义的上下文对象中。以下是一个典型的 HAL v3 设备初始化片段:

// 自定义 HAL 设备上下文
typedef struct my_camera_device {
    camera3_device_t base;          // 必须作为第一个字段
    camera3_device_ops_t ops;       // 操作函数表
    int camera_id;
    void *sensor_handle;            // 传感器驱动句柄
    // ... 其他私有成员
} my_camera_device_t;

// 实现 open 函数
int my_camera_device_open(const struct hw_module_t* module,
                          const char* id,
                          struct hw_device_t** device) {
    my_camera_device_t *dev = malloc(sizeof(my_camera_device_t));
    memset(dev, 0, sizeof(*dev));

    // 填充标准设备头
    dev->base.common.tag = HARDWARE_DEVICE_TAG;
    dev->base.common.version = CAMERA_DEVICE_API_VERSION_3_5;
    dev->base.common.module = (hw_module_t*)module;
    dev->base.common.close = my_camera_device_close;

    // 绑定操作函数表
    dev->ops.initialize = my_initialize;
    dev->ops.configure_streams = my_configure_streams;
    dev->ops.process_capture_request = my_process_capture_request;
    dev->ops.flush = my_flush;
    dev->ops.dump = my_dump;
    dev->base.ops = &dev->ops;

    dev->camera_id = atoi(id);
    // ... 初始化硬件

    *device = &dev->base.common;
    return 0;
}
编码规范: 自定义设备结构体必须将 camera3_device_t 作为第一个成员,这样框架通过 hw_device_t 指针强制转换后,能正确访问到 ops 和 priv 字段。这是 HAL 层常见的“继承”实现模式。

4.6 关键结构体对比总结

结构体 所属层级 核心作用 关键函数/字段
camera_module_t 模块层 HAL 入口,枚举设备 get_number_of_cameras, get_camera_info
camera3_device_t 设备层 设备实例,管理 pipeline ops->configure_streams, ops->process_capture_request
camera3_stream_t 数据流层 定义单路流的属性 format, width, height, max_buffers
camera3_stream_buffer_t Buffer 层 绑定 buffer 与 stream stream, buffer, status, acquire_fence
camera3_capture_request_t 请求层 封装一次 capture 请求 frame_number, settings, input_buffers, output_buffers