2. Camera Metadata 基础:Metadata 定义、Tag/Value 结构、静态/动态/控制 Metadata 分类

Camera Metadata 是 Android Camera 框架中用于描述相机硬件能力、当前状态以及应用请求参数的标准化数据集合。它贯穿于 Camera HAL 与 Framework 之间的每一次交互,是参数传递与扩展配置的核心载体。本章将深入解析 Metadata 的定义、Tag/Value 结构以及三大分类体系。

2.1 Metadata 定义与作用

在 Android Camera 系统中,Metadata 被定义为一组键值对(Key-Value Pair)的集合,每个键对应一个唯一的整数标识符(Tag),每个值可以是基本数据类型(int32、float、byte、int64、double)或复合结构(如数组、矩形、RGB 颜色等)。Metadata 的主要作用包括:

  • 能力描述:向 Framework 报告相机传感器、镜头、闪光灯等硬件支持的特性。
  • 状态反馈:在每一帧捕获完成后,返回该帧的实际曝光时间、增益、对焦位置等运行时状态。
  • 控制指令:接收来自应用层的拍摄参数,如 AE 模式、AF 模式、白平衡、输出尺寸等。
关键概念: Metadata 是 HAL 与 Framework 之间的“契约语言”,所有相机参数必须通过 Metadata 通道传递,不允许使用自定义的私有接口绕过。

2.2 Tag/Value 结构详解

每个 Metadata 条目由 Tag(键)和 Value(值)两部分组成。Tag 是一个 32 位整数,其高 16 位表示所属的 Section(如传感器、镜头、请求等),低 16 位表示在该 Section 内的索引。Value 则根据 Tag 定义的数据类型和计数进行编码。

2.2.1 Tag 的编码规则

位域 宽度 说明
Section 16 位(高) 标识所属的功能模块,如 ANDROID_SENSOR、ANDROID_LENS、ANDROID_CONTROL 等
Index 16 位(低) 在该 Section 内的唯一序号,从 0 开始递增

例如,ANDROID_SENSOR_EXPOSURE_TIME 的 Tag 值为 0x0000000E,其中 Section 为 0x0000(SENSOR),Index 为 0x000E(14)。

2.2.2 Value 的数据类型

Metadata 支持多种数据类型,每种类型在序列化时占用固定的字节对齐方式:

类型标识 C 类型 字节数 示例 Tag
BYTE uint8_t 1 ANDROID_FLASH_MODE
INT32 int32_t 4 ANDROID_SENSOR_SENSITIVITY
FLOAT float 4 ANDROID_LENS_APERTURE
INT64 int64_t 8 ANDROID_SENSOR_EXPOSURE_TIME
DOUBLE double 8 ANDROID_STATISTICS_LENS_SHADING_MAP
RATIONAL struct {int32_t num; int32_t den;} 8 ANDROID_SENSOR_FRAME_DURATION
开发提示: 在 HAL 层操作 Metadata 时,务必使用 camera_metadata_entry_t 结构体及其配套 API(如 find_camera_metadata_entry、update_camera_metadata_entry),避免直接操作内存布局,以防止跨版本兼容性问题。

2.3 静态 / 动态 / 控制 Metadata 分类

根据生命周期和用途,Metadata 被划分为三大类:静态(Static)、动态(Dynamic) 和 控制(Control)。理解这三类的区别是正确实现 HAL 的关键。

2.3.1 分类对比

分类 生命周期 设置方 读取方 典型 Tag 示例
静态 Metadata 相机打开后固定不变 HAL 在 camera_info 中填充 Framework / 应用 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE
ANDROID_LENS_INFO_AVAILABLE_APERTURES
动态 Metadata 每帧捕获后更新 HAL 在 process_capture_result 中填充 Framework / 应用 ANDROID_SENSOR_EXPOSURE_TIME
ANDROID_SENSOR_SENSITIVITY
控制 Metadata 每帧请求时设置 Framework / 应用 HAL 在 process_capture_request 中读取 ANDROID_CONTROL_AE_MODE
ANDROID_CONTROL_AF_MODE

2.3.2 三类 Metadata 的交互流程

下面的 SVG 图展示了从应用发起请求到 HAL 返回结果的过程中,三类 Metadata 的传递路径:

静态/动态/控制 Metadata 交互流程 静态 / 动态 / 控制 Metadata 交互流程 应用层 (App) Framework (CameraService) Camera HAL 静态 Metadata (能力描述,固定不变) 控制 Metadata (请求参数,每帧设置) 动态 Metadata (状态反馈,每帧更新) 说明: 静态 Metadata 在 HAL 初始化时通过 camera_info 上报;控制 Metadata 由 Framework 下发至 HAL;动态 Metadata 由 HAL 在每一帧捕获完成后回传。

2.4 静态 Metadata 详解

静态 Metadata 描述了相机硬件的固定能力,在相机设备打开后不会改变。HAL 必须在 get_camera_info() 回调中填充完整的静态 Metadata,Framework 会将其缓存供应用查询。

2.4.1 常见静态 Metadata 示例

Tag 名称 类型 描述
ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE INT32[2] 传感器有效像素阵列的宽高(单位:像素)
ANDROID_LENS_INFO_AVAILABLE_APERTURES FLOAT[] 镜头支持的光圈值列表
ANDROID_FLASH_INFO_AVAILABLE BYTE 是否支持闪光灯(1=支持,0=不支持)
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS INT32[] 支持的输出/输入流配置(格式、尺寸、方向)
常见错误: 部分 HAL 实现将本应属于静态 Metadata 的字段(如传感器尺寸)错误地放在动态 Metadata 中返回,导致 Framework 无法正确初始化相机特性。请严格遵循 AOSP 文档中每个 Tag 的“可用性”定义。

