H.264 视频的 RTP 载荷格式

本文是 IETF 的规范 RFC 6184 的一部分的翻译,该规范 地址。翻译这份文档,主要是为了编写一段用 RTP 传输 H.264 流的代码。本想在网上找一些文章完成任务了事的,但由于个人之前音视频编解码相关的知识比较匮乏,网上找的文章大都没有办法把我的问题讲的很详细很明确,所以就找来了这份 IETF 的规范来学习。

当然翻译这份文档的另外的原因是,我认为关于软件开发某些方面的知识,最为权威、准确且可靠的来源大概就是源码、规范和官方文档了,其它的信息源,无论是博客还是书籍,都很有可能存在着误解和不准确的地方。为了让自己能够学到更加权威可靠的知识,而翻译了这份文档。

RFC 6184这份规范本身比较长,我实在是没有那么多的时间与精力把这份规范全部翻译完,于是就只是翻译了与编写用 RTP/RTCP 协议传输原始 H.264 码流的代码最为相关的几个部分。

下面的内容都翻译自 RFC 6184。

概述

这份备忘录描述了 ITU-T Recommendation H.264 视频编解码和技术的相应 ISO/IEC 国际标准 14496-10 视频编解码的 RTP 载荷格式,不包括 Scalable Video Coding (SVC) 扩展和 Multiview Video Coding 扩展,它们的 RTP 载荷格式在其它地方定义。RTP 载荷格式允许在每个 RTP 载荷中,打包一个或多个由 H.264 视频编码器产生的 Network Abstraction Layer Units (NALUs)。有效载荷格式具有广泛的适用性,它支持从简单的低比特率对话使用,到具有交错传输的因特网视频流,到高比特率视频点播的应用。

这份备忘录废弃 RFC 3984。14 小节 总结了自 RFC 3984 以来的改变。15 小节 讨论了到 RFC 3984 的向后兼容性。

1. 介绍

这份备忘录描述了称为 ITU-T Recommendation H.264 和 ISO/IEC 国际标准 14496-10 (均被称为高级视频编码 (AVC))的视频编码标准的 RTP 载荷规范。在这份备忘录中,名字 H.264 用于编解码器和标准,但是这个备忘录同样适用于编码标准的 ISO / IEC 对应物。

这份备忘录废弃 RFC 3984。14 小节 总结了自 RFC 3984 以来的改变。15 小节 讨论了到 RFC 3984 的向后兼容性。

1.1 H.264 Codec

H.264 视频编解码具有广泛的应用范围,其覆盖了所有形式的数字压缩视频,从低比特率的互联网流应用到 HDTV 广播到几乎无损编码的数字影院应用。对比当前的技术状态,H.264 的总体性能是,据报告比特率节省 50% 或更多。比如据报告,数字卫星 TV 质量,可达到 1.5 Bbit/s,对比当前操作点 MPEG-2 视频在大约 3.5 Mbit/s。

Codec 规范本身在概念上区分视频编码层 (VCL) 和网络抽象层 (NAL)。VCL 包含 codec 的信号处理功能;诸如变换,量化和运动补偿预测的机制;和环路滤波器。它遵循当今大多数视频编解码器的一般概念,这是基于宏块的编码器,一个基于宏块的编码器使用图像预测,其使用具有运动补偿的帧间预测和残差信号的变换编码。VCL 编码器输出 slices:包含整数个宏块的宏块数据的位串和 slice 头部信息(包含 slice 中第一个宏块的空间地址,初始的量化参数,及类似的信息)。Slice 中的宏块以扫描的顺序排列,除非使用 slice
组语法指定了不同的宏块分配。图像预测只被用于 slice 内。更多信息在 Introduction to the special issue on the H.264/AVC video coding standard 中提供。

NAL 编码器把 VCL 编码器的 slice 输出封装进网络抽象层单元(NALUs),其适合于通过分组网络传输,或在面向分组的多种环境下使用。H.264 的附录 B 定义了通过面向流的网络传输这样的 NALU 的封装过程。本备忘录范围内,与附录 B 无关。

在内部,NAL 使用 NAL 单元。NAL 单元由一个字节的头部和载荷字节串组成。头部说明了 NAL 单元的类型,NAL 单元载荷中(潜在地)出现的位错误或语法违规,及对于解码过程而言 NAL 单元的相对重要性的信息。本 RTP 载荷规范被设计为对 NAL 单元载荷中的位串无感知。

H.264 的一个主要属性是完全解耦 slice 和图像的传输时间,解码时间,和采样或呈现时间。H.264 中描述的解码过程对时间无意识,而且 H.264 语法不携带诸如跳过的帧数(像在更早的视频压缩标准中常见的时间参照这样的形式)这样的信息。此外,还有 NAL 单位影响许多图片,因此是本质上是没有时间的。基于采样和呈现时间没有定义,或传输时间未知这些原因,NAL 单元的 RTP 时间戳的处理需要一些特殊的考虑。

1.2 参数集概念

H.264 的一个非常基本的设计概念是生成自包含包,使得不再需要诸如 RFC 4629 的头部复制或 MPEG-4 视觉的头部扩展码 (HEC) 这样的机制。这是通过从媒体流中去除与多个 slice 相关的信息来实现的。这个更高层的 meta 信息应该能够从包含 slice 包的 RTP 包流中被可靠地异步地预先发送出去。(带内发送此信息的规定也适用于不具有为了实现此目的的适当的带外传输通道的应用)。更高层参数的结合称为参数集。H.264 规范包含两种类型的参数机:序列参数集和图像参数集。有效的序列参数集在整个编码的视频序列中保持不变,而有效的图像参数集在一个编码的图像内保持不变。序列和图像参数集结构包含了诸如图像大小,可选的所用的编码模式,和宏块到 slice 组的映射这样的信息。

为了能够修改图像参数(比如图像大小)而无需同步地传输参数集合更新给 slice 包流,编码器和解码器可以维护一个多于一个序列和图像参数集合的列表。每个 slice 头部包含一个编码字,来指示要使用的序列和图像参数集。

这种机制允许将参数集合的传输从包流的传输中解耦出来,并通过外部的方法(比如,作为能力交换的一部分)或通过一个控制协议(可靠的或不可靠的)传输它们。甚至可能不传输它们,但通过应用设计规范来固定。

