介绍RTP之前我们来先看看为什么需要RTP
为什么是UDP
首先我们都知道TCP/IP协议
在传输层,它提供了节点间的数据传送服务,其中最为人所熟知的TCP协议(Transmission Control Protocol) 和 UDP协议(User Datagram Protocol) 。但是WebRTC为什么选择了UDP作为传输协议呢,对于实时音视频来说,延迟是非常敏感的。
首先,在超时重传上面,TCP协议的超时重传机制中RTT是以2的指数的增长,比如第一次失败了是1s,第二次就是2s,第三次就是4s...如果第七次之后仍然超时,则断开 TCP 连接。最坏情况7次重传失败,理论上会达到2分78秒。在延迟高的情况下,想做到正常的实时通讯显然是不可能的。其次相对于TCP来说UDP在传输数据之前不需要建立连接,传输双方可以随时发送数据,因此UDP是无连接的。而TCP协议在传输数据之前三次握手建立连接,在结束后需要四次挥手释放连接。
基于上面的原因WebRTC选择了UDP作为传输协议,而且实时音频视频数据在传输的少量数据包丢失,对接收者影响并不大。
RTP/RTCP
实时音视频如果只靠UDP是不能保证可靠性的,所以在应用层使用了RTP协议来做保障。
RTP
上一篇文章讲到视频帧的I帧最小也要几十K,而以太网的最大传输单元MTU的最大为1500字节,也就是1.5k,所以发送一个I帧需要发送几十个数据包过去,那么收到的对端需要重组成I帧,这样才能还原之前的I帧。但是如果要我们自己实现就需要标识几个东西
- 序号用于丢包和数据包排序。
- 时间戳,用于记录是哪一帧的数据包。不同帧的时间戳是肯定不一样的。
- 载荷类型,是音频还是视频
光靠UDP是肯定不能保证我们的出错在哪里,所以需要使用RTP(Real-timeTransportProtocol)作为应用层的协议。它提供了我们上面需要了几个东西。但是不包括保证送达和时序等。
那我们先来看看RTP报文长什么样吧
这里介绍一下RTP的头部
- V:version,RTP的协议版本号,2bits,当前版本号为2。
- P:padding,填充位,1bit,如果设置了该字段,报文的末尾会包含一个或多个填充字节,这些填充字节不是payload的内容。
- X:extension,1bit,如果设置了该字段,那么头数据后跟着一个拓展数据。
- CC:CSRC count,4bits,指示CSRC标识符个数。
- M:marker,1bit,标记位,一般界定视频帧的边界,具体由profile定义。
- PT:payload type,7bits,数据的载荷类型,可以用来区分音频还是视频
- Sequence number:16bits,每发送一个RTP报序号都会加一,可以通过这个字段来确定报的顺序,一般这个序号是随机的。
- Timestamp:32bits,时间戳翻页了RTP数据包生成的时候的第一块数据报的时刻,同一帧的不同分片时间戳是相同的。
- SSRC:32bits,该字段用来确定数据的发送源。
- csrc list
但是光靠RTP传输,也是会发生丢包的问题。一般可能由于网络问题导致丢包。WebRTC 对这种问题在底层都有相应的处理策略,但在处理这些问题之前,它首先要让各端都知道它们自己的网络质量到底是怎样的,这就是 RTCP 的作用。
RTCP定义了许多包类型来传输不同的控制信息:
- SR:发送者报告,发送者数据发送和接受的统计。
- RR:接收者报告,只接受数据的节点的接受统计。
- SDES:Source描述,包括CNAME
- BYE:表示退出
- APP:上层应用自定义
RTCP 有两个最重要的报文:RR(Reciever Report)和 SR(Sender Report)。通过这两个报文的交换,各端就知道自己的网络质量到底如何了。
这里通过SR报文来看看都包括了那些信息,
SR报文包含三个部分,第一个部分是报头,有8字节,各个字段的含义如下:
- version (V): 2 bits RTP协议版本
- padding (P): 1 bit 是否包含填充,最后一个填充字节标识了总共需要忽略多少个填充字节(包括自己)。Padding可能会被一些加密算法使用,因为有些加密算法需要定长的数据块。在复合包中,只有最后一个RTCP包需要添加填充。
- reception report count (RC): 5 bits 有多少个接受报告。可以为0。
- packet type (PT): 8 bits 200表示SR报文,201是RR报文。
- length: 16 bits 报文长度(按32-bit字统计),包含头部和填充字节。
- SSRC: 32 bits 身份定位符。
第二部分是发送方信息,长度为20字节,出现在每个发送方报告分组中。总结了这个发送方的传输统计。
- NTP timestamp: 64 bits Wallclock time,用于计算RTT。
- RTP timestamp: 32 bits RTP时间戳,基于NTP的某一随机偏移量。用于媒体数据内同步。
- sender's packet count: 32 bits 这个SSRC总共发送了多少包
- sender's octet count: 32 bits 这个SSRC总共发送了多少BYTE的数据。
第三部分可能什么都没有,也可能有多个接收报告,这取决的上次报告以后收到了多少个Sender的数据。每个报告块统计了一个SSRC的包数。具体内容如下:
- SSRC_n (source identifier): 32 bits 这个信息块对应的SSRC。
- fraction lost: 8 bits 上次SR或RR发送后到目前为止的丢包率。
- cumulative number of packets lost: 24 bits 整体过程的丢包总数。
- extended highest sequence number received: 32 bits 低16-bit是收到的最新的RTP报文序列号,高16-bit是序列号循环的次数。
- interarrival jitter: 32 bits RTP数据报文抵达时间的抖动。如果Si代表i包中包含的RTP时间戳,Ri代表i包被接受时的RTP时间戳,那两个包i和j的到达时间抖动算法如下:
D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)。 我们在计算这个抖动时,要结合每个包的抖动,来计算一个平均值,计算平均值的方案如下:J(i) = J(i-1) * (15 / 16) + (|D(i-1,i)|)/16 - last SR timestamp (LSR): 32 bits 该SSRC最后一个RTCP报文(SR)中带的NTP时间。
- delay since last SR (DLSR): 32 bits 从该SSSR最后一个RTCP报文(SR)被收到以来经过的时间。
通过以上的分析,你可以发现SR 报文并不仅是指发送方发了多少数据,它还报告了作为接收方,它接收到的数据的情况。当发送端收到对端的接收报告时,它就可以根据接收报告来评估它与对端之间的网络质量了,随后再根据网络质量做传输策略的调整。
这里简单介绍为什么实时音视频选择UDP作为传输层协议,以及简单介绍WebRTC所涉及协议中比较重要的两个协议RTP/RTCP。webRTC中还有非常多的技术,3A算法等等。下一篇将会介绍SDP。