Index: webrtc/modules/remote_bitrate_estimator/overuse_detector.cc |
diff --git a/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc b/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc |
index 33b234c1f3aee2d962fe301a58cf8ec225af5750..b21933a193497370c3534754b4f5cb3ba779f9e3 100644 |
--- a/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc |
+++ b/webrtc/modules/remote_bitrate_estimator/overuse_detector.cc |
@@ -11,25 +11,60 @@ |
#include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" |
#include <algorithm> |
+#include <sstream> |
#include <math.h> |
#include <stdlib.h> |
+#include "webrtc/base/checks.h" |
+#include "webrtc/base/common.h" |
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" |
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" |
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
+#include "webrtc/system_wrappers/interface/field_trial.h" |
#include "webrtc/system_wrappers/interface/trace.h" |
namespace webrtc { |
-enum { kOverUsingTimeThreshold = 100 }; |
+const char kAdaptiveThresholdExperiment[] = "WebRTC-AdaptiveBweThreshold"; |
+const char kEnabledPrefix[] = "Enabled"; |
+const size_t kEnabledPrefixLength = sizeof(kEnabledPrefix) - 1; |
+const size_t kMinExperimentLength = kEnabledPrefixLength + 3; |
+ |
+const double kMaxAdaptOffsetMs = 15.0; |
+const double kOverUsingTimeThreshold = 10; |
+ |
+bool AdaptiveThresholdExperimentIsEnabled() { |
+ std::string experiment_string = |
+ webrtc::field_trial::FindFullName(kAdaptiveThresholdExperiment); |
+ if (experiment_string.length() < kMinExperimentLength) |
+ return false; |
+ return experiment_string.substr(0, kEnabledPrefixLength) == kEnabledPrefix; |
+} |
+ |
+// Gets thresholds from the experiment name following the format |
+// "WebRTC-AdaptiveBweThreshold/Enabled-0.5,0.002/". |
+bool ReadExperimentConstants(double* k_up, double* k_down) { |
+ std::string experiment_string = |
+ webrtc::field_trial::FindFullName(kAdaptiveThresholdExperiment); |
+ return sscanf(experiment_string.substr(kEnabledPrefixLength + 1).c_str(), |
+ "%lf,%lf", k_up, k_down) == 2; |
+} |
OveruseDetector::OveruseDetector(const OverUseDetectorOptions& options) |
- : options_(options), |
- threshold_(options_.initial_threshold), |
+ : in_experiment_(AdaptiveThresholdExperimentIsEnabled()), |
+ k_up_(0.01), |
+ k_down_(0.00018), |
+ overusing_time_threshold_(100), |
+ options_(options), |
+ threshold_(12.5), |
+ last_update_ms_(-1), |
prev_offset_(0.0), |
time_over_using_(-1), |
overuse_counter_(0), |
- hypothesis_(kBwNormal) {} |
+ hypothesis_(kBwNormal) { |
+ if (in_experiment_) |
+ InitializeExperiment(); |
+} |
OveruseDetector::~OveruseDetector() {} |
@@ -37,21 +72,6 @@ BandwidthUsage OveruseDetector::State() const { |
return hypothesis_; |
} |
- |
-void OveruseDetector::SetRateControlRegion(RateControlRegion region) { |
- switch (region) { |
- case kRcMaxUnknown: { |
- threshold_ = options_.initial_threshold; |
- break; |
- } |
- case kRcAboveMax: |
- case kRcNearMax: { |
- threshold_ = options_.initial_threshold / 2; |
- break; |
- } |
- } |
-} |
- |
BandwidthUsage OveruseDetector::Detect(double offset, |
double ts_delta, |
int num_of_deltas, |
@@ -64,7 +84,6 @@ BandwidthUsage OveruseDetector::Detect(double offset, |
const double T = std::min(num_of_deltas, 60) * offset; |
BWE_TEST_LOGGING_PLOT(1, "offset", now_ms, T); |
BWE_TEST_LOGGING_PLOT(1, "threshold", now_ms, threshold_); |
- |
if (T > threshold_) { |
if (time_over_using_ == -1) { |
// Initialize the timer. Assume that we've been |
@@ -76,8 +95,7 @@ BandwidthUsage OveruseDetector::Detect(double offset, |
time_over_using_ += ts_delta; |
} |
overuse_counter_++; |
- if (time_over_using_ > kOverUsingTimeThreshold |
- && overuse_counter_ > 1) { |
+ if (time_over_using_ > overusing_time_threshold_ && overuse_counter_ > 1) { |
if (offset >= prev_offset) { |
time_over_using_ = 0; |
overuse_counter_ = 0; |
@@ -93,6 +111,45 @@ BandwidthUsage OveruseDetector::Detect(double offset, |
overuse_counter_ = 0; |
hypothesis_ = kBwNormal; |
} |
+ |
+ UpdateThreshold(T, now_ms); |
+ |
return hypothesis_; |
} |
+ |
+void OveruseDetector::UpdateThreshold(double modified_offset, int64_t now_ms) { |
+ if (!in_experiment_) |
+ return; |
+ |
+ if (last_update_ms_ == -1) |
+ last_update_ms_ = now_ms; |
+ |
+ if (fabs(modified_offset) > threshold_ + kMaxAdaptOffsetMs) { |
+ // Avoid adapting the threshold to big latency spikes, caused e.g., |
+ // by a sudden capacity drop. |
+ last_update_ms_ = now_ms; |
+ return; |
+ } |
+ |
+ const double k = fabs(modified_offset) < threshold_ ? k_down_ : k_up_; |
+ threshold_ += |
+ k * (fabs(modified_offset) - threshold_) * (now_ms - last_update_ms_); |
+ |
+ const double kMinThreshold = 6; |
+ const double kMaxThreshold = 600; |
+ threshold_ = std::min(std::max(threshold_, kMinThreshold), kMaxThreshold); |
+ |
+ last_update_ms_ = now_ms; |
+} |
+ |
+void OveruseDetector::InitializeExperiment() { |
+ DCHECK(in_experiment_); |
+ double k_up = 0.0; |
+ double k_down = 0.0; |
+ overusing_time_threshold_ = kOverUsingTimeThreshold; |
+ if (ReadExperimentConstants(&k_up, &k_down)) { |
+ k_up_ = k_up; |
+ k_down_ = k_down; |
+ } |
+} |
} // namespace webrtc |