1.3 网络抽象层单元类型

关于 NAL 设计的教程信息可以在 “H.264/AVC over IP”,“H.26L over IP: The IP-Network Adaptation Layer” 和 “H.26L/JVT Coding Network Abstraction Layer and IP-Based Transport” 等几份文档中找到。

所有的 NAL 单元由单个 NAL 单元类型字节组成,其共同作为该 RTP 载荷格式的载荷头部。NAL 单元载荷的描述如下。

NAL 单元类型字节的语法和语义在 ITU-T Recommendation H.264 中描述,但 NAL 单元类型字节的必要属性总结如下。NAL 单元类型字节具有如下的格式:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

NAL 单元类型字节的组件的语义,如 H.264规范所定,清晰地描述如下:

  • F:1 位
    forbidden_zero_bit。H.264 规范声明值为 1 表示语法违规。

  • NRI:2 位
    nal_ref_idc。值为 00 表示 NAL 单元的内容不被用于重建图像预测的参考图像。这种 NAL 单元可以被丢弃而不危及参考图像的完整性。大于 00 的值表示需要解码该 NAL 单元来维护参考图像的完整性。

  • Type:5 位
    nal_unit_type。这个组件指定 NAL 单元载荷的类型,如 ITU-T Recommendation H.264 的表 7-1 和本备忘录后面所定义的那样。要参考当前所有已定义 NAL 单元类型和它们的语义,请参考 ITU-T Recommendation H.264 的 7.4.1 节。

本备忘录引入了新的 NAL 单元类型,它们在 5.2 节 中说明。本备忘录中定义的 NAL 单元类型被标记为 ITU-T Recommendation H.264 中的 unspecified。此外,本规范扩展了 F 和 NRI 的语义,如 5.3 节 所述。

5. 载荷格式

5.1 RTP Header 用法

RFC 3550 中描述了 RTP Header 的格式,且为了方便在图 1 中再次展示了它。这里的载荷格式使用头部字段的方式与那份规范相同。

当一个 NALU 被封装进每个 RTP 包时,建议采用的 RTP 载荷格式在 5.6 小节 中描述。聚合包和分片单元的 RTP 载荷(及一些 RTP 头部位的设置)分别在 5.7.2 和 5.8 小节描述。

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |V=2|P|X|  CC   |M|     PT      |       sequence number         |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           timestamp                           |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |           synchronization source (SSRC) identifier            |
      +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
      |            contributing source (CSRC) identifiers             |
      |                             ....                              |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 1. RFC 3550 的 RTP 头部

根据本 RTP 载荷格式所需设置的 RTP 头部信息按如下方式设置:

  • Marker bit (M): 1 bit
    设置由 RTP 时间戳表示的访问单元的最后一个数据包,符合视频格式的 M 位的正常使用,以允许高效的播放缓冲处理。对于聚合包(STAP 和 MTAP),RTP 头部中的 marker 位 必须被设置为,就像聚合包的最后一个 NAL 单元在其自己的 RTP 包中传输那样的值。解码器可以使用这个位作为访问单元最后一个数据包的早期指示,但不得依赖此属性。
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    访问单元通常指一帧的图像数据? 对于聚合包来说,这个位的值主要依赖于聚合包中的最后一个 NALU ?
    yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
    资料性说明:携带多个 NAL 单元的聚合包只有一个 M 位与之关联。这样,如果网关将聚合包重新分包为多个包,则它无法可靠地设置那些包的 M 位。
  • 载荷类型 (PT):7 位
    对于新的数据包格式,RTP负载类型的分配不属于本文档的范围,这里不再赘述。载荷类型的分配必须通过所使用的 profile 或以动态的方式来执行。
  • 序列号 (SN):16 位
    根据 RFC 3550 设置和使用。对于单独的 NALU 和非交错的打包模式,序列号用于决定 NALU 解码的顺序。
  • 时间戳:32 位
    RTP 时间戳被设置为内容的采样时间戳。必须使用 90 kHz 始终频率。
    如果 NAL 单元没有它自己的时序属性(比如,参数集和 SEI NAL 单元),RTP 时间戳被设置为访问单元的主编码图像,其中包含了 NAL 单元,的 RTP 时间戳,根据 ITU-T Recommendation H.264 的 7.4.1.2 节。
    MTAPs 的 RTP 时间戳的设置在 5.7.2 小节 定义。
    接收者应该忽略只包含一个显示时间戳的访问单元中包含的任何图像时序 SEI 消息。相反,接收者应该使用 RTP 时序来同步显示过程。
    如果一个访问单元在图像时序 SEI 消息中携带了多个显示时间戳,则 SEI 消息中的信息应当被视为 RTP 时间戳的相对时间来处理,其中最早的事件发生在 RTP 时间戳给出的时间,其它事件随后发生,由图像时序 SEI 消息中携带的图像时间值的差给出。
    令 tSEI1,tSEI2,. . .,tSEIn 为访问单元的 SEI 消息中携带的显示时间戳,其中 tSEI1 为所有这些时间戳中最早的一个。令 tmadjst() 为将 SEI 消息时间调整为一个 90 kHz 时间的函数。令 TS 为 RTP 时间戳。则与 tSEI1 关联的事件的显示时间为 TS。tSEIx 的事件的显示时间为,其中 x 为 [2..n],是 TS + tmadjst (tSEIx - tSEI1)。
    资料性说明:称为 3:2 下拉的操作中通常需要将编码的帧显示为字段,其中由编码帧组成的胶片内容使用隔行扫描显示在显示器上。图片时序 SEI 消息能够为相同的编码图像携带多个时间戳,因此 3:2 下拉过程被完全地控制。图像定时
    SEI 消息机制是必要的,因为 RTP 时间戳只能为每个编码帧传送一个时间戳。

5.2 载荷结构

有效载荷格式定义三种不同的基本载荷结构。接收者可以通过 RTP 包载荷的第一个字节识别载荷结构,其共同用作 RTP 有效载荷报头,在某些情况下,作为载荷的第一个字节。这个字节总是被构造为 NAL 单元头。NAL 单元类型字段表示是哪种结构。可能的结构如下。

