2. Metadata 基础概念:Camera Metadata 定义、静态/动态/控制 Metadata 分类、Metadata Tag 与 Value 结构
Camera Metadata 是 Android Camera HAL 框架中描述相机设备能力、当前状态以及请求参数的标准化数据集合。它贯穿整个拍照与预览流程,是 HAL 层与 Framework 层之间沟通的“通用语言”。理解 Metadata 的定义、分类与结构,是掌握请求管线调试的基础。
2.1 Camera Metadata 定义
在 Android 系统中,Camera Metadata 被定义为一个键值对(Key-Value)集合,每个键对应一个唯一的整数标识符(Tag),每个值可以是基本数据类型(int32、float、byte、int64、double)或它们的数组、以及复合结构体。Metadata 通过 camera_metadata_t 结构体在进程间传递,其内存布局紧凑,支持快速查找与序列化。
核心特征:
- 标准化:所有 Tag 由 Android 框架统一定义,HAL 与 Framework 均遵循同一套规范。
- 可扩展:厂商可通过 Vendor Tag 添加私有扩展,不影响系统兼容性。
- 生命周期绑定:Metadata 与 Capture Request、Capture Result 绑定,随请求管线流动。
2.2 静态 / 动态 / 控制 Metadata 分类
根据数据来源与生命周期,Camera Metadata 被划分为三大类:静态 Metadata、动态 Metadata 和控制 Metadata。理解这三类的区别,有助于在调试时快速定位数据来源与修改权限。
| 分类 | 定义 | 生命周期 | 典型 Tag 示例 | 修改权限 |
|---|---|---|---|---|
| 静态 Metadata | 描述相机设备的固定硬件能力,在设备初始化后不再变化 | 整个相机生命周期 | ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHSANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE |
只读(HAL 初始化时上报) |
| 动态 Metadata | 描述每一帧捕获后的实际输出状态,随帧变化 | 逐帧更新 | ANDROID_SENSOR_TIMESTAMPANDROID_STATISTICS_FACE_RECTANGLES |
只读(HAL 填充 Result) |
| 控制 Metadata | 描述应用层对每一帧的捕获控制参数,由 Framework 下发 | 逐帧设置 | ANDROID_CONTROL_AE_MODEANDROID_SENSOR_EXPOSURE_TIME |
可写(Framework 设置 Request) |
调试提示:在分析 HAL 日志时,若发现某个参数未按预期生效,首先判断它属于哪一类。控制 Metadata 未生效通常是因为 HAL 未正确解析 Request;动态 Metadata 异常则可能是 HAL 内部状态机或传感器驱动问题。
2.3 Metadata Tag 与 Value 结构
每个 Camera Metadata 条目由一个唯一的 Tag(32 位整数)标识,Tag 的高 16 位表示 Section(所属模块),低 16 位表示该 Section 内的索引。Value 部分则根据数据类型与计数进行编码。
2.3.1 Tag 编码规则
| 位域 | 宽度 | 说明 | 示例 |
|---|---|---|---|
| Section | 高 16 位 (bit 31-16) | 所属模块 ID,如 0x0000 表示 ACAMERA_SECTION_COLOR_CORRECTION | 0x0000 → Color Correction |
| Tag Index | 低 16 位 (bit 15-0) | 该 Section 内的具体条目索引 | 0x0001 → ANDROID_COLOR_CORRECTION_MODE |
| 完整 Tag | 32 位 | 全局唯一标识 | 0x00000001 |
2.3.2 Value 数据结构
Metadata 的 Value 部分由 数据类型 和 数据计数 共同描述。系统使用 camera_metadata_entry_t 结构体来承载一个 Tag 的值:
typedef struct camera_metadata_entry {
size_t index; // 在 metadata 缓冲区中的索引
uint32_t tag; // Tag 标识符
uint8_t type; // 数据类型(见下方枚举)
size_t count; // 数据个数(数组长度)
union {
int32_t *i32; // TYPE_INT32
float *f; // TYPE_FLOAT
int64_t *i64; // TYPE_INT64
double *d; // TYPE_DOUBLE
uint8_t *data; // TYPE_BYTE
camera_metadata_rational_t *r; // TYPE_RATIONAL
} data;
} camera_metadata_entry_t;
2.3.3 数据类型枚举
| 类型常量 | 值 | C 类型 | 说明 |
|---|---|---|---|
TYPE_BYTE |
0 | uint8_t |
单字节无符号整数,常用于枚举或标志位 |
TYPE_INT32 |
1 | int32_t |
32 位有符号整数,最常用的整数类型 |
TYPE_FLOAT |
2 | float |
32 位浮点数,用于曝光时间、焦距等 |
TYPE_INT64 |
3 | int64_t |
64 位有符号整数,用于时间戳等大数值 |
TYPE_DOUBLE |
4 | double |
64 位浮点数,用于高精度物理量 |
TYPE_RATIONAL |
5 | camera_metadata_rational_t |
分子/分母结构体,用于分数表示(如光圈值) |
2.3.4 实际 Tag 示例
以下是一个典型的控制 Metadata Tag 在代码中的定义方式:
// 定义在 system/media/camera/include/system/camera_metadata_tags.h
// Section: ANDROID_SENSOR (0x0003)
// Tag Index: 0x0000
#define ANDROID_SENSOR_EXPOSURE_TIME // Tag: 0x00030000
.type = TYPE_INT64, // 数据类型:64 位整数
.count = 1, // 单个值(非数组)
.description = "Exposure time in nanoseconds"
// 使用示例:设置曝光时间为 33ms(33000000ns)
camera_metadata_entry_t entry;
entry.tag = ANDROID_SENSOR_EXPOSURE_TIME;
entry.type = TYPE_INT64;
entry.count = 1;
entry.data.i64[0] = 33000000; // 33ms
常见调试陷阱:
- 类型不匹配:Framework 下发 TYPE_INT32 但 HAL 期望 TYPE_INT64,会导致解析错误。
- 计数错误:数组类型的 Tag(如 AF 区域
ANDROID_CONTROL_AF_REGIONS需要 5 个 int32)若 count 设置不正确,HAL 可能读取到无效数据。 - Tag 未定义:使用厂商私有 Tag 时,若 HAL 未注册对应的 Vendor Tag,Framework 会忽略该条目。
2.4 小结
Camera Metadata 是 HAL 与 Framework 之间数据交换的核心载体。通过本节的学习,应掌握以下要点:
- Metadata 是键值对集合,使用
camera_metadata_t结构体传递。 - 静态 Metadata 描述硬件能力,动态 Metadata 反映实际输出,控制 Metadata 指导捕获行为。
- Tag 由 Section 和 Index 组成 32 位唯一标识,Value 由类型和计数共同描述。
- 调试时需关注类型匹配、计数正确性以及 Tag 的注册状态。