zoukankan      html  css  js  c++  java
  • RTP封装h264

    网络抽象层单元类型 (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单元的类型.简述如下:

      0     没有定义
      1-23  NAL单元  单个 NAL 单元包
      24    STAP-A   单一时间的组合包
      25    STAP-B   单一时间的组合包
      26    MTAP16   多个时间的组合包
      27    MTAP24   多个时间的组合包
      28    FU-A     分片的单元
      29    FU-B     分片的单元
      30-31 没有定义

    h264仅用1-23,24以后的用在RTP H264负载类型头中

     

    不同类型的NALU的重要性指示如下表所示:

    nal_unit_type

    NAL类型

    nal_reference_bit

    0

    未使用

     0

    1

    非IDR的片

    此片属于参考帧,则不等于0,

    不属于参考帧,则等与0

    2

    片数据A分区

    同上

    3

    片数据B分区

    同上

    4

    片数据C分区

    同上

    5

    IDR图像的片

    5

    6

    补充增强信息单元(SEI)

    0

    7

    序列参数集

    非0

    8

    图像参数集

    非0

    9

    分界符

    0

    10

    序列结束

    0

    11

    码流结束

    0

    12

    填充

    0

    13..23

    保留

     0

    24..31

    不保留

     0

     
     

    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
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |V=2|P|X|  CC   |M|     PT      |       sequence number         |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                           timestamp                           |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |           synchronization source (SSRC) identifier            |
          +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
          |            contributing source (CSRC) identifiers             |
          |                             ....                              |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          V: RTP协议的版本号,占2bits,当前协议版本号为2
          P: 填充标志,占1bit,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
          X: 扩展标志,占1bit,如果X=1,则在RTP报头后跟有一个扩展报头
          CC: CSRC计数器,占4位,指示CSRC 标识符的个数
          M: 1bit,标记解释由设置定义,目的在于允许重要事件在包流中标记出来。如不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

          负载类型 Payload type(PT): 7bits
          注:rfc里面对一些早期的格式定义了这个payload type。但是后来的,如h264并没有分配,那就用96来代替。因此现在96以上都不表示特定的格式,具体表示什么要用sdp或者其他协议来协商。

          序列号 Sequence number(SN): 16bits,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1,序列号的初始值是随机产生的。可以用于检查丢包以及进行数据包排序。
          时间戳 Timestamp: 32bits,必须使用90kHz时钟频率。

          同步信源(SSRC)标识符: 32bits,用于标识同步信源。该标识符是随机随机产生的,参加同一视频会议的两个同步信源不能有相同的SSRC。
          特约信源(CSRC)标识符: 每个CSRC标识符占32bits,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。

     

    上面介绍了NALU和RTP header的基本结构,下面介绍的全部都是RTP PayLoad的部分

    Rtp负载第一个字节的结构如下,它和H.264的NALU头结构一致,可以把它认为是RTP h264负载类型字节,完全是多增加的一个字节,不影响后面的NALU结构

          +---------------+
          |0|1|2|3|4|5|6|7|
          +-+-+-+-+-+-+-+-+
          |F|NRI|  Type   |
          +---------------+
    这里的Type类型除1-23外还可取以下值:

      24    STAP-A   单一时间的组合包
      25    STAP-B   单一时间的组合包
      26    MTAP16   多个时间的组合包
      27    MTAP24   多个时间的组合包
      28    FU-A     分片的单元
      29    FU-B     分片的单元

    如果使用1-23就是:单一NAL单元模式

    SDP文件描述和封包的关联:

    m=video 49170 RTP/AVP 98
    a=rtpmap:98 H264/90000
    a=fmtp:98 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-sets=Z0IACpZTBYmI,aMljiA==
    packetization-mode:  表示支持的封包模式.

    当 packetization-mode 的值为 0 时或不存在时, 必须使用单一 NALU 单元模式.
    当 packetization-mode 的值为 1 时必须使用非交错(non-interleaved)封包模式.
    当 packetization-mode 的值为 2 时必须使用交错(interleaved)封包模式.

    每个打包方式允许的NAL单元类型总结(yes = 允许, no = 不允许, ig = 忽略)

          Type   Packet    Single NAL    Non-Interleaved    Interleaved
                           Unit Mode           Mode             Mode
          -------------------------------------------------------------
     
          0      undefined     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  undefined     ig               ig               ig
     

    封包介绍:

     

    单一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 个字节的开始码就可以了.

     

    组合封包模式

      其次, 当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 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
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                          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        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    这里只介绍STAP-A模式,如果是STAP-B的话会多加入一个DON域,另外还有MTAP16、MTAP24,具体不介绍,可以看rfc文档,文章尾贴一个链接可以去看。

    转载的话注明一下作者:jwybobo2007 出处:http://blog.csdn.net/jwybobo2007/article/details/7054140

    例:

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

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

    [00 00 00 01 68 42 B0 12 58 6A D4 FF ... ]

    封装成 RTP 包将如下:

    [ RTP Header ] [78 (STAP-A头,占用1个字节)] [第一个NALU长度 (占用两个字节)] [ 67 42 A0 1E 23 56 0E 2F ] [第二个NALU长度 (占用两个字节)] [68 42 B0 12 58 6A D4 FF ... ]

     

    分片的单元:

      当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

       The FU indicator octet has the following format:

          +---------------+
          |0|1|2|3|4|5|6|7|
          +-+-+-+-+-+-+-+-+
          |F|NRI|  Type   |
          +---------------+
       别被名字吓到这个格式就是上面提到的RTP h264负载类型,Type为FU-A

       The FU header has the following format:

          +---------------+
          |0|1|2|3|4|5|6|7|
          +-+-+-+-+-+-+-+-+
          |S|E|R|  Type   |
          +---------------+
       S bit为1表示分片的NAL开始,当它为1时,E不能为1

       E bit为1表示结束,当它为1,S不能为1

       R bit保留位

       Type就是NALU头中的Type,取1-23的那个值

    例:

    0x7C85=01111100 10000101 (开始包)

    0x7C05=01111100 00000101 (中间包)

    0x7C45=01111100 01000101 (结束包)

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

      [00 00 00 01 65 42 A0 1E 23 56 0E 2F ...  02 17 C8 FD F1 B9 C7 53 59 72 ... CB FF FF F4 1A D5 C4 18 A8 ... F1 B9 C7 1D A5 FA 13 0B ...]

    封装成 RTP 包将如下:

    [ RTP Header ] [ 7C 85 42 A0 1E 23 56 0E 2F ...]

    [ RTP Header ] [ 7C 05 02 17 C8 FD F1 B9 C7 53 59 72 ...]

    [ RTP Header ] [ 7C 05 CB FF FF F4 1A D5 C4 18 A8 ...]

    [ RTP Header ] [ 7C 45 F1 B9 C7 1D A5 FA 13 0B ...]

     

    附:

    一个翻译过的rfc3984文档,翻译的有点乱,凑货的看看

    http://wenku.baidu.com/view/0f612e1ec5da50e2524d7f32.html
    ————————————————
    版权声明:本文为CSDN博主「jwybobo2007」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/jwybobo2007/article/details/7054140

  • 相关阅读:
    UVaLive 3695 Distant Galaxy (扫描线)
    UVaLive 3695 City Game (扫描线)
    CodeForces 349B Color the Fence (DP)
    UVaLive 3905 Meteor (扫描线)
    UVaLive 3902 Network (无根树转有根树,贪心)
    NodeJS学习笔记 (16)子进程-child_process(ok)
    字符编码笔记:ASCII,Unicode 和 UTF-8
    NodeJS学习笔记 (15)二进制数据-buffer(ok)
    NodeJS学习笔记 (14)URL查询字符串-querystring(ok)
    NodeJS学习笔记 (13)数据加密-crypto(OK)
  • 原文地址:https://www.cnblogs.com/cnhk19/p/15315386.html
Copyright © 2011-2022 走看看