单个 NAL 单元包:载荷中包含一个单独的 NAL 单元。NAL 头部类型等于原始的 NAL 单元类型,比如,范围在 1 到 23 ,包括 23。在 5.6 小节 中描述。

聚合包:用于将多个 NAL 单元聚合为一个单独的 RTP 载荷的包类型。这个包有四个版本,单时间聚合包类型 A (STAP-A),单时间聚合包类型 B (STAP-B),16 位偏移多时间聚合包 (MTAP) (MTAP16),和 24 位偏移多时间聚合包 (MTAP) (MTAP24)。为 STAP-A,STAP-B,MTAP16 和 MTAP24 分配的数字值分别为 24,25,26,和 27。在 5.7 小节 中描述。

分片单元:用于将一个单独的 NAL 单元分割为多个 RTP 包。有两个版本,FU-A 和 FU-B,分别由 NAL 单元类型数字 28 和 29 标识。在 5.8 小节 中描述。

资料性说明:本规范不限制在单个 NAL 单元包中封装的 NAL 单元和分片单元的大小。在任何聚合包中封装的 NAL 单元的最大大小为 65535 字节。

表 1 总结了当这些 NAL 单元直接被用作一个包载荷时,NAL 单元类型和对应的 RTP 包类型,以及本备忘录中描述这些类型的章节。

表 1. NAL 单元类型和对应的包类型总结

      NAL Unit  Packet    Packet Type Name               Section
      Type      Type
      -------------------------------------------------------------
      0        reserved                                     -
      1-23     NAL unit  Single NAL unit packet             5.6
      24       STAP-A    Single-time aggregation packet     5.7.1
      25       STAP-B    Single-time aggregation packet     5.7.1
      26       MTAP16    Multi-time aggregation packet      5.7.2
      27       MTAP24    Multi-time aggregation packet      5.7.2
      28       FU-A      Fragmentation unit                 5.8
      29       FU-B      Fragmentation unit                 5.8
      30-31    reserved                                     -

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
聚合包中的单时间聚合包中,多个 NAL 单元的存储结构是什么样的?NAL 单元间是否需要 NAL 单元分割序列 0x00000001?
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

5.3 NAL 单元头部使用

NAL 单元头部的结构和语义在 1.3 节 中介绍。为了方便,NAL 单元头部的格式重新显示如下:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

本节根据本规范描述了 F 和 NRI 的语义。

  • F:1 位
    forbidden_zero_bit。值为 0,表示 NAL 单元型八位位组和有效载荷不应包含位错误或其他语法违规。值为 1 表示 NAL 单元类型八位位组可能包含位错误或其它语法违规。
    MANEs 应该设置 F 位来表示在 NAL 单元中探测到位错误。H.264 规范要求 F 位等于 0。当设置了 F 位时,则告诉解码器 NAL 单元类型八位位组中或载荷中可能存在位错误或其它语法违规。最简单的解码器对 F 位等于 1 的 NAL 单元的响应为,丢弃这个 NAL 单元并隐藏丢弃的 NAL 单元中丢失的数据。
  • NRI:2 位
    nal_ref_idc。00 和非零值的语义与 H.264 规范中的保持不变。换句话说,00 值表示 NAL 单元的内容不用于重建用于帧间预测的参考图像。这样 NAL 单元可以被丢弃而不危及参考图像的完整性。大于 00 的值表示,为了维护参考图像的完整性,需要解码 NAL 单元。
    除了上面的规范,根据本 RTP 载荷规范,NRI 的值表示由编码器决定的相对的传输优先级。MANEs 可以使用这个信息,相对于不那么重要的 NAL 单元,更好地保护更重要的 NAL 单元。最高的传输优先级为 11,后面是 10,然后是 01;最后,00 最低。
    资料性说明:在 H.264 解码器中,以同样的方式处理 NRI 的任何非零值。因此,当接收者传递 NAL 单元给解码器时,不需要管理 NRI 值。
    当 nal_unit_type 的值在 1 到 12 (包括)范围内时,H.264 编码器必须根据 H.264 规范(7.4.1 单元)设置 NRI 的值。特别的,H.264 规范要求,对于所有 nal_unit_type 等于 6,9,10,11,或 12 的 NAL 单元,NRI 的值应该等于 0。
    对于 nal_unit_type 等于 7 或 8(分别表示序列参数集或图像参数集)的 NAL 单元,H.264 编码器应该把 NRI 的值设置为 11(二进制格式)。对于主编码图像的编码的 slice NAL 单元,其 nal_unit_type 等于 5(表示一个编码的 slice 属于 IDR 图像),H.264 编码器应该把 NRI 的值设置为 11(二进制格式)。
    其余的 nal_unit_types 到 NRI 值的映射,可以使用以下示例,并且已经被证明在某一环境中是有效的。其他映射也可能是可取的,具体取决于应用程序和使用的 H.264 配置文件。
    资料性说明:数据分区在某些配置中是不可用的,比如在 Main 和 Baseline 配置中。因此,NAL 单元类型 2,3,和 4 只发生在允许数据分区的视频比特流配置中,而不在符合 Main 或 Baseline 配置的流中。
    表 2. 主编码参考图像的编码 slice 和 编码 slice 数据分区的 NRI 值示例
       NAL Unit Type     Content of NAL Unit              NRI (binary)
       ----------------------------------------------------------------
        1              non-IDR coded slice                         10
        2              Coded slice data partition A                10
        3              Coded slice data partition B                01
        4              Coded slice data partition C                01

资料性说明:如前面提到的,H.264 强制非参考图像的 NRI 值为 00。
H.264 编码器应该设置冗余的编码参考图像的编码 slice 和 编码 slice 数据分区 NAL 单元的 NRI 的值为 01 (二进制格式)。
NAL 单元类型 24 到 29(包含)的 NRI 值的定义,在本备忘录的 5.7 和 5.8 节中给出。
nal_unit_type 在范围 13 到 23 (包含)内的 NAL 单元的 NRI 值没有建议值,因为这些值为 ITU-T 和 ISO/IEC 所保留。nal_unit_type 等于 0 或在范围 30 到 31 (包含)的 NAL 单元的 NRI 值也没有建议值,因为这些值的语义不在本备忘录中描述。

5.4 打包模式

