深入浅出WebRTC—DelayBasedBwe

WebRTC 中的带宽估计是其拥塞控制机制的核心组成部分,基于延迟的带宽估计是其中的一种策略,它主要基于延迟变化推断出可用的网络带宽。

1. 总体架构

1.1. 静态结构

1)DelayBasedBwe 受 GoogCcNetworkController 控制,接收其输入并返回带宽估计值。

2)DelayBasedBwe 内部使用 InterArrivalDelta、TrendlineEstimator 和 AimdRateControl 来完成带宽估计。

3)InterArrivalDelta 用来计算到达时间延迟。

4)TrendlineEstimator 根据到达时间延迟判断带宽使用是否过载。

5)AimdRateControl 内部运行一个状态机,根据状态机不断调整带宽估计值。

1.2. 调用流程

1)GoogCcNetworkController 收到 TransportFeedback,调用 DelayBasedBwe::IncomingPacketFeedbackVector 来计算基于延迟的带宽估计值。

2)DelaybasedBwe 调用 InterArralDelta::ComputeDeltas 计算延迟差值。

3)DelaybasedBwe 调用 TrendlineEstimator::Update 传入延迟差值计算得到带宽过载情况。

4)DelaybasedBwe 调用 AimdRateControl::Udpate 传入带宽过载情况计算得到延迟带宽估计值。

5)GoogCcNetworkController 调用 SendSideBandwidthEstimation::UpdateDelayBasedEstimate 传入延迟带宽估计值,融合基于丢包的带宽估计值,获得最终的带宽估计值。

1.3. 逻辑架构

1)DelayBaseBWE 接收一坨输入,经过计算输出DelayBasedBwe::Result(见 DelayBasedBwe 数据结构)。

2)InterArrivalDlata 基于 TransportFeedback 计算延迟差。

3)TrendLineEstimator 基于延迟差计算 BandwidthUsage。

4)LinkCapacityEstimator 基于过载状态下的 ACK 码率估算链路容量并计算 3sigma 上下界。当AIMD 升码率时,基于链路容量估计值来决定是采用加性增还是乘性增。当 AIMD 降码率时,下降之后的码率不能高于链路容量估计值。3sigma 上下界用来判断当前链路容量估计值的有效性,如果新的 ACK 码率超出 3sigma 范围,则链路容量估计值要重置并重新进行估算。

5)DelayBaseBWE 设置 ALR 状态到 AimdRateControl,当根据带宽使用情况决策应该要升码率时,如果此时进入了 ALR 状态,不允许升码率,和之前码率保持一致。

6)网络非过载状态下,DelayBaseBWE 设置 Probe bitrate 到 AimdRateControl,用探测带宽更新估计值。此时探测带宽很可能是链路的真实带宽,这样更新是合理的。

7)AimdRateControl 使用 TrendLineEstimator 输出的 BandwidthUsage 更来状态机状态,然后根据新的控制状态来更新带宽估计值,如果是 kRcHold 则保持估计值不变,如果是 kRcIncrease 则采用加性增或乘性增来增加带宽估计值,如果是 kRcDecrease 则降低估计值。

DelayBaseBWE 在调用 AimdRateControl 之前,会根据 BandwidthUsage 进行前处理:

1)如果链路处于 overusing 状态,且没有可用的 ACK 码率,则估计值砍半,这个频率(间隔)由 RTT 决定。

2)如果链路处于normal/underusing 状态,且有可用的探测带宽,则使用探测带宽更新估计值。

其他情况,才会更新 AimdRateControl 状态机,由 AimdRateControl 给出带宽估计值。

2. DelayBasedBwe

2.1. 重要属性

1)video_inter_arrival_

用来计算报文到达延迟差。

2)video_delay_detector_

TrendLineEstimator,用来检测链路过载状态。

3)rate_control_

根据链路过载状态及其变化来对带宽进行估计。

2.2. 重要方法

