• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "modules/congestion_controller/goog_cc/link_capacity_estimator.h"
11 
12 #include <algorithm>
13 
14 #include "rtc_base/numerics/safe_minmax.h"
15 
16 namespace webrtc {
LinkCapacityEstimator()17 LinkCapacityEstimator::LinkCapacityEstimator() {}
18 
UpperBound() const19 DataRate LinkCapacityEstimator::UpperBound() const {
20   if (estimate_kbps_.has_value())
21     return DataRate::KilobitsPerSec(estimate_kbps_.value() +
22                                     3 * deviation_estimate_kbps());
23   return DataRate::Infinity();
24 }
25 
LowerBound() const26 DataRate LinkCapacityEstimator::LowerBound() const {
27   if (estimate_kbps_.has_value())
28     return DataRate::KilobitsPerSec(
29         std::max(0.0, estimate_kbps_.value() - 3 * deviation_estimate_kbps()));
30   return DataRate::Zero();
31 }
32 
Reset()33 void LinkCapacityEstimator::Reset() {
34   estimate_kbps_.reset();
35 }
36 
OnOveruseDetected(DataRate acknowledged_rate)37 void LinkCapacityEstimator::OnOveruseDetected(DataRate acknowledged_rate) {
38   Update(acknowledged_rate, 0.05);
39 }
40 
OnProbeRate(DataRate probe_rate)41 void LinkCapacityEstimator::OnProbeRate(DataRate probe_rate) {
42   Update(probe_rate, 0.5);
43 }
44 
Update(DataRate capacity_sample,double alpha)45 void LinkCapacityEstimator::Update(DataRate capacity_sample, double alpha) {
46   double sample_kbps = capacity_sample.kbps();
47   if (!estimate_kbps_.has_value()) {
48     estimate_kbps_ = sample_kbps;
49   } else {
50     estimate_kbps_ = (1 - alpha) * estimate_kbps_.value() + alpha * sample_kbps;
51   }
52   // Estimate the variance of the link capacity estimate and normalize the
53   // variance with the link capacity estimate.
54   const double norm = std::max(estimate_kbps_.value(), 1.0);
55   double error_kbps = estimate_kbps_.value() - sample_kbps;
56   deviation_kbps_ =
57       (1 - alpha) * deviation_kbps_ + alpha * error_kbps * error_kbps / norm;
58   // 0.4 ~= 14 kbit/s at 500 kbit/s
59   // 2.5f ~= 35 kbit/s at 500 kbit/s
60   deviation_kbps_ = rtc::SafeClamp(deviation_kbps_, 0.4f, 2.5f);
61 }
62 
has_estimate() const63 bool LinkCapacityEstimator::has_estimate() const {
64   return estimate_kbps_.has_value();
65 }
66 
estimate() const67 DataRate LinkCapacityEstimator::estimate() const {
68   return DataRate::KilobitsPerSec(*estimate_kbps_);
69 }
70 
deviation_estimate_kbps() const71 double LinkCapacityEstimator::deviation_estimate_kbps() const {
72   // Calculate the max bit rate std dev given the normalized
73   // variance and the current throughput bitrate. The standard deviation will
74   // only be used if estimate_kbps_ has a value.
75   return sqrt(deviation_kbps_ * estimate_kbps_.value());
76 }
77 }  // namespace webrtc
78