本备忘录描述打包模式的三种情况:

  • 单 NAL 单元模式
  • 非交错模式
  • 交错模式

单 NAL 单元模式针对符合 ITU-T Recommendation H.241 的会话系统(参考 12.1 节)。非交错模式针对不符合 ITU-T Recommendation H.241 的会话系统。在非交错模式中,NAL 单元以 NAL 单元解码的顺序传输。交错模式针对不需要很低的端到端延迟的系统。交错模式允许不以 NAL 单元解码的顺序传输。

使用的打包模式可以通过可选的 packetization-mode 媒体类型参数的值来通知。所用的打包模式管理在 RTP 载荷中允许哪些 NAL 单元类型。表 3 总结了每种打包模式允许的包载荷类型。第 6 节 更详细地解释了打包模式。

表 3. 每种打包模式允许的 NAL 单元类型总结 (yes = allowed, no = disallowed, ig = ignore)

      Payload Packet    Single NAL    Non-Interleaved    Interleaved
      Type    Type      Unit Mode           Mode             Mode
      -------------------------------------------------------------
      0      reserved      ig               ig               ig
      1-23   NAL unit     yes              yes               no
      24     STAP-A        no              yes               no
      25     STAP-B        no               no              yes
      26     MTAP16        no               no              yes
      27     MTAP24        no               no              yes
      28     FU-A          no              yes              yes
      29     FU-B          no               no              yes
      30-31  reserved      ig               ig               ig

一些 NAL 单元或载荷类型值(如 表 3 中的 reserved 所示)被保留,以用于未来扩展。发送者不应该发送那些类型的 NAL 单元(直接作为包载荷,作为聚合包中的聚合单元,或作为 FU 包中的分片),且接收者必须忽略它们。比如,载荷类型 1-23,具有关联的包类型 "NAL unit",它可以出现在 "Single NAL Unit Mode" 和 "Non-Interleaved Mode" 中,但不能出现在 "Interleaved Mode" 中。然而,NAL 单元类型 1-23 的 NAL 单元可被用于 "Interleaved Mode",作为 STAP-B,MTAP16,和 MTAP24 包中的聚合单元,也可以作为 FU-A 和 FU-B 包中的分片单元。类似地,NAL 单元类型 1-23 的 NAL 单元也可被用于 "Non-Interleaved Mode" 作为 STAP-A 包中的聚合单元或 FU-A 包中的分片单元,除了直接被用作包载荷。

5.5 解码顺序号(DON)

在交错打包模式下,NAL 单元的传输顺序允许和其解码顺序不同。解码顺序号(DON)是载荷结构中表示 NAL 单元解码顺序的一个字段或一个派生变量。传输顺序与解码顺序不同的用例的基本原理和实例,以及 DON 的使用在 13 小节 给出。

传输和解码顺序的耦合由可选的 sprop-interleaving-depth 媒体类型参数控制如下。当可选的 sprop-interleaving-depth 媒体类型参数的值为 0 时(明确地或默认的),NAL 单元的传输顺序必须与 NAL 单元的解码顺序一致。当可选的 sprop-interleaving-depth 媒体类型参数的值大于 0 时:

  • MTAP16 和 MTAP24 中的 NAL 单元顺序不需要是 NAL 单元解码的顺序,且
  • 由解包两个连续的包中的 STAP-Bs,MTAPs,和 FUs 产生的 NAL 单元的顺序不需要是 NAL 单元解码的顺序。

单 NAL 单元包的 RTP 载荷结构,一个 STAP-A 或一个 FU-A 不包含 DON。STAP-B 和 FU-B 结构包含 DON,MTAPs 的结构允许 DON 的继承,如 5.7.2 小节 所述。

资料性说明:当 FU-A 出现在交错模式中时,它总是跟在 FU-B 后面,后者设置它自己的 DON。

资料性说明:如果发送端想要每个包封装一个 NAL 单元并以非解码顺序传输包,则可以使用 STAP-B 包类型。

在单 NAL 单元打包模式中,NAL 单元的传输顺序,由 RTP 序列号决定,必须与它们的 NAL 单元解码顺序相同。在非交错打包模式中,单 NAL 单元包中的 NAL 单元的传输顺序, STAP-As,和 FU-As 必须与它们的 NAL 单元解码顺序相同。STAP 内的 NAL 单元必须以它们解码的顺序出现。这样,首先通过 STAP 内的顺序明确地提供解码顺序,然后通过 STAPs,FUs 和单 NAL 单元包之间的顺序的 RTP 序列号提供。

STAP-B,MTAP,和一系列以 FU-B 开头的分片单元中携带的 NAL 单元的 DON 值的信令分别在 5.7.1,5.7.2 和 5.8 节中描述。传输顺序中第一个 NAL 单元的 DON 值可以被设置为任何值。DON 值的范围为 0 到 65535(包含)。在达到最大值之后,DON 的值环绕到 0。

任何 STAP-B,MTAP,和一系列以 FU-B 开头的分片单元中包含的两个 NAL 单元的解码顺序按如下方式决定。令 DON(i) 为传输序列中索引为 i 的 NAL 单元的解码顺序号。函数 don_diff(m,n) 描述如下:


      If DON(m) == DON(n), don_diff(m,n) = 0

      If (DON(m) < DON(n) and DON(n) - DON(m) < 32768),
      don_diff(m,n) = DON(n) - DON(m)

      If (DON(m) > DON(n) and DON(m) - DON(n) >= 32768),
      don_diff(m,n) = 65536 - DON(m) + DON(n)

      If (DON(m) < DON(n) and DON(n) - DON(m) >= 32768),
      don_diff(m,n) = - (DON(m) + 65536 - DON(n))

      If (DON(m) > DON(n) and DON(m) - DON(n) < 32768),
      don_diff(m,n) = - (DON(m) - DON(n))

正的 don_diff(m,n) 值表示发送顺序索引为 n 的 NAL 单元,其解码顺序在传输顺序索引为 m 的 NAL单元之后。当 don_diff(m,n) 等于 0 时,两个 NAL 单元的 NAL 单元解码顺序可以为任意顺序。负的 don_diff(m,n) 值表示发送顺序索引为 n 的 NAL 单元,其解码顺序在传输顺序索引为 m 的 NAL单元之前。

