H.264视频的RTP有效载荷格式(翻译自:RFC6184 第5节 RTP有效载荷格式)

RTP协议格式

RFC地址:https://datatracker.ietf.org/doc/html/rfc6184

RTP报头的格式在RFC3550中指定

复制代码
       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             |
      |                             ....                              |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

格式设置如下:

  • 标记位(M): 1位

对于由 RTP 时间戳指示的访问单元的最后一个数据包,按照视频格式中 M 位的常规用法设置,以便有效地处理播放缓冲区。对于聚合数据包(STAP 和 MTAP),RTP 头部中的标记位必须设置为聚合数据包中最后一个 NAL 单元的标记位的值,如果该单元单独传输在自己的 RTP 数据包中。解码器可以将此位用作访问单元最后一个数据包的早期指示,但不得依赖此特性。

说明:仅一个 M 位与携带多个 NAL 单元的聚合包相关联。因此,如果网关将聚合包重新分组为多个包,则无法可靠地设置这些包的 M 位。

  • 载荷类型(PT): 7位

    RTP 负载类型

  • 序列号(SN): 16位

按照 RFC 3550 的规定进行设置和使用。对于单个 NALU 以及非交错的分组化模式,序列号用于确定 NALU 的解码顺序

  • 时间戳(timestamp):32位

RTP时间戳设置为内容的采样时间戳,必须使用90kHz的时钟频率。

如果NAL单元本身没有自身的时序属性(例如,参数集和SEI NAL单元),则根据规定,RTP 时间戳将设置为包含该NAL单元的接入单元的主编码图像的 RTP 时间戳。

有效载荷结构

数据包格式定义了三种不同的基本数据包结构。 接收方可以通过 RTP 数据包数据部分的第一个字节来识别数据包结构,该字节同时充当 RTP 数据包头部,并且在某些情况下还作为数据包的第一个字节。这个字节总是以 NAL 单元头部的形式存在。NAL 单元类型字段表明当前存在哪种结构。可能存在的结构如下:以下便是具体内容。

  • 单个NAL单元数据包:其数据包中仅包含一个 NAL 单元。NAL 头部类型字段与原始 NAL 单元类型相同,即在 1 到 23 之间(包括这两个值)。

  • 聚合数据包:用于将多个 NAL 单元聚合为单个 RTP 压缩数据包的包类型。

    此包存在四种版本,分别是单次聚合包类型 A(STAP-A)、单次聚合包类型 B(STAP-B)、具有 16 位偏移量的多次聚合包(MTAP16)以及具有 24 位偏移量的多次聚合包(MTAP24)。STAP-A、STAP-B、MTAP16 和 MTAP24 分配的 NAL 单元类型编号分别为 24、25、26 和 27。

说明:并未对单个 NAL 单元数据包中封装的 NAL 单元以及分片单元的大小做出限制。任何聚合数据包中封装的 NAL 单元的最大尺寸为 65535 字节。

复制代码
      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                                     -

NAL单元头使用

NAL单元头格式:

复制代码
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
  • F:1位

forbidden_zero_bit。数值为 0 表示 NAL 单元类型字节和数据包不应出现位错误或其他语法违规情况。数值为 1 则表示 NAL 单元类型字节和数据包可以包含位错误或其他语法违规情况。

MANEs 应将 F 位设置为 1 以表明在 NAL 单元中检测到的比特错误。H.264 规范要求 F 位必须为 0。当 F 位被设置时,解码器会收到提示,表明在数据包或 NAL 单元类型字节中可能存在比特错误或其他语法违规情况。对于 NAL 单元中 F 位为 1 的情况,最简单的解码器反应是丢弃该 NAL 单元,并将丢失的数据隐藏在被丢弃的 NAL 单元中。

NRI:2位

nal_ref_idc。值 00 以及非零值的含义与 H.264 规范中的规定保持一致。换句话说,值为 00 表示该 NAL 单元的内容不会用于重建用于帧间预测的参考图像。此类 NAL 单元可以被丢弃,而不会危及参考图像的完整性。值大于 00 则表示需要对 NAL 单元进行解码以保持参考图像的完整性。