1)IncomingPacketFeedbackVector

传入 TransportFeedback 以计算报文到达延迟差,同时还会传入 ACK 码率、探测码率和 ALR 状态。

2)OnRttUpdate

更新链路 RTT,AimdRateControl 使用。

3)LatestEstimate

从 AimdRateControl 获取最近延迟带宽估计值。

4)SetStartBitrate

设置 AimdRateControl 的起始码率。

5)SetMinBitrate

设置 AimdRateControl 的最小码率。

2.3. 数据结构

带宽使用有正常、欠载和过载三种状态。

enum class BandwidthUsage {
  kBwNormal = 0,
  kBwUnderusing = 1,
  kBwOverusing = 2,
  kLast
};

延迟带宽估计器返回值。

struct DelayBasedBwe::Result {
  // 带宽估计值是否有更新
  bool updated = false;
  // 是否是使用探测值进行的更新
  bool probe = false;
  // 更新后的目标码率估计值
  DataRate target_bitrate = DataRate::Zero();
  // 是否是从过载恢复
  bool recovered_from_overuse = false;
  // 根据算法计算得到的带宽使用情况
  BandwidthUsage delay_detector_state = BandwidthUsage::kBwNormal;
};

2.4. 源码分析

2.4.1. IncomingPacketFeedbackVector

收到 TransportFeedback 后,使用延迟差值更新趋势线估计器,更新 ALR 状态,然后调用 MaybeUpdateEstimate 获取估计结果。

DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
    const TransportPacketsFeedback& msg,
    absl::optional<DataRate> acked_bitrate,
    absl::optional<DataRate> probe_bitrate,
    absl::optional<NetworkStateEstimate> network_estimate,
    bool in_alr) {
  // 按时间进行排序
  auto packet_feedback_vector = msg.SortedByReceiveTime();
  ...
  // 逐个处理feedback
  for (const auto& packet_feedback : packet_feedback_vector) {
    delayed_feedback = false;
    // 计算时延delta,并更新detector状态
    IncomingPacketFeedback(packet_feedback, msg.feedback_time);
    // 网络状态从欠载状态到正常状态,说明已经恢复
    if (prev_detector_state == BandwidthUsage::kBwUnderusing &&
        active_delay_detector_->State() == BandwidthUsage::kBwNormal) {
      recovered_from_overuse = true;
    }
    prev_detector_state = active_delay_detector_->State();
  }

  // 更新ALR状态
  rate_control_.SetInApplicationLimitedRegion(in_alr);
	
  // 从AIMD获取目标码率
  return MaybeUpdateEstimate(acked_bitrate, probe_bitrate,
                             std::move(network_estimate),
                             recovered_from_overuse, in_alr, msg.feedback_time);
}

2.4.2. MaybeUpdateEstimate

1)在没有获取到 ACK 码率的情况下,如果网络过载,算法简单粗暴,每 200ms 下降 50%。在未获得测量值的前提下,保守处理比较好。

2)在获得探测码率的情况下,如果网络不过载,则使用探测码率更新估计值。这是因为探测码率是通过主动探测获得的,它能更快、更真实地反映网络当前的实际承载能力。

DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
	absl::optional<DataRate> acked_bitrate,
	absl::optional<DataRate> probe_bitrate,
	absl::optional<NetworkStateEstimate> state_estimate,
	bool recovered_from_overuse,
	bool in_alr,
	Timestamp at_time) {
	Result result;

	// 网络过载,需要降码率
	if (active_delay_detector_->State() == BandwidthUsage::kBwOverusing) {
		if (acked_bitrate && 
				rate_control_.TimeToReduceFurther(at_time, *acked_bitrate)) {
			// 已经获取ACK码率,且符合调整频率限制,基于 ACK 码率更新估计码率
			result.updated = UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
		} else if (!acked_bitrate && 
				rate_control_.ValidEstimate() &&
				rate_control_.InitialTimeToRe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值