且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

H264的RTP负载打包的数据包格式,分组,分片

更新时间:2022-08-14 23:36:59

H264的RTP负载打包的数据包格式,分组,分片

 

1.    RTP数据包格式

RTP报文头格式(见RFC3550 Page12):

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 12 3 4 5 6 7 8 9 0 1

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |V=2|P|X| CC   |M|     PT     |       sequence number         |

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |                           timestamp                           |

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |          synchronization source (s-s-rC) identifier            |

  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

   |           contributing source (CSRC) identifiers             |

   |                             ....                              |

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

版本(V):2比特此域定义了RTP的版本.此协议定义的版本是2.

填料(P):1比特若填料比特被设置,此包包含一到多个附加在末端的填充比特,不是负载的一部分.填料的最后一个字节包含可以忽略多少个填充比特.填料可能用于某些具有固定长度的加密算法,或者在底层数据单元中传输多个RTP包.

扩展(X):1比特 若设置扩展比特,固定头(仅)后面跟随一个头扩展.

CSRC计数(CC):4比特  CSRC计数包含了跟在固定头后面CSRC识别符的数目.

标志(M):1比特 标志的解释由具体协议规定.它用来允许在比特流中标记重要的事件,如帧范围.规定该标志在静音后的第一个语音包时置位.

负载类型(PT):7比特 此域定义了负载的格式,由具体应用决定其解释.协议可以规定负载类型码和负载格式之间一个默认的匹配.其他的负载类型码可以通过非RTP方法动态定义.RTP发射机在任意给定时间发出一个单独的RTP负载类型;此域不用来复用不同的媒体流.

序列号(sequence number):16比特 每发送一个RTP数据包,序列号加一,接收机可以据此检测包损和重建包序列.序列号的初始值是随机的(不可预测),以使即便在源本身不加密时(有时包要通过翻译器,它会这样做),对加密算法泛知的普通文本攻击也会更加困难.

时间标志(timestamp):32比特 时间标志反映了RTP数据包中第一个比特的抽样瞬间.抽样瞬间必须由随时间单调和线形增长的时钟得到,以进行同步和抖动计算.时钟的分辨率必须满足要求的同步准确度,足以进行包到达抖动测量.时钟频率与作为负载传输的数据格式独立,在协议中或定义此格式的负载类型说明中静态定义,也可以在通过非RTP方法定义的负载格式中动态说明.若RTP包周期性生成,可以使用由抽样时钟确定的额定抽样瞬间,而不是读系统时钟.例如,对于固定速率语音,时间标志钟可以每个抽样周期加1.若语音设备从输入设备读取覆盖160个抽样周期的数据块,对于每个这样的数据块,时间标志增加160,无论此块被发送还是被静音压缩. 时间标志的起始值是随机的,如同序列号.多个连续的RTP包可能由同样的时间标志,若他们在逻辑上同时产生.如属于同一个图象帧.若数据没有按照抽样的 顺序发送,连续的RTP包可以包含不单调的时间标志,如MPEG交织图象帧.

同步源(s-s-rC):32比特 s-s-rC域用以识别同步源.标识符被随机生成,以使在同一个RTP会话期中没有任何两个同步源有相同的s-s-rC识别符.尽管多个源选择同一个s-s-rC识别符的概率很低,所有RTP实现工具都必须准备检测和解决冲突.若一个源改变本身的源传输地址,必须选择新的s-s-rC识别符,以避免被当作一个环路源.

有贡献源(CSRC)列表:0到15项,每项32比特 CSRC列表识别在此包中负载的有贡献源.识别符的数目在CC域中给定.若有贡献源多于15个,仅识别15个.CSRC识别符由混合器插入,用有贡献源的s-s-rC识别符.例如语音包,混合产生新包的所有源的s-s-rC标识符都被陈列,以期在接收机处正确指示交谈者.

 

注意:前12个字节出现在每个RTP包中,仅仅在被混合器插入时,才出现CSRC识别符列表.

 

RTP报文扩展头格式(见RFC3550 Page18):

  0                   1                   2                   3

    0 1 2 3 4 56 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

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |      defined by profile       |           length              |

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   |                        header extension                       |

   |                             ....                              |

 

若RTP头中的扩展比特位X置1,则一个长度可变的头扩展部分被加到RTP固定头之后,.头扩展包含16比特的长度域,指示扩展项中32比特字的个数,不包括4个字节扩展头(因此零是有效值).RTP固定头之后只允许有一个头扩展.为允许多个互操作实现独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前16比特用以识别标识符或参数.这16比特的格式由具体实现的上层协议定义.基本的RTP说明并不定义任何头扩展本身。

 

2.    网络抽象层单元 (NALU)

