GCC拥塞控制

    webrtc中拥塞控制算法有两种:基于延时的拥塞算法和基于丢包的拥塞算法。该算法有两种实现方法:
   一个是两个算法都在发送端实现,RTP接收方将记录每个接收包的到达时间和transport-wide序列号,使用RTPFB反馈包定期发送回发送方,协议建议反馈间隔时间为每接收的视频帧一次,或如果只有音频或多流,至少每30ms一次,如果需要限制反馈开销,则此时间间隔可增加到100ms,发送方将接收到包的{序列号、到达时间}对映射到反馈报告所涵盖的每个数据包的发送时间,并将这些时间戳提供给基于延迟的控制器。它还将根据反馈消息中的序列号来计算损失比。
   另一个是基于延迟的拥塞算法在接收端实现,发送方应该使用带有῏abs-send-time“的RTP报头扩展,使接收方能够计算组间延迟的变化,基于延迟控制器输出比特率率,通过发送REMB反馈消息反馈给发送方,丢包率则通过RR发送给发送方。在发送方处,REMB消息中的比特率和数据包的丢包率被输入到基于丢包控制器中,该控制器输出最终的目标比特率。
   本文讨论GCC理论知识,代码如何实现将在mediasoup服务器转发流媒体数据及发送拥塞控制文中详细介绍。
   在理解基于延迟的拥塞控制之前,需要了解webrtc中pace平滑发送策略,参考深入研究webrtc平滑发送(paced sender)文中。pace用于驱动由控制器计算的目标比特率。当媒体编码器生成数据时,它会被送到pace队列中。数据处理器每隔burst_time时间间隔向网络发送一组数据包。burst_time的推荐值为5ms。一组数据包的大小是作为目标比特率和burst_time之间的乘积来计算的。

一、基于延迟的拥塞控制
    基于延迟的控制算法可进一步分为四个部分:预滤波器(pre-filtering)、到达时间滤波器(arrival-time filter)、over-use检测器(over-use detector)和码率控制器(rate controller)
1.1、到达时间(arrival-time)模型
   到达时间滤波器是根据接收分组包的到达时间不断更新网络参数的估计。我们将∆Rt定义为两组数据包组的到达时间差:
                     ∆Rt = Rt(i)- Rt(i-1)
   其中Rt(i)表示它对应于第i个分组的最后一个数据包的接收时间,Rt(i-1)表示对应于第i-1个分组的最后一个数据包的接收时间。我们将∆St定义为两组数据包组的发送时间差:
                     ∆St = St(i)- St(i-1)
   其中St(i)是第i个分组中最后一个数据包的发送时间戳,St(i-1)表示是第i-1分组中最后一个数据包的发送时间戳,无序收到的任何数据包都将被到达时间模型忽略。最后,组间延迟变化D(i)定义为到达时间和发送时间之间的差:
                     D(i) = ∆Rt- ∆St=Rt(i)- Rt(i-1)-(St(i)- St(i-1))。
    如果D(i)>0,即到达时间大于离开时间,则组间存在延迟。组间延迟变化建模为:
                     D(i)=w(i);
   w(i)是一个随机过程W的样本,它是链路容量、当前交叉流量和当前发送的比特率的函数。如果我们过度使用信道,我们期望w(i)的平均值增加,如果网络路径上的队列被清空,w(i)的平均值将减少,否则w(i)的平均值将为零。从w(i)分解平均值m(i)使过程为零平均值:
                     D(i) = m(i) + v(i)
   噪声项v(i)表示网络抖动和模型未捕获的其他延迟效应。

1.2、到达时间滤波器(arrival-time filter)
   参数D(i)(i>1)适合每组数据包,我们想要估计m(i),并使用m(i)来检测瓶颈链路是否被过度使用,这个参数可以用任何自适应滤波器来估计——如使用卡尔曼滤波器(Kalman filter)。
   让m(i)作为时间i的估计,将状态演化建模为i+1:
                     m(i+1) = m(i) + u(i)
   其中u(i)是建模为具有均值和方差为零的高斯统计量的平稳过程的状态噪声。
   q(i) = E{u(i)^2},协议中建议q(i)=1/1000 。给定了我们得到的方程式:
                     D(i) = m(i) + v(i)
   其中,v(i)为零的平均高斯白测量噪声,方差为var_v=E{v(i)*v(i)}。
卡尔曼滤波器递归地更新我们的估计m_hat(i)为:

                     z(i) = d(i) - m_hat(i-1)
                     m_hat(i) = m_hat(i-1) + z(i)*k(i)
                          e(i-1) + q(i)
                k(i) = --------------------------------
                    var_v_hat(i) + (e(i-1) + q(i))

              e(i) = (1 - k(i)) * (e(i-1) + q(i))
   方差var_v(i)=E{v(i)^2)是使用一个指数平均滤波器估计的,修改为可变采样率。
              var_v_hat(i) = max(alpha*var_v_hat(i-1) + (1-alpha)z(i)^2, 1)
            alpha = (1-chi)(30/(1000
f_max))

   其中f_max为f_max = max {1/(T(x) - T(x-1))}接收最后K个数据包组的最高速率,x的范围为[ i-K+1,i],chi是区间[0.1,0.001]内选择的滤波器系数。由于我们假设v(i)应该是零平均白高斯统计量,在某些情况下不那么准确,我们围绕var_v_hat的更新引入了一个额外的离群值滤波器,如果z(i)>3sqrt(var_v_hat),则过滤器将用3sqrt(var_v_hat)而不是z(i)进行更新,例如,在数据包以高于通道容量的传输速率的情况下,v(i)不会是白色的,在这种情况下,它们将在后面排队
