聊聊WebRTC网关服务器4:QoS方案分析

聊聊WebRTC网关服务器4:QoS方案分析

《聊聊WebRTC网关服务器》系列文章系由WebRTCon2018中网易云信音视频技术专家的分享内容《从零开始构建音视频网关服务器》整理而成,该系列文章将和大家分享网易NRTC在WebRTC网关项目的自研过程中遇到的一些问题,以及我们最终的解决方法。

大家都知道音视频应用中的QoS策略是非常重要的部分,这里我简单为大家介绍一下WebRTC网关服务端的QoS内容,因为篇幅问题,具体的算法细节这里就不作阐述了。

本篇文章分享的内容会涉及:NACK、PLI、RTT、GCC算法、REMB与Transport-CC,ULP-FEC。

WebRTC的QoS是一个非常大的门类,也是非常重要的方向,它里面涵盖的内容非常多。有大量的QoS策略是在客户端上实现的。而对于Web来说,那些客户端侧的策略你是没办法修改的,只能通过SDP里面的配置项,来选择需要开启的策略。

首先为了开启NACK,在SDP中需要配置支持NACK属性。A发送数据到网关,网关针对上行请求NACK,转发数据包给B,同时Cache上行数据,B向网关请求NACK,由于网关的数据做了Cache,所以NACK的请求直接在服务器上回包。NACK的请求的触发条件也比较复杂,它依赖准确的RTT、NACK的重试次数、超时时间以及上行带宽。

有一个新用户加入,网关会发送FIR。当上行NACK无法恢复视频数据时,网关还会按RTT以及带宽评估的结果,向客户端发起PLI请求。另外针对特殊场景,如:互动直播秒开,就需要一个较短的定时发送PLI,时间大概在2~3秒。

NACK、PLI的算法策略中,RTT的准确计算是非常重要的。

RTT怎么计算?我们采用RTCP-XR方案,其实网关首先会发送一个RTCP-XR的RRTR协议,这个协议里面会包含了网关当前的NTP时间。WebRTC客户端收RRTR之后,它会有一些回包策略,比如基于上行带宽、拥塞情况和定时器的因素,它会在一段时间之内给RRTR回包DLRR。回的这个数据包里面包含了两时间,一个是原封不动的RRTR里NTP时间为LRR,第二个时间就是客户端从收到这个RRTR到发送DLRR的时间间隔,这个很好理解。

网关收到DLRR以后的处理就很简单了,首先是把本地的时间减去LRR,就是我原来发送的数据包的时间,再减去你发送的这个时间间隔,RTT就计算出来了,计算公式如上图所示。

接下来是比较重要的模块。WebRTC拥塞控制GCC算法,核心模块有三个:

  1. 到达时间滤波器;
  2. 过载检查器;
  3. 速率控制器。

当前网关使用的是REMB方案,为使用REMB需要首先在SDP里面配置相应的内容,这样在 RTP头部的会在扩展字段里面增加发送的绝对时间戳,而网关上的实现重点就是将GCC的基于时延的带宽估计算法移植到服务器上,服务器估算出用户的上行带宽以后,就可以通过REMB将带宽反馈回客户端。客户端根据反馈的带宽以及RR反馈的丢包进行综合的拥塞控制,包括视频码率、帧率以及分辨率的调整,以及音频码率的调整。

对于REMB方案,还需要综合考虑上下行链路。在整个视频会议中,各个与会者的下行网络的情况、带宽是不一致的。所以如果REMB回包的时候只考虑了上行网络的情况,在用户的上行网络较好时,会导致上行的码率过大,而导致同个会议中的其它网络一般的用户的下行拥塞,造成卡顿。因此在使用REMB方案时要考虑到不同与会者上下行网络的不对称,采用相应的策略,控制上下行的码流。

针对会议中上下行带宽和网络不一致的情况,业界一般有三种做法:

  1. 控制用户的上行带宽,以适应会议中最差那个与会者;
  2. 在服务器端上做转码,根据不同的用户下行网络,转码出不同的分辨率/帧率的视频;
  3. 客户端采用Simulcast多路上行,服务器为下行选择最适应的那一路作为下行。

