动态照片格式 1.0

动态照片是指同时包含静态照片图像和包含录音的短视频的单个文件。此类媒体可让用户查看高分辨率的静态图片以及视频和声音,以捕捉图片拍摄时的情感和氛围。

依赖项

以下是本规范的规范性参考资料:

简介

本文档按照 RFC2119 中定义的 IETF 标准使用“必须”“不得”“必需”“应”“不应”“建议”“可以”和“可选”字样。

动态照片格式

动态照片文件由一个主要静态图片文件、JPEGHEICAVIF 组成,并附加一个次要视频文件。主图片包含 Camera XMP 元数据(描述如何显示静态图片文件和视频文件内容),以及 Container XMP 元数据(描述如何找到视频文件内容)。

Ultra HDR JPEG 一样,图片文件可能具有增益图。

文件名模式

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

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

如果未遵循该格式,阅读器可能会忽略 XMP 元数据、附加的视频文件或视频内容。

媒体数据编码

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

XMP 属性

两组 XMP 元数据用于定义动态照片格式的额外语义信息。元数据可以按任意顺序显示。

相机元数据

相机元数据对有关如何呈现动态照片主图片和视频部分的信息进行编码。

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

以下属性可能会显示在静态图片文件 XMP 元数据中:

名称

类型

说明

Camera:MicroVideo

Camera:MicroVideoVersion

Camera:MicroVideoOffset

Camera:MicroVideoPresentation
TimestampUs

这些属性是微视频 V1 规范的一部分。它们已从此规范中删除,如果存在,必须忽略。

具体而言,MicroVideoOffset 属性已替换为 GContainer:ItemLength 值,用于在文件中定位视频数据。

Camera:MotionPhoto

Integer

0:表示不应将文件视为动态照片。

1:表示应将文件视为动态照片。

所有其他值均未定义,视为 0。

如果值为零或负数,则即使文件实际上附加了视频,系统也始终会将文件视为非动态照片。

大多数主流编辑器都支持 XMP,即使附加的视频已删除,静态图片文件的这个字段仍然可能是残差值 1。因此,此字段不是确定性的,读者必须始终确认视频是否存在。

Camera:MotionPhotoVersion

Integer

表示动态照片的文件格式版本。本规范定义的版本为“1”。

Camera:MotionPhotoPresentationTimestampUs

Long

Long 值表示与静态图片对应的视频帧的呈现时间戳(以微秒为单位)。值可以设为 -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

目录只能包含一个主图片内容,且该内容必须是目录中的第一项。

元素名称

类型

说明

Directory

有序结构数组

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

商品元素

媒体内容元素说明应用应如何使用每项内容。

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

第一项媒体内容必须是主图片。且该项内容必须包含一个 Mime 属性,用于指定内容 MIME 类型值中列出的某个图片 MIME 类型。主图片的长度可通过解析主图片(从文件容器开头开始)的 MIME 类型来确定。

第一项媒体内容可以包含 Padding 属性,用于指定已编码主图片结尾与下一项媒体内容开头之间的额外间距。只有第一项媒体内容可以包含 Padding 属性。

每项媒体内容必须包含 Mime 属性。次要媒体内容还必须包含长度属性。

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

媒体内容资源在容器中的位置为:将前面的次要内容资源的 Length 值、主图片编码长度加上 Padding(如果指定)相加。

属性名

类型

说明

Mime

String

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

Semantic

String

必需。用于指示媒体内容对于应用的特定含义的简单字符串。有关定义,请参阅“内容语义值”部分。

Length

Integer

次要媒体内容(包括视频容器)必须填写。内容的长度(以正整数显示,以字节为单位)。媒体内容应以原始形式显示,不会应用任何编码。长度值是文件中字节的实际长度。

次要媒体内容的长度为 0 表示与前一项媒体内容共享媒体内容资源。主媒体内容的长度应为 0。

Padding

Integer

[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 属性定义容器目录中每项媒体内容对于应用的特定含义。

Value

说明

Primary

表示媒体内容是容器中的主显示图片。动态照片必须包含(且只能有一个)具有此语义的内容。

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”。(如需了解扩展 Box 的类大小的定义,请参阅 ISO/IEC 14496-12:2015: 4.2。)

ISOBMFF 图片的 XMP 还必须将主媒体内容的内边距属性值定义为等于动态照片视频数据框标头(即大小和名称标头)的大小(以字节为单位)。

请参考图 1,其中展示了 HEIC 基于动态照片的示例此框结构:

展示 HEIC 动态文件中元素排列方式的折线图

图 1. 单个 HEIC 动态照片文件中 HEIC 图片示例的顶级框的插图。请注意,这些框的顺序主要仅供参考(请参阅有关如何构建 HEIF 或视频文件的相关标准);不过,“mpvd”框必须位于所有 HEIC 图片文件的框之后。

视频容器内容

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

视频容器文件可能包含一个可选的分辨率更高的辅助视频轨道。读者应使用其内容显示以 JPEG 编码的主要静态图片或 HEIC 图片的主要静态图片的替换图片。该轨道可能包含以 AVC、HEVC 或 AV1 编码的较低帧速率的视频。次要视频帧分辨率尚未定义。

预计次要视频轨道中的所有帧在主视频轨道中都有对应的帧。主视频轨道和次要视频轨道中每对对应的帧应具有相同的呈现时间戳。如果次要轨道帧没有对应的主轨道帧,观看者可以尝试选择具有最接近匹配呈现时间戳的主轨道帧,作为该次要视频轨道的代表性缩略图。

视频容器文件可能包含一个以 AAC 编码的可选 16 位 44kHz、48kHz 或 96kHz 单声道或立体声音轨。在显示主视频轨道时,读者应呈现此音轨。

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

具有机器智能评分功能的视频元数据跟踪

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

如果存在元数据轨道,则轨道的样本描述表条目(即相对于“trak”框位于“mdia.minf.stbl.stsd”处的“stsd”框)必须包含表示文本元数据样本条目(即“mett”框)的单个 Atom。“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