DON 相关字段(DON,DONB,和 DOND;参考 5.7 节)的值必须使得由上述 DON 值决定的解码顺序符合 NAL 单元解码顺序。

如果 NAL 单元解码顺序中的两个 NAL 单元顺序切换,且新的顺序与 NAL 单元解码顺序不一致,则 NAL 单元必须不具有相同的 DON。如果 NAL 单元流中两个连续 NAL 单元的顺序被交换,且新的顺序依然符合 NAL 单元解码顺序,则 NAL 单元可以具有相同的 DON 值。比如,所用的视频编码配置允许任意的编码 slice 顺序,编码图片的所有编码 slice NAL 单元允许具有相同的 DON。因此,具有相同 DON 值的 NAL 单元可以以任意顺序解码,而具有不同 DON 值的两个 NAL 单元应该以上面描述的顺序传给解码器。当 NAL 单元解码顺序中的两个连续 NAL 单元具有不同的 DON 值时,解码顺序中第二个 NAL 单元的 DON 值应该是第一个的 DON 值加一。

解包过程恢复 NAL 单元解码顺序的示例在 第 7 节 中描述。

资料性说明:接收者不应该期待 NAL 单元解码顺序中两个连续 NAL 单元的 DON 值的绝对差值等于 1,即使是在可靠传输中。在将 DON 值与 NAL 单元关联时,不要求递增 1,可能不知道所有NAL单元是否被传送到接收器。比如,当分组转发到的网络中存在缺少比特率时,网关可能不转发非参考图像或 SEI NAL 单元的编码 slice NAL 单元 。在另一个例子中,实况广播由预编码的内容(例如商业广告)不时地中断。预先编码剪辑的第一帧图像被预先发送,以确保其在接收机中容易获得。当传输第一帧图像时,在解码顺序中后面的预编码裁剪的第一帧图像之前,发起端不能精确地知道将编码多少 NAL 单元。这样,预编码裁剪的第一帧图像的 NAL 单元的DON 的值必须在它们被传输时评估,则 DON 值的 gaps 可能出现。

5.6 单 NAL 单元包

这里定义的单 NAL 单元包必须只包含一个 ITU-T Recommendation H.264 中定义的类型的 NAL 单元。这意味着聚合包或分片单元都不能用在单 NAL 单元包中。通过以
RTP 序列号顺序对单 NAL 单元包进行解包组合的 NAL 单元流必须符合 NAL 单元解码顺序。单 NAL 单元包的结构如图 2 所示。

资料性说明:NAL 单元的第一个字节共同作为 RTP 载荷头。


     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |F|NRI|  Type   |                                               |
    +-+-+-+-+-+-+-+-+                                               |
    |                                                               |
    |               Bytes 2..n of a single NAL unit                 |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 2. 单 NAL 单元包的 RTP 载荷格式

5.7 聚合包

聚合包是这份载荷规范的 NAL 单元聚合方案。引入该方案以反映两个关键目标网络的显着不同的MTU大小:有线 IP 网络(具有常常由以太网 MTU 大小限制的 MTU 大小,大约 1500 字节)和基于 IP 或非基于 IP(比如,ITU-T H.324/M)的无线通信系统,其优选传输单元为 254 字节或更少。为了防止两个世界间的媒体传输编码,并避免不必要的分组化开销,引入了 NAL 单元聚合方案。

本规范定义了两种聚合包类型:

  • 单时间聚合包(STAP):聚合具有相同 NALU 时间的 NAL 单元。定义两种 STAPs 类型,一个没有 DON(STAP-A),另一个包含 DON(STAP-B)。
  • 多时间聚合包(MTAP):聚合具有潜在不同 NALU 时间的 NAL 单元。定义了两个不同的 MTAPs,其 NAL 单元的时间戳偏移的长度不同。

聚合包中携带的每个 NAL 单元被封装在一个聚合单元中。请参考下文来了解四种不同的聚合单元及其特性。

聚合包的 RTP 载荷格式结构如图 3 所示。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |F|NRI|  Type   |                                               |
    +-+-+-+-+-+-+-+-+                                               |
    |                                                               |
    |             one or more aggregation units                     |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 3. 聚合包的 RTP 载荷格式

MTAPs 和 STAPs 共享如下的打包规则:

  • RTP 时间戳必须被设置为被聚合的所有 NAL 单元中 NALU 时间最早的那个。
  • NAL 单元类型八位位组的类型字段必须被设置为适当的值,如表 4 所示。
  • 如果被聚合的所有 NAL 单元的 F 位为 0,则 F 位必须被清除;否则,它必须被设置。
  • NRI 值必须是聚合包中携带的所有 NAL 单元的最大值。

表 4. STAPs 和 MTAPs 的字段类型

                 Table 4.  Type field for STAPs and MTAPs

      Type   Packet    Timestamp offset   DON-related fields
                       field length       (DON, DONB, DOND)
                       (in bits)          present
      --------------------------------------------------------
      24     STAP-A       0                 no
      25     STAP-B       0                 yes
      26     MTAP16      16                 yes
      27     MTAP24      24                 yes

RTP 头部中的 marker 位的值被设置为,就像聚合包的最后一个 NAL 单元在其自己的 RTP 包中传输时它的 marker 位一样的值。

聚合包的载荷由一个或多个聚合单元组成。参考 5.7.1 和 5.7.2 节来了解四种不同类型的聚合单元。聚合包可以根据需要携带尽可能多的聚合单元;然而,聚合包中总的数据量明显地必须刚好放入一个 IP 包中,选择的大小应该让最终的 IP 包大小小于 MTU 大小。聚合包必须不包含分片单元,如 5.8 节 所述。聚合包必须不嵌套;即,聚合包必须不包含另一个聚合包。

5.7.1 单时间聚合包(STAP)

所有要聚合的 NAL 单元共享相同的 NALU 时间时应该使用单时间聚合包(STAP)。STAP-A 载荷不包含 DON,且由至少一个单时间聚合单元组成,如图 4 所示。STAP-B 载荷由一个 16 位无符号解码顺序号(DON)(以网络字节序)后跟至少一个单时间聚合单元组成,如图 5. 所示。


     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    :                                               |
    +-+-+-+-+-+-+-+-+                                               |
    |                                                               |
    |                single-time aggregation units                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 4. STAP-A 载荷格式

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    :  decoding order number (DON)  |               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
    |                                                               |
    |                single-time aggregation units                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 5. STAP-B 的 载荷格式

