运动照片格式 1.0

运动照片是包含静态图像和短视频(包括音频录制)的单一文件。这种媒体类型允许用户查看高分辨率静态图像以及视频和声音,以捕捉图像拍摄时的情感和氛围。

依赖项

以下是本规范的规范性参考

简介

“必须”、“不得”、“要求”、“应该”、“不应”、“推荐”、“可以”和“可选”的用法符合 RFC2119 中定义的 IETF 标准。

运动照片格式

运动照片文件由一个主静态图像文件,JPEGHEICAVIF,以及一个附加的辅助视频文件组成。主图像包含描述如何显示静态图像文件和视频文件内容的相机 XMP 元数据,以及描述如何定位视频文件内容的容器 XMP 元数据。

图像文件可能包含增益图,例如 Ultra HDR JPEG

文件名模式

写入方应使用符合以下正则表达式的文件名

^([^\\s\\/\\\\][^\\/\\\\]*MP)\\.(JPG|jpg|JPEG|jpeg|HEIC|heic|AVIF|avif)

如果未遵循该模式,读取方可以忽略 XMP 元数据、附加的视频文件或视频内容。

媒体数据编码

主图像包含一个容器元素 XMP 元数据目录,用于定义文件容器中后续媒体文件的顺序和属性。容器中的每个文件在该目录中都有一个对应的媒体项目。该媒体项目描述了文件容器中的位置以及每个串联文件的基本属性。

XMP 属性

两组 XMP 元数据用于定义运动照片格式的额外语义信息。这些元数据可以以任何顺序出现。

相机元数据

相机元数据编码了关于如何呈现运动照片的主图像和视频部分的信息。

  • 命名空间 URI 为 http://ns.google.com/photos/1.0/camera/
  • 默认命名空间前缀为 Camera

以下属性可能出现在静态图像文件 XMP 元数据中

名称

类型

描述

Camera:MicroVideo

Camera:MicroVideoVersion

Camera:MicroVideoOffset

Camera:MicroVideoPresentation
TimestampUs

这些属性是 Microvideo V1 规范的一部分。它们在本规范中已被删除,如果存在则必须被忽略。

特别是,MicroVideoOffset 属性已被 GContainer:ItemLength 值取代,用于在文件中定位视频数据。

Camera:MotionPhoto

整数

0:表示文件不应被视为运动照片。

1:表示文件应被视为运动照片。

所有其他值均未定义,并被视为等同于 0。

如果值为零或负,则即使文件确实附加了视频,该文件也始终被视为非运动照片。

由于大多数行为良好的编辑器都会保留 XMP,因此即使附加视频已被删除,静态图像文件仍可能在该字段中保留值为 1。因此,此字段并非确定性字段,读取方必须始终确认存在视频。

Camera:MotionPhotoVersion

整数

指示运动照片的文件格式版本。本规范定义了版本“1”。

Camera:MotionPhotoPresentationTimestampUs

长整型

长整型值,表示与图像静态帧对应的视频帧的演示时间戳(以微秒为单位)。值可为 -1 表示未设置/未指定。

呈现行为

如果 XMP 数据包中不存在 Camera:MotionPhotoPresentationTimestampUs,读取方应使用紧接在视频轨道中间(即视频轨道时长除以 2)附近的时间戳之前的演示时间戳。

如果 XMP 数据包中存在 Camera:MotionPhotoPresentationTimestampUs 且视频中存在 "application/motionphoto-image-meta",则该轨道中 primaryImageFrameScoreDescrpresentationTimestampUs 字段必须出现相同的值。如果 XMP 数据包中不存在 Camera:MotionPhotoPresentationTimestampUs 且元数据轨道存在,则元数据轨道中的值必须为 -1。

容器元素

容器元素被编码到主图像的 XMP 元数据中,并定义容器中的媒体项目目录。媒体项目必须按照目录中媒体项目元素的相同顺序位于容器文件中,并且必须紧密打包。

  • 命名空间 URI 为 http://ns.google.com/photos/1.0/container/
  • 默认命名空间前缀为 Container

该目录只能包含一个主图像项目,并且它必须是目录中的第一个项目。

元素名称

类型

描述

目录

结构有序数组

定义容器布局和内容的 Container:Item 结构有序数组。

项目元素

媒体项目元素描述了应用应如何使用每个项目。

  • 命名空间 URI 为 http://ns.google.com/photos/1.0/container/item/
  • 默认命名空间前缀为 Item

第一个媒体项目必须是主图像。它必须包含一个 Mime 属性,指定“项目 MIME 类型值”中列出的图像 MIME 类型之一。主项目的长度可以通过从文件容器开头解析主图像的 MIME 类型来确定。

第一个媒体项目可以包含一个 Padding 属性,指定编码后的主图像末尾与下一个媒体项目开头之间的额外填充。只有第一个媒体项目可以包含 Padding 属性。

