音视频传输-带宽评估

音视频传输 - WebRTC带宽评估

网络拥塞是基于IP协议的数据宝交换网络中常见的一种网络传输问题。网络拥塞是导致网络吞吐降低,网络丢包等的主要原因之一。

WebRTC中传输的采用的是UDP协议,WebRTC的传输层采用的拥塞算法是GCC算法

Google congestion control

目前新版本的WebRTC的基于丢包的和基于延迟的带宽评估都是放在发送端的。
旧版本的WebRTC的基于延迟的带宽评估可能放在接收端,然后反馈给发送端。

1. 基于丢包的拥塞机制 base_bitrate

基于丢包的拥塞控制比较简单。其基本思想是根据丢包的多少来判断网络的拥塞程度,丢包越多则认为网络越拥塞,那么我们就要降低发送速率来缓解网络拥塞。如果没有丢包,则说明网络状况良好,这时候就可以提高发送码率,向上探测是否有更多的带宽可用。实现该算法主要有两点,一是获得接收端的丢包率,一是确定降低码率和提升码率的阈值。

发送端基于丢包率的控制方法在每一个 t k t_k tk时刻, A s ( t k ) A_s(t_k) As(tk) t k t_k tk时刻的带宽估计值。
WebRTC通过RTCP协议的Receive Report反馈包来获取接收端的丢包率。Receive Report包中有一个fraction lost字段,包含了接收端的丢包率。

音视频传输-带宽评估_第1张图片