1.3、预滤波器(pre-filtering)
&   预滤波的目的是处理由信道中断引起的延迟瞬变,在信道中断期间,由于与拥塞无关的原因,在网络缓冲区中排队的数据包会在中断结束时以突发形式传递,预过滤将突发到达的数据包合并在一起会满足以下任一个条件:
      ①在burst_time间隔内发送的数据包构成组
      ②组间到达时间小于burst_time且组间延迟变化体D(i)小于0的包被视为当前数据包组的一部分;
1.4、over-use检测器
   将到达时间滤波器输出得到的组间延迟偏差估计趋势modified_trend与阈值threshold_进行了比较,当modified_trend>threshold_时表示过度使用的指示标志,这样的一次检测过度使用并不足以表明网络真正处于过度使用状态,只有检测到网络处于过度使用时间至少overuse_time_th=10或以上毫秒时,才会判定网络真的处于过度使用状态了。但是,如果当前组间延迟偏差估计modified_trend小于前一次采样的组间延迟偏threshold_,即使满足overuse_time_th毫秒过度使用的条件,也不会判定网络处于过度使用。类似地,当modified_trend<-threshold_时,会检测到网络使用不充分的状态。如果既未检测到过度使用或未充分使用,则检测器将处于正常状态。
   阈值threshold_对算法的整体动态和性能有显著的影响。它表明,使用一个静态阈值threshold_,由该算法控制的流可以被一个并发的TCP流饿死。可以通过将阈值del_var_th增加到一个足够大的值来避免这种饥饿。原因是,通过使用较大的值threshold_,可以容忍较大的队列延迟,而对于小threshold_,过度检测器对很小的modified_trend增长会通过产生过度使用的信号来减少可用带宽基于延迟的估计来做出快速响应。因此,需要动态地调整阈值threshold_,以便在最常见的场景中获得良好的性能。因此,协议中建议根据动态方程动态改变阈值threshold_:
          threshold_= threshold_ + (t(i)-t(i-1))K(modified_trend-threshold_)
   其中,如果modified_trend<threshold_时 K=K_d,否则K=K_u,因为是当modified_trend超出范围(-threshold_、threshold_]时增加threshold_,而当modified_trend处于范围内时,threshold_减小;t(i)当前更新阈值时间,t(i-1)上一次更新阈值时间
   当modified_trend增加时,例如由于TCP流进入同一瓶颈,threshold_增加并避免不受控制地生成过度使用信号,这可能导致该算法控制的流量不足,如果此条件成立,则不应更新threshold_。
          modified_trend -threshold_ > 15
协议还建议将threshold_控制在[6,600]的范围内,因为太小的threshold_会导致探测器变得过于敏感。另一方面,当modified_trend下降到范围[-threshold_、threshold_]时,降低阈值threshold_,从而实现较低的排队延迟。
   建议选择K_u>K_d,以使del_var_th值的增加速率高于其降低的速率。有了这种设置,就可以在并发TCP流的情况下增加阈值,防止饥饿,以及执行协议内的公平性。threshold_初始、overuse_time_th、K_u和K_d的推荐值分别为12.5ms、10ms、0.01和0.00018。

二、基于丢包的拥塞控制
   GCC算法在发送端基于丢包率控制发送码率,其基本思想是:丢包率反映网络拥塞状况。如果丢包率很小或者为0,说明网络状况良好,在不超过预设最大码率的情况下,可以增大发送端码率;反之如果丢包率变大,说明网络状况变差,此时应减少发送端码率。在其它情况下,发送端码率保持不变。基于丢包的码率控制实现原理是基于媒体接收端发送的RR反馈包计算RTT,以及获取丢包率和丢包数来控制,将这些信息应用到拥塞控制模块rtpTransportControllerSend来评估新的发送码率。
   基于丢包的拥塞控制在每次收到接收方发送给的RR反馈时运行,如果自接收方的上次报告以来
   丢失率在2-10%,则发送方可用带宽估计保持不变;
   丢包率超过10%,则将新的码率估计值计算为newbitrate=newbitrate*(1-0.5p),其中p为损失比;
   丢包率低于2%,newbitrate将随着newbitrate=1.08*(newbitrate)而增加(即提升8%的码率);
   最后将基于丢失的码率估计值与基于延迟的码率估计值进行比较,实际发送速率设置为两者最小值。
   注意到,如果传输信道由于过度使用而有少量的包丢失,如果发送方不调整其码率,这个量很快就会增加,从而激励包丢失阈值,因此,我们很快就会达到超过10%的阈值,并调整输出码率值。但是,如果数据包丢失率没有增加,这些损失可能与自我造成的拥塞无关,因此我们无需就此做出反应。

   基于丢包的拥塞控制算法比较简单,也容易理解,基于延迟的拥塞控制算法比较难理解,会有专门的文章对webrtc或者webrtc服务器的拥塞控制算法代码进行详解,次文仅是理论,来自A Google Congestion Control Algorithm for Real-Time Communication

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱钻研技术的小羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值