每个媒体项目必须包含一个 Mime 属性。辅助媒体项目也必须包含 Length 属性。

连续媒体项目可以在文件容器中共享资源数据。第一个媒体项目确定资源在文件容器中的位置,如果资源数据本身是一个容器,则后续共享媒体项目的 Length 设置为 0。

容器中媒体项目资源的位置是通过将前面辅助项目资源的 Length 值与主图像编码的长度加上(如果指定了)Padding 值相加来确定的。

属性名称

类型

描述

Mime

字符串

必需。一个简单字符串,指示容器中媒体项目的 MIME 类型。

语义

字符串

必需。一个简单字符串,指示媒体项目的应用特定含义。请参阅“项目语义值”部分了解定义。

长度

整数

辅助媒体项目(包括视频容器)必需。项目的正整数长度(以字节为单位)。媒体项目应以其原始形式存在,未应用任何编码。长度值是文件中字节的实际长度。

辅助媒体项目中的长度 0 表示媒体项目资源与上一个媒体项目共享。主媒体项目中的长度预计为 0。

填充

整数

[基于 JPEG 的运动照片]

主媒体项目可选。简单字符串,包含编码主图像末尾与下一个媒体项目开头之间的额外填充的正整数长度(以字节为单位)。

[基于 HEIC/AVIF 的运动照片]

主媒体项目必需。值必须等于 8,即 运动照片视频数据 (“mpvd”) 框的标头长度。

项目:Mime 类型值

Item:Mime 属性定义了每个媒体项目的 MIME 类型。

描述

image/jpeg

JPEG 图像

image/heic

HEIC 图像

image/avif

AVIF 图像

video/mp4

MP4 容器

video/quicktime

MOV 容器

项目:语义值

Item:Semantic 属性定义了容器目录中每个媒体项目的应用特定含义。

描述

指示媒体项目是容器中主要的显示就绪图像。运动照片必须包含一个且仅一个具有此语义的项目。

MotionPhoto

指示媒体项目是视频容器。运动照片必须包含一个且仅一个具有此语义的项目。此媒体项目的位置必须在文件的末尾。在此媒体项目的字节终止后,不得放置其他字节。

包含主 Ultra HDR 图像的运动照片

根据本规范和Ultra HDR 图像规范中定义的项目语义值规则,包含主 Ultra HDR 图像的运动照片还必须包含一个具有 "GainMap" 项目语义的媒体项目。此外,编码运动照片的写入方必须将增益图项目元素放置在视频项目元素之前。

ISOBMFF 图像特定行为

包含 ISOBMFF 图像(例如 HEIC 和 AVIF 图像)的运动照片必须具有一种结构,使得文件的图像部分以顶级“运动照片视频数据”框终止,该框使用 ISO/IEC 14496-1:2010(E) 第 8 条中定义的语法描述语言的语义进行描述

// Box as defined in ISO/IEC 14496-12:2015: 4.2
aligned(8) class MotionPhotoVideoData extends Box('mpvd') {
  bit(8) data[];
}

其中“data”字段包含所有视频字节。“0”的特殊值不允许作为运动照片视频数据框的大小。(请参阅 ISO/IEC 14496-12:2015: 4.2 以了解扩展 Box 的类大小的定义。)

ISOBMFF 图像的 XMP 还必须定义主媒体项目的 Padding 属性值,使其等于运动照片视频数据框标头(即大小和名称标头)的字节大小。

请参阅图 1,其中说明了示例 HEIC 运动照片的此框结构

Line diagram demonstrating the arrangement of elements in an HEIC motion file

图 1. 单个 HEIC 运动照片文件中示例 HEIC 图像的顶级框示意图。请注意,框的顺序主要仅用于说明(有关如何构建 HEIF 或视频文件,请参阅相关标准);尽管如此,“mpvd”框必须在所有 HEIC 图像文件框之后。

视频容器内容

附加到主图像的视频容器文件必须至少包含一个主视频轨道。此轨道是必需的,并且包含以 AVCHEVCAV1 编码的视频。主视频帧分辨率未定义。视频颜色空间、传输函数和位深可能有所不同。例如,SDR 视频可能具有 8 位位深、BT.709 颜色空间和 sRGB 传输函数。或者,HDR 视频可能具有 10 位位深、BT.2100 颜色空间和 HLG 或 PQ 传输函数,以及 HDR 元数据和元数据轨道。

视频容器文件可以包含一个可选的更高分辨率的辅助视频轨道。读取方应使用其内容来显示 JPEG 或 HEIC 图像中编码的主静态图像的替代。此轨道可能包含以 AVC、HEVC 或 AV1 编码的较低帧率视频。辅助视频帧分辨率未定义。

预期辅助视频轨道中的所有帧都应在主视频轨道中具有相应的帧。主视频轨道和辅助视频轨道中每对相应的帧应具有相同的演示时间戳。如果存在没有相应主视频帧的辅助轨道帧,观看者可以尝试选择一个具有最接近匹配演示时间戳的主轨道帧作为该辅助视频轨道的代表性缩略图。

