2. Result回调基础概念
2.1 什么是Result回调
在Camera HAL3架构中,Result回调是HAL层向Camera Framework上报拍摄结果的核心异步通信机制。当HAL完成一个Capture Request的处理后,通过process_capture_result函数将结果数据推送给Framework,而不是由Framework主动轮询。
Result回调的本质是一个异步通知通道,它携带了以下三类关键信息:
- 元数据(Metadata):包含3A状态、传感器时间戳、曝光参数等控制结果。
- 输出缓冲区(Output Buffers):经过ISP处理后的图像数据,如YUV、JPEG或RAW图。
- 部分结果(Partial Result):允许HAL分批次上报,Framework可提前处理已就绪的数据。
关键设计意图:Result回调将HAL从同步阻塞模型中解放出来。HAL可以按自己的节奏处理流水线,Framework则通过回调及时获取进展,两者通过异步机制解耦。
2.2 Result与Request的对应关系
Result与Request之间遵循严格的1:N映射模型,但并非简单的“一个Request对应一个Result”。实际对应关系如下表所示:
| 概念 | 说明 | 示例 |
|---|---|---|
| Request | Framework下发的拍摄请求,包含帧号(frame_number)、设置(settings)、输出缓冲区列表 | frame_number=42, settings={AE, AWB, AF}, buffers=[stream1, stream2] |
| Result(完整) | HAL完成所有处理后一次性上报,包含完整metadata和所有buffer | frame_number=42, result_metadata={...}, buffers=[stream1_ready, stream2_ready] |
| Partial Result | HAL分多次上报,每次携带部分metadata或部分buffer,最后通过partial_result计数标识完成 |
frame_number=42, partial_result=1/3 → 2/3 → 3/3(最终) |
| Buffer Result | HAL单独上报某个stream的buffer状态,不携带metadata | frame_number=42, buffer=stream1, status=OK |
对应关系的核心规则:
- 每个Request必须最终产生一个完整的Result(或错误状态)。
- Partial Result可以多次上报,但
partial_result计数器必须递增至总次数。 - Buffer Result允许提前释放已处理的输出缓冲区,减少Framework端的内存压力。
- Framework通过
frame_number将Result与原始Request关联,确保时序一致性。
实践要点:在HAL实现中,务必保证同一个frame_number的Result回调按顺序上报。如果HAL乱序上报(例如frame 42的Result在frame 41之前到达),Framework会触发错误处理,可能导致相机服务重启。
2.3 Result数据流的基本路径
Result数据从HAL产生到Framework消费,经历了清晰的层级传递。下图展示了完整的Result数据流路径:
Result数据流的基本路径可以概括为以下步骤:
- HAL产生结果:HAL完成某个Request的处理后,构造
camera3_capture_result_t结构体,填充帧号、元数据、缓冲区列表和部分结果计数。 - 跨进程传递:通过HIDL或AIDL接口,将Result数据从HAL进程传递到Camera Service进程。此过程涉及序列化/反序列化,对性能敏感。
- Service校验与分发:Camera Service检查Result的合法性(帧号连续性、缓冲区状态等),然后通过内部回调机制分发给Framework层的
CameraDevice实例。 - Framework消费:Framework的
CameraCaptureSession将Result转换为应用层可识别的CaptureResult对象,触发onCaptureCompleted或onCapturePartial回调。
常见陷阱:HAL在Partial Result中上报的metadata必须与最终完整Result中的对应字段一致。如果Partial Result中上报了AE状态为CONVERGED,但最终Result中变为SEARCHING,Framework会认为HAL行为不一致,可能触发异常。
2.4 关键数据结构
Result回调在HAL层对应的核心数据结构是camera3_capture_result_t,其关键字段如下:
typedef struct camera3_capture_result {
uint32_t frame_number; // 对应Request的帧号
const camera3_stream_buffer_t *output_buffers; // 输出缓冲区数组
uint32_t num_output_buffers; // 输出缓冲区数量
const camera3_capture_result_metadata_t *result;// 结果元数据
uint32_t partial_result; // 部分结果计数(0表示完整结果)
int32_t error_stream; // 错误流标识
// ... 其他扩展字段
} camera3_capture_result_t;
其中partial_result字段是理解Result回调机制的关键:
- 值为0:表示这是该Request的最终完整Result,之后HAL不会再为该帧上报任何结果。
- 值为1~N:表示这是第几次部分结果上报,HAL必须保证从1开始递增,最终上报一次
partial_result=0的完整结果。 - 值为-1:表示该Result仅包含缓冲区状态更新,不携带任何metadata。
性能优化建议:对于高帧率预览场景(如30fps),建议HAL使用Partial Result机制,先上报预览buffer让Framework显示,再上报完整metadata。这样可以将显示延迟降低1~2帧,显著改善取景体验。