4. Camera HAL3 核心数据结构
Camera HAL3 的设计围绕“请求-结果”模型展开,其核心数据结构是连接 Framework 与底层硬件的契约。理解 camera3_device_t、camera3_callback_ops_t、camera3_stream_t 和 camera3_capture_request_t 这四个结构体,是掌握 HAL3 实现的基石。它们分别代表了设备抽象、回调通道、数据流管道和一次捕获的请求描述。
hardware/libhardware/include/hardware/camera3.h 中定义。建议读者在学习过程中对照源码阅读,以加深理解。
4.1 camera3_device_t:HAL 设备抽象
camera3_device_t 是 Framework 视角下单个 Camera 设备的句柄。它继承自 hw_device_t,并扩展了 HAL3 特有的操作接口。每一个物理 Camera(包括逻辑多摄像头)在 HAL 层都对应一个该结构体的实例。
该结构体的关键成员是 ops 指针,它指向一个 camera3_device_ops_t 结构体,其中包含了 HAL 必须实现的全部回调函数。Framework 通过调用这些函数来驱动 Camera 管道。
| 成员 | 类型 | 说明 |
|---|---|---|
| common | hw_device_t | 基类,包含设备打开/关闭、版本号等通用信息。 |
| priv | void* | HAL 实现层的私有数据指针,通常指向一个包含传感器、ISP 等硬件抽象的自定义结构体。 |
| ops | camera3_device_ops_t* | 指向操作函数表的指针,是 Framework 与 HAL 交互的主要入口。 |
4.2 camera3_callback_ops_t:异步回调通道
camera3_callback_ops_t 是 Framework 注册给 HAL 的回调接口。HAL 通过这个结构体中的函数指针,将捕获结果、错误信息、缓冲区状态等异步事件通知给 Framework。它是整个 HAL3 架构中“向上通信”的唯一通道。
该结构体中最核心的两个回调函数是:
- process_capture_result():HAL 完成一次捕获后,通过此回调将
camera3_capture_result_t返回给 Framework,包含输出缓冲区、结果元数据等。 - notify():用于发送异步事件通知,如快门回调(
CAMERA3_MSG_SHUTTER)或错误事件(CAMERA3_MSG_ERROR)。
initialize() 调用中被 Framework 注入。HAL 实现必须保证回调的线程安全性,因为 Framework 可能从多个线程同时调用 HAL 的 ops 函数,而 HAL 的回调也可能在任意线程上下文中被调用。
4.3 camera3_stream_t:数据流管道
camera3_stream_t 描述了一条从 Camera 传感器到内存缓冲区的数据流。它定义了图像的格式、分辨率、使用场景以及缓冲区的管理方式。在 configure_streams() 调用中,Framework 会向 HAL 传递一个 camera3_stream_t 数组,HAL 需要据此配置 ISP 和传感器。
该结构体的关键字段决定了数据流的属性:
| 字段 | 说明 | 典型值 |
|---|---|---|
| stream_type | 流方向:输出(到内存)、输入(如 ZSL)、双向(如 YUV 再处理)。 | CAMERA3_STREAM_OUTPUT |
| width / height | 图像分辨率,由 Framework 根据应用层需求设定。 | 1920 x 1080 |
| format | 像素格式,如 YUV420、NV12、JPEG、RAW10。 | HAL_PIXEL_FORMAT_YCbCr_420_888 |
| usage | Gralloc 使用标志,指示 Buffer 的预期用途(如 GPU 纹理、视频编码器)。 | GRALLOC_USAGE_HW_TEXTURE |
| max_buffers | HAL 请求的最大 Buffer 数量,Framework 据此分配 Buffer 池。 | 4 |
| rotation | 输出图像需要的旋转角度(0/90/180/270),用于优化显示方向。 | CAMERA3_STREAM_ROTATION_90 |
4.4 camera3_capture_request_t:一次捕获的请求
camera3_capture_request_t 是 HAL3 请求-结果模型的核心输入。它描述了一次完整的捕获请求:需要哪些输出流、使用什么 3A 参数、以及关联的输入缓冲区(如 ZSL 场景)。Framework 通过 process_capture_request() 将请求提交给 HAL。
该结构体的核心字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| frame_number | uint32_t | 帧序号,单调递增,用于关联请求与结果。HAL 必须在对应的 camera3_capture_result_t 中返回相同的序号。 |
| settings | const camera_metadata_t* | 捕获参数元数据,包含 AE/AWB/AF 模式、曝光时间、ISO、裁剪区域等。可以为 NULL 表示沿用上次设置。 |
| input_buffer | const camera3_stream_buffer_t* | 输入缓冲区指针,用于 reprocess 场景(如 ZSL 或 RAW 重处理)。非 reprocess 请求为 NULL。 |
| num_output_buffers | uint32_t | 输出缓冲区数量。一个请求可以同时输出到多个流(如预览 + 拍照 + 视频)。 |
| output_buffers | const camera3_stream_buffer_t* | 输出缓冲区数组,每个元素包含目标 stream 和待填充的 buffer_handle_t。 |
process_capture_request() 时,必须尽快返回(非阻塞),实际的图像处理和填充应在 HAL 内部的工作线程中完成。填充完成后,通过 process_capture_result() 回调将结果返回。如果 HAL 无法处理某个请求(如硬件忙),应通过 notify() 发送 CAMERA3_MSG_ERROR_REQUEST 错误。
4.5 数据结构关系总结
这四个核心数据结构共同构成了 HAL3 的通信骨架。它们之间的关系可以概括为:
- camera3_device_t 是设备句柄,通过
ops接收 Framework 的命令。 - camera3_callback_ops_t 是回调通道,HAL 通过它异步返回结果和事件。
- camera3_stream_t 定义了数据流的属性,在
configure_streams()阶段协商确定。 - camera3_capture_request_t 是每次捕获的输入描述,包含目标流和参数。