NALU 头由一个字节组成, 它的语法如下:

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

F: 1 个比特.  forbidden_zero_bit. 在H.264 规范中规定了这一位必须为 0.

NRI: 2 个比特.nal_ref_idc. 取 00 ~ 11, 似乎指示这个 NALU 的重要性, 如 00 的 NALU 解码器可以丢弃它而不影响图像的回放. 不过一般情况下不太关心这个属性.

Type: 5 个比特.nal_unit_type. 这个 NALU 单元的类型.

 Type   Packet   Type name                       

     ---------------------------------------------------------

      0     undefined                                   

      1-23  NAL unit  Single NAL unit packetper H.264  

      24    STAP-A    Single-time aggregationpacket    

      25    STAP-B    Single-time aggregationpacket    

      26    MTAP16    Multi-time aggregationpacket     

      27    MTAP24    Multi-time aggregationpacket     

      28     FU-A     Fragmentation unit                

      29     FU-B     Fragmentation unit                 

      30-31  undefined    

                              

H264 over RTP基本上分三种类型:

(1)Single NAL unit packet 也就是实际的NAL类型,可以理解为一个包就是一帧H264数据,这个在实际中是比较多的。

(2)Aggregation packet 一包数据中含有多个H264帧。

STAP-A 包内的帧含有相同的NALU-Time,没有DON

STAP-B 包内的帧含有相同的NALU-Time,有DON

MTAP16 包内的帧含有不同的NALU-Time,timestamp offset = 16

MTAP24 包内的帧含有不同的NALU-Time,timestamp offset = 24

封装在Aggregation packet中的 NAL单元大小为65535字节

(3) Fragmentation unit 一帧数据被分为多个RTP包,这也是很常见的,特别是对于关键帧。现存两个版本FU-A,FU-B。

实际应用就是要加上个H264 STREAM 的头h264_stream_head =0x00,0x00,0x00,0x01 4字节,送去解码即可。

 

3.分包规则

3.1单个NAL单元包(1-23)

对于 NALU 的长度小于MTU 大小的包,一般采用单个NAL 单元模式.一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header][NALU Payload]三部分组成, 其中 Start Code 用于标示这是一个 NALU 单元的开始, 必须是"00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容.打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可.

一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须符合NAL单元的解码顺序。单个NAL单元包的结构显示如图。(NAL单元的第一字节和RTP荷载头第一个字节重合)

       0                   1                   2                   3

       0 1 23 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 RTPpadding        |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

一个包就是一帧数据。h264_stream_head + NAL_unit_type... 就可以直接送去解码了。

 

3.2组合包(24-27)

3.2.1单时间组合包(24-25)

STAP应该用于当组合在一起的NAL单元共享相同的NALU时刻。STAP-A(24)荷载不包括DON,至少包含一个单时刻组合单元. STAP-B(25)荷载包含一个16位的无符号解码顺序号(DON) (网络字节序)紧跟至少一个单时刻组合单元.

DON域指定STAP-B传输顺序中第一个NAL单元的DON值. 对每个后续出现在STAP-B中的NAL单元,它的DON值等于(STAP-B中前一个NAL的DON值+1)%65535, %是取模运算。

单时刻组合单元有一个16位无符号大小信息(网络字节序),它指示后续NAL单元的大小(以字节为单位)(不包括这两个字节,但包括NAL单元类型字节),后面紧跟NAL单元本身, 包括它的NAL单元类型字节. 单时刻聚合单元在RTP荷载中是字节对齐的,但是可以不是32位字边界对齐。

STAP-A:一个RTP包包含一个STAP-A. STAP包含两个单时刻组合单元:

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 56 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 RTPpadding        |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 

STAP-B:一个RTP包包含一个STAP-B. STAP包含两个单时刻组合单元:

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 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 RTPpadding        |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

看这个结构应该很清楚了,先是16位的长度,就可以得到一帧,h264_stream_head + NALU 1HDR...送去解码。再算下一帧。需要注意的这个NALU Size 是不包括他本身这2个字节。STAP-B还要考虑DON

 

3.2.2多时间组合包(26-27)

多时刻时间包的NAL单元荷载有16位的无符号解码顺序号基址(DONB) (网络字节序)以及一个或多个多时刻聚合单元,DONB 必须包含MTAP中NAL单元的第一个NAL的DON的值。

NAL解码顺序中的第一个NAL单元不必要是封装在MTAP中的第一个NAL单元。、

两个多时刻组合单元都有16位的无符号大小信息用于后续NAL单元(网络字节序),一个8位无符号解码序号差值(DOND),和n位 (网络字节序) 时戳位移(TS 位移)用于本NAL单元,n可以是16/24. 不同MTAP类型的选择是应用相关的时戳位移越大, MTAP的灵活性越大, 但是负担也越大。

