3. HAL层接口定义:camera3_callback_ops_t结构体详解、process_capture_result函数签名、notify函数的作用
在Camera HAL3架构中,Result回调机制是连接HAL层与Camera Framework的核心桥梁。HAL层通过一组预定义的回调函数指针,将捕获结果、错误事件、快门事件等异步通知给上层。这组回调函数被封装在 camera3_callback_ops_t 结构体中,由Framework在初始化时注册给HAL设备。
3.1 camera3_callback_ops_t 结构体详解
camera3_callback_ops_t 定义在 hardware/libhardware/include/hardware/camera3.h 中,是HAL层向上层发送异步消息的唯一通道。该结构体包含三个核心函数指针,分别对应三种不同类型的回调事件。
| 函数指针 | 回调类型 | 触发时机 | 关键参数 |
|---|---|---|---|
process_capture_result |
捕获结果回调 | HAL完成一次捕获请求处理后 | camera3_capture_result_t *result |
notify |
事件通知回调 | 快门事件、错误事件发生时 | camera3_notify_msg_t *msg |
notify_physically |
物理相机事件通知 | 多摄像头场景下物理子相机事件 | camera3_notify_msg_t *msg |
关键设计原则:所有回调函数必须在HAL的工作线程中同步调用,Framework保证回调函数本身是线程安全的。HAL不得在回调函数内部阻塞或执行耗时操作,否则会阻塞Framework的消息处理管道。
结构体定义如下:
typedef struct camera3_callback_ops {
/**
* process_capture_result: 向Framework返回一次捕获请求的结果。
* 包含输出buffer、metadata、部分结果标记等。
*/
void (*process_capture_result)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result);
/**
* notify: 向Framework发送异步事件通知。
* 包括快门事件(SHUTTER)、错误事件(ERROR)等。
*/
void (*notify)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);
/**
* notify_physically: (Android 9+) 用于物理相机子设备的独立事件通知。
* 仅在逻辑多摄像头场景下使用。
*/
void (*notify_physically)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);
} camera3_callback_ops_t;
3.2 process_capture_result 函数签名与语义
process_capture_result 是HAL层向Framework返回捕获结果的核心回调。每次调用对应一个或多个已完成的捕获请求,携带输出buffer、结果metadata以及部分结果标记。
void (*process_capture_result)(const struct camera3_callback_ops *ops,
const camera3_capture_result_t *result);
| 参数 | 类型 | 说明 |
|---|---|---|
ops |
const struct camera3_callback_ops * |
回调结构体自身指针,Framework内部使用 |
result |
const camera3_capture_result_t * |
捕获结果数据结构体指针,包含所有结果信息 |
camera3_capture_result_t 结构体关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
frame_number |
uint32_t |
请求帧序号,与提交请求时一致 |
result |
const camera_metadata_t * |
捕获结果metadata,包含3A状态、传感器时间戳等 |
num_output_buffers |
uint32_t |
本次回调返回的output buffer数量 |
output_buffers |
const camera3_stream_buffer_t * |
output buffer数组指针 |
partial_result |
uint32_t |
部分结果序号,0表示最终结果 |
num_physcam_metadata |
uint32_t |
物理相机metadata数量(逻辑相机场景) |
physcam_ids |
const char *const * |
物理相机ID数组 |
physcam_metadata |
const camera_metadata_t ** |
物理相机metadata数组 |
input_buffer |
const camera3_stream_buffer_t * |
输入buffer(仅ZSL/ reprocess场景) |
部分结果机制:HAL可以通过多次调用
process_capture_result 返回同一个frame_number的部分结果。partial_result 字段从1递增,当设置为0时表示该请求的最终结果。Framework会等待所有部分结果到达后再进行后续处理。这允许HAL在metadata尚未完全准备好时,先返回已完成的buffer,降低延迟。
3.3 notify 函数的作用
notify 回调用于发送异步事件通知,与 process_capture_result 独立并行。它主要处理两类事件:快门事件和错误事件。
void (*notify)(const struct camera3_callback_ops *ops,
const camera3_notify_msg_t *msg);
camera3_notify_msg_t 是一个联合体,根据 type 字段区分事件类型:
| 事件类型 | 枚举值 | 数据结构 | 触发场景 |
|---|---|---|---|
CAMERA3_MSG_SHUTTER |
0 | camera3_shutter_msg_t |
传感器开始曝光,产生快门时间戳 |
CAMERA3_MSG_ERROR |
1 | camera3_error_msg_t |
设备错误、请求错误、buffer错误等 |
快门事件(SHUTTER) 是HAL必须保证在第一个output buffer返回之前发送的事件,用于通知Framework传感器曝光开始的时间戳。该时间戳是图像稳定、闪光灯同步、3A算法等模块的关键输入。
typedef struct camera3_shutter_msg {
uint32_t frame_number; // 请求帧序号
uint64_t timestamp; // 曝光开始时间戳(纳秒)
} camera3_shutter_msg_t;
错误事件(ERROR) 用于报告HAL层发生的各类异常情况。Framework根据错误类型决定后续处理策略:
| 错误码 | 枚举值 | 含义 | Framework处理策略 |
|---|---|---|---|
CAMERA3_MSG_ERROR_DEVICE |
0 | 设备级致命错误 | 关闭相机设备,通知应用 |
CAMERA3_MSG_ERROR_REQUEST |
1 | 请求处理失败 | 丢弃该请求,继续处理后续请求 |
CAMERA3_MSG_ERROR_RESULT |
2 | 结果metadata生成失败 | 丢弃该请求的metadata,buffer仍可返回 |
CAMERA3_MSG_ERROR_BUFFER |
3 | 单个buffer处理失败 | 标记该buffer为错误状态,其他buffer正常返回 |
重要约束:对于同一个frame_number,
notify 中的SHUTTER事件必须在 process_capture_result 返回任何output buffer之前被调用。如果HAL违反此顺序,Framework可能无法正确计算曝光时间,导致图像稳定、闪光灯同步等功能异常。此外,ERROR事件发送后,HAL仍需要返回该请求中所有已完成的buffer(标记为错误状态),不能直接丢弃。
3.4 回调调用时序与生命周期
理解三个回调函数的调用时序对于正确实现HAL至关重要。以下是一个典型请求的生命周期:
- 请求提交:Framework调用
process_capture_request提交请求,HAL开始处理。 - 快门事件:传感器开始曝光时,HAL调用
notify发送SHUTTER事件,携带曝光时间戳。 - 部分结果(可选):HAL调用
process_capture_result返回部分metadata(partial_result > 0),可同时返回已完成的buffer。 - 最终结果:HAL调用
process_capture_result返回最终metadata(partial_result = 0),所有剩余buffer必须在此次或之前返回。 - 错误处理:如果处理过程中发生错误,HAL在任意时刻调用
notify发送ERROR事件,然后继续返回已完成的buffer。
最佳实践:建议HAL实现中为每个请求维护一个状态机,记录快门事件是否已发送、部分结果已返回的序号、buffer完成状态等。这样可以确保回调调用顺序正确,避免因并发或异常路径导致违反Framework约束。