2. 核心数据结构:camera3_device_t、camera3_callback_ops_t、camera3_stream_t 结构体详解

Camera HAL3 接口的核心在于三个关键数据结构:camera3_device_t、camera3_callback_ops_t 和 camera3_stream_t。它们分别代表了 HAL 设备实例、回调通信通道和图像流配置。理解这三个结构体是编写 HAL3 适配代码的基础。

2.1 camera3_device_t:HAL 设备实例

camera3_device_t 是 Camera HAL3 中代表单个摄像头设备的结构体。它继承自 Android 硬件抽象层的基础设备结构 hw_device_t,并扩展了摄像头特有的操作接口。该结构体是 Framework 与 HAL 交互的入口点。

字段 类型 说明
common hw_device_t 基础硬件设备结构,包含版本号、模块句柄、关闭函数等通用字段。
ops camera3_device_ops_t* 指向操作函数表的指针,包含 initialize、configure_streams、process_capture_request 等核心方法。
priv void* 私有数据指针,HAL 实现方用于关联自定义的设备上下文(如传感器驱动句柄、状态机等)。
关键点: ops 字段是 HAL3 接口的核心,所有捕获请求、流配置、元数据回调都通过该指针指向的函数表完成。HAL 实现必须在 open() 函数中正确填充 ops 和 priv。

以下是一个典型的 camera3_device_t 初始化代码片段:

// HAL 实现中的 open() 函数片段
int my_camera_device_open(const struct hw_module_t* module,
                          const char* id,
                          struct hw_device_t** device) {
    my_camera_device_t* my_dev = (my_camera_device_t*)calloc(1, sizeof(*my_dev));
    if (!my_dev) return -ENOMEM;

    // 填充 common 字段
    my_dev->device.common.tag     = HARDWARE_DEVICE_TAG;
    my_dev->device.common.version = CAMERA_DEVICE_API_VERSION_3_5;
    my_dev->device.common.module  = (hw_module_t*)module;
    my_dev->device.common.close   = my_camera_device_close;

    // 填充 ops 函数表
    my_dev->device.ops = &my_camera_device_ops;

    // 填充私有数据
    my_dev->device.priv = my_dev->priv_data;

    *device = &my_dev->device.common;
    return 0;
}

2.2 camera3_callback_ops_t:异步回调通道

camera3_callback_ops_t 是 Framework 向 HAL 注册的一组回调函数指针。HAL 通过这组回调将捕获结果、错误信息、快门事件等异步通知给 Framework。该结构体在 initialize() 调用时由 Framework 传入。

回调函数 触发时机 说明
process_capture_result 捕获完成时 返回捕获结果元数据(camera3_capture_result_t)和输出缓冲区。
notify 事件发生时 发送快门事件、错误事件等异步通知(camera3_notify_msg_t)。
flush Framework 请求刷新时 通知 HAL 尽快完成或取消所有待处理的请求(Android 8.0+ 新增)。
实现提示: HAL 必须保存 camera3_callback_ops_t 指针,并在捕获线程中安全地调用 process_capture_result 和 notify。回调调用必须是线程安全的,且不能阻塞 Framework 的调用线程。

回调注册流程示例:

// HAL 的 initialize() 实现
int my_device_initialize(const struct camera3_device *device,
                         const camera3_callback_ops_t *callback_ops) {
    my_camera_device_t* my_dev = (my_camera_device_t*)device->priv;

    // 保存回调指针
    my_dev->callback_ops = callback_ops;

    // 初始化传感器、ISP 等硬件
    // ...

    return 0;
}

// 在捕获完成时调用回调
void my_capture_completed(my_camera_device_t* my_dev,
                          camera3_capture_result_t* result) {
    my_dev->callback_ops->process_capture_result(
        my_dev->callback_ops, result);
}

2.3 camera3_stream_t:图像流配置

camera3_stream_t 描述了一个图像流的属性,包括分辨率、格式、使用场景等。该结构体在 configure_streams() 调用中由 Framework 传入,HAL 需要根据这些配置初始化 ISP 管线。

