3. Camera HAL接口基础:HAL3架构、接口定义与关键数据结构

Camera HAL(硬件抽象层)是Android Camera框架中连接Framework与底层硬件驱动的关键桥梁。HAL3(即Camera3 HAL)自Android 5.0引入,取代了HAL1,为现代多帧流水线、ZSL(零快门延迟)和高级ISP控制提供了标准接口。理解HAL3架构、接口定义及核心数据结构,是进行CTS测试用例分析与HAL适配问题排查的基石。

3.1 HAL3架构概览

HAL3架构采用生产者-消费者模型,以Camera3Stream为核心,支持多个独立配置的数据流(如预览流、拍照流、视频流)同时运行。与HAL1的单一回调模式不同,HAL3要求HAL实现一个完整的管道(Pipeline),Framework通过发送捕获请求(Capture Request)来驱动每一帧的处理。

架构核心变化: HAL3将控制权从HAL转移到了Framework。Framework负责决定每一帧的3A(自动对焦、自动曝光、自动白平衡)策略、输出流配置和缓冲区管理,HAL仅需忠实地执行请求并返回结果。
HAL3 架构概览 HAL3 架构概览:生产者-消费者模型 Android Camera Framework (CameraService / CameraDevice) 发送 Capture Request · 管理 Buffer Queue · 接收 Capture Result Request / Result Camera HAL3 Implementation (camera3_device_t) process_capture_request · configure_streams · flush · dump 硬件控制 / 数据返回 Kernel Driver & ISP Hardware Sensor · ISP · Flash · Actuator · MIPI CSI 关键:Framework 驱动 Pipeline,HAL 负责逐帧执行,不再主动发起回调

3.2 Camera HAL接口定义

HAL3接口的核心定义在 hardware/libhardware/include/hardware/camera3.h 中。HAL模块通过 hw_module_t 和 hw_device_t 标准结构暴露,但具体操作由 camera3_device_ops_t 函数指针表定义。

3.2.1 关键接口函数

接口函数 方向 功能描述 CTS 关注点
initialize() Framework → HAL 传入 camera3_callback_ops_t,建立通信通道 必须正确保存回调指针,否则后续通知无法送达
configure_streams() Framework → HAL 配置所有活跃的 camera3_stream_t 流 必须验证流参数合法性,返回 CAMERA3_STATUS_OK 或错误码
process_capture_request() Framework → HAL 提交一个捕获请求,包含所有输出缓冲区及设置 必须同步或异步处理,超时或错误将导致 CTS 失败
flush() Framework → HAL 清空所有待处理的请求,停止当前操作 必须在 1000ms 内完成,否则 CTS 判定为 ANR
dump() Framework → HAL 输出调试信息到 fd 必须实现,不能为空函数,否则 CTS 会调用并检查输出
适配提示: configure_streams() 是 CTS 测试的高频调用点。HAL 必须在此函数中检查流格式(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED 的处理)、分辨率是否超出 sensor 能力、以及流数量是否超过硬件限制。错误的配置拒绝逻辑是 CTS 失败的常见原因。

3.2.2 回调接口

HAL通过 camera3_callback_ops_t 向Framework发送异步通知:

  • process_capture_result():返回已完成的捕获结果,包含元数据和缓冲区句柄。
  • notify():发送错误、快门事件等异步消息。

3.3 关键数据结构

HAL3中,数据以结构体形式在Framework与HAL之间传递。以下三个结构体是CTS测试和HAL适配中最常打交道的对象。

3.3.1 camera_metadata_t

camera_metadata_t 是Android Camera系统的“通用语言”,用于编码所有控制参数和结果信息。它是一个序列化的键值对(key-value)容器,支持嵌套、数组和复杂类型。

  • 存储位置: system/media/camera/include/system/camera_metadata.h
  • 内部结构: 包含一个头部(entry count、data count)和两个连续区域:entry 区(存储 key、type、data offset)和 data 区(存储实际值)。
  • 常用操作:
    • camera_metadata_get():读取指定 tag 的值。
    • camera_metadata_set():设置指定 tag 的值。
    • camera_metadata_allocate():预分配空间,避免动态增长。
// camera_metadata_t 使用示例:读取 ANDROID_SENSOR_EXPOSURE_TIME
camera_metadata_t *result = ...; // 从 process_capture_result 获取
camera_metadata_entry_t entry;
int ret = camera_metadata_get(result, ANDROID_SENSOR_EXPOSURE_TIME, &entry);
if (ret == 0 && entry.count > 0) {
    int64_t exposure_time = entry.data.i64[0];
    ALOGI("Exposure time: %ld ns", (long)exposure_time);
} else {
    ALOGE("Failed to get exposure time, ret=%d", ret);
}
CTS 适配陷阱: 许多 CTS 测试用例会检查 camera_metadata_t 中特定 tag 的存在性和值范围。例如,android.control.aeMode 必须返回 ANDROID_CONTROL_AE_MODE_ON 或 OFF 等合法枚举值。如果 HAL 返回了未定义的枚举值,CTS 将直接报错。务必使用 validate_camera_metadata_structure() 进行自检。