除了上述规定之外,根据此 RTP 压缩数据包规范,NRI 的值表示的是由编码器确定的相对传输优先级。MANE 可以利用此信息更好地保护更重要的 NAL 单元,而不会像对待不那么重要的 NAL 单元那样那样对待它们。最高的传输优先级为 11,其次是 10,然后是 01;最后,00 是最低的优先级。

说明:在 H.264 解码器中,任何非零的 NRI 值均按相同方式处理。因此,接收方在将 NAL 单元传递给解码器时无需对 NRI 的值进行任何操作。

当 nal_unit_type 的值处于 1 到 12(包括 1 和 12)的范围内时,H.264 编码器必须根据 H.264 规范来设置 NRI 的值。具体而言,H.264 规范要求,对于所有 nal_unit_type 值为 6、9、10、11 或 12 的 NAL 单元,NRI 的值都应等于 0

对于 nal_unit_type 值为 7 或 8 的 NAL 单元(分别表示序列参数集或图像参数集),H.264 编码器应将 NRI 的值设置为 11(以二进制格式表示)。对于具有 nal_unit_type 值为 5 的主编码图像的编码片 NAL 单元(表示属于 IDR 图像的编码片),H.264 编码器应将 NRI 的值设置为 11(以二进制格式表示)。

为了将剩余的 nal_unit_types 映射为 NRI 值,可以参考以下示例,该示例在特定环境中已被证明是高效的。当然,根据应用需求和所使用的 H.264 规范,可能还需要其他不同的映射方式。

说明:在某些配置文件中(例如主配置文件或基线配置文件),数据分区功能不可用。因此,NAL 单元类型 2、3 和 4 只能在允许数据分区的配置文件所对应的视频比特流中出现,而不能在主配置文件或基线配置文件所对应的比特流中出现。

复制代码
      Table 2.  Example of NRI values for coded slices and coded slice
                data partitions of primary coded reference pictures
​
       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
​
            Informative note: As mentioned before, the NRI value of non-
            reference pictures is 00 as mandated by H.264.

分包模式

包含三种打包模式:

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

单个 NAL 单元模式适用于符合 ITU-T 建议 H.241 [3](见第 12.1 节)的会话系统。非交错模式适用于那些可能不符合 ITU-T H.241 推荐标准的对话式系统。**在非交错模式下,NAL 单元会按照 NAL 单元解码顺序进行传输。**交错模式适用于那些对端到端延迟要求不十分严格的系统。该模式允许以不同于NAL单元解码顺序的方式传输NAL单元。

所采用的分组模式可通过"可选分组模式"媒体类型参数的值来指示。所使用的分组模式决定了 RTP 数据包中允许包含哪些 NAL 单元类型。表 3 概述了每种分组模式下允许的分组数据包类型。

复制代码
      Table 3.  Summary of allowed NAL unit types for each packetization
                mode (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 中所示为保留值)是为未来扩展预留的。**此类类型的 NAL 单元(无论是以直接的分组数据包形式发送,还是作为聚合包中的聚合单元发送,亦或是作为 FU 包中的分片单元发送)都不应由发送方发送,并且接收方必须忽略这些单元。**例如,编号为 1 至 23 的数据包类型(其对应的包类型为"NAL 单元")在"单个 NAL 单元模式"和"非交错模式"中是被允许使用的,但在"交错模式"中则被禁止使用。然而,编号为 1 至 23 的 NAL 单元可以作为 STAP-B、MTAP16 和 MTAP24 数据包中的聚合单元,或者在 FU-A 和 FU-B 数据包中作为分片单元使用。同样,编号为 1 至 23 的 NAL 单元也可以在"非交错模式"中作为聚合单元使用在 STAP-A 数据包中,或者在 FU-A 数据包中作为分片单元使用,此外还可以直接用作数据包的负载。

解码顺序号(DON)

在交错分组模式下,NAL 单元的传输顺序允许与 NAL 单元的解码顺序不同。解码顺序号(DON)是有效载荷结构中的一个字段或一个导出变量,用于指示 NAL 单元的解码顺序。