DON 字段描述了 STAP-B 中传输顺序的第一个 NAL 单元的 DON 值。对于 STAP-B 中的每个连续的 NAL 单元,其 DON 值等于 (STAP-B 中前一个 NAL 单元的 DON 值+ 1) % 65536,其中 '%' 表示取模操作。

单时间聚合单元由一个表示下面的 NAL 单元的字节大小(不包含这两个8位位组,但包含 NAL 单元的 NAL 单元类型八位位组)的 16 位无符号大小信息(以网络字节序),后跟 NAL 单元自身,包含它的 NAL 单元类型字节组成。单时间聚合单元是 RTP 载荷内字节对齐的,但它可能不是对齐到 32 位字边界的。图 6 展示了单时间聚合单元的结构。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    :        NAL unit size          |               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
    |                                                               |
    |                           NAL unit                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 6. 单时间聚合单元的结构

图 7 展示了一个 RTP 包的示例,其包含了一个 STAP-A。STAP 包含两个单时间聚合单元,由图中的 1 和 2 表示。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          RTP Header                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |STAP-A NAL HDR |         NALU 1 Size           | NALU 1 HDR    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         NALU 1 Data                           |
    :                                                               :
    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               | NALU 2 Size                   | NALU 2 HDR    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         NALU 2 Data                           |
    :                                                               :
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 7. 包含一个包含两个单时间聚合单元的 STAP-A 的 RTP 包示例

图 8 展示了一个 RTP 包示例,其包含一个 STAP-B。STAP 包含两个单时间聚合单元,由图中的 1 和 2 标识。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          RTP Header                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |STAP-B NAL HDR | DON                           | NALU 1 Size   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | NALU 1 Size   | NALU 1 HDR    | NALU 1 Data                   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
    :                                                               :
    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               | NALU 2 Size                   | NALU 2 HDR    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                       NALU 2 Data                             |
    :                                                               :
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 8. 包含一个包含两个单时间聚合单元的 STAP-B 的 RTP 包示例

5.7.2 多时间聚合包(MTAPs)

MTAPs 的 NAL 单元载荷由一个 16 位的无符号解码顺序号基数(DONB)(以网络字节序)和一个或多个多时间聚合单元组成,如图 9 所示。DONB 必须是 MTAP 中的 NAL 单元的 NAL 单元解码顺序号中的第一个的 DON 值。

资料性说明:NAL 单元解码顺序号的第一个 NAL 单元不一定是按封装进 MTAP 的顺序来算的第一个 NAL 单元。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    :  decoding order number base   |               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
    |                                                               |
    |                 multi-time aggregation units                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 9. MTAPs 的 NAL 单元载荷格式

本规范定义了两个不同的多时间聚合单元。它们都由后面的 NAL 单元的 16 位无符号大小信息(以网络字节序),一个 8 位无符号解码顺序号差值(DOND),和这个 NAL 单元的 n 位(以网络字节序)时间戳偏移(TS offset)组成,其中 n 可以是 16 或 24。不同 MTAP 类型(MTAP16 和 MTAP24)间的选择依赖于应用:时间戳偏移越大,MTAP 的灵活性越高,但开销也更高。

MTAP16 和 MTAP24 的多时间聚合单元的结构分别如图 10 和 11 所示。一个包内聚合单元的开始或结束位置不要求是 32 位字的边界。一个多时间聚合单元中包含的 NAL 单元的 DON 等于(DONB + DOND) % 65536,其中 % 表示取模操作。本备忘录不描述 MTAP 内的 NAL 单元如何排序,但是,在大多数情况下,应该使用 NAL 单元解码顺序。

必须将时间戳偏移字段设置为等于以下公式的值:如果 NALU 时间大于等于包的 RTP 时间戳,则时间戳偏移等于 (NAL 单元的 NALU 时间 - 包的 RTP 时间戳)。如果 NALU 时间小于包的 RTP 时间戳,则时间戳偏移等于 NALU 时间 +
(2^32 - 包的 RTP 时间戳)。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    :        NAL unit size          |      DOND     |  TS offset    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  TS offset    |                                               |
    +-+-+-+-+-+-+-+-+              NAL unit                         |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 10. MTAP16 的多时间聚合单元

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    :        NAL unit size         |      DOND     |  TS offset    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |         TS offset             |                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
    |                              NAL unit                         |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 11. MTAP24 的多时间聚合单元

对于一个 MTAP 中 “最早的” 多时间聚合单元,其时间戳偏移必须是 0。因此,MTAP 自身的 RTP 时间戳与最早的 NALU 时间一样。

资料性说明:如果包含在聚合单元中的 NAL 单元被封装在单个 NAL 单元包中,则“最早”的多时间聚合单元将是 MTAP 的所有聚合单元中具有最小扩展 RTP 时间戳的那个。扩展时间戳是具有超过32位的时间戳,并且能够对时间戳字段的环绕进行计数,因此可以在时间戳环绕时确定最小值。这个 “最早的” 聚合单元可能不是以封装进 MTAP 中的顺序来计算的第一个聚合单元。“最早的” NAL 单元不需要与 NAL 单元解码顺序的第一个 NAL 单元相同。

图 12 展示了一个 RTP 包的示例,其包含了一个 MTAP16 类型的多时间聚合包,其中包含了两个多时间聚合单元,由图中的 1 和 2 标识。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          RTP Header                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |MTAP16 NAL HDR |  decoding order number base   | NALU 1 Size   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  NALU 1 Size  |  NALU 1 DOND  |       NALU 1 TS offset        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  NALU 1 HDR   |  NALU 1 DATA                                  |
    +-+-+-+-+-+-+-+-+                                               +
    :                                                               :
    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               | NALU 2 SIZE                   |  NALU 2 DOND  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |       NALU 2 TS offset        |  NALU 2 HDR   |  NALU 2 DATA  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
    :                                                               :
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 12. 包含一个包含了两个多时间聚合单元的类型 MTAP16 的多时间聚合包的 RTP 包

