本页介绍了一项规范,该规范允许 MP4 文件在视频拍摄过程中嵌入有关相机移动的元数据。拍摄视频的设备通常配有传感器,可提供有关拍摄的更多信息。例如:
- 手机通常配备陀螺仪、加速度计、磁力计和 GPS 传感器。
- 传感器融合可用于跟踪设备的 3 个自由度 (3DoF) 姿势。
- 同时定位和映射 (SLAM) 可用于跟踪设备的 6 个自由度 (6DoF) 姿态(例如 Tango)。
- 曝光信息可用于插入每个扫描的动作。
这些元数据可以保存在视频中,以便在各种应用中进行高级后期处理。例如:
- 帧级旋转信息可用于稳定视频,扫描线级运动数据可用于降低滚动快门效果。
- IMU 读数和派生的 3DoF 姿态可用于评估 IMU 与相机之间的时间对齐和几何对齐。
以下各部分指定了 CAmera Motion Metadata (CAMM) 轨道,其中包含一个新的示例条目,用于指明相应轨道是否存在以及各轨道样本的数据格式。
示例条目
视频文件应包含以下示例条目框,以指示自定义元数据轨道,并且该轨道的 subComponentType
应设置为 meta
。
Camera Motion Metadata Sample Entry (camm) Definition Box Type: camm Container: stsd A sample entry indicating the data track that saves the camera motion. Syntax aligned(8) class CameraMotionMetadataSampleEntry extends SampleEntry('camm') { }
数据格式
元数据轨道包含格式如下的元数据样本流。
字段 | 单位 | 说明 |
---|---|---|
uint16 reserved; |
预留。应为 0。 | |
uint16 type; |
数据包的类型(见下文)。每个数据包都有一种类型的数据。 | |
switch (type) { |
||
case 0: float angle_axis[3]; break; |
角度轴方向,以弧度表示从本地相机坐标到世界坐标系的旋转角度。世界坐标系由应用定义。 假设 M 是与角度轴向量对应的 3x3 旋转矩阵。对于局部坐标系中的任何光线 X,世界坐标的光线方向为 M * X。 这些信息可以通过在设备上运行 3DoF 传感器融合来获取。集成 IMU 读数后,只需要记录集成的全球屏幕方向。 这三个值表示角度轴向量,因此弧度的旋转角度由矢量的长度指定,旋转轴由归一化向量指定。 您可以使用 编码表示法可以使用 |
|
case 1: int32 pixel_exposure_time; int32 rolling_shutter_skew_time; break; |
纳秒 |
这些元数据是按视频帧划分的。此元数据的呈现时间 (PTS) 应该是视频帧中首次使用的扫描线的开始时间。 pixel_exposure_time_ns 是单个像素的曝光时间(以纳秒为单位),rolling_shutter_skew_time_ns 是首次使用的扫描线和上次使用的扫描线之间的曝光时间。可用于插入每个扫描的元数据。 相应帧的 PTS 应在 pts_of_this_metadata 和 pts_of_this_metadata + pixel_exposure_time_ns + scroll_shutter_skew_time_ns 内。 如果未保存此信息,设备应尽最大努力尝试将视频帧的 PTS 调整为位于帧曝光的中心。 |
case 2: float gyro[3]; break; |
弧度/秒 |
相机 XYZ 轴周围的陀螺仪信号(以弧度/秒为单位)。逆时针方向旋转为正。 应用定义 IMU 坐标系和相机坐标系之间的关系。我们建议您尽可能使二者保持一致。 请注意,初始陀螺仪读数位于其驱动程序定义的 IMU 坐标系中,需要进行适当的转换才能将其转换为相机坐标系。 请参阅 Android 传感器.TYPE_GYROSCOPE。 |
case 3: float acceleration[3]; break; |
米/秒^2 |
沿摄像头 XYZ 轴的加速度计读数(米/秒^2)。 应用定义 IMU 坐标系和相机坐标系之间的关系。我们建议您尽可能使二者保持一致。 请参阅 Android 传感器.TYPE_ACCELEROMETER。 |
case 4: float position[3]; break; |
相机的 3D 位置。3D 位置和角度轴旋转角度共同定义了相机的 6DoF 姿态,并且它们位于常见的应用定义的坐标系中。 您可以通过在设备上运行 6DoF 跟踪来获取此信息。 |
|
case 5: double latitude; double longitude; double altitude; break; |
度数 |
样本的最小 GPS 坐标。 |
case 6: double time_gps_epoch; int gps_fix_type; double latitude; double longitude; float altitude; float horizontal_accuracy; float vertical_accuracy; float velocity_east; float velocity_north; float velocity_up; float speed_accuracy; break; |
seconds degrees degrees meters meters meters meters/seconds meters/seconds meters/seconds meters/seconds |
time_gps_epoch - 测量以来 GPS 周期以来的时间 gps_fix_type - 0(无修正)、2(2D 修复)、3(3D 修复) 纬度 - 纬度(以度为单位) 经度 - 经度(以度为单位) 海拔 - WGS-84 椭球体上方的高度 horizontal_accuracy - 水平(纬度/经度)精度 vertical_accuracy - 垂直(海拔)精度 velocity_east - 东方速度 velocity_north - 北方速度 velocity_up - 向上速度 speed_accuracy - 速度精确度 |
case 7: float magnetic_field[3]; break; |
Microtesla |
环境磁场。 请参阅 Android Sensor.TYPE_MAGNETIC_FIELD。 |
} |
备注
- 每个 MP4 文件只能有一个 CAMM 轨道,其中包含上述所有数据类型(通过对上述数据类型进行多路复用)。
- 情形 5 和 6 中的 GPS 样本必须是传感器生成的原始值。当 GPS 没有变化时,无法对其进行内插或重复。
- 坐标系位于右侧。相机坐标系定义为 X 指向右侧,Y 指向下方,Z 指向前方。全局坐标系的 Y 轴应指向重力矢量。
- IMU 读数通常位于单独的 IMU 坐标系中,如果两个坐标系不同,则需要旋转它们才能将其映射到相机坐标系。
- 所有字段均采用小端字节序(最低有效字节位),32 位浮点数采用 IEEE 754-1985 格式。
- 为了准确地同步视频帧和元数据,视频帧的 PTS 应位于曝光中心(也可以通过曝光元数据推断出来)。
- 多路复用这些数据的应用应选择足够长的时间刻度来获得准确的 PTS。
潜在问题
-
这种设计只允许每个数据样本使用一个数据包。嵌入式设备在写入超高频率的数据包时可能会遇到问题,因为如果数据包大小不同,会增加 I/O 压力以及标头大小(例如,
stsc
和stsz
atom)。 - 混合不同类型数据的混合模式会导致 PTS 随着数据包写入文件时正向和反向运行。不过,通过缓冲数据包并以单调的顺序写入它们,可以克服此问题。