传输与解码顺序的耦合由"OPTIONAL sprop-interleaving-depth"媒体类型参数进行控制,具体如下: 当"OPTIONAL sprop-interleaving-depth"媒体类型参数的值等于 0(无论是明确设定的还是默认的)时,NAL 单元的传输顺序必须与NAL单元的解码顺序一致。当"sprop-interleaving-depth"媒体类型参数的值大于 0 :

  • 在 MTAP16 和 MTAP24 中,NAL 单元的排列顺序并不需要与 NAL 单元解码顺序一致。
  • 在连续两个数据包中,由解包后的 STAP-B、MTAP 和 FU 生成的 NAL 单元的顺序并不需要与 NAL 单元的解码顺序一致。

单个 NAL 单元数据包、STAP-A 和 FU-A 的 RTP 压缩数据包结构中均不包含 DON。而 STAP-B 和 FU-B 的结构包含 DON,并且 MTAP 的结构能够根据第 5.7.2 节的规定推导出 DON。

说明:在交错模式下,如果出现 FU-A,则它总是紧随其后的是 FU-B,而 FU-B 会设置其"开启"状态。

说明:如果发送方希望每个数据包中仅包含一个净荷单元,并且按照非解码顺序发送这些数据包,那么可以使用 STAP-B 数据包类型。

在单个 NAL 单元的分组模式中,由 RTP 序号确定的 NAL 单元的传输顺序必须与它们的 NAL 单元解码顺序相同。在非交错分组模式中,单个 NAL 单元包、STAP-As 和 FU-As 中的 NAL 单元的传输顺序必须与它们的 NAL 单元解码顺序相同。 STAP 内的 NAL 单元必须按照 NAL 单元解码顺序出现。因此,解码顺序首先通过 STAP 内的隐式顺序提供,然后通过 STAP、FU 和单个 NAL 单元包之间的顺序的 RTP 序号提供。

在 STAP-B、MTAP 以及一系列以 FU-B 开头的分段单元中,DON 对于 NAL 单元的值的标识分别在第 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 单元的解码顺序可以是任意的。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 值可以相同。例如,当所使用的视频编码规范允许任意的切片顺序时,一个编码图像的所有编码切片 NAL 单元都可以具有相同的 DON 值。因此,具有相同 DON 值的 NAL 单元可以以任何顺序进行解码,而具有不同 DON 值的两个 NAL 单元则应按照上述指定的顺序传递给解码器。当 NAL 单元解码顺序中的两个连续 NAL 单元具有不同的 DON 值时,解码顺序中的第二个 NAL 单元的 DON 值应为第一个 NAL 单元的 DON 值加 1。

第 7 节中给出了一个用于恢复NAL单元解码顺序的解包过程示例。

**说明:接收方不应期望在NAL单元解码顺序中,连续两个NAL单元的DON值的绝对差值会恰好等于1,即便在无误传输的情况下也是如此。增加1并不一定必要,因为在将DON值与NAL单元关联起来时,可能还不清楚所有NAL单元是否都已送达接收方。**例如,当网络中的带宽不足时,网关不会转发非参考图像的编码片段NAL单元或SEI NAL单元。在另一个例子中,实时直播会不时地被预先编码的内容(如广告)打断。预先编码片段的第一个帧会提前传输,以确保它能在接收方中随时可用。在传输第一个帧内图像时,发起方并不确切知道在预先编码片段的第一个帧按照解码顺序出现之前会编码多少个NAL单元。因此,在传输预先编码片段的第一个帧内图像时,必须估计该帧内图像的NAL单元的DON值,并且可能会出现DON值的不连续情况。

单NAL单元包

此处定义的单个 NAL 单元数据包必须仅包含按照 [1] 中定义的类型所规定的唯一一个 NAL 单元。这意味着在单个 NAL 单元数据包内既不能使用聚合数据包也不能使用分片单元。由按照 RTP 序列号顺序解包的单个 NAL 单元数据包组成的 NAL 单元流必须符合 NAL 单元解码顺序。单个 NAL 单元数据包的结构如图 2 所示。

复制代码
      Informative note: The first byte of a NAL unit co-serves as the
      RTP payload header.
​
     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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 2.  RTP payload format for single NAL unit packet

聚合数据包

