RTP报文头格式

RTP报文由报文头和报文体组成,报文头格式如下图所示。

V:RTP协议的版本号,占2位,当前协议版本号为2。
P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头。
CC:CSRC计数器,占4位,指示CSRC 标识符的个数。
M:标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。
PT:有效载荷类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是           用来区分音频流和视频流的,这样便于客户端进行解析。
SN:序列号,占16位,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢             复包序列。序列号的初始值是随机的。
timestamp:时间戳,占32位,记录了该包中数据的第一个字节的采样时刻。它是去除抖动和实现同步不可缺少的。
SSRC:同步源标识符,占32位,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。                    该标识符是随机选取的 RFC1889推荐了MD5随机算法。
CSRC:特约信源标识符,每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中               的所有特约信源。

三、时间戳与同步

      时间戳段是RTP报文头中说明数据包时间的同步信息,是数据能以正确的时间顺序恢复的关键。时间戳的值给出了分组中数据的第一个字节的采样时间(Sampling Instant),要求发送方时间戳的时钟是连续、单调增长的,即使在没有数据输入或发送数据时也是如此。在静默时,发送方不必发送数据,保持时间戳的增长,在接收端,由于接收到的数据分组的序号没有丢失,就知道没有发生数据丢失,而且只要比较前后分组的时间戳的差异,就可以确定输出的时间间隔。
        RTP规定一次会话的初始时间戳必须随机选择,但协议没有规定时间戳的单位,也没有规定该值的精确解释,而是由负载类型来确定时钟的颗粒,这样各种应用类型可以根据需要选择合适的输出计时精度。
        在RTP传输音频数据时,一般选定逻辑时间戳速率与采样速率相同,但是在传输视频数据时,必须使时间戳速率大于每帧的一个滴答。如果数据是在同一时刻采样的,协议标准还允许多个分组具有相同的时间戳值。
        RTCP的一个关键作用就是能让接收方同步多个RTP流,例如:当音频与视频一起传输的时候,由于编码的不同,RTP使用两个流分别进行传输,这样两个流的时间戳以不同的速率运行,接收方必须同步两个流,以保证声音与影像的一致。为能进行流同步,RTCP要求发送方给每个传送一个唯一的标识数据源的规范名(Canonical Name),尽管由一个数据源发出的不同的流具有不同的同步源标识(SSRC),但具有相同的规范名,这样接收方就知道哪些流是有关联的。

1、SSRC的作用

        SSRC相当于一个RTP传输session的ID,就象每个人都有一个名字一样,每一个RTP传输也都有一个名字。这个数字是随机产生,并且要保证唯一。当RTP session改变(如IP等)时,这个ID也要改变。

2、序列号字段是否可以作为流内的同步标时

          我在上面已经说过,序列号只表示了包发出的先后顺序,它表示不了任何时间上的其它概念,所有严格的说,序列号并不能作为流内的同步标志。但是,由于一般来说,包的发送时间都会有严格限制,比如音频包是每秒种发送30个数据包,也就是说,每个包间隔1000/30MS,而这个时间就可以作为一个同步时间来播放。也就是说,按照序列号,每1000/30MS间隔播放一个数据包,这样也能保证同步,但是这时候请考虑丢包问题。

3、绝对时间戳和相对时间戳在进行同步处理时有什么不同

   当我们取得绝对时间后,我们就可以根据这个绝对时间来播放这些数据包。这个绝对时间,加上我们需要的延时(用于数据传输,解码等等的时间)就是我们的播放时间,这样我们可以保证时间的严格同步(相当于把对方的动作延时一段时间后原原本本的再现出来)。目前,在RTP中,能得到这个绝对时间的办法只有RTCP。
          对于相对时间戳,我们更关心的是两个时间戳之间的时间间隔,依靠这个时间间隔,来确定两个包的播放时间间隔。

4、单个媒体内的同步和不同媒体流之间的同步在处理方式上有什么不同
        应该说,不同媒体之间同步比单媒体同步要复杂得多,除了要保证本身的播放要和时间同步外,还要保证两个或多个媒体间同步(比如音视频的同步)。这种不同更关心的两个时间戳时间的换算统一,前面我已经说过,不同编码有不同的采样频率,那么时间戳的增长速度就不同。另外,两个时间戳也需要有一个标准时间来表示时间戳的同步。最简单的方法是两个媒体的第一个时间戳相同,表示两个流的采集开始时间统一。另外还可以通过RTCP来做不同流之间的同步,这在下个问题中会提到。

5、时间戳字段如何用于作为流间同步标识

          在RTP协议中,我们取得时间戳的方法有两个:一个是RTP包中的时间戳,另外一个是RTCP包中的绝对时间戳和相对时间戳。绝对时间戳的概念上面我已经说了,它可以表示系统的绝对时间。而RTCP包中的相对时间就是RTP包中的时间。根据这两个时间,不同流都可以纠正自己播放时间和真正时间的偏差以达到和绝对时间同步的目的。

     RTP payload类型

