loss-based controller 通常在 sender 实现
delay-based controller 既可以在 sender 实现 也可以 在 receviver 实现
sender-based :实际上是 loss-based controller 的实现。
receiver-based :实际上便是 delay-based controller 在 receviver 的实现。在 2012 的版本中,暂未提供 delay-based controller 在 sender 的实现,而在 2016 的版本中进行了补充。
本文档描述了两种用于 RTCWEB 的拥塞控制方法:one delay-based and one loss-based 。
拥塞控制是共享 internet 资源的所有应用程序的需求。
为实时流媒体进行拥塞控制是一个极大的挑战,主要涉及以下原因:
本文档描述了两种拥塞控制算法,它们一起能够与使用相同拥塞控制算法(即本文描述的两种拥塞控制算法)的其他音视频流以及共享相同链路的 TCP 流提供良好的性能和合理的带宽共享。
拥塞控制系统中包含以下要素:
loss-based controller 和 delay-based controller 共同实现 拥塞控制 算法。
有两种方法可实现提出的算法:
loss-based controller 和 delay-based controller 都运行在发送端。
RTP 接收者将记录每个 RTP 包的到达时间和 transport-wide(传输范围) sequence number,它将 transport-wide feedback message 定期发送回发送者。建议的反馈间隔是每个接收到的视频帧一次,如果是纯音频或多流,则至少每 30 毫秒一次,如果需要限制反馈开销,这个间隔可以增加到 100 毫秒。
RTP 发送者将从接收到的 feedback message 获得 {sequence number, arrival time} ,并将 feedback message 所涵盖的每个包的 sequence number 映射其 send-time ,然后将 {send-time, arrival time} 喂给 delay-based controller 。同时,发送者还将根据 feedback message 中的 sequence number 计算丢包率。
依赖 TWCC 消息,接收端 通过 TWCC 消息向 发送端 反馈 一组包的到达时间,发送端根据 TWCC 消息反馈的 {sequence number, arrival time} 以及本地的 send-time 喂给 delay-based controller 计算bitrate ,并计算丢包率,最后 loss-based controller 根据 bitrate 和 丢包率 给出最终的目标 bitrate 。
delay-based controller 在发送端,但是发送端不知道 RTP 包的到达时间,因此需要接收端使用 TWCC 消息向发送端反馈 RTP 包的到达时间,以便 delay-based controller 进行带宽估计,此时带宽估计的计算量在发送端。
loss-based controller 运行在发送端,delay-based controller 运行在接收端。
丢包通过 RTCP receviver reports 发回。
发送端 将 REMB message 中的 bitrate 和 RTCP report 中的 丢包率 喂给 loss-based controller, loss-based controller 输出最终的目标码率。建议在检测到拥塞后立即发送 REMB 消息,否则至少每秒发送一次。
依赖 REMB 消息,接收端的 delay-based controller 输出一个 bitrate,通过 REMB 消息告知 发送端,发送端的 loss-based controller 根据 REMB 消息的 bitrate 以及丢包率 给出 最终的目标 bitrate 。
delay-based controller 在接收端,即基于延迟的带宽估计在接收端,通过 REMB 消息向发送端报告基于延迟的带宽估计结果。
Pacing 用于驱动 controller 计算的目标比特率。
当媒体编码器产生数据时,这将被送入 Pacer 队列。
Pacer 每隔 burst_time 间隔向网络发送一组数据包。推荐的 burst_time 是 5 ms 。一组数据包的大小被计算为目标 bitrate 和 burst_time 之间的乘积。
Delay-based control 算法可进一步拆分为 4 部分:
前置过滤 的目的在于 处理由通道中断引起的延迟瞬变。在中断期间在网络缓冲区中排队的数据包,由于与拥塞无关的原因,在中断结束后以突发方式传递。
前置过滤 的实现是 将一下子到达的多组包合并。
如果以下的两个条件之一成立,那么数据包将被合并在同一组中:
当 i > 1 时,参数组间延迟变化 d(i) 对每一组包是可用的。我们希望估算 Arrival-time model 中的 m(i) ,并使用这个估算值来检测瓶颈链路是否 over-used 。参数 m(i) 可以使用任何可用的 filter 进行估算,在此我们采用了 Kalman filter 。
arrival-time filter 输出组间延迟变化估计值 m(i), m(i) 被用于与阈值 del_var_th(i) 进行比较:若 m(i) 高于 del_var_th(i) 则被认为是 over-use 的一个指示。这样的指示是不足以让检测器向速率控制子系统(rate control subsystem)发出 over-use 的信号的。只有 在至少 overuse_time_th 毫秒内连续检测到 over-use 时,才会发出 over-use 信号。
但是,如果 m(i) < m(i-1),即使满足上述所有条件,也不会发出 over-use 信号。
类似地,当 m(i) < - del_var_th(i) 时,检测到相反的状态,under-use(over-use 的反义词)。 如果既没有检测到过度使用(over-use)也没有检测到使用不足(under-use),则检测器将处于 normal 状态。
阈值 del_var_th 对算法的整体动态和性能有显着影响。
特别是,已经有实践表明,使用静态阈值 del_var_th,由所提出算法控制的流可能会被并发 TCP 流 [Pv13] 饿死。可以通过将阈值 del_var_th 增加到足够大的值来避免这种饥饿。
原因是,通过使用较大的 del_var_th,可以容忍较大的排队延迟 (即允许较大的 m(i) 值);对于较小的 del_var_th,over-use detector 会通过生成 over-use 信号来快速对偏移估计 m(i) 的小幅增加做出反应(减少基于延迟估计的可用带宽 A_hat)。
出于这个原因,我们建议根据以下动态方程改变阈值 del_var_th(i):
Rate control 被分为两部分:
只要没有检测到拥塞,两者都旨在增加对可用带宽 A_hat 的估计,并确保最终匹配信道的可用带宽,并检测到 over-use。
一旦发现 over-use,由 delay-based controller 估计的可用带宽减少。通过这种方式,我们得到了可用带宽的递归和自适应估计。
在本文档中,我们假设 rate control subsystem 是周期性执行的,并且这个周期是恒定的。
rate control subsystem 有 3 个 states:Increase、Decrease 和 Hold。
subsystem 从 increase 状态开始,increase 状态将一直停留在 subsystem 中直到 over-use 或 under-use 。 在 increase 状态下,每次更新时,基于延迟估计的可用带宽都会增加(无论是 multiplicative increase 还是 additive increase,乘法还是加法取决于其当前状态,见下文)。
如果当前带宽估计看起来离收敛很远,则系统会进行乘法增加,而如果看起来更接近收敛,系统会进行加法增加。(何为离收敛很远,何为接近收敛,见下文)。
接近收敛如果当前输入的比特率 R_hat(i) 接近我们之前处于 Decrease 状态时的输入比特率的平均值,我们假设我们接近收敛。“接近”定义为围绕该平均值的三个标准差。建议使用平滑因子为 0.95 的指数移动平均线测量此平均值和标准差,因为预计该平均值涵盖了我们处于 Decrease 状态的多个场合。
远离收敛每当这些统计数据的有效估计不可用时,我们假设我们尚未接近收敛,因此仍处于乘法 Increase 状态。
如果 R_hat(i) 增加到平均最大比特率的三个标准偏差以上,我们假设当前拥塞级别已经改变,此时我们重置平均最大比特率并返回乘法 Increase 状态。
R_hat(i)R_hat(i) 是 delay-based controller 在 T 秒窗口内测量的输入比特率:
N(i) 是过去 T 秒接收到的数据包数量,L(j) 是数据包 j 的有效负载大小。 建议使用 0.5 到 1 秒之间的窗口 T。
乘法增加delay-based controller 的可用带宽估计 A_hat 。在乘法增加(multiplicative increase)期间,估计每秒最多增加 8% :
加法增加delay-based controller 的可用带宽估计 A_hat 。在加法增加(additive increase)期间,每个 response_time 间隔最多增加一半数据包的估计值。 response_time 间隔估计为往返时间加上 100 ms ( 100ms 作为 over_use 估计器和检测器反应时间的估计 ) 。
当检测到过度使用时,系统转换到 Decrease 状态,其中 delay-based control 可用带宽估计 A_hat(i) 降低到当前 接收bitrate R_hat(i) 的一个因子。
beta 通常选择在区间 [0.8, 0.95] 内,0.85 是推荐值。
当检测器向速率控制子系统发出 under-use 的信号时,我们知道网络路径中的队列正在被清空,这表明我们的可用带宽估计值 A_hat 低于实际可用带宽。 收到该信号后,速率控制子系统将进入 hold 状态,在此状态下接收端可用带宽估计将保持不变,同时等待队列稳定在较低级别——这是一种尽可能降低延迟的方法。
建议更新 A_hat(i) 的例程至少在每个 response_time 间隔运行一次。
第二部分的拥塞控制器(Loss-based controller)的决策基于 RTT ,丢包 packet loss 和 来自 delay-based controller 的可用带宽估计 A_hat 。
Loss-based controller 的可用带宽估计用 As_hat 表示。
由 Delay-based controller 产生的可用带宽估计 A_hat 仅在沿路径的队列大小足够大时才可靠。如果队列非常短,over-use 只会通过丢包可见(如果队列长,over-use 会引起 packet 在队列中排队的时间长,从而引起时延的变化,delay-based control 就能感知到 over-use),而 Delay-based controller 不会关心丢包。
每次接收到来自 receiver 的反馈(反馈 丢包 等信息))时,Loss-based controller 都应该运行:
将 Loss-based controller 的估计 As_hat 与 Delay-based controller 的估计 A_hat 进行比较。 实际发送速率设置为 As_hat 和 A_hat 之间的最小值。
我们通过注意到如果传输通道由于 over-use 而有少量丢包,如果发送者不调整他的比特率,这个量很快就会增加,那么很快就会超过 10% 的阈值并调整 As_hat(i)。 但是,如果丢包率没有增加,那么丢包可能与自己造成的拥塞无关,因此我们不应该对它们做出反应。
能够在连接上插入或删除消息的攻击者将能够破坏速率控制。 这可能使算法产生一个发送速率不足利用瓶颈链路容量,或者发送速率过高导致网络拥塞。
在这种情况下,控制信息是在 RTP 内部携带的,并且可以使用 SRTP 来防止修改或消息插入,就像媒体一样。 鉴于时间戳包含在未加密的 RTP 标头中,因此无法防止泄露,但仅基于时间信息似乎很难发起攻击。