libstreaming源码分析三之H264 RTP打包

来源:互联网 发布:淘宝上买格力空调 编辑:程序博客网 时间:2024/06/07 22:49

一、H.264的RTP封包

感谢网友的讲解,非常详细 http://www.cppblog.com/czanyou/archive/2009/12/25/67940.html。在此做个记录,以备查询。

*********************************************
NALU header结构介绍
        +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
     
      F: 1bit forbidden_zero_bit. h264规定这一位必须为0
     
      NRI:2bit nal_ref_idc. 取00~11,代表NALU的重要性,如00的NALU解码器可以丢弃它而不影响图像的回放
     
      Type:5bit nal_unit_type. 代表这个NALU单元的类型。
                  0     没有定义
                  1-23  NAL单元 单个NAL单元包
                  24          STAP-A 单一时间的组合包
                  25          STAP-B 单一时间的组合包
                  26          MTAP16 多个时间的组合包
                  27          MTAP24多个时间的组合包
                  28          FU-A 分片的单元
                  29          FU-B 分片的单元
                  
                  nal_unit_type     NAL类型
                  1                       不分片、非IDR图像的片
                  2                       片分区A
                  3                       片分区B
                  4                       片分区C
                  5                       IDR图像中的片
                  6                       补充增强信息单元(SEI)
                  7                       序列参数集(SPS)
                  8                       图像参数集(PPS)
                  9                       分界符
                  10                      序列结束
                  11                      码流结束
                  12                      填充
                  13-23             保留
                  
                  
**********************************************************
RTP header (一般12 bytes)

         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             |
      |                             ....                              |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      V:版本号 (2 bits)
      P:padding
      M: marker bit(1 bit) 指示相同时间戳的最后一个 rtp包。
      PT:payload type(7 bits) 96代表h264打包
      SN: sequence number(16 bits) 包的序号,对于单个NALU模式与非交错打包方式,序号用于对定NALU解码顺序
       Timestamp: 时间戳(32 bits) 设置为内容的采样时间戳。必须使用90kHz时钟频率。


**********************************************************
单一NALU模式
      对于NALU的长度小于MTU大小的包,一般采用单一NAL单元模式。
      一个原始的H.264 NALU常由 [Start Code] [NALU header] [NALU Payload]三部分组成。
      Start Code用于标示这是一个NALU单元的内容,必须是 “00 00 00 01” 或 “00 00 01”。
      NALU header 仅一个字节,其后都是NALU内容。
      
      RTP打包时,去除“00 00 00 01”或“00 00 01”的开始码,把其他数据封包到RTP包即可。
      
      [RTP header] [NALU header] [NALU payload]
      实例:
      有一个 h.264 的NALU是这样的:
      [00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
      这是一个序列参数集NAL单元。[00 00 00 01]是四个字节的开始码,67是NALU header,42开头的数据时NALU内容。
      封装成 RTP 包将如下:
      [RTP header][67 42 A0 1E 23 56 0E 2F ... ] 去掉4个字节的开始码
      
      
************************************************************************
FU-A 分片模式 (Fragmentation Units)
当一个NALU长度大于MTU时,就必须对NALU进行分片封包。
    [RTP header] [FU indicator] [FU header] [FU payload]
    FU indicator:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
      NRI : 设置成NAL单元的NRI
      Type: 28 表示 FU-A
     
    FU header:
      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+
      S: 1 bit 设置成1,开始位指示NAL单元的开始。
      E: 1 bit 设置成1,结束位指示分片NAL单元的结束。
      R: 1 bit 预留位,必须设置为0
      Type: 设置成NAL单元的荷载类型
                  

***********************************************************************
RTP时间戳( http://blog.csdn.net/bripengandre/article/details/2238818 
RTP包头的第2个32bit即为RTP包的时间戳,Time Stamp。
     时间戳反映了RTP分组中的数组的第一个字节的采样时刻。在一次会话开始时的时间戳是随机选择的。即使没有信号发送时,时间戳的数值也要随时间不断的增加。接收端使用时间戳可准确知道应当在什么时间还原哪一个数据块,从而消除传输中的抖动。时间戳还可用来使音视频同步。
     在RTP协议中并没有规定时间戳的粒度,这取决于有效载荷类型。因此RTP的时间戳又称为媒体时间戳,以强调这种时间戳的粒度取决于信号的类型。例如,对于8kHz采用的语音信号,若每隔20ms构成一个数据块,则一个数据块中包含有160个样本(0.02*8000=160)。因此每发送一个RTP分组,其时间戳的值就增加160.

关于libstreaming对时间戳的设置,有些许不解,有时间要好好研究。


二、RtpSocket类

未完待续...

0 0
原创粉丝点击