聚合数据包是此数据包规范中的 NAL 单元聚合方案。该方案的引入是为了反映两个关键目标网络(有线 IP 网络(其最大传输单元大小通常受以太网最大传输单元大小的限制,约为 1500 字节)和基于 IP 或非基于 IP(例如,ITU-T H.324/M)的无线通信系统,其首选传输单元大小为 254 字节或更小)的显著不同的最大传输单元大小。为了防止两个世界之间的媒体转码,并避免不必要的分组化开销,引入了 NAL 单元聚合方案。

该规范定义了两种聚合数据包类型:

  • 单次聚合包(STAP):将具有相同 NALU 时长的 NAL 单元进行聚合。定义了两种类型的 STAP,一种不包含 DON(STAP-A),另一种包含 DON(STAP-B)。
  • 多次聚合数据包(MTAP):将具有可能不同 NALU 时间戳的 NAL 单元进行聚合。定义了两种不同的 MTAP,其区别在于 NAL 单元时间戳偏移量的长度。
复制代码
   The structure of the RTP payload format for aggregation packets is
   presented in Figure 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 3.  RTP payload format for aggregation packets

每个要包含在聚合数据包中的 NAL 单元都会被封装在一个聚合单元中。请查看以下四种不同的聚合单元及其特性。

MTAPs 和 STAPs 具有以下相同的分组规则:

  • RTP 时间戳必须设置为所有待聚合的 NAL 单元的 NALU 时间戳中的最早值。
  • NAL 单元类型八位字的类型字段必须设置为表 4 中所指示的相应值。
  • 如果所有聚合的 NAL 单元的 F 位均为零,则 F 位必须清零;否则,该位必须置位。
  • NRI 的值必须为聚合数据包中所携带的所有 NAL 单元中的最大值。
复制代码
                 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 报头中的标记位被设置为这样一种值:如果将聚合数据包中的最后一个 NAL 单元单独封装成一个 RTP 数据包进行传输,那么该 NAL 单元的标记位将会是这种值。

聚合数据包的负载由一个或多个聚合单元组成。有关四种不同类型的聚合单元,请参阅第 5.7.1 节和第 5.7.2 节。聚合数据包可以包含所需数量的聚合单元;然而,聚合数据包中的总数据量必须符合 IP 数据包的容量限制,并且大小应选择得当,使得生成的 IP 数据包的大小小于最大传输单元(MTU)的大小。聚合数据包不得包含分段单元,这在第 5.8 节中有明确规定。聚合数据包不能嵌套;也就是说,聚合数据包不能包含另一个聚合数据包。

单时间聚合数据包(STAP)