视频容器文件可以包含一个可选的 16 位单声道或立体声音频轨道,编码为 AAC,采样率分别为 44kHz、48 kHz 或 96 kHz。当主视频轨道显示时,读取方应呈现此音频轨道。

辅助视频轨道(如果存在)应始终在主视频轨道之后。关于其他轨道没有其他排序限制。主视频轨道必须具有低于任何辅助视频轨道的轨道索引。也就是说,如果主视频轨道的轨道号为 2,则任何辅助视频轨道的轨道号必须大于或等于 3。

带机器学习评分的视频元数据轨道

写入方可以选择性地向视频容器文件添加一个类型为“meta”的元数据轨道。该元数据轨道应仅包含一个样本,其中包含“语法”中描述的格式的字节流。

如果元数据轨道存在,则该轨道的样本描述表条目(即,相对于“trak”框位于“mdia.minf.stbl.stsd”处的“stsd”框)必须包含一个单独的原子,该原子指示文本元数据样本条目(即“mett”框)。“mett”框的 MIME 类型字符串必须等于“application/motionphoto-image-meta”。

语法

如果定义了此元数据轨道,其内容必须由符合此 MotionPhotoMetadataDescriptor 规范的字节流组成,此处使用 ISO/IEC 14496-1:2010(E) 第 8 条中定义的语法描述语言的语义进行描述。

// BaseDescriptor as defined in ISO/IEC 14496-1:2010(E): 7.2.2.2
abstract aligned(8) expandable((1<<28) - 1) class BaseDescriptor
    : bit(8) tag=0 {
  // Empty. To be filled by classes extending this class.
}

// Score data for a frame.
class MotionPhotoFrameScoreDescriptor extends BaseDescriptor
    : bit(8) tag=MotionPhotoFrameScoreDescrTag {
  // The frame's score in the range [0, 1].
  float(32) score;

  // The frame's presentation timestamp in microseconds.
  int(64) presentationTimestampUs;
}

// Score data for a track.
class MotionPhotoTrackScoreDescriptor extends BaseDescriptor
    : bit(8) tag=MotionPhotoTrackScoreDescrTag {
  // The number of scored frames in the track.
  unsigned int(32) numScoredFrames;

  // The track's frames' score data. They must be in ascending order with
  // respect to the presentation timestamp.
  MotionPhotoFrameScoreDescriptor trackFrameScoreDescr[numScoredHighResFrames];
}

// Score data for a motion photo.
class MotionPhotoScoreDescriptor extends BaseDescriptor
    : bit(8) tag=MotionPhotoScoreDescrTag {

  // Machine-intelligence model version used to calculate the scores. Writers
  // using a scoring model should set this field to 1 or greater. Writers not
  // using any scoring model should set this field to 0.
  unsigned int(32) modelVersion;

  // The primary image's frame score data.
  MotionPhotoFrameScoreDescriptor primaryImageFrameScoreDescr;

  // The high-resolution motion photo frames' score data.
  MotionPhotoTrackScoreDescriptor highResTrackScoreDescr;
}

// Flag data for a track.
class MotionPhotoTrackFlagsDescriptor extends BaseDescriptor
    : bit(8) tag=MotionPhotoTrackFlagDescrTag {
  // Set to true to indicate the video frames have been stabilized and don't
  // require readers of the track to apply any further stabilization.
  bit(1) isStabilized;
}

// Flags for a motion photo.
class MotionPhotoFlagsDescriptor extends BaseDescriptor
        : bit(8) tag=MotionPhotoFlagDescrTag {
  // The low-resolution motion photo track's flag data.
  MotionPhotoTrackFlagDescriptor lowResTrackFlagsDescr;

  // The high-resolution motion photo track's flag data.
  MotionPhotoTrackFlagDescriptor highResTrackFlagsDescr;
}

// Container for motion photo metadata, like stabilization indicators and
// quality scoring.
class MotionPhotoMetadataDescriptor extends BaseDescriptor
    : bit(8) tag=MotionPhotoMetadataDescrTag {
  // Scoring data for the still and high-res frames.
  MotionPhotoScoreDescriptor motionPhotoScoreDescr;

  // Flags for the low-res and high-res frames.
  MotionPhotoFlagDescriptor motionPhotoFlagDescr;
}

// Class tags for MotionPhotoData using the "User Private" tag space 0xC0-0xFE
// for descriptors defined in ISO/IEC 14496-1:2010(E): 7.2.2.1, Table 1.
// 0xC0 MotionPhotoMetadataDescrTag
// 0xC1 MotionPhotoScoreDescrTag
// 0xC2 MotionPhotoTrackScoreDescrTag
// 0xC3 MotionPhotoFrameScoreDescrTag
// 0xC4 MotionPhotoFlagsDescrTag
// 0xC5 MotionPhotoTrackFlagDescrTag