Camera HAL开发:Metadata处理与调试方法 - 第2节
2.1 什么是 Camera Metadata
Camera Metadata 是 Android 相机框架中用于描述相机硬件能力、当前状态以及每一帧图像捕获参数的结构化数据集合。它本质上是一个键值对(Key-Value)存储系统,贯穿于 Camera HAL(硬件抽象层)与 Framework 之间的所有通信路径。
在 Android Camera 架构中,Metadata 承担着“配置契约”的角色:
- 下行路径(Framework → HAL):应用通过 Camera API 设置的拍照参数(如曝光时间、ISO、对焦区域)被封装为 CaptureRequest 中的 Metadata 下发至 HAL。
- 上行路径(HAL → Framework):HAL 完成图像捕获后,将实际使用的参数、传感器状态、统计信息等封装为 CaptureResult 中的 Metadata 返回。
核心要点:Metadata 是 Android Camera 系统中唯一的结构化通信协议,任何相机功能(自动对焦、自动曝光、HDR、人脸检测)的开启与配置都通过 Metadata 的 Tag 进行控制。
2.2 Metadata 的作用
Camera Metadata 在 Android 相机系统中承担着三大核心作用:
| 作用类别 | 详细说明 | 典型示例 |
|---|---|---|
| 能力描述 | 通过 CameraCharacteristics 静态 Metadata 向 Framework 和应用层报告相机硬件支持的功能范围 | ANDROID_SENSOR_INFO_SENSITIVITY_RANGE 定义 ISO 范围 |
| 参数配置 | 应用通过 CaptureRequest 中的 Metadata 设置每一帧的捕获参数 | ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION 设置曝光补偿 |
| 结果反馈 | HAL 通过 CaptureResult 中的 Metadata 返回实际执行结果和传感器状态 | ANDROID_SENSOR_TIMESTAMP 返回帧时间戳 |
开发提示:在 HAL 开发中,Metadata 的三大作用对应三个关键接口:
getCameraCharacteristics()(能力描述)、processCaptureRequest()(参数配置)、processCaptureResult()(结果反馈)。理解这三者的关系是掌握 Metadata 处理的基础。
2.3 Metadata 的存储结构:Tag / Value / Type
Android Camera Metadata 采用三层结构进行存储和访问:Tag(标签)、Value(值)、Type(类型)。这种设计保证了数据的高效序列化和跨进程传递。
2.3.1 Tag(标签)
Tag 是 Metadata 的唯一标识符,采用 32 位整数编码。每个 Tag 对应一个特定的相机参数或状态。Tag 的编码规则如下:
- 高 16 位:Section ID,表示所属的功能模块(如传感器、镜头、控制等)
- 低 16 位:Tag ID,表示该模块内的具体参数
常见的 Section 及其 Tag 示例:
| Section | Section ID(十六进制) | 典型 Tag 示例 | Tag 值(十六进制) |
|---|---|---|---|
| ANDROID_SENSOR | 0x0010 | ANDROID_SENSOR_EXPOSURE_TIME | 0x0010000E |
| ANDROID_LENS | 0x0011 | ANDROID_LENS_FOCAL_LENGTH | 0x00110006 |
| ANDROID_CONTROL | 0x0012 | ANDROID_CONTROL_AE_MODE | 0x00120001 |
| ANDROID_STATISTICS | 0x0013 | ANDROID_STATISTICS_FACE_DETECT_MODE | 0x00130001 |
2.3.2 Value(值)
Value 是 Tag 对应的具体数据。根据 Type 的不同,Value 可以是单个数值、数组、字符串或复合结构体。在 HAL 层,Value 通过 camera_metadata_entry_t 结构体访问:
// camera_metadata.h 中的核心数据结构
typedef struct camera_metadata_entry {
size_t index; // 在 metadata 数组中的索引
uint32_t tag; // Tag 标识符
uint8_t type; // 数据类型
size_t count; // 数据个数
union {
uint8_t *u8; // TYPE_BYTE
int32_t *i32; // TYPE_INT32
float *f; // TYPE_FLOAT
int64_t *i64; // TYPE_INT64
double *d; // TYPE_DOUBLE
camera_metadata_rational_t *r; // TYPE_RATIONAL
} data;
} camera_metadata_entry_t;
2.3.3 Type(类型)
Android Camera Metadata 定义了 7 种基本数据类型,每种类型对应不同的编码方式和内存布局:
| 类型枚举 | 类型值 | C 类型 | 字节数 | 说明 |
|---|---|---|---|---|
| TYPE_BYTE | 0 | uint8_t | 1 | 枚举值、布尔标志 |
| TYPE_INT32 | 1 | int32_t | 4 | 整数参数(如 ISO、宽度) |
| TYPE_FLOAT | 2 | float | 4 | 浮点参数(如焦距、光圈) |
| TYPE_INT64 | 3 | int64_t | 8 | 时间戳、帧序号 |
| TYPE_DOUBLE | 4 | double | 8 | 高精度浮点(如物理尺寸) |
| TYPE_RATIONAL | 5 | camera_metadata_rational_t | 8 | 分数(分子/分母,各 4 字节) |
2.4 Metadata 的访问与操作
在 HAL 开发中,Metadata 的访问通过 camera_metadata_t 句柄和配套 API 完成。以下是常用的操作函数:
| 操作 | API 函数 | 说明 |
|---|---|---|
| 查找 | find_camera_metadata_entry() |
根据 Tag 查找对应的 entry |
| 读取 | camera_metadata_entry_t.data |
通过联合体按类型读取值 |
| 更新 | update_camera_metadata_entry() |
修改已有 Tag 的值 |
| 添加 | add_camera_metadata_entry() |
新增一个 Tag-Value 对 |
| 删除 | delete_camera_metadata_entry() |
移除指定 Tag |
常见陷阱:在 HAL 中操作 Metadata 时,必须确保 Type 匹配。例如,使用 TYPE_INT32 的 Tag 不能通过 TYPE_FLOAT 的 data 指针访问,否则会导致数据解析错误或内存越界。建议在访问前通过
camera_metadata_entry_t.type 字段进行类型校验。
2.5 Metadata 的三种生命周期形态
根据数据来源和更新频率,Camera Metadata 分为三种形态:
- 静态 Metadata(Static):通过
CameraCharacteristics获取,在相机打开后固定不变。描述硬件能力,如传感器分辨率、支持的 AE 模式等。 - 请求 Metadata(Request):通过
CaptureRequest下发,每帧可变化。应用设置的拍照参数,如曝光时间、对焦位置。 - 结果 Metadata(Result):通过
CaptureResult返回,每帧更新。HAL 实际执行后的状态和统计信息,如实际曝光时间、3A 收敛状态。
2.6 本章小结
Camera Metadata 是 Android Camera HAL 开发的核心数据模型,理解其基本概念是后续深入学习的基础:
- 什么是 Metadata:结构化键值对系统,是 Framework 与 HAL 之间的通信协议。
- Metadata 的作用:能力描述、参数配置、结果反馈三大职责。
- 存储结构:Tag(32 位唯一标识)→ Value(联合体数据)→ Type(7 种基本类型)三层架构。
- 生命周期:静态(硬件能力)、请求(应用配置)、结果(HAL 反馈)三种形态。
学习路径提示:下一章将深入讲解 Metadata 的序列化格式(VNDK 与 vendor 之间的传递机制)以及如何在 HAL 层高效地创建、解析和调试 Metadata。建议先通过
adb shell dumpsys media.camera 查看实际设备上的 Metadata 内容,建立直观认识。