4. Camera HAL3 核心数据结构详解
Camera HAL3 的设计围绕一套精炼的数据结构展开,它们是 HAL 层与 Camera Service 之间通信的契约。掌握这些结构是理解 HAL3 运作机制的基础。本章将深入剖析 camera3_device_t、camera3_callback_ops_t、camera3_stream_t 和 camera3_capture_request_t 这四大核心数据结构。
4.1 camera3_device_t:HAL 设备实例
camera3_device_t 是 HAL3 设备在 Camera Service 中的抽象表示。它继承自 Android 硬件抽象层的通用设备结构 hw_device_t,并扩展了 Camera HAL3 特有的操作接口。每一个打开的 Camera 设备(如后置摄像头)都对应一个 camera3_device_t 实例。
4.1.1 结构体定义与核心字段
typedef struct camera3_device {
hw_device_t common; // 继承自通用硬件设备结构
camera3_device_ops_t *ops; // 指向设备操作函数集的指针
void *priv; // HAL 私有数据指针,由 HAL 实现管理
} camera3_device_t;
| 字段 | 类型 | 说明 |
|---|---|---|
common |
hw_device_t |
标准硬件设备结构,包含版本号、模块 ID、close 函数指针等。 |
ops |
camera3_device_ops_t* |
指向 camera3_device_ops_t 结构体的指针,该结构体包含了所有 HAL3 设备操作函数,如 initialize、configure_streams、process_capture_request 等。 |
priv |
void* |
HAL 实现可以在此指针上挂载自己的私有上下文数据,例如设备状态、传感器信息等。 |
4.1.2 设备操作函数集 (camera3_device_ops_t)
camera3_device_ops_t 是 HAL3 的核心操作接口,它定义了 Camera Service 可以调用的所有功能。以下是最关键的几个函数:
initialize:在设备打开后调用,用于初始化 HAL 设备,并注册回调函数。configure_streams:配置 Camera 的输入/输出流,是建立数据管道的核心步骤。process_capture_request:提交一个捕获请求,HAL 需要处理该请求并返回结果。flush:清空所有正在处理的请求,用于快速停止或重置设备。dump:导出 HAL 设备的调试信息。
camera3_device_t 时,务必正确初始化 common.tag、common.version 和 common.close 回调。错误的版本号会导致 Service 拒绝加载 HAL。
4.2 camera3_callback_ops_t:异步回调接口
Camera HAL3 是一个异步系统。当 HAL 处理完一个请求或产生事件时,它不能直接调用 Service 的内部方法,而是通过 camera3_callback_ops_t 结构体中注册的回调函数来通知 Service。这个结构体由 Camera Service 实现,并在 initialize() 时传递给 HAL。
4.2.1 核心回调函数
| 回调函数 | 触发时机 | 关键参数 |
|---|---|---|
process_capture_result |
当 HAL 完成一个捕获请求的处理时 | camera3_capture_result_t *result:包含元数据、输出 buffer 等 |
notify |
当发生异步事件时(如快门、错误) | camera3_notify_msg_t *msg:事件类型和具体数据 |
4.2.2 回调机制的重要性
- 解耦:HAL 不需要知道 Service 的内部实现细节,只需调用函数指针。
- 异步性:HAL 可以在自己的线程中处理完请求后,通过回调返回结果,不会阻塞 Service。
- 生命周期管理:Service 通过
notify回调中的CAMERA3_MSG_ERROR事件来感知 HAL 层的错误,并进行恢复或销毁操作。
process_capture_result 或 notify 后尽快释放对 buffer 和元数据的所有权。Service 期望在回调返回后,这些资源可以被回收或复用。延迟释放会导致 buffer 泄漏和性能下降。
4.3 camera3_stream_t:数据流描述
camera3_stream_t 描述了一个 Camera 数据流的属性。它定义了图像的格式、尺寸、用途以及 HAL 和 Service 之间传递 buffer 的方式。在 configure_streams() 阶段,Service 会创建一个或多个 camera3_stream_t 实例,并传递给 HAL 进行配置。
4.3.1 核心字段解析
| 字段 | 类型 | 说明 |
|---|---|---|
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) 等。 |
usage |
uint32_t |
Gralloc 使用标志,描述了 buffer 的预期用途(如 CPU 读、GPU 纹理、视频编码器)。 |
max_buffers |
uint32_t |
HAL 为该流请求的最大同时使用的 buffer 数量。 |
priv |
void* |
HAL 私有指针,可用于关联流特定的上下文。 |
4.3.2 流配置流程
- Service 创建流数组:根据应用层的需求(如预览、拍照、录像)创建
camera3_stream_t数组。 - 调用
configure_streams():Service 将流数组传递给 HAL。 - HAL 验证并调整:HAL 检查流参数是否支持,并可以修改
usage、max_buffers和format字段。 - 分配 buffer:配置完成后,Service 和 HAL 通过 Gralloc 分配器为这些流分配实际的图形 buffer。
max_buffers 字段是 HAL 向 Service 请求的 buffer 池深度。设置过小会导致 pipeline 饥饿,设置过大会增加内存占用。通常,预览流设置为 3-4 个 buffer,拍照流可以设置为 1-2 个。
4.4 camera3_capture_request_t:捕获请求
每一个拍照或预览帧的请求都由 camera3_capture_request_t 结构体描述。它包含了 HAL 处理一帧图像所需的所有信息:目标流、元数据、输入 buffer 等。Service 通过 process_capture_request() 将请求提交给 HAL。
4.4.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; // 请求的元数据 (3A 参数等)
uint32_t num_physcam_settings; // 物理相机设置数量 (多摄)
const camera_metadata_t **physcam_settings; // 物理相机设置数组
} camera3_capture_request_t;
4.4.2 请求生命周期
- 创建:Service 根据应用层的请求(如点击拍照按钮)创建一个
camera3_capture_request_t实例。 - 填充:Service 填充帧序号、输出 buffer 列表(从对应流的 buffer 池中取出)、以及包含 AE/AWB/AF 等参数的元数据。
- 提交:Service 调用
process_capture_request()将请求发送给 HAL。 - 处理:HAL 解析请求,驱动 ISP 进行图像处理,并将结果填充到输出 buffer 中。
- 返回:HAL 通过
process_capture_result()回调将填充好的 buffer 和结果元数据返回给 Service。
frame_number 的唯一性和递增性。Service 使用 frame_number 来匹配请求和结果。如果 HAL 丢弃了一个请求,它必须通过 notify() 回调发送一个 CAMERA3_MSG_ERROR_REQUEST 错误消息。
4.5 数据结构关系总结
这四种数据结构共同构成了 HAL3 的通信骨架:
camera3_device_t是通信的端点,提供了操作入口。camera3_callback_ops_t是反向通道,用于异步通知。camera3_stream_t定义了数据的格式和流向。camera3_capture_request_t是驱动数据流动的指令单元。
camera3_device_ops_t 中的 configure_streams 和 process_capture_request 函数入手,跟踪这些数据结构的创建、传递和销毁过程,可以快速理解 HAL3 的整体数据流。