WebRTC中GCC 算法原理介绍与分析
近期主要关注实时音视频的弱网优化技术,重点分析WebRTC的相关技术实现,主要包括抗拥塞、抗丢包,会通过一系列文章来分享我的学习所得,本次介绍拥塞控制算法GCC(Google Congestion Contrl) 原理与实现。
GCC 作为官方的拥塞控制算法,被广泛应用在实时音视频领域,包括腾讯会议、Agora、华为WeLink等VoIP音视频产品中。主要用来估计带宽,根据可用带宽控制当前的发送速度,减少传输链路发生拥塞的概率,尽可能降低传输链路带来的延时。
网络拥塞产生的原因,网络传输链路所承载的数据量超过了它所能处理的极限,传输延时增大,产生丢包、抖动。进而导致实时通讯中音视频质量降低、表现为卡顿次数增加,延时增大,影响用户体验。
延时增大、产生丢包是链路发生拥塞的标志性事件。GCC正是基于这两个标志性事件设计的算法,它包括delay-based的拥塞算法和loss_based的拥塞算法。
发送端收到接收端反馈的Feedback事件,会计算出延时梯度变化,链路丢包率据此估算出两个可用带宽,取其中较小的带宽值作为链路的可用带宽。
基于延迟(delay-based)的拥塞控制算法
通过每组包的到达时间延迟差(delta delay)的增长趋势来判断网络是否过载,如果过载进行码率下降,如果处于平衡态维持当前码率,如果网络利用不饱和要提升码率。具体关键技术包括 包组延时评估(InterArrival), 到达时间滤波器(arrival-time filter),过载检测器(over-use detector),码率控制器(AIMD)。
包组延时评估(InterArrival)
WebRTC 中计算时延不是逐个包单独计算,而是先将数据进行分组,再计算这些包组间的时延。将发包间隔小于5ms的数据包归为一组,这种做可避免无线网络环境下突发数据对带宽估计准确性的影响。
图中TG1包括seq 1~4,TG2包括 5~6,因此我们可以计算出 Trendline滤波器需要的三个参数:发送时间差值 delta_times、到达时间差值 delta_arrival、包组大小差值 delta_size。
delta_times = TG2:timestamp - TG1:timestamp; delta_arrival = TG2:complete_time_ms - TG1:complete_time_ms; delta_size = TG2:size - TG1:size;
到达时间滤波器(arrival-time filter)
根据上述包组延迟评估计算结果,不难计算出包组传输时延变化 delta_ms,如果 delta_ms 值在增大,说明延时在增大将要发生拥塞;如果值在缩小,说明网络正在恢复。
delta_ms = delta_arrival - delta_tims
为减少网络波动影响,使用中会将最近1000个 包组传输时延进行叠加,计算出一个平滑延迟值 smoothed_delay。 WebRTC 使用了线性回归进行时延梯度趋势预测,通过最小二乘法求拟合直线的斜率,根据斜率判断增长趋势。
对于一堆样本点(x,y),拟合直线方程y=bx+a的斜率b按如下公式计算:
实际计算时将时间作为x,平滑延迟值smoothed_delay 作为y,根据上述公式计算出 时延梯度值 trend。理想网络情况下trend的值应该等于 0。
- 0 < trend < 1 延时增大,路由buffer 正在被填充。
- trend == 0 延时没有发生变化。
- trend< 0 延时开始降低,路由buffer正在排空。
过载检测器(over-use detector)
将trend值与动态阈值 threshold 进行比较,决策当前网络处于哪种状态。WebRTC中网络状态有如下三种。
- normal 带宽常态使用,既不过载、也不拥塞。
- overuse 带宽使用过载,网络发生拥塞。
- underuse 当前带宽利用不足,可充分利用。
实际使用中,由于trend 是一个非常小的值,会乘以包组数量和增益系数进行放大得到modified_trend。
- modified_trend > threshold ,持续时间超过100ms并且 trend值持续变大,认为此时处于 overuse 状态。
- modified_trend < – threshold ,认为此时处于underuse 状态。
- -threshold < modifed_trend < threshold ,认为此时处于normal 状态。
判断依据是,网络发生拥塞时,数据包会在中间网络设备排队等待转发,延迟梯度就会增长。网络流量开始回落时,中间网络设备快速转发其它发送队列中的数据包,延迟梯队开始降低。网络流量回归正常后,中简网络设备转发数据包耗时更短,这时延迟梯度减小或为负值。
从判断过程可以看出动态阈值threshold很关键,它决定了算法对时延梯度的灵敏度。
- 阈值不能过于敏感,否则会导致网络一直处于拥塞状态;
- 如果灵敏度过低,无法检测到网络拥塞。
- 采用固定值,会被TCP流饿死。
这个阈值threshold根据如下公式计算:
每处理一个新包组信息,就会更新一次阈值,其中ΔT表示距离上次阈值更新经历的时间,m(ti)是前面说到的调整后的斜率值modified_trend。
kγ(ti)按如下定义:
kd与ku分别决定阈值增加以及减小的速度。
码率控制器(AIMD)
计算出当前网络状态之后,根据速率控制状态机,按照和式增加、积式减少的原则,估算出当前的网络速率。
- 当网络拥塞时,收到 overuse 信号,说明网络拥塞很严重,状态机进入Decr状态,降低发送码率。
- 当网络中排队的数据包被快速释放时,收到underuse信号,状态机进入 Hold状态,保持码率,继续排空。
- 当网络平稳时,收到normal信号,状态机进入 Incr状态,开始探测是否可以增加发送码率。
- 当前是Incr 状态,如果吞吐量(Rг)和链路容量(历史吞吐量的指数平滑)相差较大,则对当前码率(上次更新的码率)使用乘性增加;如果相差较小,则使用加性增加。
- 当前是Decr状态,直接将当前吞吐量 * 0.85 作为新码率,如果该码率可能仍大于上一个调整后的码率,则使用链路容量 * 0.85 作为新码率。
据此,得到基于延时预估出来的码率。
基于丢包(loss-based)的拥塞控制算法
WebRTC基于丢包的拥塞控制核心思想:丢包产生说明网络已经开始发生拥塞,如果丢包率为0 或者非常小,则说明网络状态良好,可以适当增大码率,提高清晰度。 如果丢包率变大,说明网络质量出现恶化要减少向网络中发送的数据量,降低发送端编码码率,其它情况发送码率保持不变。
发送端收到反馈的Feedback 报文后,根据收包情况计算出丢包率。As(tk) 即为 tk 时刻的带宽估计值,fl(tk)即为 tk 时刻的丢包率。
- 当丢包率大于0.1时,说明网络发生拥塞,此时降低发送端码率;
- 当丢包率小于0.02时,说明网络状况良好,此时增大发送端码率;
- 其他情况下,码率保持不变。
GCC基于丢包的拥塞控制策略,更为严格,想要通过降低码率减少网络中发送的数据量,缓解链路拥塞。实际情况下,用户网络发生丢包的原因,并不仅限于发生拥塞。
- 背景流量恶意竞争引起拥塞,丢包就降码率,缺乏冗余数据,VoIP的质量就会更差。
- 月底用户流量被限速,此时会发生丢包、但是没有发生拥塞。
- WiFi/4G 网络波动,产生随机丢包,也没有发生拥塞。
据此,得到基于丢包预估出来的码率。
GCC 算法预估出链路的有效码率,是在丢包预估出来的码率和延时预估出来的码率中取较小值,作为预估出来的最终码率。
算法优缺点总结
这种策略能够在带宽限制场景下能够快速做出反应,表现出较好的带宽适应能力。但在丢包场景下会变现不足,不能分配足够的码率给冗余数据,抗丢包能力不足,与测试结果表现一致。在国内使用,需要进一步优化丢包抗性。