zoukankan      html  css  js  c++  java
  • RTP分包解包 ---- H264

    分包

    1、单个NAL包单元

    12字节的RTP头后面的就是音视频数据,比较简单。一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须符合NAL单元的解码顺序。
    对于 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 包即可.

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

    如有一个 H.264 的 NALU 是这样的:

    [00 00 00 01 67 42 A0 1E 23 56 0E 2F … ]

    这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.

    封装成 RTP 包将如下:

    [ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]

    即只要去掉 4 个字节的开始码就可以了.

    2. 组合封包模式

    当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 RTP 包中.

    3、FU-A的分片格式

    数据比较大的H264视频包,被RTP分片发送。12字节的RTP头后面跟随的就是FU-A分片:
    而当 NALU 的长度超过 MTU 时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units (FUs).

       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

    1) FU indicator有以下格式:

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

    FU指示字节的类型域的28,29表示FU-A和FU-B。NRI域的值必须根据分片NAL单元的NRI域的值设置。(此处Type就是rtp分片类型) 见下表

      .Type   Packet      Type name                       
      ---------------------------------------------------------
      0      undefined                                    -
      1-23   NAL unit    Single NAL unit packet per H.264  
      24     STAP-A     Single-time aggregation packet    
      25     STAP-B     Single-time aggregation packet    
      26     MTAP16    Multi-time aggregation packet     
      27     MTAP24    Multi-time aggregation packet     
      28     FU-A      Fragmentation unit                
      29     FU-B      Fragmentation unit                 
      30-31  undefined  

     FU header的格式如下:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+

    S: 1 bit 当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。

    E: 1 bit 当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。
    当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。

    R: 1 bit
    保留位必须设置为0,接收者必须忽略该位。

    Type: 5 bits
    此处的Type就是NALU头中的Type,取1-23的那个值,表示 NAL单元荷载类型定义。

    注意:

    1. 装载FU payload部分时候,需要去掉nalu的header(第一个字节)

    2. 一般I帧前面发送sps和pps,时间戳和I帧相同

    3. h264的采样率固定是9000hz

    拆包和解包

    拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:

    原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,

    FU indicator与FU header的剩余位数根据实际情况决定。

    解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:

    还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:

    nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)

  • 相关阅读:
    英文哲理短句
    经历的一次诈骗
    英文哲理短句
    反思对待新人的方式
    Java 开源报表制作
    现在开始写字
    关于Visual C++ 6.0的调试技巧和经验总结
    一步一步教你实现CTreeCtrl 自绘
    VC中动态加载ODBC解决方法
    VC++程序编译链接的原理与过程
  • 原文地址:https://www.cnblogs.com/vczf/p/13933729.html
Copyright © 2011-2022 走看看