在开发过程中,直播、点播 CDN 等云服务往往会经过从「能用」、「好用」到「大规模使用」等阶段。 类似地,RTC 正处于从「能用」走向「好用」的过程中。 我们需要提升用户的视频观赏体验,实现标准化的服务,而抗弱网技术是一个关键性的步骤。
另一方面,不同于RTMP、RTSP 等「尽力而为」的网络协议,它们只解决网络问题。 RTC 是一个面向视频交付的协议,联动传输和编解码,形成可靠的视频交付。 因此,抗弱网技术是实现全场景交付的支撑性技术。
最典型的RTC系统结构通常包括两个部分:平台侧和终端。
而平台侧通常又分以下两部分: 用户端接入, 包括信令和媒体。
服务间流的中转和控制,包括媒体分发、调度。
抗弱网的技术手段可以归纳为2个层面,包含4个方法。
「2个层面」即网络层面和音视频层面。
「4个方法」包括:
(1)自适应方法。自适应地对网络的带宽进行评估、合理使用带宽,并根据带宽自适应地调整码率。
(2)纠错方法。针对丢包、丢帧等情况,通过前向纠错,在网络数据包、视频、音频层面上进行纠错。
(3)缓存方法。针对网络抖动、设备不稳定、设备性能有限等问题,设置视频、音频的缓存区。
(4)调度方法。尽可能地将用户调度到最好的接入点,或在服务器侧进行中转,实现最优的内容分发调度,从而解决低延时和稳定性问题。 s
WebRTC 提供了包含一系列组件的低延时框架,主要环节包括:编码、发送、接收和解码。
绝大部分自研系统的架构也与此类似,但会在具体实现过程中对算法做相应的调整。
编码环节:就发送方而言,我们需要根据其网络情况自适应地采用合适的码率;就接收方而言,我们会通过 Simulcast、SVC 等编码手段根据网络情况自适应地选择接收方法。此外,我们还可以通过动态 Gop 根据场景控制传输压力。
发送环节:首先进行带宽估计和分配。如果发生了数据错误,我们会进行 RTX 重传,或采取 FEC 等手段。此外,我们还可以采用 PACING实现网络的平滑发送,并确定数据带宽使用和发送的优先级。
接受环节:需要与发送方就带宽的估计、重传等操作进行配合。我们可以通过 NACK 请求发送方重新发送数据包,或者通过 RTCP 的反馈指示接收方实际的接受情况,也可以通过动态视频、音频缓存适应网络的抖动。
解码环节:需要解决错误隐藏问题,在数据出错之后尽可能提升用户体验。此外,我们还需要针对不均衡、不稳定的网络实现稳定的持续输出。 之前的流媒体协议主要作用在网络层面,没有实现网络和编解码环节的联动,而WebRTC 可以大大提升对弱网的适应性。
进一步归纳,抗弱网技术主要需要解决丢包、延时、乱序抖动、限速、网络质量突变等情况。 我们会在带宽评估、带宽分配、带宽使用、缓存、解码渲染等环节上解决上述问题。
在进行带宽估计时,我们可以采用基于丢包、基于时延、基于 ACK 带宽的方法,也可以通透与探测实现带宽估计。
在进行带宽分配时,我们可以通过网络情况动态地分配视频、音频的编码码率, 实现 FEC 前向纠错和相互纠错重传的带宽预分配。
在带宽使用方面,对于纠错后分配的带宽,我们需要通过 Nack、Sack、FEC 等数据重传, 或通过 Pacing 等技术确定数据的优先级,提升发送的均衡性。
就缓存技术而言,WebRTC 中提供了面向视频的 JitterBuff 和面向音频的 NetEQ, 从而适应网络的抖动、修补数据的残缺、将网络数据包转换成音频帧或视频帧。
TCC 是一种带宽评估技术,其输入为接收状况的反馈,该数据会输入给带宽估计的三个控制点:丢包估计、延时估计、确认带宽估计。
丢包估计:根据丢包率的大小,在上次评估的带宽基础上,判断是增加带宽还是降低带宽。
延时估计:采用 Aimd 调节实现「和」式的带宽增加,以及乘法级的带宽降低。 具体实现方式:分别计算在发送端和接收端,连续两个包之间的差值之差,拟合线性回归函数, 根据斜率判定网络是拥塞、轻载、稳定,再确定如何调节带宽,带宽基值依赖于接受方反馈带宽估值,调节方式依照和增乘减方式。
确认带宽估计:基于FeedBack接收统计丢包率,采用贝叶斯评估接收方到码率,该值作为延时估计的带宽基值。
我们对丢包估计得出的带宽值和由 Aimd 处理后的时延估计结果取最小值,从而得到最终的带宽评估结果。 值得一提的是,确认带宽估计提供带宽需要调节的基准值,而丢包估计和时延估计则提供调节意向。
TCC技术的设计优点包括:
采用「丢包+延时」网络拥塞检测方法,实现了边界性的保护。 面向视频应用,考虑未充分使用的带宽、应用已确认的带宽,并探测估计出的带宽是否有效。 TCC 技术的不足之处在于:
所有估计强烈依赖反馈,接收端会影响发送端。 发送方的丢包、延时拥塞估计都基于统计实现,反映灵敏度低。 未覆盖高抖动等场景。
带宽分配最典型的应用场景是对视频和音频的带宽分配。
就音频而言,其带宽主要包含音频的原始码率以及为重传、纠错预留的带宽。
大部分的带宽将分配给视频,视频的带宽分为三部分: 1、视频原始码率 2、前向纠错的 FEC带宽 3、视频的 Nack 所需要的带宽
需要指出的是,Nack 的带宽不是预分配得到的,而是根据之前的网络情况统计得出。 在具体实现中,我们会采取一些保护措施, 例如:要求视频 FEC 的码率加上实际重传的码率小于等于最终分配给视频的带宽的一半。 在这种设置下,WebRTC 的抗丢包率约为20-30%, 我们可以根据实际的丢包、延时情况改变 nack+fec 的带宽分配比例,从而提升抗丢包率。
带宽使用主要涉及重传和 FEC 两个场景。 就重传而言,如上图所示,发送端的 host1 丢掉了 101、102 两个包。 接收方发现丢包的时机可能有两个: 1、在接收 103 号包时,基于包序规则发现丢掉了前两个包,因此重新对发送方申请发送 101 和 102 号包。 2、如果重新请求后经过了 RTT+退避期的时间仍然没有收到这两个包,则会通过基于超时的方式重传包,避免了 NACK 的风暴。 发送方收到NACK的请求之后,也会采取一定的措施进行控制。如:同一个RTP包,在两次重传间会隔1倍的RTT,通过这种方式可以保护因多次发送导致的带宽占用。
前向纠错 FEC 技术经历了从 UlpFEC 到FlexFEC 的发展。
UlpFEC 是一种基于行式的生成方式,如果连续丢掉了两个包就很难恢复。 为此,FlexFEC 采取了行列交织的方式,即使连续丢包也有可能恢复,但是会引入额外的计算开销,计算开销与恢复率成正比。
FEC 在稳定环境(例如,丢包率成正态分布)中较为容易恢复,然而在现实网络中的效果会有一定的降低。
在启用 FEC 时,我们要进行发送端和接收端的 SDP 协商,并根据当前网络带宽状况选择是否开启。 就 FEC 的参数而言,我们需要设定帧内的 FEC,确定每个 FEC 包由多少数据包生成、行列矩阵的组成,以及带宽的使用情况。 目前,WebRTC 根据 FEC 通过异或计算生成 FEC 包,记录包的依赖关系,并根据它恢复出丢失的原始 RTP 包。
JitterBuff 的输入为网络的 RTP 包,输出为一个视频帧,它实现了以下功能: 1、一套动态缓存机制,处理丢包、超时、乱序、延迟、帧残缺等异常情况。 2、一套将 RTP 包解码成帧的控制机制,确定还原帧的时机、参考关系,以及根据 RTP 包还原残缺帧的方法。 3、计算网络抖动延时,通过卡尔曼滤波,预测包到达的时间,实现出帧的平滑性。
NetEQ 被用于实现音频的动态缓存,通过计算网络抖动,实现 RTP 包的缓存、去重、排序、纠错等功能。
NetEQ 采用直方图估算平稳抖动,通过峰值检测应对突发变化情况。当缓存中数据不足时,降低出帧的频率。 当缓存中数据过多时,提升出帧频率,从而实现均匀出帧。对于空帧,NetEQ 会根据前帧和后帧拟合出补偿帧。 日前,Opus 编码格式下开启 DTX 的帧内 FEC 后,抗弱网的能力会大大提升。
RTC是一种低延时的通信技术,也可以被用于低延时直播等场景,更好的实现对弱网的适应性。
RTC 抗弱网技术主要被应用于 1对1、N对N,以及流场景下。
我们不仅需要考虑如何应对媒体环境下的抗弱网问题,还需要从接入、调度、用户体验的角度考虑如何抗弱网。
就媒体抗弱网而言,
在带宽估计阶段,我们首先要判断丢包的类型,确定对带宽的调整方案,提升抗乱序抖动效果、提升对网络变化感知的灵敏度。
在带宽分配阶段,我们以清晰和流畅为目标导向,根据对丢包率、延时、抖动的统计情况, 预测恢复效果,动态调整 ARQ、FEC,以及编码带宽比。
在带宽使用阶段,我们需要精细地考虑重传机制,优化接收方发起重传的时机和发送方发送数据包的时机, 从而避免重传风暴,保证重传的有效性。 在重传 Nack 请求丢失时,我们需要及早发现并尽可能快速恢复。 此外,我们还需要重点优化音频的连续丢包问题、采用 Pacing Sender 优化, 也会结合解码环节采用多码流的 Simulcast 和 SVC 技术。
在缓存\解码\渲染阶段,我们对视频、音频 Jitter 进行了优化,从而适应抖动、乱序等场景。 值得注意的是,目前的 WebRTC协议是端到端的,然而目前许多商业系统并不是端到端的系统, 它们只考虑了服务器端的优化,而我们还需要考虑发送端的抖动情况。
为了增强对丢包的抗性,我们将丢包的情况分为拥塞丢包、非拥塞丢包和偶发丢包。
非拥塞丢包场景下,个体的避让对整体信号质量的影响有限, 为了保证视频的流畅,我们不能降低带宽,需要发送更多的数据包,将带宽分配给纠错部分。
目前,我们还很难解决拥塞丢包问题。 偶发丢包问题可能是非持续的网络信号抖动,无需通过降低带宽来优化。
带宽估计对乱序抖动的适应性较差。 为此,我们需要避免将乱序误判为丢包。 在存在一定丢包的情况下,也应该考虑对乱序和延时的估计,提升对弱网的适应性。
在带宽估计过程中,默认的实现以事后统计数据为基础。 为了提升探测拥塞的灵敏度,我们可以通过在发送端增加 TCP 拥塞窗口, 动态地分配窗口,可以很灵敏地感知到发送方下行带宽出现的拥塞。
弱网中可能会出现丢包、延时、抖动、乱序以及一些突发情况,每个因素可能会影响到上行、下行信号, 而不同的控制机制会涉及推流和拉流方。因此,抗弱网场景十分复杂。
如上图所示,我们会提取一些关键路径上的组合点,并且在每一步中对算法进行调整优化。 接着,我们会重新在上述场景下检测优化后的算法,并且在线上进行 A/B 验证,逐渐得到理想的算法。
如今,手机/电脑等终端往往可以同时使用 4G 和WiFi 信号。 我们会持续检测 4G 和 WiFi 的网络质量,在 WiFi 信号较差时及时使用 4G 信号作为补偿,强化音频传输,保证音频数据的连续性。
在分发与调度环节中,我们试图得到服务器之间的最优分发路径, 不断检测部署的云节点、公网的边缘节点之间的连通性,挑选出较优的连接,形成虚拟的低延时中转网络。
在下次使用时,我们优先使用事先挑选出的虚拟中转网络。 为了降低服务器网络波动对实时通信结果的影响,我们在分发时会建立多条冗余备路, 随时自动切换,并采用重传、纠错等手段避免分发不稳定的问题。