Motion Photo 格式 1.0

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

依赖项

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

简介

“必须”、“禁止”、“必需”、“应该”、“不应该”、“推荐”、“可以”和“可选”的使用符合IETF标准,该标准在RFC2119中定义。

动态照片格式

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

图像文件可能具有增益映射,就像超高清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",则相同的值必须出现在该轨道的primaryImageFrameScoreDescr presentationTimestampUs字段中。如果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,则加上Padding)来确定的。

属性名称

类型

描述

Mime

字符串

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

语义

字符串

必需。简单的字符串,指示媒体项的应用程序特定含义。有关定义,请参见“媒体项语义值”部分。

长度

整数

对于次要媒体项(包括视频容器)是必需的。项的字节长度(正整数)。媒体项应为其原始形式,不应用任何编码。长度值是文件中字节的实际长度。

次要媒体项中的长度为0表示媒体项资源与前一个媒体项共享。在主媒体项中,长度应为0。

填充

整数

[基于JPEG的动态照片]

对于主媒体项是可选的。简单的字符串,包含编码的主图像末尾和下一个媒体项开始之间额外填充的字节长度(正整数)。

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

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

Item:MIME类型值

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

描述

image/jpeg

JPEG图像

image/heic

HEIC图像

image/avif

AVIF图像

video/mp4

MP4容器

video/quicktime

MOV容器

Item:语义值

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

描述

主图像

指示媒体项是容器中主要的可显示图像。动态照片必须包含一个且只有一个具有此语义的项。

动态照片

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

具有主超高清图像的动态照片

根据本规范和超高清图像规范中定义的项目语义值规则,具有主超高清图像的动态照片还必须包含一个项目语义为"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[];
}

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

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位单声道或立体声音频轨道,采样率为44kHz、48 kHz或96 kHz,使用AAC编码。显示主视频轨道时,阅读器应呈现此音频轨道。

如果存在次要视频轨道,则它应始终位于主视频轨道之后。关于其他轨道的顺序没有其他约束。主视频轨道的轨道索引必须低于任何次要视频轨道的轨道索引。也就是说,如果主视频轨道的轨道号为2,则任何次要视频轨道的轨道号都必须大于或等于3。

带有机器智能评分的视频元数据轨道

编写者可以选择向视频容器文件添加类型为“meta”的元数据轨道。元数据轨道应只有一个样本,其中包含“语法”部分所述格式的字节流。

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

语法

如果定义了此元数据轨道,则其内容必须由符合此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