1. 程式人生 > >webrtc QOS方法之Sender Side BWE(待續)

webrtc QOS方法之Sender Side BWE(待續)

背景介紹

BWE(Bandwidth Estimation)可能是WebRTC視訊引擎中最關鍵的部分。BWE模組負責決定你可以傳送多大位元速率視訊不會使網路擁塞,以防止視訊質量下降。

最初該演算法比較簡單,主要基於接收端的丟包率,來判斷髮送端使用多大位元速率視訊比較合適。但是丟包已經發生,說明網路已經擁塞,只是一個事後補救的手段。若是能夠在網路擁塞之前預估出網路的未來的趨勢,適當調整位元速率,這樣就可以實現一個比較好的視訊質量和流暢性。

webrtc使用trendline演算法實現網路擁塞預估,早期版本使用KalmanFilter演算法。兩種演算法都是基於接收端的網路延遲進行位元速率估計。早期的KalmanFilter演算法是在接收端根據網路延時,計算出合適的頻寬,反饋給傳送端,讓傳送端按照該位元速率傳送視訊資料。trendline演算法對此進行了優化,在傳送端計算網路延時,計算合適的頻寬。

實現原理

webrtc具體實現

1、當視訊位元速率發生變化後,需要將該資訊傳送給pacer、fec、encode模組。

void SendSideCongestionController::MaybeTriggerOnNetworkChanged() {
  uint32_t bitrate_bps;
  uint8_t fraction_loss;
  int64_t rtt;
  bool estimate_changed = bitrate_controller_->GetNetworkParameters(
      &bitrate_bps, &fraction_loss, &rtt);
  if (estimate_changed) {
    pacer_->SetEstimatedBitrate(bitrate_bps);
    probe_controller_->SetEstimatedBitrate(bitrate_bps);
    retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
  }

  bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;

  if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
    int64_t probing_interval_ms;
    {
      rtc::CritScope cs(&bwe_lock_);
      probing_interval_ms = delay_based_bwe_->GetExpectedBwePeriodMs();
    }
    {
      rtc::CritScope cs(&observer_lock_);
      if (observer_) {
        observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt,
                                    probing_interval_ms);
      }
    }
  }
}

2、最終決定當前位元速率函式。

void SendSideBandwidthEstimation::CapBitrateToThresholds(int64_t now_ms,
                                                         uint32_t bitrate_bps) {
  if (bwe_incoming_ > 0 && bitrate_bps > bwe_incoming_) {
    bitrate_bps = bwe_incoming_;
  }
  if (delay_based_bitrate_bps_ > 0 && bitrate_bps > delay_based_bitrate_bps_) {
    bitrate_bps = delay_based_bitrate_bps_;
  }
  if (bitrate_bps > max_bitrate_configured_) {
    bitrate_bps = max_bitrate_configured_;
  }
  if (bitrate_bps < min_bitrate_configured_) {
    if (last_low_bitrate_log_ms_ == -1 ||
        now_ms - last_low_bitrate_log_ms_ > kLowBitrateLogPeriodMs) {
      LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate_bps / 1000
                      << " kbps is below configured min bitrate "
                      << min_bitrate_configured_ / 1000 << " kbps.";
      last_low_bitrate_log_ms_ = now_ms;
    }
    bitrate_bps = min_bitrate_configured_;
  }

  if (bitrate_bps != current_bitrate_bps_ ||
      last_fraction_loss_ != last_logged_fraction_loss_ ||
      now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) {
    event_log_->LogLossBasedBweUpdate(bitrate_bps, last_fraction_loss_,
                                      expected_packets_since_last_loss_update_);
    last_logged_fraction_loss_ = last_fraction_loss_;
    last_rtc_event_log_ms_ = now_ms;
  }
  current_bitrate_bps_ = bitrate_bps;
}

AimdRateControl rate_control_; Delay_based_bwe.cc trendline_estimator.cc