2.5 动态 Metadata 详解

动态 Metadata 记录了每一帧捕获完成后的实际硬件状态。HAL 在 process_capture_result() 中必须为每个已设置的请求返回对应的动态 Metadata,即使某些参数未发生变化。

2.5.1 动态 Metadata 的更新规则

  • 必须返回:所有在请求中设置的控制 Metadata 对应的实际值(如实际曝光时间、实际增益)。
  • 可选返回:额外的传感器状态信息(如帧序号、时间戳、3A 状态)。
  • 禁止返回:静态 Metadata 中已定义的字段(如传感器尺寸),避免冗余和冲突。

2.5.2 典型动态 Metadata 示例

Tag 名称 类型 说明
ANDROID_SENSOR_EXPOSURE_TIME INT64 实际使用的曝光时间(纳秒)
ANDROID_SENSOR_SENSITIVITY INT32 实际使用的 ISO 感光度
ANDROID_SENSOR_TIMESTAMP INT64 帧捕获开始时的 CLOCK_MONOTONIC 时间戳(纳秒)
ANDROID_CONTROL_AE_STATE BYTE 自动曝光当前状态(如 AE_CONVERGED、AE_FLASH_REQUIRED)

2.6 控制 Metadata 详解

控制 Metadata 是应用层向 HAL 发送的拍摄指令。每个捕获请求(Capture Request)都包含一组控制 Metadata,HAL 必须根据这些参数配置硬件并生成对应的结果。

2.6.1 控制 Metadata 的设置流程

  1. 应用通过 CameraCaptureSession.capture() 提交请求。
  2. Framework 将请求中的控制 Metadata 序列化后传递给 HAL 的 process_capture_request()。
  3. HAL 解析控制 Metadata,配置传感器、ISP、闪光灯等硬件模块。
  4. HAL 在返回结果时,通过动态 Metadata 反馈实际生效的参数值。

2.6.2 常用控制 Metadata 示例

Tag 名称 类型 可选值示例
ANDROID_CONTROL_AE_MODE BYTE OFF (0), ON (1), ON_AUTO_FLASH (2)
ANDROID_CONTROL_AF_MODE BYTE OFF (0), AUTO (1), CONTINUOUS_PICTURE (4)
ANDROID_CONTROL_AWB_MODE BYTE OFF (0), AUTO (1), DAYLIGHT (3)
ANDROID_SENSOR_EXPOSURE_TIME INT64 手动设置曝光时间(纳秒),仅在 AE OFF 时生效
最佳实践: 在 HAL 中处理控制 Metadata 时,建议先校验每个 Tag 的值是否在静态 Metadata 声明的可用范围内。例如,如果静态 Metadata 中 ANDROID_CONTROL_AE_AVAILABLE_MODES 不包含 ON_AUTO_FLASH,则 HAL 应拒绝该请求并返回错误。

2.7 三类 Metadata 的代码示例

以下代码片段展示了在 HAL 中如何区分和处理三类 Metadata:

// 静态 Metadata 填充示例(在 get_camera_info 中)
static camera_metadata_t* construct_static_metadata() {
    camera_metadata_t* metadata = allocate_camera_metadata(
        CAMERA_METADATA_ENTRY_COUNT, CAMERA_METADATA_DATA_SIZE);
    
    // 传感器像素阵列尺寸(静态)
    int32_t pixel_array_size[2] = {4032, 3024};
    add_camera_metadata_entry(metadata,
        ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
        pixel_array_size, 2);
    
    // 可用光圈值(静态)
    float apertures[] = {1.8f, 2.4f};
    add_camera_metadata_entry(metadata,
        ANDROID_LENS_INFO_AVAILABLE_APERTURES,
        apertures, 2);
    
    return metadata;
}

// 控制 Metadata 解析示例(在 process_capture_request 中)
void parse_control_metadata(const camera_metadata_t* request) {
    camera_metadata_entry_t entry;
    
    // 读取 AE 模式(控制 Metadata)
    if (find_camera_metadata_entry(request,
            ANDROID_CONTROL_AE_MODE, &entry) == 0) {
        uint8_t ae_mode = entry.data.u8[0];
        configure_ae_hardware(ae_mode);
    }
    
    // 读取曝光时间(控制 Metadata,仅在 AE OFF 时有效)
    if (find_camera_metadata_entry(request,
            ANDROID_SENSOR_EXPOSURE_TIME, &entry) == 0) {
        int64_t exposure_time = entry.data.i64[0];
        set_sensor_exposure(exposure_time);
    }
}

// 动态 Metadata 填充示例(在 process_capture_result 中)
void fill_dynamic_metadata(camera_metadata_t* result,
                           int64_t actual_exposure_time,
                           int32_t actual_sensitivity) {
    // 实际曝光时间(动态)
    add_camera_metadata_entry(result,
        ANDROID_SENSOR_EXPOSURE_TIME,
        &actual_exposure_time, 1);
    
    // 实际 ISO 感光度(动态)
    add_camera_metadata_entry(result,
        ANDROID_SENSOR_SENSITIVITY,
        &actual_sensitivity, 1);
}

2.8 本章小结

Camera Metadata 是 Android Camera HAL 开发的核心数据模型。通过本章的学习,你应该掌握:

  • Metadata 的本质是键值对集合,Tag 采用 Section + Index 的编码方式。
  • 静态 Metadata 描述固定能力,在相机打开时上报一次;动态 Metadata 反馈每帧状态,在结果中返回;控制 Metadata 下发每帧请求参数。
  • 三类 Metadata 的交互流程构成了 Camera HAL 参数传递的主干,任何扩展配置都必须遵循这一分类体系。