图 13 展示了一个 RTP 包的示例,其包含了一个 MTAP24 类型的多时间聚合包,其中包含了两个多时间聚合单元,由图中的 1 和 2 标识。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                          RTP Header                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |MTAP24 NAL HDR |  decoding order number base   | NALU 1 Size   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  NALU 1 Size  |  NALU 1 DOND  |       NALU 1 TS offs          |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |NALU 1 TS offs |  NALU 1 HDR   |  NALU 1 DATA                  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
    :                                                               :
    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               | NALU 2 SIZE                   |  NALU 2 DOND  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |       NALU 2 TS offset                        |  NALU 2 HDR   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  NALU 2 DATA                                                  |
    :                                                               :
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 13. 包含一个包含了两个多时间聚合单元的类型 MTAP24 的多时间聚合包的 RTP 包

5.8 分片单元(FUs)

这个载荷类型允许把一个 NAL 单元分片为多个 RTP 包。在应用层做这件事,而不是依赖于更底层的分片(比如,通过 IP)具有如下这些优势:

  • 载荷格式能够通过 IPv4 网络传输可能出现在预录制视频中大于 64 kbytes 的 NAL 单元,特别是高清格式。(有一个每图片最大 slice 数的限制,其将导致每图片 NAL 单元的限制,其可能导致大的 NAL 单元)。
  • 分片机制允许将单个 NAL 单元分片,并应用 12.5 节 所述的通用的前向纠错。

分片只是为单 NAL 单元定义的,而不是为任何聚合包定义的。NAL 单元的片由一个该 NAL 单元的连续八位位组的整数组成。NAL单元的每个八位字节必须是该NAL单元的正好一个片段的一部分。相同 NAL 单元的片段必须连续顺序发送,具有升序的 RTP 序列号(被发送的相同 RTP 包流中第一个和最后一个片段间没有其它 RTP 包)。类似地,NAL 单元必须以 RTP 序列号顺序重新装好。

当 NAL 单元被分片并在分片单元(FUs)中传送时,它被称为一个分片的 NAL 单元。STAPs 和 MTAPs 必须不被分片。FUs 必须不被嵌套;即,FU 必须不包含另一个 FU。

携带一个 FU 的 RTP 包的 RTP 时间戳被设置为被分片的 NAL 单元的 NAL 时间。

图 14 展示了 FU-As 的 RTP 载荷格式。FU-A 由一个八位的分片单元指示器,一个八位的分片单元头,和一个分片单元载荷构成。


     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | FU indicator  |   FU header   |                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
    |                                                               |
    |                         FU payload                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 14. FU-A RTP 载荷格式

图 15 展示了 FU-Bs 的 RTP 载荷格式。FU-B 由一个八位的分片单元指示器,一个八位的分片单元头,一个解码顺序号(DON)(以网络字节序),和一个分片单元载荷构成。换句话说,FU-B 的结构与 FU-A 的结构相同,除了额外的 DON 字段。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | FU indicator  |   FU header   |               DON             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
    |                                                               |
    |                         FU payload                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 15. FU-B RTP 载荷格式

NAL 单元类型 FU-B 必须被用在交错打包模式中,被分片的 NAL 单元的第一个分片单元中。NAL 单元类型 FU-B 必须不被用在其它情况下。换句话说,在交错打包模式中,被分片的每个 NALU 单元具有一个 FU-B 作为第一个片段,后面是一个或多个 FU-A 片段。

FU 指示器字节具有如下的格式:

       +---------------+
       |0|1|2|3|4|5|6|7|
       +-+-+-+-+-+-+-+-+
       |F|NRI|  Type   |
       +---------------+

FU 指示器的类型字段的值 28 和 29 分别标识 FU-A 和 FU-B。F 位的使用如 5.3 节 所述。NRI 字段的值必须根据被分片的 NAL 单元中 NRI 字段的值设置。

FU 头部具有如下的格式:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+
  • S:1 位
    当被设置为 1 时,Start 位表示被分片 NAL 单元的开始。当后面的 FU 载荷不是被分片 NAL 单元载荷的开始时,Start 位被设置为 0。

  • E:1 位
    当被设置为 1 时,End 位表示被分片 NAL 单元的结束,比如,载荷的最后一个字节也是被分片的 NAL 单元的最后一个字节。当后面的 FU 载荷不是被分片的 NAL 单元的最后一个片段时,End 位被设置为0。

  • R:1 位
    Reserved 位必须等于 0,且接收者必须忽略它。

  • Type:5 位
    NAL 单元载荷类型,如 ITU-T Recommendation H.264 的表 7-1 所定义的那样。

FU-Bs 中的 DON 的值的选择如 5.5 节 所描述的那样。

资料性说明:FU-Bs 中的 DON 字段允许网关把 NAL 单元分片为 FU-Bs,而不将传入的 NAL 单元组织到 NAL 单元解码顺序。

被分片的 NAL 单元必须不在一个 FU 中传输:即,Start 位和 End 位必须不在相同的 FU 头中同时设置。

FU 载荷由被分片的 NAL 单元的载荷的片段组成,使得如果连续的 FU 的分片单元载荷被顺序连接,则可以重构分段的 NAL 单元的有载荷。被分片 NAL 单元的 NAL 单元类型字节没有包含分片单元载荷中,而是被分片 NAL 单元的 NAL 单元类型字节的的信息,由分片单元的 FU 指示器字节的 F 和 NRI 字段,以及 FU 头部的类型字段携带。FU 载荷可以具有任何数量的字节且可以是空的。

资料性说明:允许空的 FUs 减少几乎无损环境中某一类发送者的延迟。这些发送者的特征是,它们在 NALU 完全生成之前打包 NALU 片段,因此,在 NALU 大小已知之前。如果不允许零长度 NALU 片段,则发送方必须在可以发送当前片段之前,生成后面的片段的至少一位数据。由于H.264的特点,有时几个宏块占用零个位,这是不希望的,并且可以增加延迟。然而,应该仔细权衡零长度 NALU 片段的(潜在)使用,因为用于传输的附加数据包,NALU 的至少一部分丢失的风险增加了。

如果分片单元丢失了,则接收者应该丢弃以传输顺序对应于相同被分片 NAL 单元的所有后面的分片单元。