字段 类型 说明
stream_type int 流类型:CAMERA3_STREAM_OUTPUT(输出)、CAMERA3_STREAM_INPUT(输入)、CAMERA3_STREAM_BIDIRECTIONAL(双向)。
width / height uint32_t 图像分辨率(像素)。
format int 像素格式,如 HAL_PIXEL_FORMAT_YCbCr_420_888、HAL_PIXEL_FORMAT_BLOB(JPEG)、HAL_PIXEL_FORMAT_RAW16。
usage uint32_t 使用标志位,如 GRALLOC_USAGE_SW_READ_OFTEN、GRALLOC_USAGE_HW_CAMERA_WRITE。
max_buffers uint32_t HAL 请求的最大缓冲区数量(由 HAL 在 configure_streams() 中设置)。
priv void* HAL 私有数据指针,可用于关联每个流的上下文(如 DMA 通道、缓冲区队列)。
data_space android_dataspace_t 色彩空间,如 HAL_DATASPACE_V0_JFIF(JPEG)、HAL_DATASPACE_STANDARD_BT709。
rotation int 输出旋转角度:CAMERA3_STREAM_ROTATION_0、90、180、270。
常见陷阱: max_buffers 必须在 configure_streams() 返回前由 HAL 设置。如果设置过小,可能导致预览卡顿或拍照失败;设置过大则浪费内存。通常预览流设置为 3~4,拍照流设置为 1~2。

流配置处理示例:

// HAL 的 configure_streams() 实现片段
int my_configure_streams(const struct camera3_device *device,
                         camera3_stream_configuration_t *stream_list) {
    my_camera_device_t* my_dev = (my_camera_device_t*)device->priv;

    for (size_t i = 0; i < stream_list->num_streams; i++) {
        camera3_stream_t* stream = stream_list->streams[i];

        // 根据流类型和格式配置硬件
        if (stream->stream_type == CAMERA3_STREAM_OUTPUT) {
            if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
                // JPEG 拍照流:设置最大缓冲区为 1
                stream->max_buffers = 1;
                // 配置 JPEG 编码器
            } else if (stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
                // 预览流:设置最大缓冲区为 4
                stream->max_buffers = 4;
                // 配置预览管线
            }
        }

        // 为每个流分配私有上下文
        stream->priv = my_alloc_stream_context(stream);
    }

    return 0;
}
Camera HAL3 核心数据结构关系图 camera3_device_t HAL 设备实例 • common: hw_device_t • ops: camera3_device_ops_t* • priv: void* (自定义上下文) • 包含: initialize, configure_streams, process_capture_request 等操作 camera3_callback_ops_t Framework 回调通道 • process_capture_result() → 返回元数据 + 缓冲区 • notify() → 快门事件 / 错误事件 • flush() (Android 8.0+) camera3_stream_t 图像流配置 • stream_type: OUTPUT/INPUT • width, height, format • usage, max_buffers • data_space, rotation • priv: 流私有上下文 initialize() 注册回调 configure_streams() 配置流参数 数据流交互流程 1. Framework 调用 device->ops->initialize(),传入 callback_ops 指针。 2. Framework 调用 device->ops->configure_streams(),传入 camera3_stream_t 数组。 3. HAL 根据 stream 配置初始化 ISP 管线,设置 max_buffers 和 priv。 4. Framework 发送 capture_request,HAL 处理后将结果通过 callback_ops 返回。 5. 错误或快门事件通过 callback_ops->notify() 异步通知 Framework。 6. 所有回调调用必须线程安全,且不能阻塞 Framework 的调用线程。

2.4 三个结构体的协作关系

在 Camera HAL3 的运行时环境中,这三个结构体通过以下方式协同工作:

  1. 初始化阶段: Framework 通过 camera3_device_t.ops->initialize() 将 camera3_callback_ops_t 注册到 HAL。
  2. 流配置阶段: Framework 通过 configure_streams() 传入 camera3_stream_t 数组,HAL 根据这些配置初始化硬件管线。
  3. 捕获阶段: Framework 发送 camera3_capture_request_t,其中包含指向 camera3_stream_t 的缓冲区句柄。
  4. 结果返回阶段: HAL 通过 camera3_callback_ops_t.process_capture_result() 返回填充好的缓冲区及元数据。
最佳实践: 在 HAL 实现中,建议将 camera3_device_t 的 priv 指针指向一个包含设备状态、回调指针、流列表和硬件句柄的自定义结构体。这样可以避免全局变量,提高代码的可维护性和线程安全性。