3.3.2 camera3_stream_t

camera3_stream_t 描述一个单向数据流,可以是输出流(到Framework)或输入流(来自Framework,用于 reprocessing)。它是 configure_streams() 的核心参数。

字段 类型 说明 CTS 测试关注点
stream_type int CAMERA3_STREAM_OUTPUT 或 CAMERA3_STREAM_INPUT 必须与配置意图一致,否则 configure_streams 失败
width / height uint32_t 图像分辨率 必须在 android.scaler.availableStreamConfigurations 中声明
format int 像素格式,如 HAL_PIXEL_FORMAT_YCbCr_420_888 必须支持 IMPLEMENTATION_DEFINED 的灵活映射
usage uint32_t Gralloc 使用标志,如 GRALLOC_USAGE_HW_TEXTURE HAL 可以修改此字段,但必须合法
max_buffers uint32_t HAL 请求的最大缓冲区数 必须合理,过大或过小都会导致 CTS 性能测试失败
priv void* HAL 私有数据指针,Framework 不解析 可用于关联硬件管道上下文
camera3_stream_t 数据结构 camera3_stream_t 数据结构与流向 camera3_stream_t stream_type: CAMERA3_STREAM_OUTPUT / INPUT width: 1920 | height: 1080 format: HAL_PIXEL_FORMAT_YCbCr_420_888 usage: GRALLOC_USAGE_HW_TEXTURE | ... max_buffers: 4 | priv: (HAL私有指针) Framework 配置 HAL 解析 HAL 可以在 configure_streams 中修改 usage 和 max_buffers,但不能修改 width/height/format

3.3.3 camera3_capture_request_t 与 camera3_capture_result_t

这两个结构体构成了HAL3 Pipeline的请求-响应循环:

  • camera3_capture_request_t:由Framework发送给HAL,包含:
    • frame_number:帧序号,必须单调递增。
    • settings:指向 camera_metadata_t,包含该帧的3A、效果、裁剪等控制参数。
    • input_buffer / output_buffers:输入/输出缓冲区数组。
  • camera3_capture_result_t:由HAL返回给Framework,包含:
    • frame_number:对应请求的帧序号。
    • result:指向 camera_metadata_t,包含该帧的实际3A值、统计信息等。
    • output_buffers:已填充数据的输出缓冲区。
    • partial_result:部分结果序号,用于支持分阶段返回。
// process_capture_request 的典型实现骨架
int hal_process_capture_request(const camera3_capture_request_t *request) {
    // 1. 校验 frame_number 连续性
    if (request->frame_number <= last_frame_number) {
        ALOGE("Non-monotonic frame number: %d", request->frame_number);
        return -EINVAL;
    }
    last_frame_number = request->frame_number;

    // 2. 解析 settings 元数据
    camera_metadata_entry_t entry;
    if (camera_metadata_get(request->settings, ANDROID_SENSOR_SENSITIVITY, &entry) == 0) {
        int32_t iso = entry.data.i32[0];
        // 设置硬件 ISO
    }

    // 3. 处理输出缓冲区
    for (size_t i = 0; i < request->num_output_buffers; i++) {
        const camera3_stream_buffer_t &buf = request->output_buffers[i];
        // 将硬件数据填充到 buf.buffer->handle 指向的图形缓冲区
    }

    // 4. 异步或同步返回结果
    camera3_capture_result_t result;
    memset(&result, 0, sizeof(result));
    result.frame_number = request->frame_number;
    result.result = build_result_metadata(); // 构造结果元数据
    result.num_output_buffers = request->num_output_buffers;
    result.output_buffers = request->output_buffers;
    callback_ops->process_capture_result(callback_ops, &result);

    return 0;
}

3.4 数据结构关系总结

以下表格总结了三个关键数据结构在HAL3 Pipeline中的角色与交互关系:

数据结构 生命周期 传递方向 CTS 验证重点
camera_metadata_t 逐帧创建与销毁 双向(Request / Result) Tag 完整性、值范围、枚举合法性
camera3_stream_t configure_streams 期间 Framework → HAL 格式支持、分辨率匹配、usage 修改合法性
camera3_capture_request_t 单帧请求 Framework → HAL frame_number 单调性、缓冲区有效性
camera3_capture_result_t 单帧响应 HAL → Framework 结果完整性、partial_result 顺序、缓冲区状态
适配总结: HAL3 接口的精髓在于“请求驱动”和“元数据传递”。HAL 开发者必须熟练掌握 camera_metadata_t 的读写操作,确保 configure_streams() 的流配置与静态元数据(android.scaler.availableStreamConfigurations 等)严格一致,并在 process_capture_request() 中正确管理缓冲区生命周期。任何环节的疏忽都会直接导致 CTS 测试用例失败,尤其是在 TestStreamConfiguration、TestCameraMetadata 和 TestRequestPipeline 等核心测试套件中。