PT     Encoding Name     Audio/Video (A/V)     Clock Rate (Hz)     Channels     Reference 
0    PCMU    A    8000    1    [RFC3551]
1    Reserved                    
2    Reserved                    
3    GSM    A    8000    1    [RFC3551]
4    G723    A    8000    1    [Vineet_Kumar][RFC3551]
5    DVI4    A    8000    1    [RFC3551]
6    DVI4    A    16000    1    [RFC3551]
7    LPC    A    8000    1    [RFC3551]
8    PCMA    A    8000    1    [RFC3551]
9    G722    A    8000    1    [RFC3551]
10    L16    A    44100    2    [RFC3551]
11    L16    A    44100    1    [RFC3551]
12    QCELP    A    8000    1    [RFC3551]
13    CN    A    8000    1    [RFC3389]
14    MPA    A    90000         [RFC3551][RFC2250]
15    G728    A    8000    1    [RFC3551]
16    DVI4    A    11025    1    [Joseph_Di_Pol]
17    DVI4    A    22050    1    [Joseph_Di_Pol]
18    G729    A    8000    1    [RFC3551]
19    Reserved    A               
20    Unassigned    A               
21    Unassigned    A               
22    Unassigned    A               
23    Unassigned    A               
24    Unassigned    V               
25    CelB    V    90000         [RFC2029]
26    JPEG    V    90000         [RFC2435]
27    Unassigned    V               
28    nv    V    90000         [RFC3551]
29    Unassigned    V               
30    Unassigned    V               
31    H261    V    90000         [RFC4587]
32    MPV    V    90000         [RFC2250]
33    MP2T    AV    90000         [RFC2250]
34    H263    V    90000         [Chunrong_Zhu]
35-71    Unassigned    ?               
72-76    Reserved for RTCP conflict avoidance                   [RFC3551]
77-95    Unassigned    ?               
96-127    dynamic    ?              [RFC3551]
    除了上表中明确指定PT值的负载类型,还有些负载类型由于诞生的较晚,没有具体的PT值,只能使用动态(dynamic)PT值,即96到127,这就是为什么大家普遍指定H264的PT值为96。具体PT值的负载类型可以在这里查询到: RTP Payload Type


   RTP Payload H264详细文档可以参考:

    https://tools.ietf.org/html/rfc6184

    https://datatracker.ietf.org/doc/rfc6184/?include_text=1

    RTP负载为H.264定义了三种不同的基本的负载结构,接收端可能通过RTP负载的首字节来识别它们。这一个字节类似NALU头的格式,它的类型字段则指出了代表的是哪一种结构,这个字节的结构如下:

+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI|  Type   |
+---------------+
Type定义如下:
0     没有定义
1-23  NAL单元   单个NAL单元包.
24    STAP-A   单一时间的组合包
25    STAP-B   单一时间的组合包
26    MTAP16   多个时间的组合包
27    MTAP24   多个时间的组合包
28    FU-A     分片的单元
29    FU-B     分片的单元
30-31 没有定义

首字节的类型字段和H.264的NALU头中类型字段的区别是,当Type的值为24~31表示这是一个特别格式的NAL单元,而H.264中,只取1~23是有效的值。下面分别说明这三种负载结构。

一.Single NALU Packet(单一NAL单元模式)

    
    即一个RTP负载仅由首字节和一个NALU负载组成,对于小于1400字节的NALU便采用这种打包方案。这种情况下首字节类型字段和原始的H.264的NALU头类型字段是一样的。也就是说,在这种情况下RTP的负载是一个完整的NALU。

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

二. Aggregation Packet(组合封包模式)

    在一个RTP中封装多个NALU,对于较小的NALU可以采用这种打包方案,从而提高传输效率。即可能是由多个NALU组成一个RTP包。分别有4种组合方式,STAP-A、STAP-B、MTAP16和MTAP24。那么这里的RTP负载首字节类型值分别是24、25、26和27。

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

三.Fragmentation Units(分片封包模式FUs)


    一个NALU封装在多个RTP中,每个RTP负载由首字节(这里实际上是FU indicator,但是它和原首字节的结构一样,这里仍然称首字节)、FU header和NALU负载的一部分组成。对于大于1400字节的NALU便采用这种方案进行拆包处理。存在两种类型FU-A和FU-B,类型值分别是28和29。

FU-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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FU indicator  |   FU header   |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
|                                                               |
|                         FU payload                            |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               :...OPTIONAL RTP padding        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

FU-B类型如下图所示

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


与FU-A相比,FU-B多了一个DON(decoding order number),DON使用的是网络字节序。FU-B只能用于隔行扫描封包模式,不能用于其他方面。

FU indicator字节结构如下所示:

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

Type=28或29

FU header字节结构如下所示:

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

S(Start): 1 bit,当设置成1,该位指示分片NAL单元的开始。当随后的FU负载不是分片NAL单元的开始,该位设为0。
E(End): 1 bit,当设置成1, 该位指示分片NAL单元的结束,此时荷载的最后字节也是分片NAL单元的最后一个字节。当随后的FU荷载不是分片NAL单元的结束,该位设为0。
R(Reserved): 1 bit,保留位必须设置为0,且接收者必须忽略该位。

Type:与NALU头中的Type值相同


 

转载https://blog.csdn.net/li_wen01/article/details/68944149

猜你喜欢

转载自blog.csdn.net/linke_linux/article/details/88668557