1. Metadata概念与HAL层角色
各位同学好,我是老张。今天咱们开始聊Metadata,这个在HAL层开发中绕不开的话题。
先说说我自己的经历。几年前我接手一个相机HAL项目,调试时发现预览画面总是卡顿。查了两天,最后发现是Metadata里一个标记位没设对。嗯,从那以后我就特别重视Metadata的设计。
1.1 什么是Metadata
Metadata,说白了就是「描述数据的数据」。你想想看,一张照片本身是数据,但照片的拍摄时间、光圈值、ISO、白平衡——这些就是Metadata。
在HAL层,Metadata扮演的角色更关键。它不只是描述信息,更是驱动硬件行为的「控制指令」。举个例子:
// 典型的Camera Metadata结构
struct camera_metadata_t {
uint32_t tag; // 标签ID,比如AE模式
uint32_t type; // 数据类型:BYTE, INT32, FLOAT等
uint32_t count; // 数据个数
uint8_t data[]; // 实际数据
};
我个人习惯把Metadata分成三类:
- 静态Metadata:硬件出厂就定死的,比如传感器分辨率、支持的帧率范围
- 动态Metadata:运行时变化的,比如当前帧的曝光时间、增益值
- 控制Metadata:上层下发来控制硬件的,比如设置对焦位置、开启闪光灯
核心要点:Metadata是HAL层和上层Framework之间的「通信协议」。没有它,上层根本不知道硬件能做什么,硬件也不知道上层想让它做什么。
1.2 HAL层在Android/IoT架构中的位置
咱们先画个简化的架构图:
+------------------+
| Application | ← 你的App
+------------------+
| Framework | ← Android SDK/API
+------------------+
| HAL Layer | ← 我们负责的这一层
+------------------+
| Kernel Driver | ← Linux驱动
+------------------+
| Hardware | ← 物理设备
+------------------+
HAL层夹在Framework和Kernel之间。它的职责很明确:
- 向上:提供统一的接口,让Framework不用关心底层硬件差异
- 向下:直接操作硬件,把Framework的请求翻译成硬件能理解的指令
我记得有个IoT项目,用的是非标准的传感器。如果没有HAL层做抽象,上层应用每换一个传感器就得改一遍代码。有了HAL,换硬件只需要换HAL实现,上层代码纹丝不动。
1.3 Metadata与HAL的关系
Metadata和HAL的关系,我总结为三个层面:
| 层面 | 作用 | 实际例子 |
|---|---|---|
| 能力描述 | HAL通过Metadata告诉上层「我能做什么」 | ANDROID_SENSOR_INFO_MAX_FRAME_DURATION |
| 状态反馈 | HAL通过Metadata反馈「我现在怎么样」 | ANDROID_SENSOR_TIMESTAMP |
| 控制指令 | 上层通过Metadata告诉HAL「你要做什么」 | ANDROID_CONTROL_AE_TARGET_FPS_RANGE |
说白了,Metadata就是HAL层的「神经系统」。没有它,HAL就是个空壳子。
我的建议:刚开始接触HAL开发的同学,先花时间把Metadata的tag列表过一遍。不用全记住,但要知道哪些是静态的、哪些是动态的、哪些是控制用的。这能帮你少走很多弯路。
注意:Metadata的格式和定义在不同Android版本间可能有变化。比如Android 10到11,Camera的Metadata就新增了几个tag。升级平台时一定要检查兼容性。
1.4 一个实际场景
讲个真实案例。之前做车载摄像头HAL,客户要求支持HDR模式。上层Framework下发了一个控制Metadata:
// 上层下发的HDR控制
metadata[ANDROID_CONTROL_SCENE_MODE] = ANDROID_CONTROL_SCENE_MODE_HDR;
HAL层收到后,需要做两件事:
- 检查硬件是否支持HDR(查静态Metadata)
- 如果支持,配置ISP寄存器开启HDR模式
- 把当前HDR状态通过动态Metadata反馈回去
你看,一个简单的HDR功能,Metadata贯穿了整个过程。这就是为什么我说Metadata是HAL层的灵魂。
好,这一章就到这里。下一章咱们深入聊聊Metadata的数据结构设计和内存管理,那才是真正考验功底的地方。