当对所有具有相同 NALU 时间的 NAL 单元进行聚合时,应当使用单次聚合包(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                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 4.  Payload format for 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                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 5.  Payload format for STAP-B

"DON"字段指定了在传输顺序中 STAP-B 中首个 NAL 单元的 DON 值。对于 STAP-B 中按出现顺序排列的每个后续 NAL 单元,DON 的值等于(STAP-B 中前一个 NAL 单元的 DON 值 + 1)对 65536 取模的结果,其中"%"表示取模运算。

单次聚合单元由 16 位无符号大小信息(采用网络字节序)构成,该信息表示接下来的 NAL 单元的字节数(不包括这两个字节,但包括 NAL 单元类型的 NAL 单元字节),随后是 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                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 6.  Structure for single-time aggregation unit

图 7 展示了一个包含 STAP-A 的 RTP 数据包的示例。该 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 7.  An example of an RTP packet including an STAP-A
               containing two single-time aggregation units

图 8 展示了一个包含 STAP-B 的 RTP 数据包的示例。该 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 8.  An example of an RTP packet including an STAP-B
               containing two single-time aggregation units

多时间聚合数据包(MTAPS)

MTAP 的 NAL 单元数据包包含一个 16 位无符号解码顺序号基(DONB)(以网络字节序表示)以及一个或多个多时间聚合单元,如图 9 所示。DONB 必须包含在 MTAP 的 NAL 单元解码顺序中,作为第一个 NAL 单元的 DON 值。

说明:在NAL单元解码顺序中,第一个NAL单元并不一定是这些NAL单元在MTAP封装顺序中的第一个位置。

复制代码
     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                  |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 9.  NAL unit payload format for MTAPs

在本规范中定义了两种不同的多时间聚合单元。它们均由以下 NAL 单元的 16 位无符号大小信息(采用网络字节序)、8 位无符号解码顺序号差值(DOND)以及 n 位(采用网络字节序)的此 NAL 单元的时间戳偏移量(TS 偏移量)组成,其中 n 可为 16 或 24。不同类型的 MTAP(MTAP16 和 MTAP24)的选择取决于应用:时间戳偏移量越大,MTAP 的灵活性就越高,但开销也会越大。

MTAP16 和 MTAP24 的多时间聚合单元结构分别如图 10 和图 11 所示。在一个数据包中,聚合单元的起始或结束位置并不需要位于 32 位字边界上。多时间聚合单元中包含的 NAL 单元的 DON 值等于 (DONB + DOND) % 65536,其中 % 表示取模运算。本说明并未规定多时间聚合单元内 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                         |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 10.  Multi-time aggregation unit for 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                         |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 11.  Multi-time aggregation unit for MTAP24

对于"最早的"多时间聚合单元而言,其时间戳偏移量必须为零。因此,该多时间聚合单元自身的 RTP 时间戳与最早的 NALU 时间完全相同。

说明:在所有多时间聚合单元中,"最早"的聚合单元是指在所有聚合单元的NAL单元被封装为单个NAL单元包的情况下,其扩展的RTP时间戳最小的那个单元。扩展时间戳是一种位数超过32位的时戳,能够计数时间戳字段的循环,从而能够确定如果时间戳循环时的最小值。这样的"最早"聚合单元可能并非在MTAP中封装聚合单元的顺序中的第一个。最早的那个NAL单元不一定与NAL单元解码顺序中的第一个NAL单元相同。

图 12 展示了一个包含多时间聚合数据包(类型为 MTAP16)的 RTP 数据包示例,该数据包包含两个多时间聚合单元,分别标记为图中的 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 12.  An RTP packet including a multi-time aggregation
                packet of type MTAP16 containing two multi-time
                aggregation units

图 13 展示了一个包含多时间聚合数据包(类型为 MTAP24)的 RTP 数据包示例,该数据包包含两个多时间聚合单元,分别标记为图中的 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 13.  An RTP packet including a multi-time aggregation
                packet of type MTAP24 containing two multi-time
                aggregation units

分片单元(FUs)

这种数据包类型允许将一个 NAL 单元分割成多个 RTP 数据包。在应用层进行这种分割,而非依赖于较低层的分割方式(例如通过 IP 进行分割),具有以下优点:

  • 该数据包格式能够通过 IPv4 网络传输超过 64 k字节的 NAL 单元,该网络可能存在于预先录制的视频中,特别是在高清晰度格式中(每个画面的分片数量有限,从而导致每个画面的 NAL 单元数量有限,这可能会导致 NAL 单元变得很大)。
  • 分片机制允许将单个 NAL 单元进行分割,并按照第 12.5 节所述应用通用的前向纠错技术。

分片仅针对单个 NAL 单元定义,而不适用于任何聚合数据包 。NAL 单元的分片由该 NAL 单元的连续整数个字节组成。NAL 单元的每个字节必须恰好属于该 NAL 单元的一个分片中。同一 NAL 单元的分片必须按顺序连续发送,且其 RTP 序列号递增(在同一个 RTP 数据包流中,第一片和最后一片之间不应发送其他 RTP 数据包)。同样,NAL 单元必须按照 RTP 序列号的顺序进行重新组装。

当一个 NAL 单元被分片并封装在分片单元(FUs)中时,它被称为分片后的 NAL 单元。STAP 和 MTAP 不能被分片。分片单元(FUs)不能嵌套;也就是说,一个 FUs 不能包含另一个 FUs。

携带 FU 的 RTP 数据包的 RTP 时间戳被设置为分片 NAL 单元的 NALU 时间。

图 14 展示了 FU-A 的 RTP 数据包格式。一个 FU-A 包括一个 8 位字节的分片单元指示符、一个 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
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    | FU indicator  |   FU header   |                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
    |                                                               |
    |                         FU payload                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 14.  RTP payload format for FU-A

图 15 展示了 FU-B 的 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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
​
    Figure 15.  RTP payload format for FU-B

对于一个分片的 NAL 单元的第一个分片单元,必须使用 NAL 单元类型 FU-B 在交错分组模式下进行处理。在任何其他情况下,NAL 单元类型 FU-B 均不得使用。换句话说,在交错分组模式下,每个被分片的 NALU 都以 FU-B 作为第一个分片单元,随后是 1 个或多个 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"时,起始位表示一个分片 NAL 单元的开始。如果后续的 FU 数据包并非分片 NAL 单元数据的起始部分,则起始位将被设置为"0"。

  • E:1位

当设置为"1"时,结束位表示分片NAL 单元的结束,即有效载荷的最后一个字节也是该分片 NAL 单元的最后一个字节。如果后续的 FU 有效载荷不是分片 NAL 单元的最后一个片段,则结束位设置为"0"。

  • R:1位

"保留位"必须等于 0,并且接收方必须忽略该位。

  • Type:5位

如[1]表 7-1 中所定义的 NAL 单元数据包类型。

FU-Bs 中 DON 的值的选取方式如第 5.5 节所述。

说明:在 FU-B 中的 DON 字段允许网关将 NAL 单元进行分片处理,并将其发送至 FU-B,而无需按照 NAL 单元的解码顺序对传入的 NAL 单元进行排序。

一个分片的NAL单元不能在一个帧单元中进行传输;也就是说,在同一个帧单元的头部中,起始位和结束位都不能都设置为"1"。

FU 的数据包由分片的 NAL 单元的数据包片片组成,这样如果连续的 FU 数据包的 NAL 单元数据包按顺序连接起来,就可以重组分片的 NAL 单元的数据包。分片的 NAL 单元的 NAL 单元类型八位字节并未包含在分段单元数据包中,而是分片单元指示八位字节的 F 和 NRI 字段以及 FU 头部的类型字段中传达了分片 NAL 单元的 NAL 单元类型八位字节的信息。一个 FU 数据包可以包含任意数量的八位字节,并且可以为空。

说明:在近乎无丢包的环境中,空的转发单元(FU)能够降低某些类型发送者的延迟。这些发送方的特点在于,在 NALU 完全生成之前(即在 NALU 大小尚未确定之前),他们会将 NALU 的片段进行打包。如果不允许零长度的 NALU 片段存在,那么发送方就必须在当前片段发送之前生成至少一个后续片段的数据位。由于 H.264 的特性(有时几个宏块占用零比特),这种情况是不可取的,还会增加延迟。然而,零长度 NALU 片段的(潜在)使用应当与因传输其所需额外的包而导致至少部分 NALU 失效的风险增加进行仔细权衡。

如果一个分片单元丢失了,接收方应当按照传输顺序丢弃与该相同分片 NAL 单元相对应的所有后续分片单元。

在终端设备或 MANE 中的接收器可以将一个 NAL 单元的前 n - 1 个分片聚合为一个(不完整的)NAL 单元,即便该 NAL 单元的第 n 个分片未被接收。在这种情况下,该 NAL 单元的"禁止零位"位必须设置为 1,以表明存在语法错误。

相关推荐
蝸牛ちゃん12 分钟前
万字深度详解DHCP服务:动态IP地址分配的自动化引擎
网络·网络协议·tcp/ip·系统架构·自动化·软考高级·dhcp
一只小bit6 小时前
Linux网络:阿里云轻量级应用服务器配置防火墙模板开放端口
linux·网络·阿里云
BachelorSC8 小时前
【网络工程师软考版】网络安全
网络·安全·web安全
天天进步20158 小时前
Python全栈项目--基于深度学习的视频内容分析系统
python·深度学习·音视频
(Charon)9 小时前
【C语言网络编程】HTTP 客户端请求(基于 Socket 的完整实现)
网络·网络协议·http
bubiyoushang88810 小时前
CentOS安装ffmpeg并转码视频为mp4
ffmpeg·centos·音视频
Bryce李小白10 小时前
Kotlin实现Retrofit风格的网络请求封装
网络·kotlin·retrofit
亿坊电商11 小时前
AI 数字人在处理音频时,如何确保声音的自然度?
人工智能·算法·音视频
Lovyk11 小时前
Linux网络管理
服务器·网络·php
MC皮蛋侠客12 小时前
AsyncIOScheduler 使用指南:高效异步任务调度解决方案
网络·python·fastapi