A Google Congestion Control Algorithm for Real-Time Communication draft-alvestrand-rmcat-congestion-03论文理解
看中文的GCC算法一脸懵。看一看英文版的,找一找感觉。
本文档介绍了适用于webRTC两种拥塞控制算法。一种是 基于时延(delay-based) 一种是基于损失(loss-based)。
带宽变化很大,媒体的编码形式不能快速改变以适应变化的带宽。
编码对丢包是很敏感的,然而,媒体流出于实时性的要求会减少包的重传。
略
有两种方法来实现提出的算法,一种是两个控制器都在发送端运行,另一种是delay-based控制器在接收端运行,loss-based控制器在发送端运行。
第一种:RTP receiver会记录到达时间和每个收到的包的transport-wide sequence number,这些东西用transport-wide feedback message会定期发给发送端。【反馈的时间:时间每接收一次视频帧就反馈一次,如果只有音频或多流,至少每30毫秒一次反馈一次。如果反馈开销需要被限制,这个间隔可以增加到100ms。】RTP sender 把接收到的{序列号,到达时间}映射到“反馈报告所涵盖的每个包的发送时间”,并将这些时间戳提供给delay-based的控制器。它还会根据反馈信息中的序列号计算出一个损失率。
第二种:接收端的delay-based控制器,用来监控和处理到达时间和入包大小。发送方使用abs-send-time RTP报头扩展使接收者能够计算组间延迟变化。从delay-based controller输出的是一个比特率,它将用REMB feedback message传给回发送者。丢包率通过RTCP接收器报告发送回来。
在发送端 REMB消息中的比特率和数据包的百分比损耗被输入loss-based控制器,该控制器输出一个终值目标比特率。当检测到拥塞时建议尽快发送REMB消息,或者至少每秒一次。
在接收端
基于延迟的控制算法可以进一步分解为三部分:到达时间过滤器(an arrival-time filter)、过度使用检测器(an over-use detector)和速率控制器(a rate controller)
本节介绍了一个自适应滤波器(an adaptive filter),它根据接收到的数据包的时间持续更新网络参数的估计值。
到达间隔时间inter-arrival time, t(i) - t(i-1)
:表示两个包或者两组包的到达时间不同. t(i)是对应于组中最后一个包被接收的时间。
出发间隔时间inter-departure time,T(i) - T(i-1)
:作为两个包或两组的出发时间的不同。其中T(i)
是当前包组中最后一个包的出发时间戳
组间延迟变化inter-group delay variation,d(i):d(i) = t(i) - t(i-1) - (T(i) - T(i-1))
在接收端,我们观察一组一组的传入数据包,其中一组包定义如下:在burst_time间隔内发送的包序列组成一个小组。burst_time的建议值为5ms。此外,如果其inter-arrival time小于burst_time并且d(i)<0的数据包也被认为是当前组的一部分。 将这些数据包纳入组内的原因是为了更好地处理由"因与拥堵无关的原因,数据包排队"引起的延迟瞬变。任何无序接收的数据包都被Arrival-time model忽略。
t(i) - t(i-1) > T(i) - T(i-1)
网络有拥塞
由于在一条容量为C的路径上发送一组大小为L的数据包的时间ts大致为 ts = L/C
我们可以将组间延迟变化建模为:
根据卡尔曼滤波,根据之前的θ和延迟来估计现在的θ,从而判断网络的拥塞
阈值gamma对算法的整体动态和性能有显著影响。和算法的性能有显著影响。使用静态的阈值的流量控制算法会被并发的TCP流饿死。这种饥饿可以通过增加阈值gamma_1到一个足够大的值来避免。原因是,通过使用较大的gamma值,可以容忍较大的排队延迟,而在较小的gamma下,Over-use detector会对偏移估计值m(i)的微小增加迅速做出反应,产生一个过度使用信号,减少基于延迟的可用带宽估计值A_hat。【gamma很小,m很快就超过gamma,判断网络是过度使用的,可用带宽很小】因此,有必要动态地调整阈值gamma_1,以便在最常见的情况下获得良好的性能,例如在与基于损耗的流量竞争时。
通过这个设置,可以在并发TCP流的情况下增加阈值,防止饥饿以及强制协议内部公平。
速率控制分为两部分,一部分控制基于延迟的带宽估计,另一部分控制基于损失的带宽估计。只要没有检测到拥塞,这两种方法都旨在增加可用带宽A_hat的估计值,并确保我们最终匹配通道的可用带宽并检测过度使用。
一旦检测到over-use,基于delay-based控制器估计的可用带宽就会减少。通过这种方法,我们得到了一个递归的和自适应的可用带宽估计。
在本文档中,我们假设速率控制子系统周期性地执行,并且这个周期是常数。
速率控制子系统有三种状态:增加、减少和保持。“增加”为未检测到拥塞时的状态;“减少”是检测到拥堵的状态,而“保持”是一种等待,直到建成的队列耗尽才进入的状态。
状态转换(空白字段表示“保持状态”)如下:
上面的表解释:子系统如果从增加状态开始,它将一直保持到探测器子系统检测到过度使用或未充分使用为止。
在每次更新时,基于延迟的可用带宽估计值都会根据当前状态以乘法或加法的方式增加。如果当前带宽估计看起来远离收敛,系统会进行乘法式增加,而如果它看起来更接近收敛,系统会进行加法式增加。如果当前输入的比特率R_hat(i)接近之前处于递减状态时输入比特率的平均值,我们就假设我们接近收敛。“接近”的定义是在这个平均值附近有三个标准差。它是建议使用平滑因子为0.95的指数移动平均来测量此平均值和标准偏差,因为预计此平均值涵盖了我们处于下降状态的多个情况。当无法获得这些统计数据的有效估计值时,我们假设我们还没有接近收敛,因此仍处于乘法增长状态。如果R_hat(i)增加到平均最大比特率的三个标准差以上,我们假设当前拥塞级别已经改变,此时我们重置平均最大比特率并回到乘法增加状态。
R_hat(i)是基于delay-based的控制器在T秒窗口内测量的传入比特率:
L(j)为报文j的大小.
在乘法增加过程中,估计值最多增加8%每秒。
在加法增加过程中,每过 response_time 的间隔时间,这个估计值 A_hat(i-1) 会增加大约半个数据包的大小。response_time间隔估计为往返时间加上100 ms作为over-use估计器和检测器反应时间的估计。
我们假设帧率是30的时候:
bits_per_frame = A_hat(i-1) / 30 每一帧的比特率
packets_per_frame = ceil(bits_per_frame / (1200 * 8)) (相当于bytes_per_frame/mtu)
avg_packet_size_bits = bits_per_frame / packets_per_frame
因为这个算法依赖 over-use 来判断当前的可用带宽估计值,我们必须确保我们的估计值不会远离发送端实际的发送码率。所以,如果发送端无法产生这个拥塞控制器要求的 bitrate,我们需要将可用带宽估计值限制到一个范围:A_hat(i) < 1.5 * R_hat(i)。
当探测到over-use,这个系统会转换为 Decrease 状态,可用带宽会降低到:A_hat(i) = alpha * R_hat(i)
。alpha在范围[0.8 0.95]之间,建议为0.85。
当检测器向速率控制子系统发出under use 的信号时,我们知道网络路径中的队列正在被清空,我们的可用带宽估计值A_hat低于实际可用带宽。根据该信号,速率控制子系统将进入hold状态,接收方可用带宽估计值将保持不变,直到队列长度稳定。这是一种控制低延迟的方法。延迟的减小可能是由于这里的带宽估计值减小,也有可能由于一些交叉网络的连接减少了。建议每个response_time 间隔都要更新一个 A_hat(i)
+------------+-------------------------------------+----------------+
| Parameter | Description | RECOMMENDED |
| | | Value |
+------------+-------------------------------------+----------------+
| burst_time | Time limit in milliseconds between | 5 ms |
| | packet bursts which identifies a | |
| | group | |
| Q | State noise covariance matrix | diag(Q(i)) = |
| | | [10^-13 |
| | | 10^-3]^T |
| E(0) | Initial value of the system error | diag(E(0)) = |
| | covariance | [100 0.1]^T |
| chi | Coefficient used for the measured | [0.1, 0.001] |
| | noise variance | |
| gamma_1(0) | Initial value for the adaptive | 12.5 ms |
| | threshold | |
| gamma_2 | Time required to trigger an overuse | 10 ms |
| | signal | |
| K_u | Coefficient for the adaptive | 0.01 |
| | threshold | |
| K_d | Coefficient for the adaptive | 0.00018 |
| | threshold | |
| T | Time window for measuring the | [0.5, 1] s |
| | received bitrate | |
| alpha | Decrease rate factor | 0.85 |
+------------+-------------------------------------+----------------+
在发送端
拥塞控制器的第二部分基于从基于延迟的控制器接收到的往返时间、数据包丢失和可用带宽估计A_hat做出决策。
基于延迟的控制器产生的可用带宽估计值A_hat只有在路径上的队列足够大时才可靠。如果队列长度很短,则 over-use 状态只能通过丢包得知,这样 delay-based controller 便不可用了。
丢包率控制器应该在收到每个反馈信息(收到 rtcp)的时候运行一次。
8*s
As_hat(i) >= ---------------------------------------------------------
R*sqrt(2*b*p/3) + (t_RTO*(3*sqrt(3*b*p/8)*p*(1+32*p^2)))
As_hat(i) <= A_hat(i)
公式中的 b 表示单个 tcp 的确认的包的数量。t_RTO 是TCP的重传超时时间,单位是秒,我们在这里设它为 4*R。s 是 平均每个包的字节数。R 是 rtt 时间,单位是秒。(我们将上述公式的分子乘8,用于将字节数转换为比特数)
简而言之:loss-based 的估计值不会大于 delay-based 估计值,也不会小于 TFRC 计算公式。(除非 delay-based 的估计值小于 TFRC)
一开始当传输通道 over-use,它应该只有很小的丢包率,这时我们由于发现丢包率没有达到 10%,所以并不会降低发送码率。于是,信道由于不断堆积,很快就会超过10%的丢包率(由于前面的数据包已经将队列填满,后续的数据包到来的速度又大于队列消耗的速度)。如果这个丢包率的产生和拥塞无关(那么它将上升到10%的丢包率),那么我们不应该对它进行处理。
如果传输通道由于over-use而有少量的丢包,如果发送方不调整他的比特率,这个丢包量很快就会增加来激励丢包阈值。因此,很快就会达到10%以上的阈值,我们应该调整As_hat(i)。但是,如果丢包率没有增加,那么这些丢包可能与自己造成的拥塞无关,因此我们不应该对它们做出处理。
如果发送方实现了这些算法,而接收方实现,建议发送方关注接收方的RTCP报告,并使用丢包率和rtt作为基于损失的控制器的输入。基于延迟的控制器就禁止使用了。
基于loss的和基于delay的都是通过控制发送的编码每次传几个包,来控制发送的带宽,然后控制拥塞。超过的包就直接丢掉了,发了也没有用,接收端会直接丢掉。