文|网易智慧企业资深流媒体开发工程师算法
背 景服务器
科技的进步以及通信基建的高速发展,使得人们对交流的模式要求愈来愈即时,对交流内容要求愈来愈具象,这些要求催化着内容交换模式的不断发展,从传统的信件,到短信电话再到互联网场景下的微信语音、抖音短视频、视频直播及实时音视频通话。随着5G正式商用元年的真正到来,更加即时与具象的实时音视频通信将被更普遍的应用。实时音视频系统,是一个相对比较复杂的内容传输系统,从大的流程上来说,系统覆盖音视频采集、音视频编码、音视频传输、音视频解码、音视频绘制。想要作到高质量的音视频通话,每一个环节都须要丰富的手段才能进行各类场景及设备的适配与效果提优。微信
实时音视频的最显著的特色是低延迟,也就是说实时音视频对于网络的要求是很是高的,甚至能够说是矛盾的。一方面它为了追求低延迟,它可以容许网络传输中的丢包,另外一方面由于视频编解码的传递参考性,任何的丢包都会形成很大的视频质量的损失,最终将下降实时通话的QoE评价,因此又不能容忍网络传输中的丢包。为此搭建一个高质量实时音视频系统,尤为是多方参与的会议系统,应对于参与通话各方上下行网络复杂性(带宽受限/丢包/抖动/高时延)的传输QoS策略的设计是很是有必要的。本文就会议场景下,服务器端的QoS策略,作一些详细的分享。网络
会议场景分段QoS并发
会议场景的通话,决定了参与通话的各方都要经过中转的流媒体分发服务器进行传输内容的交换。会话传输链路能够划分为实时通话发送端到流媒体分发服务器的上行传输链路,以及流媒体分发服务器到实时通话接受端的下行传输链路。上下行传输链路,从服务器角度而言其承担传输角色是不一样的,传输策略做用轻重亦不相同,为此针对于这种多人会议场景,须要制定上下行独立的QoS传输方案,去保障上下行的传输质量。咱们称之为分段QoS策略。框架
上行QoS高并发
网易云信的设计里,QoS的强控制权都交由发送端。接收端作被动的接受信息反馈和丢包请求与恢复。针对于上行QoS的策略,服务器端做为接收端,设计了一系列的QoS手段,进行高可靠的链路传输。包括但不局限于:丢包重传请求(NACK)、前向纠错(FEC)、关键帧请求(PLI/FIR)、接受信息反馈(FeedBack)等手段。这里选取两个抗丢包手段作一些深刻的讲解。性能
丢包重传请求 测试
丢包重传请求,简单的实现就是服务器做为接收端,在实时接收传输的流媒体的时候,进行传输层媒体包序的连续性检查,当出现非连续包出现的时候,通过必定的超时时间(考虑到实时音的低时延要求每每这个超时时间会设置的比较短),便会向发送端进行丢失包的重传请求。因为丢包的不肯定性,丢失的包序的分布也会呈现出不肯定性。为此咱们须要设计出一个合适的重传协议来覆盖丢包的各类分布状况,达到重传请求的最小带宽占用的目的。优化
咱们设计了灵活NACK请求协议,其协议设计能够很好的解决上述状况:
协议容许单个NACK请求包对多个流,进行不一样丢包状况的重传请求。
前向纠错
前向纠错(FEC)实际上是一种冗余错误恢复的算法。应用在网络传输中,主要是用来抵抗网络丢包致使的信源错误。
其具体的作法就是将原始的信源数据进行可逆的运算,生成额外的冗余包,在实际发送的时候会将原始包和冗余包分为一组发送到网络上。在网络出现丢包的时候,接收端能够经过同一分组的原始包和冗余包进行逆运算去还原所丢失的原始包。固然这里的还原是有条件的,还原的成功率跟咱们冗余算法的冗余度大小有关,通常状况下成正相关。但过多的冗余包会占据不少的发送流量,这样实际上是不利于正常的媒体传输的。
关于冗余算法的选取在服务器端也是很是重要的一个课题,主要涉及到两点:
-
冗余度在算法层面是否支持动态调整。
-
计算复杂度可否知足服务器性能要求。
第一点很容易理解,由于网络丢包是复杂多变的,固定冗余度的算法要么会带来带宽的浪费要么恢复效果不理想。第二点的话,源自于实时音视频服务器主要的角色是作媒体分发的,其根本要求是分发的高效,一旦FEC的算法复杂度太高,在高并发高I/O吞吐的状况下,势必会下降服务器并发性能,甚至会引入额外的端到端的delay。
目前已经实现的FEC算法不少,简单有基于异或的实现,复杂的有基于矩阵运算的,以及一些其余的算法,这里就不详细描述了。
网易云信实践
以上简单的介绍了丢包重传请求和前向纠错的策略。这两种机制是常见的抗丢包策略。在具体的应用上,各个音视频厂商,只是在协议实现和算法选取上略有不一样而已。既然ARQ和FEC都是为了对抗丢包而制定出来的策略,那么在网易云信中咱们如何作最优的策略选取的呢?
首先在作策略选取以前,咱们先回顾一下两种策略对抗丢包的不一样思路。
第一种丢包重传策略(ARQ),解决的是当前丢包已经发生,须要作短暂的时延牺牲(即作丢包重传的时候会形成Jitter),来对抗丢包,其优势明显,即不会实时的占用信道带宽,缺点就是引入的Delay,一些不当的NACK请求策略的设计甚至会形成流量尖刺。
第二种FEC策略,其做用效果是实时观测丢包率的变化,作丢包率的预估,实时产生冗余数据来对抗可能出现的丢包。其优势在基本不须要牺牲时延,能够作快速的丢包恢复。但其缺点亦很明显,即依赖于丢包预测的准确度,太高的冗余会形成带宽流量的浪费,甚至挤压正常的信源的传输,致使一个不健康的信道传输状态。
下面介绍一下网易云信对这两种策略组合的使用方法。
1. 创建网络状态的观测器。
其主要监控当前网络的丢包率、抖动、时延、拥塞状态。观测器的创建质量好坏会很大程度的反应到咱们的抗丢包效果上去,在丢包率上咱们会根据关心的阈值去作不一样区间的采样标本,作多个细分丢包率的观测和预估。这里的丢包率有平均RTT内的丢包率,有去抖动的丢包率,以及跟NACK请求相关的丢包重传超时时间相关的丢包率。观测器主要的做用是进行网络可数据化的状态侦测。为后侧的策略提供网络类型的分析,并提供确切的指标,供核心调控模块来调节自适应的参数。
2. ARQ手段先行,FEC手段作兜底。
具体的意思是咱们会根据预设的最大端到端Delay(这个Delay跟用户设置模式有关,能够动态调节),再根据观测器观测出来的相关网络指标去计算ARQ的成功率,剩下的失败率由FEC作兜底。具体算法以下:假设当前选取的网络平均丢包为L,当前Rtt为R,咱们能容忍的最大Delay时间为D,最小NACK请求间隔为I,则单个包能够进行NACK的请求次数C = (D-R) / I,那么通过重传以后,单个包仍处于丢失的几率为:XL = L * LC= L(C+1),那么FEC冗余率设计的参考丢包率TL = a * XL + b * BL,其中a为增益系数,属于自适应调整参数,BL是基于观测器获得的网络基本(最小)丢包率,b为调节系数(b 小于等于1.0),通常在网络带宽不受限的状况下,将b设置为 1.0。此外基于丢包率如何去选取冗余度,有不少计算方式,这里就不展开了。
3. 基于接收端反馈以及模块自检的策略调整。
服务器做为接收端会创建抗丢包效果评估模块,具体到指标有NACK成功率,NACK响应时长,FEC 成功率等。发送端会基于此类的反馈,以及两个模块自身的相关统计数据,如Rtx(重传包)、FEC流量与原始信源的流量占比,以及拥塞控制模块的拥塞状态等,进行模块内策略相关的参数(D、I、a、b等)的动态的调整。
网络自己是复杂的,须要有一个合理的调度器来控制ARQ和FEC抗丢包模块的协同做用,要作到具体网络状况作具体的调节,咱们的抗丢包策略不该形成过多的网络信道的挤压,进而反向压制了信源的质量,甚至致使拥塞的时而发生,这样将会和咱们的抗丢包策略设计的初衷背道而驰。
下行QoS
相比较上行QoS,服务器在下行QoS能够作的策略能够更多,上文提到了咱们的QoS设计里更多的控制权是交由发送方,对于下行QoS服务器角色即是发送方。除去抗丢包手段以外,服务器须要作的几个重要的QoS相关的工做在于:
-
设计出下行接收端可弹性接收流组合的方案。
-
准确的探测出用户真实的下行带宽。
-
制定合理的带宽分配方案。
-
进行流量的平滑发送以及拥塞控制。
下行QoS模块控制总图
设计合理的接收端可弹性接收的方案,是整个下行QoS的设计基础。一个完整的拥塞控制系统,其必然要完成两个基本的工做:
-
感知当前信道的传输状态,这个状态能够是信道的最大带宽,也能够是当前合适传输速度。
-
可以根据这个状态对发送信源进行调节,将信源的码率控制在可承受范围以内。
因此,对于服务器端下行拥塞控制而言道理也是同样。服务器设计了多流+SVC的机制进行下行流量的控制。来实现对下行传输链路的控制,应对于用户不一样的下行状态,作到最佳的QoE效果。
多流机制
咱们的多流机制选取大小双流的方案,为了给服务器下行调节最大空间,以及考虑实际体验效果,这里的大小流的分辨率也不是固定的,会随着服务器调节的码率,作弹性的伸缩。针对于多流而言,上行用户能够根据本身的网络能力作不一样流的发布,下行用户能够根据自身的须要以及网络带宽,作符合自身能力的流的订阅。另外辅助SVC的策略,服务器能够作到最大的调节空间,充分利用用户的下行网络带宽,作到用户接收的最佳体验。这里发送端弹性分辨率的双流机制以及SVC方案,服务器就不作过多的描述了,感兴趣的同窗能够继续关注咱们网易云信的相关技术分享。
带宽探测
带宽探测。这个模块实现的好坏,直接影响到下行QoS的效果。对于拥塞控制而言,开源的实现有GCC,PCC,BBR及其余的拥塞控制方法。
网易云信服务器下行QoS是基于Google的BBR算法,在实时音视频场景下作了大量的优化,进而创建了完整的拥塞控制方案。
选取BBR算法两个最主要的缘由:
-
基于可测量的准确带宽。
-
算法层面的最大带宽利用率。
服务器下行和客户端上行拥塞控制的本质区别在于,下行要求的带宽大。客户端上行能够经过平滑的调整信源作到最佳的发送速率,而服务器只是基于现有上行流的转发,要作到平滑的信源调节很是困难。因此客户端的拥塞控制通常使用GCC比较多,缘由在于GCC更侧重于发送码率的动态调节来进行拥塞控制。
BBR自己的算法这里就不具体描述了,Webrtc对BBR在实时音频场景下的应用也有代码的实现,处于测试阶段。
在网易云信实际运用BBR作下行带宽探测的时候,咱们作了不少优化,这里罗列一些笔者认为在实时音场景下,尤为在服务器端作带宽探测,BBR建议作相应优化的点:
-
Probe_RTT 阶段的隐藏弱化
-
上行网络丢包带宽补偿
-
上行网络RTT突变以及高Jitter场景优化
-
下行链路抖动以及丢包的优化
-
Padding流量的优化
-
快速上探机制的实现
这里的上下行网络,是针对于BBR网络带宽探测端而言的。通过咱们一系列的优化,基本将带宽探测的准确度作到95%左右。
900kbps + 15% loss + 100jitter
带宽分配策略
带宽分配模块要作的事情,其实就是结合下行用户的探测出来的带宽,以及下行用户的原有的订阅关系,帮用户智能的选取最佳接收流的组合。在介绍具体介绍带宽分配策略以前,简单回顾一下咱们下行QoS的设计基础,即多流+ SVC的机制:用户上行的多流中的每条流都会在发布的时候把本身的可调控码率空间信息,即档位信息告知发布订阅管理器。经过这样的实现,服务器即可制定灵活的带宽分配方案。
基于此实现,那么对于服务器下行接收而言,能作的手段有两种:
-
源端无感知的,接收端大小流切换
-
源端配合的流内码率(档位)调整
这两种手段都交由统一的带宽分配策略来控制,具体的思路有两点:
1. 尽量不去反向压制发送端的编码码率,在基于可选取的大小流的基础上作最佳接收流的组合,来匹配用户下行可实际接收的带宽。
2. 反向压制发送端编码码率须要创建在接收端用户举手表决的基础上进行结果裁定。
平滑发送及拥塞控制
平滑发送及拥塞控制。前面几个模块讲的是用户怎么接收的问题,最终如何控制下行的发送,交由这个模块来管理。这个模块的设计的每一个细节和用户体验息息相关。大的思路有以下几点:
1. 平滑发送。就平滑发送而言,咱们主要的实现是建立Pacer对象,在单独的发送线程中,起高精定时器,进行发送的平滑,让网络流量不会在观察区间内有Burst的现象。
2. 基于流级别的优先级策略以及可选择性发送策略。缓冲在发送队列的流,会有不一样的优先级。在咱们的默认设计里优先级顺序为 重传包 > 音频包 > 大于视频包 > 被切掉的流 > Padding包。另外也设计了用户态的流的优先级。整体策略是用户态优先级最高,而后再参考QoS自己的优先级。可选择性发送策略的设计主要基于SVC,观察Pacer的堆积状况,以及对应流的堆积状况,进行转发分层的选取。
3. 拥塞避免。这个模块的实现,主要是从BBR带宽探测模块获取建议的发送码率,而且严格按照码率发送,在某些场景下如真实媒体数据不足的状况,甚至能够减小发送码率。固然这些行为都可以让带宽探测模块感知到。
4. 拥塞缓解。这里的拥塞缓解更可能是模块内部拥塞状态的缓解。主要的方法是经过获取发送队列的堆积状况,来进行模块内部拥塞状态的判断。一旦源端超发或者带宽分配模块调节没那么灵敏,致使模块出现拥塞状态。那么就要及时的进行堆积的处理,而不是把数据放到网络上,形成网络的拥塞,带来更多不肯定因素。这里堆积判断,主要基于Trendline 配合绝对Delay的固定阈值。
如图,在t0时刻,Delay超过了咱们的绝对阈值,可是计算出来的Trend并不高,既不是一个持续拥塞的状态,反而它多是一个拥塞缓解的状态。在t1时刻这里咱们看到Trend值已经很高,并且Delay已经超过咱们的阈值。那么t1时刻是咱们须要进行拥塞缓解的时刻。拥塞缓解的具体作法就是根据流的优先级进行选择性的丢弃。因此,在进行拥塞缓解的时候,咱们判断拥塞的状态必定要严谨,一旦主动代替网络丢包,那么用户体验确定会受影响。
平滑发送及拥塞控制总图
总 结
以上从大的框架上讲述网易云信搭建的音视频服务,在服务器端实现的一些QoS方案的介绍,其中细节不少,很难一一描述,但每每是细节决定最终的通话质量。
音视频通信自己一个复杂的通信系统,本文开头也提到了,QoS的设计也只是其中的一环,想要达到最佳的通话效果,每一个环节作到环节内的最优,环节间也要创建有效的反馈调节机制。才能将整个端到端的体验作到最优,这样才能获得用户的承认。