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 描述一次捕获请求的结果,包含输出缓冲区、结果元数据以及部分结果状态。
HAL3 核心结构体交互关系图 Android Framework (CameraService) Camera HAL 设备 (CameraProvider) camera3_device_ops_t (操作函数指针表) camera3_callback_ops_t (回调函数指针表) 调用操作函数 异步回调通知 camera3_stream_t camera3_capture_request_t camera3_capture_result_t

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 命令触发。
故障排查要点: 在排查 HAL3 问题时,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)等。 当发生需要框架知晓的异步事件时。
最佳实践: HAL 应尽快通过 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 可以通过多次回调返回部分结果,以降低延迟。
请求-结果生命周期 camera3_capture_request_t frame_number, settings, buffers HAL 处理 ISP, 3A, 统计 camera3_capture_result_t frame_number, result, buffers 部分结果 (Partial Result) 机制 HAL 可以分多次调用 process_capture_result 返回同一个 frame_number 的结果。 例如:先返回 metadata (partial_result=1),再返回 buffer (partial_result=2),最后返回完整结果。

2.6 结构体交互流程总结

理解这些核心结构体的交互流程,是掌握 HAL3 通信原理的关键。以下是一个典型的请求-响应流程:

  1. 初始化: CameraService 调用 camera3_device_ops_t->initialize,传入 camera3_callback_ops_t 指针。HAL 保存此指针。
  2. 配置流: CameraService 调用 camera3_device_ops_t->configure_streams,传入包含 camera3_stream_t 数组的配置。HAL 确认或修改流配置。
  3. 下发请求: CameraService 调用 camera3_device_ops_t->process_capture_request,传入 camera3_capture_request_t。
  4. 异步处理: HAL 处理请求,可能涉及 ISP、3A 算法等。
  5. 回调结果: HAL 通过保存的 camera3_callback_ops_t->process_capture_result 返回 camera3_capture_result_t。同时,通过 camera3_callback_ops_t->notify 发送事件通知(如快门事件)。
  6. 重复步骤 3-5: 持续进行,直到设备关闭或发生错误。
故障排查提示: 当遇到预览无画面、拍照无响应或应用 ANR 时,应首先检查 process_capture_request 是否被正确调用,以及 HAL 是否通过 process_capture_result 和 notify 及时返回了结果。使用 dumpsys media.camera 可以查看框架侧记录的请求和结果状态,是定位 HAL3 问题的有力工具。