三种方案各有优劣,大家可以按项目的具体场景和需求来选择。

Transport-CC就是刚才说的另外一种方案,现在火狐还不支持,谷歌Chrome支持。要使用了Transport-CC,首先需要在SDP配置“a=extmap:5 ietf.org/id/draft-holme”,通过配置后,WebRTC客户端在发包时就会RTP的扩展字段里面增加一个绝对序列号。Transpot-CC其实是一种反馈协议,采用这种协议后服务器端不再需要实现具体的GCC算法,只需要把统计到的收包序列号以及相关delay信息封装在这个协议里面,反馈回发送端,发送端就会自己根据回包做相关的GCC算法。

WebRTC为什么要这么做?

按我个人的理解:因为WebRTC认为各端实现的GCC算法质量是不可控的,比如不同的厂家在实现GCC的算法不一样,反馈给发送方的带宽也不可靠,不能完全信任。而对于发送方来说,本端的GCC的算法是最符合本端的标准的,对于发送端只需要获得对端的统计信息,就能在发送端做拥塞控制。但是这样做对于我们网关的服务器来说,我们对整个QoS的控制权就会变小,所有的控制权都会在端上,当前WebRTC的网关服务器使用的还是REMB。未来谷歌更倾向于Transport-CC,REMB会慢慢退出,因此我们也在调研如何使用Trasnport-CC的方案,更好的提高拥塞控制的效果。

QoS模块的最后一点就是FEC。FEC前向纠错是在实时通话领域是必不可少的。ULP-FEC是当前WebRTC使用的基于XOR的FEC算法,但是经过我们测试在WebRTC中打开FEC没有起到效果,为了定位这个问题我们看了一下WebRTC的源码。

按照WebRTC客户端源码的注释,我们可以清楚的看到,如果视频编码使用H264,在开启NACK的前提下,FEC是直接关闭的。主要原因是RTP在封装H264时没有picture
ID,所以在同时开了NACK和FEC的时候,会浪费带宽重传一些没有必要的数据,重传效率很低,同时因为无法识别是哪一帧,在接收端还需要进行卡顿等待,因此效果比单独开NACK要差,所以我们就没有使用NACK+FEC,WebRTC在新版本的FlexFEC解决了这个问题,但是当前FlexFEC还处于实验阶段。但是FEC无法使用,这是非常大的一个损失。

另外,音频的ULP-FEC也没办法用,音频主要用的FEC就是Opus的inband FEC,这个是有SDP的选项的,需要使用的时候打开。

最后我可以看一下NRTC的QoS技术。NRTC和WebRTC不一样,NRTC是私有协议,所以可以做很多WebRTC标准协议以外的策略。NRTC整个的QoS的策略是跟场景模式相关的。我们有不同的场景,需要流畅,需要清晰,还是需要低带宽,还有全自动自适应场景,不同场景的QoS的策略有不同的定制。第二就是有一个智能的FEC的策略,因为FEC在WebRTC里面没办法使用,因此在NRTC里面使用了智能FEC之后它的效果会比WebRTC提高一个水平。同时,因为NRTC将FEC与NACK深度结合,用FEC恢复一些包,用NACK重传一些包,可以做到重传和恢复的最佳的效率,同时,NRTC的服务端还会考虑更多的上下行网络情况,因为是基于私有协议的,所以在回调网络情况的时候就会做得更加智能和更贴近真实的网络情况,在上下行数据选择的时候也可以针对不同的下行网络选择不同的分辨率策略与FEC冗余度。

最后看一下这个效果,可以看到NRTC相比于WebRTC在弱网对抗方面做得会更优秀一些。

以上就是我对WebRTC QoS方案的分析以及对NRTC的QoS技术的介绍,非常感谢各位的关注,欢迎大家积极留言,与我们交流你的想法和见解。

发布于 2018-06-01