一端的接收者或 MANE 中可以聚合 NAL 单元的前面 n - 1 个片段为一个(不完整的)NAL 单元,即使那个 NAL 单元的片段 n 没有收到。在这种情况下,NAL 单元的 forbidden_zero_bit 必须被设置为 1 以表示语法违规。

6. 打包规则

打包模式在 5.2 节 介绍。对于多个打包模式通用的打包规则在 6.1 节 说明。单 NAL 单元模式,非交错模式,和交错模式的打包规则分别在 6.1,6.3,和 6.4 节说明。

6.1 通用打包规则

所有发送者 必须 执行如下的打包规则,无论使用的打包模式是什么:

  • 属于相同编码图片的编码切片 NAL 单元或编码切片数据分区 NAL 单元(它们拥有相同的 RTP 时间戳值)可以 以任何顺序发送; 然而,对于延迟敏感的系统,它们 应该 以它们原始的解码顺序发送以最小化延迟。注意解码顺序是 NAL 单元在比特流中的顺序。

  • 参数集按照第 8.4节 中给出的规则和建议进行处理。

  • 除了序列或图像参数集NAL单元之外,MANE 不得 复制任何 NAL 单元,因为该备忘录和 H.264 规范都没有提供识别重复NAL单元的方法。可以复制序列和图像参数集 NAL 单元以使其更有可能被正确接收,但任何这样的复制都不得影响任何活动序列或图像参数集的内容。复制应该在应用层执行,而不是通过复制 RTP 数据包(具有相同的序列号)。

使用非交错模式和交错模式的发送者 必须 强制执行以下打包规则:

  • 在 RTP 转换器中,MANE 可以将单个 NAL 单元包转换为一个聚合包,将聚合包转换为几个单个 NAL 单元包,或者混合这两个概念。RTP 转换器 应该 至少考虑以下参数:路径 MTU 大小,不相等的保护机制(例如,根据 RFC 5109 [18] 通过基于包的FEC,特别是对于序列和图像参数集 NAL 单元和编码切片数据分区 A NAL单元),系统的可承受延迟,以及接收器的缓冲能力。

信息性说明:根据 RFC 3550,需要 RTP 转换器处理 RTP 控制协议(RTCP)。

6.2 单 NAL 单元模式

可选 的打包模式媒体类型参数的值等于 0 或者不存在打包模式时,使用该模式。所有接收者 必须 支持这种模式。它主要用于与使用 ITU-T H.241 建议书[3] 的系统兼容的低延迟应用(见第 12.1节)。在此模式下只 使用单个 NAL 单元数据包。不得 使用 STAP,MTAP 和 FU。单 NAL 单元包的传输顺序 必须 符合 NAL 单元解码顺序。

6.3 非交错模式

可选 的打包模式媒体类型参数的值等于 1 时,使用该模式。应该 支持这种模式。它主要用于低延迟应用。在此模式下,只 使用单 NAL单元数据包,STAP-As 和 FU-As。不得 使用 STAP-B,MTAP和 FU-B。NAL 单元的传输顺序 必须 符合 NAL 单元的解码顺序。

6.3 交错模式

可选 的打包模式媒体类型参数的值等于 2 时,使用该模式。有些接收者 可能 支持这种模式。可以使用 STAP-B,MTAP,FU-As 和 FU-B。不得 使用 STAP-As 和单 NAL 单元包。数据包和 NAL 单元的传输顺序受第 5.5节 中规定的约束。

7. 解包过程

解包过程取决于实现。因此,应将以下描述视为适当的实现的例子。也可以使用其他方案,只要相同输入的输出与下面描述的过程相同即可。相同的输出意味着得到的 NA L单元及其顺序是相同的。相对于所描述的算法的优化可能是可能的。第 7.1 节 介绍了单 NAL 单元和非交错打包模式的解包过程,而第 7.2节 描述了交错模式的过程。第7.3节 包括智能接收者的附加解包指南。

适用于与缓冲区管理相关的所有正常 RTP 机制。特别地,移除复制或过期的 RTP 包(如 RTP 序列号和 RTP 时间戳所示)。为了确定解码的确切时间,必须考虑诸如可能的有意延迟以允许适当的流间同步等因素。

7.1 单 NAL 单元和非交错模式

接收者包含一个接收缓冲区以补偿传输延迟抖动。接收者把接收到的包以接收的顺序存储到接收缓冲器中。数据包以RTP 序列号的顺序解包。如果要解的包是一个单 NAL 单元包,则数据包中的 NAL 单元被直接传递给解码器。如果要解的包是一个 STAP-A,则包含 NAL 单元的数据包以它们被封装进数据包的顺序传递给解码器。对于包含单个 NAL 单元的分片的所有 FU-A 数据包,解的分片以它们发送的顺序级联起来以恢复 NAL 单元,然后传递给解码器。

信息性说明:如果解码器支持任意切片顺序,则图片的编码切片可以以任何顺序传递到解码器,而不管它们的接收和传输顺序如何。

7.2 交错模式

这些解包规则背后的一般概念是将 NAL 单元从传输顺序重新排序到NAL单元解码顺序。

接收者有一个接收缓冲区,用于补偿传输延迟抖动并将 NAL 单元从传输顺序重新排序到 NAL 单元解码顺序。在这一节中,对于接收者操作的描述,基于没有传输延迟抖动的假设。为了与同时被用于补偿传输延迟抖动的实际的接收缓冲区进行区别,本节的后面把这个接收缓冲区称为去交替缓冲区。接收者 应该 也为传输延迟抖动做准备,比如,或者为传输延迟抖动缓冲和去交替缓冲保留不同的缓冲区,或者使用一个接收缓冲区同时用于传输延迟抖动和去交替。此外,接收者 应该 在缓冲操作中考虑传输延迟抖动,例如,在开始解码和重放之前通过附加的初始缓冲。

本节的结构如下:7.2.1 小节 介绍了如何计算解交替缓冲区的大小。第 7.2.2小节 规定了如何将接收到的 NAL 单元以 NAL 单元解码的顺序进行组织的接收过程。

7.2.1 解交替缓冲区的大小

NAL 单元类型码

H.264 视频的 RTP 载荷格式_第1张图片
NAL 单元类型码

原文

你可能感兴趣的:(H.264 视频的 RTP 载荷格式)