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 模式、白平衡、输出尺寸等。
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 |
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_SIZEANDROID_LENS_INFO_AVAILABLE_APERTURES |
| 动态 Metadata | 每帧捕获后更新 | HAL 在 process_capture_result 中填充 |
Framework / 应用 | ANDROID_SENSOR_EXPOSURE_TIMEANDROID_SENSOR_SENSITIVITY |
| 控制 Metadata | 每帧请求时设置 | Framework / 应用 | HAL 在 process_capture_request 中读取 |
ANDROID_CONTROL_AE_MODEANDROID_CONTROL_AF_MODE |
2.3.2 三类 Metadata 的交互流程
下面的 SVG 图展示了从应用发起请求到 HAL 返回结果的过程中,三类 Metadata 的传递路径:
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[] | 支持的输出/输入流配置(格式、尺寸、方向) |
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 的设置流程
- 应用通过
CameraCaptureSession.capture()提交请求。 - Framework 将请求中的控制 Metadata 序列化后传递给 HAL 的
process_capture_request()。 - HAL 解析控制 Metadata,配置传感器、ISP、闪光灯等硬件模块。
- 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 时生效 |
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 参数传递的主干,任何扩展配置都必须遵循这一分类体系。