目录
一、UDP与TCP
1. TCP
2. UDP
二、RTP
1. RTP协议头
(1)V(Version)字段
(2)P(Padding)字段
(3)X(eXtension)字段
(4)CC(CSRC Count)字段
(5)M(Marker)字段
(6)PayloadType:区分音、视频类型
(7)Sequence Number:快速定位丢失数据包
(8)timestamp字段
(9)SSRC:区分不同源(参与人)的数据
(10)CSRC字段
2.RTP使用
3.RTP扩展头
4. RTP中的填充数据
三、RTCP
1. RTCP报文分类
(1)SR(Sender Report)报文
(2)RR(Receiver Report)报文
(3)SDES(Source Description)报文
(4)BYE报文
(5)APP报文
(6)RTPFB报文
(7)PSFB报文
四、总结
一、UDP与TCP
1. TCP
TCP为了实现数据传输的可靠性,采用的是“发送→确认→丢包→重传”这样一套机制。而且为了增加网络的吞吐量,还采用了延迟确认和Nagle算法(Nagle算法,将多个小包组成一个大包发送,组合包的大小不超过网络最大传输单元)。这套机制就是TCP产生延迟的根本原因。
为了增加网络的吞吐量,接收端不必每收到一个包就确认一次,而是对一段时间内收到的所有数据集体确认一次即可。为了实现该功能,TCP通常会在接收端启动一个定时器。定时器的时间间隔一般设置为200ms,即每隔200ms确认一次接收到的数据。这就是延迟确认机制。除此之外,TCP在发送端也启动了一个定时器,不过该定时器的功能不是发送确认消息,而是用来判别是否有丢包的情况。发送端定时器的时长为一个RTO(Retransmission Timeout,重传超时时长。其值约等于RTT的平均值,每次超时后以指数级增长。RTT表示一个数据包从发送端到接收端,然后再回到发送端所用的时长)。如果在定时器超时后仍然没有收到包的确认消息,则认为包丢失了,需要发送端重发丢失的包。这就是TCP的丢包重传机制。
2. UDP
UDP属于不可靠传输协议。在传输数据时,它不保证数据能可靠到达,也不保证数据有序,但它最大的优点就是传输速度“快”。由于UDP没有TCP那一套保证数据可靠、有序的控制逻辑,所以它不会被“人为”地变慢,因此它的实时性是最高的。
争对UDP丢包和抖动的问题,WebRTC给出了一套比较完美的解决方案,通过NACK、FEC、Jitter Bufer以及NetEQ技术既可以解决丢包和抖动问题,又不会产生影响服务质量的时延。通过上面的分析可以知道,由于TCP在极端网络情况下无法控制传输的时延大小,所以在做实时通信传输时,应该首选UDP。
二、RTP
实时通信产品首选的传输协议是UDP。但UDP也有其缺陷,尤其是用它传输一些有前后逻辑关系的数据时,就显得捉襟见肘了,而音视频数据正是这种数据。为了解决这个问题,在传输音视频数据时,通常在UDP之上增加一个新协议,即RTP(实时传输协议)。
RTP属于应用层传输协议的一种,它与HTTP/HTTPS处于同一级别。
1. RTP协议头
(1)V(Version)字段
占2位,表示RTP的版本号,现在使用的都是第2个版本,所以该域固定为2。
(2)P(Padding)字段
占1位,表示RTP包是否有填充值。为1时表示有填充,填充以字节为单位。一般数据加密时需要固定大小的数据块,此时需要将该位置1。
(3)X(eXtension)字段
占1位,表示是否有扩展头。如果有扩展头,扩展头会放在CSRC之后。扩展头主要用于携带一些附加信息。详见下文。
(4)CC(CSRC Count)字段
占4位,记录了CSRS标识符的个数。每个CSRC占4字节,如果CC=2,则表示有两个CSRC,共占8字节。
(5)M(Marker)字段
其含义是由配置文件决定的,一般情况下用于标识边界。比如一帧H264被分成多个包发送,那么最后一个包的M位就会被置位,表示这一帧数据结束了。
(6)PayloadType:区分音、视频类型
为了让接收端可以区分出从同一端口获取的不同类型的数据,RTP在其协议头中设置了PT(PayloadType)字段,通过该字段就可以将不同类型的数据区分出来。比如VP8的PT一般为96,而Opus的PT一般为111。
(7)Sequence Number:快速定位丢失数据包
如果给每个发送的数据包都打上一个编号,并且编号是连续的,那么,接收端就可以很容易地判断出哪些包丢失了。在RTP头中,有一个专门记录该编号的字段,称作Sequence Number。
(8)timestamp字段
占4字节,用于记录该包产生的时间,主要用于组包和音视频同步。
(9)SSRC:区分不同源(参与人)的数据
同一个端口不仅可以同时传输不同类型的数据包,还可以传输同一类型但不同源的数据包。比如流媒体服务就可以将多个不同源(参与人)的视频通过同一个端口发送给客户端。那么客户端(接收端)又是如何将不同源的数据区分出来的呢?这就要说到RTP中另一个字段SSRC了。
RTP要求所有不同的源的数据流之间可以通过SSRC字段进行区分,且每个源的SSRC必须唯一。Sequence Number也是与SSRC关联在一起的。也就是说,每个SSRC所代表的数据流的Sequence Number都是单独计数的。
(10)CSRC字段
指该RTP包中的数据是由哪些源贡献的。比如混音数据是由三个音频混成的,那么这三个音频源都会被记录在CSRS列表中。
2.RTP使用
关于RTP的使用主要包括以下两个方面:一是创建/解析RTP包;二是根据RTP包进行逻辑处理,比如创建一个接收队列来消除包抖动。(WebRTC中解决RTP包抖动的缓冲队列就是我们通常所说的JitterBufer)
3.RTP扩展头
RTP头中的X位用于标识RTP包中是否有扩展头。即如果X位为1,则说明RTP包中含有扩展头。
RTP扩展头由三部分组成,分别为profile、length以及header extension。其中,profile字段用于区分不同的配置。在RFC5285中定义了两种profile,分别是{0xBE,0xDE}和{0x10,0x0X}。接收端解析RTP扩展头时,通过profile来区分header extension中的内容该如何解析。length字段表示扩展头所携带的header extension的个数。如果length为4,表示有4个header extension;header extension字段是扩展头信息,以4字节为单位,其具体含义由profile决定。
扩展头中的两个profile值{0xBE,0xDE}和{0x10,0x0X}分别代表存放在header extension中的两种不同的数据格式,即one-byte-header和two-byte-header。
RTP扩展头有三个要点:
- 一是RTP标准头中的X位,该位置1时,RTP中才会有扩展头。
- 二是扩展头中的profile字段指明了扩展头中数据的格式。如果profile为0xBEDE,则说明使用的扩展头格式为one-byte-header;如果profile为0x100X(X表示任意值),则说明使用的扩展头格式为two-byte-header。
- 三是one-byte-header与two-byte-header的区别。如果ID和len放在一个字节中,说明它是one-byte-header格式;如果ID和len放在两个字节中,说明它是two-byte-header格式。
4. RTP中的填充数据
与RTP扩展头类似,RTP头中的P位用于标识RTP包中是否有填充数据。如果P位为1,说明RTP包中含有填充数据。
当RTP包中包含有填充数据时,其数据包的最后一个字节记录着包中填充字节的个数,即图中的Padding Size部分。如果Padding Size为5,说明RTP包中共有5个填充字节,其中包括它自己。这些填充数据不属于RTP Payload的部分,因此在解析RTP Payload部分之前,应将填充部分去掉。
三、RTCP
除了RTP外,在RTP协议簇中还包括RTCP,其与RTP处于同一层级。RTCP是RTP的控制协议,其中最为大家熟知的就是丢包控制。
1. RTCP报文分类
(1)SR(Sender Report)报文
发送端报告,向接收端发送,包含发送端的统计信息,如发送的数据包数量、字节数、丢包数量等。
(2)RR(Receiver Report)报文
接收端可以使用RTCP的RR报文向发送端发送接收报告,报告中记录着从上一次报告到本次报告之间丢失了多少包、丢包率是多少、延时是多少等一系列信息。
(3)SDES(Source Description)报文
源描述报文,包含有关参与会话的参与者的信息,如CNAME(参与者的标识符)、名称、电话号码等。
(4)BYE报文
结束会话报文,用于说明哪些(音视频)媒体源现在不可用了。当WebRTC收到该报文后,应该将SSRC所对应的通道删除。
(5)APP报文
给应用预留的RTCP报文,应用可以根据自己的需要自定义一些应用层可以解析的报文。
(6)RTPFB报文
RTP的反馈报文,是指RTP传输层面的报文。该报文可以装入不同类型的子报文。该报文中可以包含多个子报文,其中WebRTC使用到的报文只有4项。
- NACK,接收端用于通知发送方在上次包发送周期内有哪些包丢失了。在NACK报文中包含两个字段:PID和BLP。PID(Package ID)字段用于标识从哪个包开始统计丢包;而BLP(16位)字段表示从PID包开始,接下来的16个RTP包的丢失情况。
- TMMBR和TMMBN是一对报文,TMMBR表示临时最大码流请求报文,TMMBN是对临时最大码流请求的应答报文。这两个报文虽然在WebRTC中实现了,但已被WebRTC废弃,其功能由TFB和REMB报文所代替。
- TFB是WebRTC中TCC算法的反馈报文,该报文会记录包的延迟情况,然后交由发送端的TCC算法计算下行带宽。
(7)PSFB报文
RTP中与负载相关的反馈报文。同样,该报文也可以装入不同类型的子报文。
- PLI报文与FIR报文很类似,当发送端收到这两个报文时,都会触发生成关键帧(IDR帧),但两者还是有一些区别的。PLI报文是在接收端解码器无法解码时发送的报文。FIR报文主要应用于多方通信时后加入房间的参与者向已加入房间的共享者申请关键帧。通过这种方式,可以保障后加入房间的参与者不会因收到的第一帧不是关键帧而引起花屏或黑屏的问题。
- REMB报文是WebRTC增加的反馈报文,用于将接收端评估出的带宽值发给发送端。不过,由于最新的WebRTC已全面启用基于发送端的带宽估算方法,即TCC,因此目前REMB仅用于向后兼容,不再做进一步更新。
四、总结
RTP是一个非常轻量的传输协议,特别适合传输音视频数据,或者说它就是专门为传输音视频数据而开发的。RTP控制协议RTCP对于传输服务质量起着关键的作用,WebRTC的服务质量系统中的大量控制参数都是通过RTCP获取的。