RTP和RTCP
一、RTP
1、RTP简介
实时传输协议(Real-time Transport Protocol或简写RTP)是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的。RTP协议常用于流媒体系统(配合RTSP协议),视频会议和一键通(Push to Talk)系统(配合H.323或SIP),使它成为IP电话产业的技术基础。RTP协议和RTP控制协议(RTCP)一起使用,而且它是创建在UDP协议上的。
2、特征
RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 为了实行有序传送, RTP 中的***允许接收方重组发送方的包序列,同时***也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。
3、组成
RTP标准定义了两个子协议,RTP和RTCP。
(1)数据传输协议RTP:
用于实时传输数据。该协议提供的信息包括:时间戳(用于同步)、***(用于丢包和重排序检测)、以及负载格式(用于说明数据的编码格式)。
(2)控制协议RTCP:
用于QoS反馈和同步媒体流。相对于RTP来说,RTCP所占的带宽非常小,通常只有5%。
RTP 使用偶数端口号接收发送数据,相应的RTCP则使用相邻的下一位奇数端口号。RTP和RTCP使用UDP端口1024 - 65535。
4、RTP的协议层次
RTP(实时传输协议),顾名思义它是用来提供实时传输的,因而可以看成是传输层的一个子层。下图给出了流媒体应用中的一个典型的协议体系结构。
从图中可以看出,RTP被划分在传输层,它建立在UDP上。同UDP协议一样,为了实现其实时传输功能,RTP也有固定的封装形式。RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。服务质量由RTCP来提供。
RTP实现者在发送RTP数据时,需先将数据封装成RTP包,而在接收到RTP数据包,需要将数据从RTP包中提取出来。
RTP协议的目的是提供实时数据(如交互式的音频和视频)的端到端传输服务,因此在RTP中没有连接的概念,它可以建立在底层的面向连接(TCP)或面向非连接(UDP)的传输协议之上;RTP也不依赖于特别的网络地址格式,而仅仅只需要底层传输协议支持组帧(Framing)和分段(Segmentation)就足够了;
5、RTP的封装
RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。
下面是 RFC 3550 中规定的 RTP 头的结构:
0 1 2 3 4
0 1 2 3 4 5 6 7 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 负载类型 Payload type (PT): 7 bits
- *** Sequence number (SN): 16 bits
- 时间戳 Timestamp: 32 bits
- 版本号(V):RTP协议的版本号,占2位,当前协议版本号为2
- 填充位(P):填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
- 扩展位(X):扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头
- CSRC计数器(CC):CSRC计数器,占4位,指示CSRC 标识符的个数(作用信源CSRC计数器)
- 标志位(M): 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。(对于分组中的重要事件可用该位标识)
- 载荷类型(PT): 有效荷载类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。
- ***(SN):占16位,用于标识发送者所发送的RTP报文的***,每发送一个报文,***增1。这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。同时出现网络抖动的情况可以用来对数据进行重新排序,***的初始值是随机的,同时音频包和视频包的sequence是分别记数的。
- 时戳(Timestamp):占32位,必须使用90 kHz 时钟频率。时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。
- 同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。同步信源是指产生媒体流的信源,例如麦克风、摄像机、RTP混合器等;它通过RTP报头中的一个32位数字SSRC标识符来标识,而不依赖于网络地址,接收者将根据SSRC标识符来区分不同的信源,进行RTP报文的分组。
- 特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。特约信源是指当混合器接收到一个或多个同步信源的RTP报文后,经过混合处理产生一个新的组合RTP报文,并把混合器作为组合RTP报文的 SSRC,而将原来所有的SSRC都作为CSRC传送给接收者,使接收者知道组成组合报文的各个SSRC。
RTP扩展头:
很多时候,在传输H264数据的时候,也需要传输其他的协议数据信息,这个时候,就可以放在RTP的扩展头部分传输。根据上面RTP协议格式,第一个字节的bit2(X),这个字段如果是1的话,就表示当前RTP协议带着扩展头。
这个扩展头就跟在RTP确定的头部后面。如果有CSRC,就跟在CSRC后面,CSRC的个数,可以看第一个字节的bit4~bit7(CC),每一个CSRC 4个字节。这样就可以确定扩展头的位置了。
扩展头的内部格式:
0 1 2 3 4
0 1 2 3 4 5 6 7 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| defined by profile | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| header extension |
...... ......
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- defined by profile :按照私有的协议文档自己定义就行了,相当于一个标识。
- length:扩展头长度,更确切地说,是扩展头个数,比如length == 2,标识有两个,每个扩展头4字节,则共 2 * 4 = 8字节。即扩展头内容长度为 4 * length(字节)。
6、RTP的会话过程
当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包,使得RTP/RTCP数据能够正确发送。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。 RTP的发送过程如下,接收过程则相反。
(1)RTP协议从上层接收流媒体信息码流(如H.263),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。
(2) RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。
7、h264的rtp打包
(1)单NALU: P帧或者B帧比较小的包,直接将NALU打包成RTP包进行传输 RTP header(12bytes) + NALU header (1byte) + NALU payload
(2)多NALU: 特别小的包几个NALU放在一个RTP包中
(3)FUs(Fragment Units): I帧长度超过MTU的,就必须要拆包组成RTP包了,有FU-A,FU-B
问答:
(a)NALU头不见了,如何判断类型?实际上NALU头被分散填充到FU indicator和FU header里面了。bit位按照从左到右编号0-7来算,nalu头中0-2前三个bit放在FU indicator的0-2前三个bit中,后3-7五个bit放入FU header的后3-7五个中
//NALU header = (FU indicator & 0xe0) | (FU header & 0x1F) 取FU indicator前三和FU header后五
headerStart[1] = (headerStart[0]&0xE0)|(headerStart[1]&0x1F);
(b)多个RTP包如何还原组合成回一个完整的I帧? 在FU header中有标记为判断。
照旧从左到右,Fu header前两个bit表示start和end标记,start为1表示一个i帧分片开始,end为1表示一个i帧分片结束
(c)如何查看是一个I帧分片开始?
看第一个字节FU Indicator,照旧从左到右,Fu Indicator前三个bit是NALU头的前三个bit,后五位为类型FU-A:28(11100),FU-B:29(11101)。
RTP抓包看下来整个字节是0x7c开头。
如果不是分片,第一字节就是NALU头,如:0x67,0x68,0x41等
二、RTCP
1、RTCP功能
服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。在RTP会话期间,各参与者周期性地传送RTCP包。RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,各参与者可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。
2、RTCP分组类型
RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,因而分组很短,所以可以将多个RTCP分组封装在一个UDP包中。RTCP有如下五种分组类型。
类型 |
缩写表示 |
用途 |
200 |
SR(Sender Report) |
发送端报告 |
201 |
RR(Receiver Report) |
接收端报告 |
202 |
SDES(Source Description Items) |
源点描述 |
203 |
BYE |
结束传输 |
204 |
APP |
特定应用 |
- SR:发送端报告,所谓发送端是指发出RTP数据报的应用程序或者终端,发送端同时也可以是接收端。
- RR:接收端报告,所谓接收端是指仅接收但不发送RTP数据报的应用程序或者终端。
- SDES:源描述,主要功能是作为会话成员有关标识信息的载体,如用户名、邮件地址、电话号码等,此外还具有向会话成员传达会话控制信息的功能。
- BYE:通知离开,主要功能是指示某一个或者几个源不再有效,即通知会话中的其他成员自己将退出会话。
- APP:由应用程序自己定义,解决了RTCP的扩展性问题,并且为协议的实现者提供了很大的灵活性。
所有RTCP包至少必须以两个包组合形式发送,推荐格式如下:
- 加密前缀(Encryption prefix):
仅当组合包被加密,才加上一个32位随机数用于每个组合包发送。
- SR或RR:
组合包中第一个RTCP包必须是一个报告包,以帮助分组头的确认。即使没有数据发送,也没有接收到数据,也要发送一个空RR,那怕组合包中RTCP包为BYE。
- 附加RR:
如报告统计源数目超过31,在初始报告包后应该有附加RR包。
- SDES:
包含CNAME 项的SDES包必须包含在每个组合RTCP包中。SDES包可能包括其他源描述项,这要根据特别的应用需要,并同时考虑带宽限制。
- BYE或APP:
除了BYE应作为最后一个包发送,其它RTCP包类型可以任意顺序排列,包类型出现可不止一次。
混合器从多个源组合单个RTCP包,如组合包整体长度超过网络路径最大传输单元,可分成多个较短组合包用低层协议以单个包形式发送。注意,每个组合包必须以SR或RR包开始。附加RTCP包类型可在Internet Assigned NumbersAuthority (IANA)处注册,以获得合法的类型号。
2、SR类型
上述五种分组的封装大同小异,下面只讲述SR类型,而其它类型请参考RFC3550。
- 版本(V):同RTP包头域。
- 填充(P):同RTP包头域。
- 接收报告计数器(RC):5比特,该SR包中的接收报告块的数目,可以为零。
- 包类型(PT):8比特,SR包是200。
- 长度域(Length):16比特,其中存放的是该SR包以32比特为单位的总长度减一。
- 同步源(SSRC):SR包发送者的同步源标识符。与对应RTP包中的SSRC一样。
- NTP Timestamp(Network time protocol):SR包发送时的绝对时间值。NTP的作用是同步不同的RTP媒体流。
- RTP Timestamp:与NTP时间戳对应,与RTP数据包中的RTP时间戳具有相同的单位和随机初始值。
- Sender’s packet count:从开始发送包到产生这个SR包这段时间里,发送者发送的RTP数据包的总数. SSRC改变时,这个域清零。
- Sender`s octet count:从开始发送包到产生这个SR包这段时间里,发送者发送的净荷数据的总字节数(不包括头部和填充)。发送者改变其SSRC时,这个域要清零。
- 同步源n的SSRC标识符:该报告块中包含的是从该源接收到的包的统计信息。
- 丢失率(Fraction Lost):表明从上一个SR或RR包发出以来从同步源n(SSRC_n)来的RTP数据包的丢失率。
- 累计的包丢失数目:从开始接收到SSRC_n的包到发送SR,从SSRC_n传过来的RTP数据包的丢失总数。
- 收到的扩展最大***:从SSRC_n收到的RTP数据包中最大的***,
- 接收抖动(Interarrival jitter):RTP数据包接受时间的统计方差估计
- 上次SR时间戳(Last SR,LSR):取最近从SSRC_n收到的SR包中的NTP时间戳的中间32比特。如果目前还没收到SR包,则该域清零。
- 上次SR以来的延时(Delay since last SR,DLSR):上次从SSRC_n收到SR包到发送本报告的延时。
3、RTCP组合包的约束
不同类型的RTCP信息包可堆叠,不需要插入任何分隔符就可以将多个RTCP包连接起来形成一个RTCP组合包,然后由低层协议用单一包发送出去。由于需要低层协议提供整体长度来决定组合包的结尾,在组合包中没有单个RTCP包的显式计数。
组合包中每个RTCP包可独立处理,而不需要按照包组合的先后顺序处理。在组合包中有以下几条强制约束:
- 只要带宽允许,在SR包或RR包中的接收统计应该经常发送,因此每个周期发送的组合RTCP 包中应包含报告包。
- 每个组合包中都应该包含SDES CNAME,因为新接收者需要通过接收CNAME来识别源,并与媒体联系进行同步。
- 组合包前面是包类型数量,其增长应该受到限制。
4、相关协议
(1)实时流协议RTSP
实时流协议RTSP(Real-Time Streaming Protocol)是IETF提出的协议,对应的RFC文档为RFC2362。
从上图可以看出,RTSP是一个应用层协议(TCP/IP网络体系中)。它以C/S模式工作,它是一个多媒体播放控制协议,主要用来使用户在播放流媒体时可以像操作本地的影碟机一样进行控制,即可以对流媒体进行暂停/继续、后退和前进等控制。
(2)资源预定协议RSVP
资源预定协议RSVP(Resource Reservation Protocol)是IETF提出的协议,对应的RFC文档为RFC2208。
从上可以看出,RSVP工作在网络层是一个网络控制协议。RSVP通过在路由器上预留一定的带宽,能在一定程度上为流媒体的传输提供服务质量。在某些试验性的系统如网络视频会议工具vic中就集成了RSVP。