webrtc弱网-LossBasedBandwidthEstimation类源码分析与算法原理
LossBasedBandwidthEstimation类基于网络丢包率动态估算可用带宽上限。它通过分析丢包统计数据,使用多阈值控制和RTT自适应算法,决定增加、减少或保持当前带宽估计,实现网络拥塞控制,是WebRTC GCC拥塞控制体系的核心组件之一。
1. 核心功能
该模块的核心功能是根据网络丢包率动态估计可用带宽上限。它是WebRTC GCC(Google Congestion Control)拥塞控制算法体系中的重要组成部分,其主要职责包括:
丢包统计:接收传输反馈(RTCP),计算近期丢包率。
带宽调整:根据当前丢包率与目标阈值的比较,决定增加、减少或保持当前带宽估计值。
状态维护:维护历史丢包率、确认速率等状态,以平滑噪声并避免过度反应。
复位机制:在特定条件下(如极低丢包率)将估计值重置为当前目标速率,以快速适应网络改善。
2. 核心算法原理
该模块的算法基于以下核心思想:
丢包率与带宽的模型关系:算法假设存在一个函数关系,描述了在给定丢包率下可支持的最大带宽。该关系由以下公式定义:
丢包率计算:
loss = (loss_bandwidth_balance / bitrate) ^ exponent
带宽计算:
bitrate = loss_bandwidth_balance * (loss) ^ (-1 / exponent)
其中,loss_bandwidth_balance
和exponent
是可配置参数,决定了模型的形状。
多阈值控制:算法定义了三个关键丢包率阈值,用于触发不同的行为:
Reset阈值:极低丢包率时,直接将带宽估计重置为当前目标速率(
wanted_bitrate
)。Increase阈值:低丢包率时,谨慎增加带宽估计。
Decrease阈值:高丢包率时,果断减少带宽估计。
RTT自适应增加:带宽增加的幅度与当前的RTT(Round-Trip Time)相关。RTT越高,增加的因子越小,增长越保守。这是在网络延迟较大时的一种谨慎策略。
指数平滑:对丢包率(
average_loss_
,average_loss_max_
)和确认速率(acknowledged_bitrate_max_
)进行指数加权移动平均(EWMA),以平滑瞬时波动,获取更稳定的长期趋势。
3. 关键数据结构
LossBasedControlConfig
:
存储所有可配置的实验参数,通过字段试验(Field Trials)动态解析。关键参数包括:min/max_increase_factor
: 带宽增加的最小/最大乘数。increase_low_rtt
/increase_high_rtt
: 用于归一化RTT的范围。decrease_factor
: 带宽减少的乘数。loss_bandwidth_balance_increase/decrease/reset
: 用于计算不同操作下阈值的平衡点带宽。loss_bandwidth_balance_exponent
: 模型指数。allow_resets
: 是否允许复位操作。
LossBasedBandwidthEstimation
:
核心类,维护算法状态:average_loss_
: 经过平滑的短期平均丢包率。average_loss_max_
: 经过平滑的短期平均丢包率的最大值(用于增加决策,避免单次波动触发增加)。loss_based_bitrate_
: 当前基于丢包的带宽估计值。acknowledged_bitrate_max_
: 经过平滑的确认速率最大值(用于计算减少后的带宽)。time_last_decrease_
,has_decreased_since_last_loss_report_
: 用于控制减少操作的频率,防止短时间内连续多次减少。last_loss_packet_report_
,last_loss_ratio_
: 最近一次上报的丢包统计的时间和比率。
4. 核心方法详解
UpdateLossStatistics
:输入:一批数据包的反馈结果 (
packet_results
) 和当前时间。处理:计算该批数据包的即时丢包率 (
last_loss_ratio_
)。平滑:使用
ExponentialUpdate
函数计算平滑系数,更新短期平均丢包率 (average_loss_
) 及其历史最大值 (average_loss_max_
)。
UpdateAcknowledgedBitrate
:输入:最新计算得到的确认速率和当前时间。
处理:同样使用指数平滑,更新确认速率的长期最大值 (
acknowledged_bitrate_max_
)。该值用于在减少带宽时提供一个底线(decreased_bitrate()
)。
Update
(核心方法):状态检查:检查丢包报告是否新(
loss_report_valid
)以及是否允许进行减少操作(allow_decrease
)。决策树:
复位:如果允许复位且平均最大丢包率极低 (
< loss_reset_threshold()
),则将loss_based_bitrate_
重置为wanted_bitrate
。增加:如果丢包率较低 (
< loss_increase_threshold()
),则计算一个新的更高的带宽。新带宽受两个值约束:一是基于RTT计算出的增量(min_bitrate * factor + offset
),二是根据丢包模型计算出的上限(BitrateFromLoss(...)
)。最终取两者中较小的值,并与当前估计值取大。减少:如果丢包率较高 (
> loss_decrease_threshold()
) 且允许减少,则根据丢包模型计算出一个新的、更低的带宽下限(BitrateFromLoss(...)
)。新的估计值取这个下限和基于确认速率计算出的值(decreased_bitrate()
)中的较大者。同时更新减少时间戳和状态。
返回:返回更新后的
loss_based_bitrate_
。
5. 设计亮点
字段试验高度可配置:几乎所有算法参数都可通过FieldTrials动态配置,便于A/B测试和算法迭代,而无需重新编译。
双重平滑:对丢包率使用双重平滑(
average_loss_
和average_loss_max_
),有效区分单次噪声和持续趋势,增加决策的稳定性。RTT自适应增加:将网络延迟(RTT)引入带宽增加策略,在高延迟网络中采取更保守的策略,提升了算法在不同网络条件下的鲁棒性。
减少操作频率限制:通过
decrease_interval
和状态变量(has_decreased_...
)防止算法在单个丢包脉冲后过度反应,连续多次削减带宽。模型驱动阈值:三个阈值并非固定值,而是随着当前带宽估计值动态变化的,其计算基于一个简化的丢包-带宽模型,使算法行为更具理论依据。
6. 典型工作流程
初始化:通过
Initialize
方法设置一个初始的带宽估计值。持续反馈:
接收端定期通过RTCP发送传输反馈,包含数据包的接收状态。
发送端的拥塞控制器(如
GoogCcNetworkController
)接收到反馈后,调用UpdateLossStatistics
更新丢包统计。控制器计算出的确认速率被传递给
UpdateAcknowledgedBitrate
。
定期更新:控制器以固定的时间间隔(或事件驱动)调用
Update
方法,传入当前时间、最小比特率、目标比特率和最新RTT。决策与执行:
Update
方法根据最新的状态(丢包率、确认速率)和配置参数,决定新的带宽估计值。该估计值被返回给控制器,控制器将其与其他约束(如延迟基估计、端到端控制)结合,最终确定发送码率。
循环往复:上述过程不断重复,使发送码率能够自适应地跟踪网络可用带宽的变化。
WebRTC的基于丢包的带宽估计是一个融合了启发式规则、数学模型和高度可配置参数的复杂自适应系统。它的设计充分考虑了实时通信中对稳定性、响应性和公平性的需求。