3. Camera HAL 接口定义:camera3.h 关键结构体与函数指针
camera3.h 是 Android Camera HAL3 的核心接口头文件,位于 hardware/libhardware/include/hardware/ 目录下。它定义了 HAL 层与 Camera Framework 之间交互的所有数据结构、回调函数指针以及设备操作接口。理解该文件中的关键结构体与函数指针,是进行 HAL 层移植适配的第一步。
3.1 顶层设备结构:camera3_device_t
camera3_device_t 是 HAL3 设备的抽象,继承自 hw_device_t。它包含一个指向 camera3_device_ops_t 的函数指针表,Framework 通过该表调用 HAL 的具体实现。
typedef struct camera3_device {
hw_device_t common;
camera3_device_ops_t *ops;
void *priv;
} camera3_device_t;
| 字段 | 类型 | 说明 |
|---|---|---|
| common | hw_device_t | 标准硬件设备结构,包含 tag、version、close 等基础字段 |
| ops | camera3_device_ops_t* | 函数指针表,HAL 必须实现所有接口 |
| priv | void* | HAL 私有数据指针,通常指向自定义的设备上下文 |
camera3_device_t 的 priv 字段中,通常存放指向具体传感器驱动、ISP 控制块、Stream 管理器的指针。初始化时务必分配并绑定该结构。
3.2 核心操作接口:camera3_device_ops_t
该结构体定义了 HAL3 设备的所有操作函数指针,是移植工作中需要完整实现的接口集合。以下列出最关键的 6 个函数指针:
| 函数指针 | 原型 | 功能描述 |
|---|---|---|
| initialize | int (*)(const struct camera3_device *, const camera3_callback_ops_t *) | 初始化设备,注册 Framework 回调 |
| configure_streams | int (*)(const struct camera3_device *, camera3_stream_configuration_t *) | 配置数据流(分辨率、格式、方向等) |
| process_capture_request | int (*)(const struct camera3_device *, camera3_capture_request_t *) | 提交一次捕获请求 |
| flush | int (*)(const struct camera3_device *) | 清空所有待处理的请求 |
| dump | void (*)(const struct camera3_device *, int fd) | 导出调试信息到文件描述符 |
| signal_stream_flush | void (*)(const struct camera3_device *, uint32_t num_streams, const camera3_stream_t *const *streams) | 通知 HAL 指定流即将被清空 |
3.3 流配置结构:camera3_stream_configuration_t
当 Framework 需要改变输出流(如切换预览分辨率、开启录像)时,会调用 configure_streams,并传入该结构体。HAL 需要根据配置重新分配 buffer 并设置 ISP 参数。
typedef struct camera3_stream_configuration {
uint32_t num_streams;
camera3_stream_t **streams;
uint32_t operation_mode;
const camera3_stream_buffer_set_t *input_buffers;
} camera3_stream_configuration_t;
| 字段 | 说明 |
|---|---|
| num_streams | 流数量,通常为 1~3(预览、拍照、录像) |
| streams | 指向 camera3_stream_t 指针数组,每个元素描述一条流 |
| operation_mode | 操作模式,如 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE 或 CONSTRAINED_HIGH_SPEED_MODE |
| input_buffers | 输入 buffer 配置(仅 reprocessing 场景使用) |
configure_streams 中必须检查 operation_mode,高速模式(如 120fps 录像)需要单独配置 ISP 时钟和 buffer 队列深度,否则会导致帧率不达标。
3.4 捕获请求与结果回调
camera3_capture_request_t 描述一次捕获请求,包含帧号、输出 buffer 列表、输入 buffer(reprocessing)、设置参数等。HAL 处理完成后,通过 camera3_callback_ops_t 中的 process_capture_result 回调返回结果。
typedef struct camera3_capture_request {
uint32_t frame_number;
uint32_t num_output_buffers;
const camera3_stream_buffer_t *output_buffers;
const camera3_stream_buffer_t *input_buffer;
const camera_metadata_t *settings;
} camera3_capture_request_t;
| 字段 | 说明 |
|---|---|
| frame_number | 帧序号,必须与结果回调中的 frame_number 一致 |
| output_buffers | 输出 buffer 数组,每个 buffer 对应一条 stream |
| input_buffer | 输入 buffer(仅 reprocessing 时有效) |
| settings | 本次请求的 metadata 参数(AE/AWB/AF 等) |
3.5 关键结构体关系图
下图展示了 camera3.h 中核心结构体之间的调用与数据流向关系:
3.6 回调接口:camera3_callback_ops_t
Framework 通过 initialize 将回调结构体注册给 HAL。HAL 在处理完请求后,必须通过以下回调通知 Framework:
| 回调函数 | 触发时机 | 说明 |
|---|---|---|
| process_capture_result | 每帧处理完成 | 返回 metadata 和填充好的 buffer |
| notify | 异步事件 | 如快门事件、错误事件、3A 状态变化 |
typedef struct camera3_callback_ops {
void (*process_capture_result)(const struct camera3_callback_ops *, const camera3_capture_result_t *);
void (*notify)(const struct camera3_callback_ops *, const camera3_notify_msg_t *);
} camera3_callback_ops_t;
process_capture_result 必须在帧周期内尽快返回。如果 HAL 在回调中执行耗时操作(如 JPEG 编码),会导致 buffer 无法及时归还,进而阻塞后续请求。建议将编码等重操作放在独立线程中完成。
3.7 移植适配检查清单
在开始编写 HAL 代码前,建议对照以下清单确认接口完整性:
- camera3_device_ops_t:是否实现了全部 10 个函数指针?
initialize、configure_streams、process_capture_request为强制实现。 - camera3_stream_t:在
configure_streams中是否正确设置了max_buffers和usage_flags? - camera3_capture_result_t:返回结果时
frame_number是否与请求一致?partial_result是否按需设置? - 错误处理:当硬件出错时,是否通过
notify发送CAMERA3_MSG_ERROR_REQUEST或CAMERA3_MSG_ERROR_DEVICE? - Buffer 管理:是否实现了
register_stream_buffers(Android N 之前)或使用dequeue_buffer/queue_buffer模式?
register_stream_buffers 已被废弃,HAL 必须通过 process_capture_request 中的 buffer 句柄直接操作。如果仍使用旧接口,在 Treble 架构下会导致 Camera 服务崩溃。
3.8 典型初始化流程
以下伪代码展示了 HAL 设备初始化的标准步骤:
// 1. 分配 camera3_device_t
camera3_device_t *dev = malloc(sizeof(camera3_device_t));
memset(dev, 0, sizeof(camera3_device_t));
// 2. 填充 hw_device_t 公共字段
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = CAMERA_DEVICE_API_VERSION_3_5;
dev->common.close = hal_dev_close;
// 3. 绑定操作接口
static camera3_device_ops_t ops = {
.initialize = hal_initialize,
.configure_streams = hal_configure_streams,
.process_capture_request = hal_process_capture_request,
.flush = hal_flush,
.dump = hal_dump,
// ... 其他接口
};
dev->ops = &ops;
// 4. 分配私有上下文
dev->priv = hal_create_device_context();
hal_initialize 中打印 camera3_callback_ops_t 的地址,并在 process_capture_result 入口处添加帧号日志。这能快速定位回调注册失败或帧丢失问题。