A s ( t k ) = { A s ( t k − 1 ) ∗ ( 1 − 0.5 ∗ f l ) f l > 0.1 1.05 ∗ ( A s ∗ ( t k − 1 ) ) f l < 0.02 A s ( t k − 1 ) o t h e r w i s e A_s(t_k)=\left\{ \begin{array}{rcl} A_s(t_{k-1}) * (1 - 0.5 * fl) & & {fl > 0.1}\\ 1.05 * (A_s * (t_{k-1}) )& & {fl < 0.02}\\ A_s(t_{k-1}) & & {otherwise} \end{array} \right. As(tk)=As(tk1)(10.5fl)1.05(As(tk1))As(tk1)fl>0.1fl<0.02otherwise

2. 基于延迟拥塞机制

  • 基于延迟梯度的带宽估计有两种版本,最早一种是在接收端实现,评估的带宽结果通过RTCP REMB消息反馈到发送端,在此种实现中,为了准确计算延迟梯度,WebRTC添加了一种RTP扩展头部abs-send-time,用来表示每个RTP包的精确发送时间,从而避免发送端延迟给网络传播延迟的估计带来误差。这种模式也是RFC和google的paper中描述的模式。
  • 在新近的WebRTC的实现中,所有的带宽估计都放在了发送端,也就是说发送端除了做基于丢包的带宽估计,同时也做基于延迟梯度的带宽估计。为了能够在发送端做基于延迟梯度的带宽估计,WebRTC扩展了RTP/RTCP协议,其一是增加了RTP扩展头部,添加了一个session级别的sequence number,目的是基于一个session做反馈信息的统计,而不仅仅是一条音频流或视频流,其二是增加了一个RTCP反馈信息transport-cc-feedback,该消息负责反馈接收端收到的所有媒体包的到达时间。发送端根据包间的接收延迟和发送间隔可以计算的延迟梯度,从而估计带宽。

2.1 基于延迟的拥塞控制 bwe_bitrate

基于延迟的拥塞控制是通过没组包的到达时间的延迟差的增长趋势来判断网络是否过载,如果过载进行码率下调,如果处于平衡范围维持当前码率,如果网络承载不饱满进行码率上调。

2.1.1 包组

WebRTC在评估延迟差的视乎不是对每个包进行估算,而是采用了包组间进行延迟评估,这符合视频传输(视频帧是需要切分成多个UDP包)的特点,也减少了频繁计算带来的误差。那什么是包组呢?就是距包组中第一个包的发送时刻 t 0 t_0 t0小于 b u r s t _ t i m e burst\_time burst_time发送的所有的包成为一组,第一个超过 b u r s t _ t i m e burst\_time burst_time的包作为下一个包组的第一个包。

  • 为什么是 b u r s t _ t i m e burst\_time burst_time一组呢,这是由于WebRTC的发送端实现了一个平滑发送模块,该模块的发送时间间隔是 b u r s t _ t i m e burst\_time burst_time发送一批数据包。
  • 到达时间间隔小于 b u r s t _ t i m e burst\_time burst_time的数据包被归为一组,这是由于在wifi网络下,某些wifi设备的转发模式是,在某个固定时间片内才有机会转发数据包,这个时间片的间隔可能长达100ms,造成的结果是100ms的数据包堆积,并在发送时形成burst,这个burst内的所有数据包就会被视为一组。

b u r s t _ t i m e burst\_time burst_time可以与平滑发送的时间间隔联系,比它小就可以。
一般认为:

b u r s t _ t i m e = 5 m s burst\_time = 5ms burst_time=5ms

2.1.2 延迟梯度

设相邻的两个数据分组到达接收方的时间间隔为 t ( i ) − t ( i − 1 ) t(i) - t(i-1) t(i)t(i1), 而两者被发送的时间间隔则为 T ( i ) − T ( i − 1 ) T(i) - T(i-1) T(i)T(i1),那么就有延迟变量 d ( i ) = t ( i ) − t ( i − 1 ) − ( T ( i ) − T ( i − 1 ) ) d(i)=t(i)-t(i-1) - (T(i)-T(i-1)) d(i)=t(i)t(i1)(T(i)T(i1))。如果 d ( i ) > 0 d(i) > 0 d(i)>0,就说明数据在网络传输时存在延迟的现象。

这里的 d ( i ) d(i) d(i)也称为延迟梯度。
音视频传输-带宽评估_第2张图片

  • 由于延迟梯度 d i d_{i} di的测量精度很小,为了避免网络噪音带来的误差,旧版本WebRTC在接收端利用了卡尔曼滤波来平滑延迟梯度的测量结果,新版本WebRTC则在客户端使用了trendline滤波分析
  • WebRTC的实现中,并不是单纯的测量单个数据包彼此之间的延迟梯度,而是前面提到的分组测量。分组的时间间隔为5ms。
  • 为了计算延迟梯度,所有接收端要反馈每个媒体包的接收状态,同时发送端也要记录每个媒体包的发送状态,记录其发送的时间值。在这个情况下abs-send-time扩展不再需要。

2.1.3 过载检测

到达时间滤波器计算出每组数据包的延迟梯度之后,就要据此判断当前的网络拥塞状态,通过和某个阈值的比较,高过某个阈值就认为时网络拥塞,低于某个阈值就认为网路状态良好,因此如何确定阈值就至关重要。这就是过载检测器的主要工作,它主要有两部分,一部分是确定阈值的大小,另一部分就是依据延迟梯度和阈值的判断,估计出当前的网络状态,一共有三种网络状态: overuse underuse normal,我们先看网络状态的判断。

音视频传输-带宽评估_第3张图片
其中 m ( t i ) m(t_i) m(ti)表示的过去一段时间计算出来的延迟梯度的平均值
这里用 γ ( t i ) \gamma(t_i) γ(ti)表示阈值,阈值根据时间自适应。

  • m ( t i ) > γ ( t i ) m(t_i) > \gamma(t_i) m(ti)>γ(ti), overuse状态。
  • m ( t i ) < − γ ( t i ) m(t_i) < -\gamma(t_i) m(ti)<γ(ti),underuse状态。
  • − γ ( t i ) < m ( t i ) < γ ( t i ) -\gamma(t_i) < m(t_i) < \gamma(t_i) γ(ti)<m(ti)<γ(ti) normal状态。

这样计算的依据是,网络发生拥塞时,数据包会在中间网络设备中排队等待转发,这会造成延迟梯度的增长,当网络流量回落时,网络设备快速消耗(转发)其发送队列中的数据包,而后续的包排队时间更短,这时延迟梯度减小或为负值。

  • 在实际WebRTC的实现中,虽然每个数据包组(前面提到了如何分组)的到达都会触发这个探测过程,但是使用的m(ti)这个值并不是直接使用每组数据到来时的计算值,而是将这个值放大了60倍。这么做的目的可能是m(ti)这个值通常情况下很小,理想网络下基本为0,放大该值可以使该算法不会应为太灵敏而波动太大。
  • 在判断是否overuse时,不会一旦超过阈值就改变当前状态,而是要满足延迟梯度大于阈值至少持续100ms,才会将当前网络状态判断为overuse。

2.1.4 阈值自适应

γ ( t i ) \gamma(t_i) γ(ti),它是判断当前网络状况的依据,所以如何确定它的值也就非常重要了。虽然理想状况下,网络的延迟梯度是0,但是实际的网络中,不同转发路径其延迟梯度还是有波动的,波动的大小也是不一样的,这就导致如果设置固定的。 γ ( t i ) \gamma(t_i) γ(ti)太大可能无法探测到拥塞,太小又太敏感,导致速率了变化很大。同时,另外一个问题是,实验中显示固定的值会导致在和TCP链接的竞争中,自己被饿死的现象(TCP是基于丢包的拥塞控制),因此WebRTC使用了一种自适应的阈值调节算法,具体如下:

γ ( t i ) = γ ( t i − 1 ) + Δ T ⋅ K γ ( t i ) ⋅ ( ∣ m ( t i ) ∣ − γ ( t i − 1 ) ) \gamma(t_i) = \gamma(t_{i-1}) + \Delta{T} \cdot K_{\gamma(t_i)} \cdot (|m(t_i)| - \gamma(t_i -1)) γ(ti)=γ(ti1)+ΔTKγ(ti)(m(ti)γ(ti1))

Δ T = t i − t i − 1 \Delta{T} = t_i - t_{i-1} ΔT=titi1

K γ ( t i ) = { k d ∣ m ( t i ) ∣ < γ ( t i − 1 ) k u o t h e r w i s e K_{\gamma(t_i)}=\left\{ \begin{array}{rcl} k_d & & |m(t_i)| < \gamma(t_{i} -1) \\ k_u & & {otherwise} \end{array} \right. Kγ(ti)={kdkum(ti)<γ(ti1)otherwise
建议
k u > k d k_{u} > k_{d} ku>kd
推荐值
k u = 0.01 k_{u} = 0.01 ku=0.01 k d = 0.00018 k_d = 0.00018 kd=0.00018

从这个式子可以看出,当延迟梯度减小时,阈值会以一个更慢的速率减小;延迟梯度增加时,阈值也会以一个更慢的速度增加。不过相对而言,阈值的减小速度要小于增加速度。这样主要是为了防止饥饿。

2.1.5 速率调整状态机

在过载检测中有提到三种情况,normal, underuse, overuser。
然后estimator通过根据三个情况来更新状态。采用一定的比值,对速率进行调整。
三个状态分别是Increase, Hold, Decrease。

这三种状态的状态机如下,系统在Increase状态下启动。
音视频传输-带宽评估_第4张图片
一般可以认为带宽评估的更新 A s ( t k ) A_s(t_k) As(tk)按照以下公式进行。
A s ( t k ) = { η ∗ A s ( t k − 1 ) I n c r e a s e β ∗ R r ( t i ) D e c r e a s e A s ( t k − 1 ) H o l d A_s(t_k)=\left\{ \begin{array}{rcl} \eta * A_s(t_{k-1}) & & Increase\\ \beta * R_r (t_{i}) & & Decrease\\ A_s(t_{k-1}) & & {Hold} \end{array} \right. As(tk)=ηAs(tk1)βRr(ti)As(tk1)IncreaseDecreaseHold

其中
η = 1.05 \eta = 1.05 η=1.05

β = 0.85 \beta = 0.85 β=0.85

R r ( t i ) 指 的 是 过 去 500 m s 窗 内 的 最 大 a c k e d b i t r a t e R_r(t_{i}) 指的是过去500ms窗内的最大acked bitrate Rr(ti)500msackedbitrate

值得注意的是,Incease状态时 A s ( t k ) A_s(t_k) As(tk)的增加策略应该权衡multiplicatively or additively
界定:
如果当前的 R r ( t i ) R_r(t_{i}) Rr(ti)比较接近我们上一次在Decrease阶段的平均的 R r ( t i ) R_r(t_{i}) Rr(ti),我们就认为现在大概率在拥塞的边缘,这时候应该选择加性增。

乘法增:
η = 1.08 ⋅ m i n ( t i m e _ s i n c e _ l a s t _ u p d a t e _ m s / 1000 , 1.0 ) \eta = 1.08 \cdot min(time\_since\_last\_update\_ms / 1000,1.0) η=1.08min(time_since_last_update_ms/1000,1.0)

A s ( t k ) = η ⋅ A s ( t k − 1 ) A_s(t_k) = \eta \cdot A_s(t_{k-1}) As(tk)=ηAs(tk1)

加性增:

r e s p o n s e _ t i m e _ m s = 100 + r t t _ m s response\_time\_ms = 100 + rtt\_ms response_time_ms=100+rtt_ms

α = 0.5 ∗ m i n ( t i m e _ s i n c e _ l a s t _ u p d a t e _ m s / r e s p o n s e _ t i m e _ m s , 1.0 ) \alpha = 0.5 * min(time\_since\_last\_update\_ms / response\_time\_ms,1.0) α=0.5mintime_since_last_update_ms/response_time_ms1.0

A s ( t k ) = A s ( t k − 1 ) + m a x ( 1000 , α ∗ e x p e c t e d _ p a ​ ​ c k e t _ s i z e _ b i t s ) A_s(t_k)= A_s(t_{k-1})+ max(1000,\alpha * expected\_pa​​cket\_size\_bits) As(tk)=As(tk1)+max1000αexpected_packet_size_bits

最后:

  • 带宽评估不应该过于剧烈
    所以最后要有:
    A s ( t k ) < 1.5 ⋅ R r ( t i ) A_s(t_k) < 1.5 \cdot R_r (t_{i}) As(tk)<1.5Rr(ti)
    R r ( t i ) 指 的 是 过 去 一 段 时 间 内 最 大 a c k e d b i t r a t e R_r(t_{i}) 指的是过去一段时间内最大acked bitrate Rr(ti)ackedbitrate

  • 带宽评估触发的时间间隔 t i + 1 − t i t_{i+1} - t_{i} ti+1ti应该尽量均匀

综合

WebRTC会根据上述丢包得到的带宽base_bitrate和基于延迟得到的bwe_bitrate得到的最小值,这个最小值作为estimator最终评估出来的码率。

参考链接

https://tools.ietf.org/html/draft-ietf-rmcat-gcc-02#section-1.1
http://www.sohu.com/a/210713395_629429
http://www.ctiforum.com/news/guandian/535764.html

你可能感兴趣的:(音视频传输)