相机移动元数据规范

本页介绍了一项规范,该规范允许 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 读数后,只需要记录集成的全球屏幕方向。

这三个值表示角度轴向量,因此弧度的旋转角度由矢量的长度指定,旋转轴由归一化向量指定。

您可以使用 float[3] angle_axis := angle_radians * normalized_axis_vec3 通过轴和角度创建编码表示法。正角表示沿轴逆时针旋转。

编码表示法可以使用 float[3] axis := normalize(axis_angle)float angle_radians := length(angle_axis) 转换回轴和角度。

  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_metadatapts_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 压力以及标头大小(例如,stscstsz atom)。
  • 混合不同类型数据的混合模式会导致 PTS 随着数据包写入文件时正向和反向运行。不过,通过缓冲数据包并以单调的顺序写入它们,可以克服此问题。