WebRtc码率控制模块之AcknowledgedBitrateEstimator

   AcknowledgedBitrateEstimator是当前接收方吞吐量。与当前估计码率相差甚远的样本,或基于少数数据包的样本被赋予较小的权重,因为它们被认为更有可能是与拥塞无关的延迟峰值造成的。
   模块主要是在时间窗内估计接收方码率estmate_bitrate,不在时间窗内的,沿用前一个估计值estmate_bitrate,初始时间窗为500ms,后续时间窗为150ms。模块还会通过贝叶斯估计算法对前一个估计值和当前样本的观测值重新计算估计最新值。
代码解读

void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector(//处理RTPFB反馈包中接收到的包
    const std::vector<PacketResult>& packet_feedback_vector) {//packet_feedback_vector为接收方接收到的包信息队列
  for (const auto& packet : packet_feedback_vector) {
    if (alr_ended_time_ && packet.sent_packet.send_time > *alr_ended_time_) {//当alr处于不激活状态
      bitrate_estimator_->ExpectFastRateChange();//通过将码率估计方差增加一个较高的值,原始方差=50,增加一个200的方差值,允许码率在接
      //下来的几个样本中快速变化。
      alr_ended_time_.reset();
    }
    DataSize acknowledged_estimate = packet.sent_packet.size;
    acknowledged_estimate += packet.sent_packet.prior_unacked_data;//acknowledged_estimate 统计净荷
    bitrate_estimator_->Update(packet.receive_time, acknowledged_estimate,//根据输入样本的接收时间和净荷估计码率值
                               in_alr_);
  }
}

根据输入样本的接收时间和净荷估计码率值

void BitrateEstimator::Update(Timestamp at_time, DataSize amount, bool in_alr) {
  int rate_window_ms = noninitial_window_ms_;//统计窗口noninitial_window_ms_=150ms
  // 在开始时使用一个更大的窗口initial_window_ms_=500ms来获得一个更稳定的样本,我们可以用它来初始化估计值。
  if (bitrate_estimate_kbps_ < 0.f)//初始时bitrate_estimate_kbps_=-1
    rate_window_ms = initial_window_ms_;
  float bitrate_sample_kbps =
      UpdateWindow(at_time.ms(), amount.bytes(), rate_window_ms);//计算时间窗口内的码率=字节总数/时间窗
  if (bitrate_sample_kbps < 0.0f)//没有达到窗口条件时,样本bitrate_sample_kbps=-1;
    return;
  if (bitrate_estimate_kbps_ < 0.0f) {
    // 初始化码率估计值
    bitrate_estimate_kbps_ = bitrate_sample_kbps;
    return;
  }
 
  //将样本不确定性sample_uncertainty 定义为距离当前估价值有多远的函数。在uncertainty_symmetry_cap_ 较低的情况下,我们增加的不确定度要大于减少的不确定度。对于较高的值,我们接近对称。
  float scale = uncertainty_scale_;//初始化uncertainty_scale_=10
  if (in_alr && bitrate_sample_kbps < bitrate_estimate_kbps_) {
    // Optionally use higher uncertainty for samples obtained during ALR.
    scale = uncertainty_scale_in_alr_;
  }
  float sample_uncertainty =
      scale * std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) /
      (bitrate_estimate_kbps_ +
       std::min(bitrate_sample_kbps,
                uncertainty_symmetry_cap_.Get().kbps<float>()));

  float sample_var = sample_uncertainty * sample_uncertainty;
  // 更新码率的贝叶斯估计,如果样本不确定性较大,则降低其权重。
  //码率估计的不确定性随着比码率随时间变化的模型的每次更新而增加。
  float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f;
  bitrate_estimate_kbps_ = (sample_var * bitrate_estimate_kbps_ +
                            pred_bitrate_estimate_var * bitrate_sample_kbps) /
                           (sample_var + pred_bitrate_estimate_var);
  bitrate_estimate_kbps_ =
      std::max(bitrate_estimate_kbps_, estimate_floor_.Get().kbps<float>());
  bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var /
                          (sample_var + pred_bitrate_estimate_var);
  MS_DEBUG_DEV(
    "acknowledged_bitrate %" PRIu64", %f",
    at_time.ms(), bitrate_estimate_kbps_ * 1000);
}

计算时间窗内的码率

float BitrateEstimator::UpdateWindow(int64_t now_ms,
                                     int bytes,
                                     int rate_window_ms) {
  // Reset if time moves backwards.
  if (now_ms < prev_time_ms_) {
    prev_time_ms_ = -1;
    sum_ = 0;
    current_window_ms_ = 0;
  }
  if (prev_time_ms_ >= 0) {
    current_window_ms_ += now_ms - prev_time_ms_;//统计时间间隔
    // 如果前后两个包的接收时间超过时间窗,则清零字节统计
    if (now_ms - prev_time_ms_ > rate_window_ms) {
      sum_ = 0;
      current_window_ms_ %= rate_window_ms;
    }
  }
  prev_time_ms_ = now_ms;
  float bitrate_sample = -1.0f;
  if (current_window_ms_ >= rate_window_ms) {//超过时间窗时计算码率
    bitrate_sample = 8.0f * sum_ / static_cast<float>(rate_window_ms);//8表示一个字节8个bit
    current_window_ms_ -= rate_window_ms;
    sum_ = 0;
  }
  sum_ += bytes;//统计时间窗内,接收到的总字节。
  return bitrate_sample;
}

输出的码率值作为输入,用于在基于延时的码率估计中评估目标码率。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱钻研技术的小羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值