MTAP16/MTAP24多时刻组合单元的结构如图示。

MTAP16:

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 0 1

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      :       NAL unit size          |      DOND    |  TS offset    |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      | TS offset    |                                              |

      +-+-+-+-+-+-+-+-+              NAL unit                         |

      |                                                               |

      |                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |                               :

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 

MTAP24:

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 0 1

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      :       NALU unit size         |      DOND    |  TS offset    |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |        TS offset             |                               |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |

      |                              NAL unit                         |

      |                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |                               :

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 

一个包中的组合单元的开始/结束不要求位于32位的边界。跟随NAL单元的DON 等于(DONB + DOND) % 65536,  %代表取摸操作. 本文没有指定MTAP内的NAL单元如何排序,但大多数情况,应该使用NAL单元解码顺序。

时戳位移域必须设置成等于以下公式的值:如果NALU-time大于等于包的RTP时戳,则时戳位移等于(NALU-time - 包的RTP时戳).如果NALU-time小于包的RTP时戳,则时戳位移等于 NALU-time + (2^32 - 包的RTP时戳).

(1)一个RTP包包含一个多时刻MTAP16类型的组合包,包括两个多时刻组合单元

 

 

 

 

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 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 RTPpadding        |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

(2)一个RTP包包含一个多时刻MTAP24类型的组合包,包括两个多时刻组合单元

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 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   |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |  NALU2 DATA                                                 |

      :                                                              :

      |                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |                               :...OPTIONAL RTPpadding        |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

看这个结构应该很清楚了,先是16位的DONB,然后是16位的长度,8位的DOND,根据DONB计算出DON,去掉时间戳(16-24bits),就可以得到一帧,h264_stream_head + NALU 1 HDR...。得到该RTP包中所有的NAL单元后,根据DON确定解码顺序。需要注意的这个NALU Size 是不包括他本身这2个字节。

 

3.2.2分片单元 (FUs)(28-29)

当NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包,NAL单元的一个分片由整数个连续NAL单元字节组成. 每个NAL单元字节必须正好是该NAL单元一个分片的一部分。相同NAL单元的分片必须使用递增的RTP序号连续顺序发送(第一和最后分片之间没有其他的RTP包)。相似, NAL单元必须按照RTP顺序号的顺序装配。

当一个NAL单元被分片运送在分片单元(FUs)中时,被引用为分片NAL单元。STAPs,MTAP不可以被分片。 FUs不可以嵌套,即,一个FU 不可以包含另一个FU. 运送FU的RTP时戳被设置成分片NAL单元的NALU时刻.

FU-A的RTP荷载格式。FU-A由1字节的分片单元指示,1字节的分片单元头,和分片单元荷载组成。

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 0 1

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      | FU indicator |   FU header   |                               |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |

      |                                                               |

      |                         FU payload                            |

      |                                                              |

      |                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |                              :...OPTIONAL RTPpadding        |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 

FU-B的RTP荷载格式. FU-B由1字节的分片单元指示,1字节的分片单元头,和解码顺序号(DON)以及分片单元荷载组成。

       0                   1                   2                   3

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 0 1

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      | FU indicator |   FU header   |               DON             |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|

      |                                                              |

      |                         FU payload                            |

      |                                                              |

      |                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |                               :...OPTIONAL RTPpadding        |

     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

对于分片NAL单元的第一个分片如果用于交错打包方式,则必须使用NAL单元类型FU-B。NAL单元类型FU-BMUST不可以用于其他情况。换句话, 在交错打包方式,每个被分片的NALU,FU-B作为第一个分片,后面跟随的是一个或多个FU-A分片.

 

 

FU指示字节有以下格式:

      +---------------+

      |0|1|2|3|4|5|6|7|

      +-+-+-+-+-+-+-+-+

      |F|NRI| Type   |

      +---------------+

 FU指示字节的类型域的28,29表示FU-A和FU-B。NRI域的值必须根据分片NAL单元的NRI域的值设置。

FU头的格式如下:

      +---------------+

      |0|1|2|3|4|5|6|7|

      +-+-+-+-+-+-+-+-+

      |S|E|R| Type   |

      +---------------+

S:1 表示是一帧的开始包

E:1 表示是一帧的结束包,和RTP marker位一致

R:0 必须

 

这里要注意一下,组包时,NAL unit type 必须自己拼装FU Indicator前四字节+ FU Header后四字节。也就是type字段是 FU header里的nal_unit_type= (fu_indicator & 0xe0) | (fu_header & 0x1f)等帧收齐了,加上H264_streaming_head+ nal_unit_type....送去解码。