2. HAL3接口标准详解:核心结构体定义与职责
Android Camera HAL3 接口是 CameraProvider 与底层硬件驱动之间的核心契约。理解 camera3_device_ops_t 和 camera3_callback_ops_t 等关键结构体,是掌握 HAL3 通信原理和进行故障排查的基础。本章将深入剖析这些结构体的字段定义、职责以及它们在相机流水线中的交互关系。
2.1 核心结构体总览
HAL3 接口围绕几个关键结构体展开,它们共同定义了 Camera HAL 设备的行为和与框架的通信方式。下表列出了最核心的结构体及其主要职责:
| 结构体名称 | 定义位置 | 核心职责 |
|---|---|---|
camera3_device_ops_t |
hardware/libhardware/include/hardware/camera3.h |
定义 HAL 设备向框架暴露的操作函数指针表,是框架调用 HAL 的入口。 |
camera3_callback_ops_t |
hardware/libhardware/include/hardware/camera3.h |
定义框架向 HAL 提供的回调函数指针表,用于 HAL 异步通知框架事件和返回数据。 |
camera3_stream_t |
hardware/libhardware/include/hardware/camera3.h |
描述一个数据流(如预览、拍照、录像流)的配置信息,包括格式、分辨率、使用场景等。 |
camera3_capture_request_t |
hardware/libhardware/include/hardware/camera3.h |
描述一次捕获请求,包含目标流、输入缓冲区、以及请求的元数据(settings)。 |
camera3_capture_result_t |
hardware/libhardware/include/hardware/camera3.h |
描述一次捕获请求的结果,包含输出缓冲区、结果元数据以及部分结果状态。 |
2.2 camera3_device_ops_t:HAL 设备操作接口
camera3_device_ops_t 是 HAL 设备向 CameraService 提供的函数指针表。CameraService 通过调用这些函数来配置 HAL 设备、下发捕获请求、以及控制设备状态。该结构体是 HAL3 接口中最重要的“下行”通道。
2.2.1 关键函数指针定义与职责
| 函数指针 | 职责描述 | 调用时机 |
|---|---|---|
initialize |
初始化 HAL 设备,并将框架提供的 camera3_callback_ops_t 传递给 HAL。HAL 必须保存此回调指针用于后续通信。 |
设备打开后,首次配置前。 |
configure_streams |
配置相机数据流。HAL 根据传入的 camera3_stream_t 数组配置内部硬件流水线,并返回每个流最终的格式、分辨率和使用场景。 |
初始化后,以及每次流配置变更时。 |
construct_default_request_settings |
为指定的使用场景(如预览、拍照)构造默认的捕获请求设置(metadata)。 | 框架需要获取默认设置时。 |
process_capture_request |
处理一个捕获请求。这是 HAL3 最核心的函数,HAL 在此函数中接收请求,进行 ISP 处理,并最终通过回调返回结果。 | 每次需要捕获帧时。 |
flush |
刷新所有正在处理的请求。HAL 应尽快完成或丢弃所有待处理的请求,并通过回调返回结果或错误状态。 | 设备关闭、错误恢复或需要快速停止时。 |
dump |
输出 HAL 设备的调试信息到文件描述符。 | 通过 dumpsys 命令触发。 |
process_capture_request 和 configure_streams 是最常出现问题的函数。例如,configure_streams 返回错误通常意味着流配置不被硬件支持;而 process_capture_request 未及时返回结果或返回错误状态,则会导致预览黑屏或拍照失败。
2.2.2 结构体定义示例
typedef struct camera3_device_ops {
int (*initialize)(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *,
camera3_stream_configuration_t *stream_list);
const camera_metadata_t* (*construct_default_request_settings)(
const struct camera3_device *, int type);
int (*process_capture_request)(const struct camera3_device *,
camera3_capture_request_t *request);
void (*get_metadata_vendor_tag_ops)(const struct camera3_device *,
vendor_tag_query_ops_t *ops);
void (*dump)(const struct camera3_device *, int fd);
int (*flush)(const struct camera3_device *);
/* ... 其他函数指针 ... */
} camera3_device_ops_t;
2.3 camera3_callback_ops_t:框架回调接口
camera3_callback_ops_t 是 CameraService 提供给 HAL 设备的回调函数指针表。HAL 设备通过调用这些回调函数,将处理结果、事件通知和错误信息异步地返回给框架。这是 HAL3 接口中最重要的“上行”通道。
2.3.1 关键函数指针定义与职责
| 函数指针 | 职责描述 | 调用时机 |
|---|---|---|
process_capture_result |
返回一个捕获请求的结果。HAL 可以分多次调用此函数来返回部分结果(partial result),最终必须返回完整结果。 | 当 HAL 完成一个请求的部分或全部处理时。 |
notify |
通知框架一个异步事件,例如快门事件(SHUTTER)、请求错误(ERROR_REQUEST)、设备错误(ERROR_DEVICE)等。 |
当发生需要框架知晓的异步事件时。 |
notify 回调发送 SHUTTER 事件,以便框架可以及时更新 UI 或触发闪光灯。延迟发送快门事件会导致用户体验上的快门延迟感。
2.3.2 结构体定义示例
typedef struct camera3_callback_ops {
void (*process_capture_result)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result);
void (*notify)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);
} camera3_callback_ops_t;
2.4 camera3_stream_t:数据流描述
camera3_stream_t 用于描述一个数据流,例如预览流、拍照流或录像流。在 configure_streams 调用中,框架会传入一个 camera3_stream_t 数组,HAL 需要根据硬件能力确认或修改每个流的配置。
2.4.1 关键字段
| 字段名 | 类型 | 描述 |
|---|---|---|
stream_type |
int |
流类型:CAMERA3_STREAM_OUTPUT(输出流,如预览)、CAMERA3_STREAM_INPUT(输入流,如 reprocessing)。 |
width / height |
uint32_t |
流的宽高(像素)。 |
format |
int |
像素格式,如 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED、HAL_PIXEL_FORMAT_YCbCr_420_888 等。 |
usage |
uint32_t |
Gralloc 使用标志,指示缓冲区将被如何使用(如 GRALLOC_USAGE_HW_TEXTURE、GRALLOC_USAGE_HW_VIDEO_ENCODER)。 |
max_buffers |
uint32_t |
HAL 请求的最大缓冲区数。框架会根据此值分配缓冲区。 |
rotation |
int |
流需要的旋转角度(0, 90, 180, 270)。HAL 可以修改此值。 |
format 字段使用 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 时,HAL 可以自由选择最有效的内部格式。但 HAL 必须在 configure_streams 返回前,将 format 修改为实际使用的具体格式,否则框架可能无法正确分配缓冲区。
2.5 camera3_capture_request_t 与 camera3_capture_result_t:请求与结果
这两个结构体构成了 HAL3 流水线的核心数据单元。框架通过 camera3_capture_request_t 下发请求,HAL 通过 camera3_capture_result_t 返回结果。
2.5.1 camera3_capture_request_t 关键字段
| 字段名 | 描述 |
|---|---|
frame_number |
帧序号,用于唯一标识一个请求,并在结果中匹配。 |
settings |
指向 camera_metadata_t 的指针,包含本次请求的 3A 参数、AE/AF 区域、效果等设置。 |
input_buffer |
指向 camera3_stream_buffer_t 的指针,用于 reprocessing 场景的输入缓冲区。 |
num_output_buffers |
输出缓冲区的数量。 |
output_buffers |
指向 camera3_stream_buffer_t 数组的指针,每个元素描述一个输出缓冲区及其所属流。 |
2.5.2 camera3_capture_result_t 关键字段
| 字段名 | 描述 |
|---|---|
frame_number |
与请求中的 frame_number 对应,用于匹配请求和结果。 |
result |
指向 camera_metadata_t 的指针,包含本次捕获的结果元数据(如最终的 3A 值、传感器时间戳等)。 |
num_output_buffers |
本次返回的输出缓冲区数量。 |
output_buffers |
指向 camera3_stream_buffer_t 数组的指针,包含已填充数据的输出缓冲区。 |
partial_result |
指示本次结果是第几个部分结果。HAL 可以通过多次回调返回部分结果,以降低延迟。 |
2.6 结构体交互流程总结
理解这些核心结构体的交互流程,是掌握 HAL3 通信原理的关键。以下是一个典型的请求-响应流程:
- 初始化: CameraService 调用
camera3_device_ops_t->initialize,传入camera3_callback_ops_t指针。HAL 保存此指针。 - 配置流: CameraService 调用
camera3_device_ops_t->configure_streams,传入包含camera3_stream_t数组的配置。HAL 确认或修改流配置。 - 下发请求: CameraService 调用
camera3_device_ops_t->process_capture_request,传入camera3_capture_request_t。 - 异步处理: HAL 处理请求,可能涉及 ISP、3A 算法等。
- 回调结果: HAL 通过保存的
camera3_callback_ops_t->process_capture_result返回camera3_capture_result_t。同时,通过camera3_callback_ops_t->notify发送事件通知(如快门事件)。 - 重复步骤 3-5: 持续进行,直到设备关闭或发生错误。
process_capture_request 是否被正确调用,以及 HAL 是否通过 process_capture_result 和 notify 及时返回了结果。使用 dumpsys media.camera 可以查看框架侧记录的请求和结果状态,是定位 HAL3 问题的有力工具。