Using unit classes in AimdRateControl.
Bug: webrtc:9718
Change-Id: I1efed4e55c9d1ccec3c32ed012cb3cd82d7f4ee8
Reviewed-on: https://webrtc-review.googlesource.com/c/110788
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25705}
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
index 60f52a1..7a1ee11 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
@@ -175,12 +175,11 @@
// Call constructor. An alternative would be to return an empty Result here,
// or to estimate the throughput based on the feedback we received.
RTC_DCHECK(rate_control_.ValidEstimate());
- rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2,
- arrival_time.ms());
+ rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, arrival_time);
Result result;
result.updated = true;
result.probe = false;
- result.target_bitrate = DataRate::bps(rate_control_.LatestEstimate());
+ result.target_bitrate = rate_control_.LatestEstimate();
RTC_LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to "
<< ToString(result.target_bitrate);
return result;
@@ -239,27 +238,26 @@
// Currently overusing the bandwidth.
if (delay_detector_->State() == BandwidthUsage::kBwOverusing) {
if (acked_bitrate &&
- rate_control_.TimeToReduceFurther(at_time.ms(), acked_bitrate->bps())) {
+ rate_control_.TimeToReduceFurther(at_time, *acked_bitrate)) {
result.updated =
UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
} else if (!acked_bitrate && rate_control_.ValidEstimate() &&
- rate_control_.InitialTimeToReduceFurther(at_time.ms())) {
+ rate_control_.InitialTimeToReduceFurther(at_time)) {
// Overusing before we have a measured acknowledged bitrate. Reduce send
// rate by 50% every 200 ms.
// TODO(tschumim): Improve this and/or the acknowledged bitrate estimator
// so that we (almost) always have a bitrate estimate.
- rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2,
- at_time.ms());
+ rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, at_time);
result.updated = true;
result.probe = false;
- result.target_bitrate = DataRate::bps(rate_control_.LatestEstimate());
+ result.target_bitrate = rate_control_.LatestEstimate();
}
} else {
if (probe_bitrate) {
result.probe = true;
result.updated = true;
result.target_bitrate = *probe_bitrate;
- rate_control_.SetEstimate(probe_bitrate->bps(), at_time.ms());
+ rate_control_.SetEstimate(*probe_bitrate, at_time);
} else {
result.updated =
UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate);
@@ -287,16 +285,13 @@
bool DelayBasedBwe::UpdateEstimate(Timestamp at_time,
absl::optional<DataRate> acked_bitrate,
DataRate* target_rate) {
- absl::optional<int> acked_bitrate_bps;
- if (acked_bitrate)
- acked_bitrate_bps = acked_bitrate->bps<int>();
- const RateControlInput input(delay_detector_->State(), acked_bitrate_bps);
- *target_rate = DataRate::bps(rate_control_.Update(&input, at_time.ms()));
+ const RateControlInput input(delay_detector_->State(), acked_bitrate);
+ *target_rate = rate_control_.Update(&input, at_time);
return rate_control_.ValidEstimate();
}
void DelayBasedBwe::OnRttUpdate(TimeDelta avg_rtt) {
- rate_control_.SetRtt(avg_rtt.ms());
+ rate_control_.SetRtt(avg_rtt);
}
bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
@@ -311,23 +306,23 @@
return false;
*ssrcs = {kFixedSsrc};
- *bitrate = DataRate::bps(rate_control_.LatestEstimate());
+ *bitrate = rate_control_.LatestEstimate();
return true;
}
void DelayBasedBwe::SetStartBitrate(DataRate start_bitrate) {
RTC_LOG(LS_INFO) << "BWE Setting start bitrate to: "
<< ToString(start_bitrate);
- rate_control_.SetStartBitrate(start_bitrate.bps());
+ rate_control_.SetStartBitrate(start_bitrate);
}
void DelayBasedBwe::SetMinBitrate(DataRate min_bitrate) {
// Called from both the configuration thread and the network thread. Shouldn't
// be called from the network thread in the future.
- rate_control_.SetMinBitrate(min_bitrate.bps());
+ rate_control_.SetMinBitrate(min_bitrate);
}
TimeDelta DelayBasedBwe::GetExpectedBwePeriod() const {
- return TimeDelta::ms(rate_control_.GetExpectedBandwidthPeriodMs());
+ return rate_control_.GetExpectedBandwidthPeriod();
}
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index f21c6d8..f6991ea 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -42,6 +42,7 @@
deps = [
"../..:webrtc_common",
"../../api/units:data_rate",
+ "../../api/units:timestamp",
"../../modules:module_api",
"../../modules:module_api_public",
"../../modules/rtp_rtcp:rtp_rtcp_format",
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index a992e7f..4c91776 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -26,10 +26,9 @@
namespace webrtc {
-static const int64_t kDefaultRttMs = 200;
-static const int64_t kMaxFeedbackIntervalMs = 1000;
-static const float kDefaultBackoffFactor = 0.85f;
-static const int64_t kDefaultInitialBackOffIntervalMs = 200;
+constexpr TimeDelta kDefaultRtt = TimeDelta::Millis<200>();
+constexpr float kDefaultBackoffFactor = 0.85f;
+constexpr TimeDelta kDefaultInitialBackOffInterval = TimeDelta::Millis<200>();
const char kBweBackOffFactorExperiment[] = "WebRTC-BweBackOffFactor";
const char kBweInitialBackOffIntervalExperiment[] =
@@ -55,7 +54,7 @@
return kDefaultBackoffFactor;
}
-int64_t ReadInitialBackoffIntervalMs() {
+TimeDelta ReadInitialBackoffInterval() {
std::string experiment_string =
webrtc::field_trial::FindFullName(kBweInitialBackOffIntervalExperiment);
int64_t backoff_interval;
@@ -63,7 +62,7 @@
sscanf(experiment_string.c_str(), "Enabled-%" SCNd64, &backoff_interval);
if (parsed_values == 1) {
if (10 <= backoff_interval && backoff_interval <= 200) {
- return backoff_interval;
+ return TimeDelta::ms(backoff_interval);
}
RTC_LOG(WARNING)
<< "Initial back-off interval must be between 10 and 200 ms.";
@@ -71,188 +70,193 @@
RTC_LOG(LS_WARNING) << "Failed to parse parameters for "
<< kBweInitialBackOffIntervalExperiment
<< " experiment. Using default.";
- return kDefaultInitialBackOffIntervalMs;
+ return kDefaultInitialBackOffInterval;
}
AimdRateControl::AimdRateControl()
- : min_configured_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
- max_configured_bitrate_bps_(30000000),
- current_bitrate_bps_(max_configured_bitrate_bps_),
- latest_estimated_throughput_bps_(current_bitrate_bps_),
+ : min_configured_bitrate_(congestion_controller::GetMinBitrate()),
+ max_configured_bitrate_(DataRate::kbps(30000)),
+ current_bitrate_(max_configured_bitrate_),
+ latest_estimated_throughput_(current_bitrate_),
avg_max_bitrate_kbps_(-1.0f),
var_max_bitrate_kbps_(0.4f),
rate_control_state_(kRcHold),
rate_control_region_(kRcMaxUnknown),
- time_last_bitrate_change_(-1),
- time_last_bitrate_decrease_(-1),
- time_first_throughput_estimate_(-1),
+ time_last_bitrate_change_(Timestamp::MinusInfinity()),
+ time_last_bitrate_decrease_(Timestamp::MinusInfinity()),
+ time_first_throughput_estimate_(Timestamp::MinusInfinity()),
bitrate_is_initialized_(false),
beta_(webrtc::field_trial::IsEnabled(kBweBackOffFactorExperiment)
? ReadBackoffFactor()
: kDefaultBackoffFactor),
- rtt_(kDefaultRttMs),
+ rtt_(kDefaultRtt),
in_experiment_(!AdaptiveThresholdExperimentIsDisabled()),
smoothing_experiment_(
webrtc::field_trial::IsEnabled("WebRTC-Audio-BandwidthSmoothing")),
in_initial_backoff_interval_experiment_(
webrtc::field_trial::IsEnabled(kBweInitialBackOffIntervalExperiment)),
- initial_backoff_interval_ms_(kDefaultInitialBackOffIntervalMs) {
+ initial_backoff_interval_(kDefaultInitialBackOffInterval) {
if (in_initial_backoff_interval_experiment_) {
- initial_backoff_interval_ms_ = ReadInitialBackoffIntervalMs();
+ initial_backoff_interval_ = ReadInitialBackoffInterval();
RTC_LOG(LS_INFO) << "Using aimd rate control with initial back-off interval"
- << " " << initial_backoff_interval_ms_ << " ms.";
+ << " " << ToString(initial_backoff_interval_) << ".";
}
RTC_LOG(LS_INFO) << "Using aimd rate control with back off factor " << beta_;
}
AimdRateControl::~AimdRateControl() {}
-void AimdRateControl::SetStartBitrate(int start_bitrate_bps) {
- current_bitrate_bps_ = start_bitrate_bps;
- latest_estimated_throughput_bps_ = current_bitrate_bps_;
+void AimdRateControl::SetStartBitrate(DataRate start_bitrate) {
+ current_bitrate_ = start_bitrate;
+ latest_estimated_throughput_ = current_bitrate_;
bitrate_is_initialized_ = true;
}
-void AimdRateControl::SetMinBitrate(int min_bitrate_bps) {
- min_configured_bitrate_bps_ = min_bitrate_bps;
- current_bitrate_bps_ = std::max<int>(min_bitrate_bps, current_bitrate_bps_);
+void AimdRateControl::SetMinBitrate(DataRate min_bitrate) {
+ min_configured_bitrate_ = min_bitrate;
+ current_bitrate_ = std::max(min_bitrate, current_bitrate_);
}
bool AimdRateControl::ValidEstimate() const {
return bitrate_is_initialized_;
}
-int64_t AimdRateControl::GetFeedbackInterval() const {
+TimeDelta AimdRateControl::GetFeedbackInterval() const {
// Estimate how often we can send RTCP if we allocate up to 5% of bandwidth
// to feedback.
- static const int kRtcpSize = 80;
- const int64_t interval = static_cast<int64_t>(
- kRtcpSize * 8.0 * 1000.0 / (0.05 * current_bitrate_bps_) + 0.5);
- const int64_t kMinFeedbackIntervalMs = 200;
- return rtc::SafeClamp(interval, kMinFeedbackIntervalMs,
- kMaxFeedbackIntervalMs);
+ const DataSize kRtcpSize = DataSize::bytes(80);
+ const DataRate rtcp_bitrate = current_bitrate_ * 0.05;
+ const TimeDelta interval = kRtcpSize / rtcp_bitrate;
+ const TimeDelta kMinFeedbackInterval = TimeDelta::ms(200);
+ const TimeDelta kMaxFeedbackInterval = TimeDelta::ms(1000);
+ return interval.Clamped(kMinFeedbackInterval, kMaxFeedbackInterval);
}
-bool AimdRateControl::TimeToReduceFurther(
- int64_t now_ms,
- uint32_t estimated_throughput_bps) const {
- const int64_t bitrate_reduction_interval =
- std::max<int64_t>(std::min<int64_t>(rtt_, 200), 10);
- if (now_ms - time_last_bitrate_change_ >= bitrate_reduction_interval) {
+bool AimdRateControl::TimeToReduceFurther(Timestamp at_time,
+ DataRate estimated_throughput) const {
+ const TimeDelta bitrate_reduction_interval =
+ rtt_.Clamped(TimeDelta::ms(10), TimeDelta::ms(200));
+ if (at_time - time_last_bitrate_change_ >= bitrate_reduction_interval) {
return true;
}
if (ValidEstimate()) {
// TODO(terelius/holmer): Investigate consequences of increasing
// the threshold to 0.95 * LatestEstimate().
- const uint32_t threshold = static_cast<uint32_t>(0.5 * LatestEstimate());
- return estimated_throughput_bps < threshold;
+ const DataRate threshold = 0.5 * LatestEstimate();
+ return estimated_throughput < threshold;
}
return false;
}
-bool AimdRateControl::InitialTimeToReduceFurther(int64_t now_ms) const {
+bool AimdRateControl::InitialTimeToReduceFurther(Timestamp at_time) const {
if (!in_initial_backoff_interval_experiment_) {
return ValidEstimate() &&
- TimeToReduceFurther(now_ms, LatestEstimate() / 2 - 1);
+ TimeToReduceFurther(at_time,
+ LatestEstimate() / 2 - DataRate::bps(1));
}
// TODO(terelius): We could use the RTT (clamped to suitable limits) instead
// of a fixed bitrate_reduction_interval.
- if (time_last_bitrate_decrease_ == -1 ||
- now_ms - time_last_bitrate_decrease_ >= initial_backoff_interval_ms_) {
+ if (time_last_bitrate_decrease_.IsInfinite() ||
+ at_time - time_last_bitrate_decrease_ >= initial_backoff_interval_) {
return true;
}
return false;
}
-uint32_t AimdRateControl::LatestEstimate() const {
- return current_bitrate_bps_;
+DataRate AimdRateControl::LatestEstimate() const {
+ return current_bitrate_;
}
-void AimdRateControl::SetRtt(int64_t rtt) {
+void AimdRateControl::SetRtt(TimeDelta rtt) {
rtt_ = rtt;
}
-uint32_t AimdRateControl::Update(const RateControlInput* input,
- int64_t now_ms) {
+DataRate AimdRateControl::Update(const RateControlInput* input,
+ Timestamp at_time) {
RTC_CHECK(input);
// Set the initial bit rate value to what we're receiving the first half
// second.
// TODO(bugs.webrtc.org/9379): The comment above doesn't match to the code.
if (!bitrate_is_initialized_) {
- const int64_t kInitializationTimeMs = 5000;
- RTC_DCHECK_LE(kBitrateWindowMs, kInitializationTimeMs);
- if (time_first_throughput_estimate_ < 0) {
- if (input->estimated_throughput_bps)
- time_first_throughput_estimate_ = now_ms;
- } else if (now_ms - time_first_throughput_estimate_ >
- kInitializationTimeMs &&
- input->estimated_throughput_bps) {
- current_bitrate_bps_ = *input->estimated_throughput_bps;
+ const TimeDelta kInitializationTime = TimeDelta::seconds(5);
+ RTC_DCHECK_LE(kBitrateWindowMs, kInitializationTime.ms());
+ if (time_first_throughput_estimate_.IsInfinite()) {
+ if (input->estimated_throughput)
+ time_first_throughput_estimate_ = at_time;
+ } else if (at_time - time_first_throughput_estimate_ >
+ kInitializationTime &&
+ input->estimated_throughput) {
+ current_bitrate_ = *input->estimated_throughput;
bitrate_is_initialized_ = true;
}
}
- current_bitrate_bps_ = ChangeBitrate(current_bitrate_bps_, *input, now_ms);
- return current_bitrate_bps_;
+ current_bitrate_ = ChangeBitrate(current_bitrate_, *input, at_time);
+ return current_bitrate_;
}
-void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
+void AimdRateControl::SetEstimate(DataRate bitrate, Timestamp at_time) {
bitrate_is_initialized_ = true;
- uint32_t prev_bitrate_bps = current_bitrate_bps_;
- current_bitrate_bps_ = ClampBitrate(bitrate_bps, bitrate_bps);
- time_last_bitrate_change_ = now_ms;
- if (current_bitrate_bps_ < prev_bitrate_bps) {
- time_last_bitrate_decrease_ = now_ms;
+ DataRate prev_bitrate = current_bitrate_;
+ current_bitrate_ = ClampBitrate(bitrate, bitrate);
+ time_last_bitrate_change_ = at_time;
+ if (current_bitrate_ < prev_bitrate) {
+ time_last_bitrate_decrease_ = at_time;
}
}
-int AimdRateControl::GetNearMaxIncreaseRateBps() const {
- RTC_DCHECK_GT(current_bitrate_bps_, 0);
- double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
- double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
- double avg_packet_size_bits = bits_per_frame / packets_per_frame;
+double AimdRateControl::GetNearMaxIncreaseRateBpsPerSecond() const {
+ RTC_DCHECK(!current_bitrate_.IsZero());
+ const TimeDelta kFrameInterval = TimeDelta::seconds(1) / 30;
+ DataSize frame_size = current_bitrate_ * kFrameInterval;
+ const DataSize kPacketSize = DataSize::bytes(1200);
+ double packets_per_frame = std::ceil(frame_size / kPacketSize);
+ DataSize avg_packet_size = frame_size / packets_per_frame;
// Approximate the over-use estimator delay to 100 ms.
- const int64_t response_time = in_experiment_ ? (rtt_ + 100) * 2 : rtt_ + 100;
- constexpr double kMinIncreaseRateBps = 4000;
- return static_cast<int>(std::max(
- kMinIncreaseRateBps, (avg_packet_size_bits * 1000) / response_time));
+ TimeDelta response_time = rtt_ + TimeDelta::ms(100);
+ if (in_experiment_)
+ response_time = response_time * 2;
+ double increase_rate_bps_per_second =
+ (avg_packet_size / response_time).bps<double>();
+ double kMinIncreaseRateBpsPerSecond = 4000;
+ return std::max(kMinIncreaseRateBpsPerSecond, increase_rate_bps_per_second);
}
-int AimdRateControl::GetExpectedBandwidthPeriodMs() const {
- const int kMinPeriodMs = smoothing_experiment_ ? 500 : 2000;
- constexpr int kDefaultPeriodMs = 3000;
- constexpr int kMaxPeriodMs = 50000;
+TimeDelta AimdRateControl::GetExpectedBandwidthPeriod() const {
+ const TimeDelta kMinPeriod =
+ smoothing_experiment_ ? TimeDelta::ms(500) : TimeDelta::seconds(2);
+ const TimeDelta kDefaultPeriod = TimeDelta::seconds(3);
+ const TimeDelta kMaxPeriod = TimeDelta::seconds(50);
- int increase_rate = GetNearMaxIncreaseRateBps();
+ double increase_rate_bps_per_second = GetNearMaxIncreaseRateBpsPerSecond();
if (!last_decrease_)
- return smoothing_experiment_ ? kMinPeriodMs : kDefaultPeriodMs;
-
- return std::min(kMaxPeriodMs,
- std::max<int>(1000 * static_cast<int64_t>(*last_decrease_) /
- increase_rate,
- kMinPeriodMs));
+ return smoothing_experiment_ ? kMinPeriod : kDefaultPeriod;
+ double time_to_recover_decrease_seconds =
+ last_decrease_->bps() / increase_rate_bps_per_second;
+ TimeDelta period = TimeDelta::seconds(time_to_recover_decrease_seconds);
+ return period.Clamped(kMinPeriod, kMaxPeriod);
}
-uint32_t AimdRateControl::ChangeBitrate(uint32_t new_bitrate_bps,
+DataRate AimdRateControl::ChangeBitrate(DataRate new_bitrate,
const RateControlInput& input,
- int64_t now_ms) {
- uint32_t estimated_throughput_bps =
- input.estimated_throughput_bps.value_or(latest_estimated_throughput_bps_);
- if (input.estimated_throughput_bps)
- latest_estimated_throughput_bps_ = *input.estimated_throughput_bps;
+ Timestamp at_time) {
+ DataRate estimated_throughput =
+ input.estimated_throughput.value_or(latest_estimated_throughput_);
+ if (input.estimated_throughput)
+ latest_estimated_throughput_ = *input.estimated_throughput;
// An over-use should always trigger us to reduce the bitrate, even though
// we have not yet established our first estimate. By acting on the over-use,
// we will end up with a valid estimate.
if (!bitrate_is_initialized_ &&
input.bw_state != BandwidthUsage::kBwOverusing)
- return current_bitrate_bps_;
+ return current_bitrate_;
- ChangeState(input, now_ms);
+ ChangeState(input, at_time);
// Calculated here because it's used in multiple places.
- const float estimated_throughput_kbps = estimated_throughput_bps / 1000.0f;
+ const float estimated_throughput_kbps = estimated_throughput.kbps<double>();
// Calculate the max bit rate std dev given the normalized
// variance and the current throughput bitrate.
const float std_max_bit_rate =
@@ -270,45 +274,41 @@
avg_max_bitrate_kbps_ = -1.0;
}
if (rate_control_region_ == kRcNearMax) {
- uint32_t additive_increase_bps =
- AdditiveRateIncrease(now_ms, time_last_bitrate_change_);
- new_bitrate_bps += additive_increase_bps;
+ DataRate additive_increase =
+ AdditiveRateIncrease(at_time, time_last_bitrate_change_);
+ new_bitrate += additive_increase;
} else {
- uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease(
- now_ms, time_last_bitrate_change_, new_bitrate_bps);
- new_bitrate_bps += multiplicative_increase_bps;
+ DataRate multiplicative_increase = MultiplicativeRateIncrease(
+ at_time, time_last_bitrate_change_, new_bitrate);
+ new_bitrate += multiplicative_increase;
}
- time_last_bitrate_change_ = now_ms;
+ time_last_bitrate_change_ = at_time;
break;
case kRcDecrease:
// Set bit rate to something slightly lower than max
// to get rid of any self-induced delay.
- new_bitrate_bps =
- static_cast<uint32_t>(beta_ * estimated_throughput_bps + 0.5);
- if (new_bitrate_bps > current_bitrate_bps_) {
+ new_bitrate = estimated_throughput * beta_;
+ if (new_bitrate > current_bitrate_) {
// Avoid increasing the rate when over-using.
if (rate_control_region_ != kRcMaxUnknown) {
- new_bitrate_bps = static_cast<uint32_t>(
- beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f);
+ new_bitrate = DataRate::kbps(beta_ * avg_max_bitrate_kbps_);
}
- new_bitrate_bps = std::min(new_bitrate_bps, current_bitrate_bps_);
+ new_bitrate = std::min(new_bitrate, current_bitrate_);
}
rate_control_region_ = kRcNearMax;
- if (bitrate_is_initialized_ &&
- estimated_throughput_bps < current_bitrate_bps_) {
+ if (bitrate_is_initialized_ && estimated_throughput < current_bitrate_) {
constexpr float kDegradationFactor = 0.9f;
if (smoothing_experiment_ &&
- new_bitrate_bps <
- kDegradationFactor * beta_ * current_bitrate_bps_) {
+ new_bitrate < kDegradationFactor * beta_ * current_bitrate_) {
// If bitrate decreases more than a normal back off after overuse, it
// indicates a real network degradation. We do not let such a decrease
// to determine the bandwidth estimation period.
last_decrease_ = absl::nullopt;
} else {
- last_decrease_ = current_bitrate_bps_ - new_bitrate_bps;
+ last_decrease_ = current_bitrate_ - new_bitrate;
}
}
if (estimated_throughput_kbps <
@@ -320,51 +320,49 @@
UpdateMaxThroughputEstimate(estimated_throughput_kbps);
// Stay on hold until the pipes are cleared.
rate_control_state_ = kRcHold;
- time_last_bitrate_change_ = now_ms;
- time_last_bitrate_decrease_ = now_ms;
+ time_last_bitrate_change_ = at_time;
+ time_last_bitrate_decrease_ = at_time;
break;
default:
assert(false);
}
- return ClampBitrate(new_bitrate_bps, estimated_throughput_bps);
+ return ClampBitrate(new_bitrate, estimated_throughput);
}
-uint32_t AimdRateControl::ClampBitrate(
- uint32_t new_bitrate_bps,
- uint32_t estimated_throughput_bps) const {
+DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate,
+ DataRate estimated_throughput) const {
// Don't change the bit rate if the send side is too far off.
// We allow a bit more lag at very low rates to not too easily get stuck if
// the encoder produces uneven outputs.
- const uint32_t max_bitrate_bps =
- static_cast<uint32_t>(1.5f * estimated_throughput_bps) + 10000;
- if (new_bitrate_bps > current_bitrate_bps_ &&
- new_bitrate_bps > max_bitrate_bps) {
- new_bitrate_bps = std::max(current_bitrate_bps_, max_bitrate_bps);
+ const DataRate max_bitrate = 1.5 * estimated_throughput + DataRate::kbps(10);
+ if (new_bitrate > current_bitrate_ && new_bitrate > max_bitrate) {
+ new_bitrate = std::max(current_bitrate_, max_bitrate);
}
- new_bitrate_bps = std::max(new_bitrate_bps, min_configured_bitrate_bps_);
- return new_bitrate_bps;
+ new_bitrate = std::max(new_bitrate, min_configured_bitrate_);
+ return new_bitrate;
}
-uint32_t AimdRateControl::MultiplicativeRateIncrease(
- int64_t now_ms,
- int64_t last_ms,
- uint32_t current_bitrate_bps) const {
+DataRate AimdRateControl::MultiplicativeRateIncrease(
+ Timestamp at_time,
+ Timestamp last_time,
+ DataRate current_bitrate) const {
double alpha = 1.08;
- if (last_ms > -1) {
- auto time_since_last_update_ms =
- rtc::SafeMin<int64_t>(now_ms - last_ms, 1000);
- alpha = pow(alpha, time_since_last_update_ms / 1000.0);
+ if (last_time.IsFinite()) {
+ auto time_since_last_update = at_time - last_time;
+ alpha = pow(alpha, std::min(time_since_last_update.seconds<double>(), 1.0));
}
- uint32_t multiplicative_increase_bps =
- std::max(current_bitrate_bps * (alpha - 1.0), 1000.0);
- return multiplicative_increase_bps;
+ DataRate multiplicative_increase =
+ std::max(current_bitrate * (alpha - 1.0), DataRate::bps(1000));
+ return multiplicative_increase;
}
-uint32_t AimdRateControl::AdditiveRateIncrease(int64_t now_ms,
- int64_t last_ms) const {
- return static_cast<uint32_t>((now_ms - last_ms) *
- GetNearMaxIncreaseRateBps() / 1000);
+DataRate AimdRateControl::AdditiveRateIncrease(Timestamp at_time,
+ Timestamp last_time) const {
+ double time_period_seconds = (at_time - last_time).seconds<double>();
+ double data_rate_increase_bps =
+ GetNearMaxIncreaseRateBpsPerSecond() * time_period_seconds;
+ return DataRate::bps(data_rate_increase_bps);
}
void AimdRateControl::UpdateMaxThroughputEstimate(
@@ -394,11 +392,11 @@
}
void AimdRateControl::ChangeState(const RateControlInput& input,
- int64_t now_ms) {
+ Timestamp at_time) {
switch (input.bw_state) {
case BandwidthUsage::kBwNormal:
if (rate_control_state_ == kRcHold) {
- time_last_bitrate_change_ = now_ms;
+ time_last_bitrate_change_ = at_time;
rate_control_state_ = kRcIncrease;
}
break;
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index 24b8535..47afce6 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -16,6 +16,9 @@
#include "absl/types/optional.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
+#include "api/units/data_rate.h"
+#include "api/units/timestamp.h"
+
namespace webrtc {
// A rate control implementation based on additive increases of
@@ -32,28 +35,28 @@
// either if it has been explicitly set via SetStartBitrate/SetEstimate, or if
// we have measured a throughput.
bool ValidEstimate() const;
- void SetStartBitrate(int start_bitrate_bps);
- void SetMinBitrate(int min_bitrate_bps);
- int64_t GetFeedbackInterval() const;
+ void SetStartBitrate(DataRate start_bitrate);
+ void SetMinBitrate(DataRate min_bitrate);
+ TimeDelta GetFeedbackInterval() const;
// Returns true if the bitrate estimate hasn't been changed for more than
// an RTT, or if the estimated_throughput is less than half of the current
// estimate. Should be used to decide if we should reduce the rate further
// when over-using.
- bool TimeToReduceFurther(int64_t now_ms,
- uint32_t estimated_throughput_bps) const;
+ bool TimeToReduceFurther(Timestamp at_time,
+ DataRate estimated_throughput) const;
// As above. To be used if overusing before we have measured a throughput.
- bool InitialTimeToReduceFurther(int64_t now_ms) const;
+ bool InitialTimeToReduceFurther(Timestamp at_time) const;
- uint32_t LatestEstimate() const;
- void SetRtt(int64_t rtt);
- uint32_t Update(const RateControlInput* input, int64_t now_ms);
- void SetEstimate(int bitrate_bps, int64_t now_ms);
+ DataRate LatestEstimate() const;
+ void SetRtt(TimeDelta rtt);
+ DataRate Update(const RateControlInput* input, Timestamp at_time);
+ void SetEstimate(DataRate bitrate, Timestamp at_time);
// Returns the increase rate when used bandwidth is near the link capacity.
- int GetNearMaxIncreaseRateBps() const;
+ double GetNearMaxIncreaseRateBpsPerSecond() const;
// Returns the expected time between overuse signals (assuming steady state).
- int GetExpectedBandwidthPeriodMs() const;
+ TimeDelta GetExpectedBandwidthPeriod() const;
private:
friend class GoogCcStatePrinter;
@@ -64,41 +67,41 @@
// in the "decrease" state the bitrate will be decreased to slightly below the
// current throughput. When in the "hold" state the bitrate will be kept
// constant to allow built up queues to drain.
- uint32_t ChangeBitrate(uint32_t current_bitrate,
+ DataRate ChangeBitrate(DataRate current_bitrate,
const RateControlInput& input,
- int64_t now_ms);
- // Clamps new_bitrate_bps to within the configured min bitrate and a linear
+ Timestamp at_time);
+ // Clamps new_bitrate to within the configured min bitrate and a linear
// function of the throughput, so that the new bitrate can't grow too
// large compared to the bitrate actually being received by the other end.
- uint32_t ClampBitrate(uint32_t new_bitrate_bps,
- uint32_t estimated_throughput_bps) const;
- uint32_t MultiplicativeRateIncrease(int64_t now_ms,
- int64_t last_ms,
- uint32_t current_bitrate_bps) const;
- uint32_t AdditiveRateIncrease(int64_t now_ms, int64_t last_ms) const;
- void UpdateChangePeriod(int64_t now_ms);
+ DataRate ClampBitrate(DataRate new_bitrate,
+ DataRate estimated_throughput) const;
+ DataRate MultiplicativeRateIncrease(Timestamp at_time,
+ Timestamp last_ms,
+ DataRate current_bitrate) const;
+ DataRate AdditiveRateIncrease(Timestamp at_time, Timestamp last_time) const;
+ void UpdateChangePeriod(Timestamp at_time);
void UpdateMaxThroughputEstimate(float estimated_throughput_kbps);
- void ChangeState(const RateControlInput& input, int64_t now_ms);
+ void ChangeState(const RateControlInput& input, Timestamp at_time);
- uint32_t min_configured_bitrate_bps_;
- uint32_t max_configured_bitrate_bps_;
- uint32_t current_bitrate_bps_;
- uint32_t latest_estimated_throughput_bps_;
+ DataRate min_configured_bitrate_;
+ DataRate max_configured_bitrate_;
+ DataRate current_bitrate_;
+ DataRate latest_estimated_throughput_;
float avg_max_bitrate_kbps_;
float var_max_bitrate_kbps_;
RateControlState rate_control_state_;
RateControlRegion rate_control_region_;
- int64_t time_last_bitrate_change_;
- int64_t time_last_bitrate_decrease_;
- int64_t time_first_throughput_estimate_;
+ Timestamp time_last_bitrate_change_;
+ Timestamp time_last_bitrate_decrease_;
+ Timestamp time_first_throughput_estimate_;
bool bitrate_is_initialized_;
float beta_;
- int64_t rtt_;
+ TimeDelta rtt_;
const bool in_experiment_;
const bool smoothing_experiment_;
const bool in_initial_backoff_interval_experiment_;
- int64_t initial_backoff_interval_ms_;
- absl::optional<int> last_decrease_;
+ TimeDelta initial_backoff_interval_;
+ absl::optional<DataRate> last_decrease_;
};
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
index 5cde7ce..4bec9e8 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
@@ -40,13 +40,26 @@
states.simulated_clock.reset(new SimulatedClock(kClockInitialTime));
return states;
}
-
+absl::optional<DataRate> OptionalRateFromOptionalBps(
+ absl::optional<int> bitrate_bps) {
+ if (bitrate_bps) {
+ return DataRate::bps(*bitrate_bps);
+ } else {
+ return absl::nullopt;
+ }
+}
void UpdateRateControl(const AimdRateControlStates& states,
const BandwidthUsage& bandwidth_usage,
absl::optional<uint32_t> throughput_estimate,
int64_t now_ms) {
- RateControlInput input(bandwidth_usage, throughput_estimate);
- states.aimd_rate_control->Update(&input, now_ms);
+ RateControlInput input(bandwidth_usage,
+ OptionalRateFromOptionalBps(throughput_estimate));
+ states.aimd_rate_control->Update(&input, Timestamp::ms(now_ms));
+}
+void SetEstimate(const AimdRateControlStates& states, int bitrate_bps) {
+ states.aimd_rate_control->SetEstimate(
+ DataRate::bps(bitrate_bps),
+ Timestamp::ms(states.simulated_clock->TimeInMilliseconds()));
}
} // namespace
@@ -54,40 +67,40 @@
TEST(AimdRateControlTest, MinNearMaxIncreaseRateOnLowBandwith) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 30000;
- states.aimd_rate_control->SetEstimate(
- kBitrate, states.simulated_clock->TimeInMilliseconds());
- EXPECT_EQ(4000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
+ SetEstimate(states, kBitrate);
+ EXPECT_EQ(4000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}
TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn90kbpsAnd200msRtt) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 90000;
- states.aimd_rate_control->SetEstimate(
- kBitrate, states.simulated_clock->TimeInMilliseconds());
- EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
+ SetEstimate(states, kBitrate);
+ EXPECT_EQ(5000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}
TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 60000;
- states.aimd_rate_control->SetEstimate(
- kBitrate, states.simulated_clock->TimeInMilliseconds());
- states.aimd_rate_control->SetRtt(100);
- EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
+ SetEstimate(states, kBitrate);
+ states.aimd_rate_control->SetRtt(TimeDelta::ms(100));
+ EXPECT_EQ(5000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}
TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) {
// Smoothing experiment disabled
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 300000;
- states.aimd_rate_control->SetEstimate(
- kBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kBitrate);
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate,
states.simulated_clock->TimeInMilliseconds());
- EXPECT_NEAR(14000, states.aimd_rate_control->GetNearMaxIncreaseRateBps(),
+ EXPECT_NEAR(14000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond(),
1000);
EXPECT_EQ(kDefaultPeriodMsNoSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriodSmoothingExp) {
@@ -95,21 +108,20 @@
test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 300000;
- states.aimd_rate_control->SetEstimate(
- kBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kBitrate);
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate,
states.simulated_clock->TimeInMilliseconds());
- EXPECT_NEAR(14000, states.aimd_rate_control->GetNearMaxIncreaseRateBps(),
+ EXPECT_NEAR(14000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond(),
1000);
EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, BweLimitedByAckedBitrate) {
auto states = CreateAimdRateControlStates();
constexpr int kAckedBitrate = 10000;
- states.aimd_rate_control->SetEstimate(
- kAckedBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kAckedBitrate);
while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime <
20000) {
UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate,
@@ -118,14 +130,13 @@
}
ASSERT_TRUE(states.aimd_rate_control->ValidEstimate());
EXPECT_EQ(static_cast<uint32_t>(1.5 * kAckedBitrate + 10000),
- states.aimd_rate_control->LatestEstimate());
+ states.aimd_rate_control->LatestEstimate().bps());
}
TEST(AimdRateControlTest, BweNotLimitedByDecreasingAckedBitrate) {
auto states = CreateAimdRateControlStates();
constexpr int kAckedBitrate = 100000;
- states.aimd_rate_control->SetEstimate(
- kAckedBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kAckedBitrate);
while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime <
20000) {
UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate,
@@ -135,10 +146,10 @@
ASSERT_TRUE(states.aimd_rate_control->ValidEstimate());
// If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x
// what's being acked, but also shouldn't get to increase more.
- uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate();
+ uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate().bps();
UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate / 2,
states.simulated_clock->TimeInMilliseconds());
- uint32_t new_estimate = states.aimd_rate_control->LatestEstimate();
+ uint32_t new_estimate = states.aimd_rate_control->LatestEstimate().bps();
EXPECT_NEAR(new_estimate, static_cast<uint32_t>(1.5 * kAckedBitrate + 10000),
2000);
EXPECT_EQ(new_estimate, prev_estimate);
@@ -147,35 +158,34 @@
TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) {
// Smoothing experiment disabled
auto states = CreateAimdRateControlStates();
- states.aimd_rate_control->SetStartBitrate(300000);
+ states.aimd_rate_control->SetStartBitrate(DataRate::kbps(300));
EXPECT_EQ(kDefaultPeriodMsNoSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
states.simulated_clock->AdvanceTimeMilliseconds(100);
UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000,
states.simulated_clock->TimeInMilliseconds());
EXPECT_NE(kDefaultPeriodMsNoSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, MinPeriodUntilFirstOveruseSmoothingExp) {
// Smoothing experiment enabled
test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
auto states = CreateAimdRateControlStates();
- states.aimd_rate_control->SetStartBitrate(300000);
+ states.aimd_rate_control->SetStartBitrate(DataRate::kbps(300));
EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
states.simulated_clock->AdvanceTimeMilliseconds(100);
UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000,
states.simulated_clock->TimeInMilliseconds());
EXPECT_NE(kMinBwePeriodMsSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, ExpectedPeriodAfter20kbpsDropAnd5kbpsIncrease) {
auto states = CreateAimdRateControlStates();
constexpr int kInitialBitrate = 110000;
- states.aimd_rate_control->SetEstimate(
- kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kInitialBitrate);
states.simulated_clock->AdvanceTimeMilliseconds(100);
// Make the bitrate drop by 20 kbps to get to 90 kbps.
// The rate increase at 90 kbps should be 5 kbps, so the period should be 4 s.
@@ -183,8 +193,9 @@
(kInitialBitrate - 20000) / kFractionAfterOveruse;
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
states.simulated_clock->TimeInMilliseconds());
- EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
- EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ EXPECT_EQ(5000,
+ states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
+ EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, MinPeriodAfterLargeBitrateDecreaseSmoothingExp) {
@@ -192,8 +203,7 @@
test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
auto states = CreateAimdRateControlStates();
constexpr int kInitialBitrate = 110000;
- states.aimd_rate_control->SetEstimate(
- kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kInitialBitrate);
states.simulated_clock->AdvanceTimeMilliseconds(100);
// Make such a large drop in bitrate that should be treated as network
// degradation.
@@ -201,20 +211,19 @@
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) {
auto states = CreateAimdRateControlStates();
constexpr int kInitialBitrate = 10000;
- states.aimd_rate_control->SetEstimate(
- kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kInitialBitrate);
states.simulated_clock->AdvanceTimeMilliseconds(100);
// Make a small (1.5 kbps) bitrate drop to 8.5 kbps.
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kInitialBitrate - 1,
states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(kMinBwePeriodMsNoSmoothingExp,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxSmoothingExp) {
@@ -222,29 +231,27 @@
test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
auto states = CreateAimdRateControlStates();
constexpr int kInitialBitrate = 50000000;
- states.aimd_rate_control->SetEstimate(
- kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kInitialBitrate);
states.simulated_clock->AdvanceTimeMilliseconds(100);
// Make a large (10 Mbps) bitrate drop to 10 kbps.
constexpr int kAckedBitrate = 40000000 / kFractionAfterOveruse;
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(kMaxBwePeriodMs,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxNoSmoothingExp) {
auto states = CreateAimdRateControlStates();
constexpr int kInitialBitrate = 10010000;
- states.aimd_rate_control->SetEstimate(
- kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+ SetEstimate(states, kInitialBitrate);
states.simulated_clock->AdvanceTimeMilliseconds(100);
// Make a large (10 Mbps) bitrate drop to 10 kbps.
constexpr int kAckedBitrate = 10000 / kFractionAfterOveruse;
UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(kMaxBwePeriodMs,
- states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+ states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}
TEST(AimdRateControlTest, SendingRateBoundedWhenThroughputNotEstimated) {
@@ -265,7 +272,7 @@
states.simulated_clock->TimeInMilliseconds());
states.simulated_clock->AdvanceTimeMilliseconds(100);
}
- EXPECT_LE(states.aimd_rate_control->LatestEstimate(),
+ EXPECT_LE(states.aimd_rate_control->LatestEstimate().bps(),
kInitialBitrateBps * 1.5 + 10000);
}
diff --git a/modules/remote_bitrate_estimator/bwe_defines.cc b/modules/remote_bitrate_estimator/bwe_defines.cc
index 6cbe468..91f3cd4 100644
--- a/modules/remote_bitrate_estimator/bwe_defines.cc
+++ b/modules/remote_bitrate_estimator/bwe_defines.cc
@@ -34,8 +34,8 @@
RateControlInput::RateControlInput(
BandwidthUsage bw_state,
- const absl::optional<uint32_t>& estimated_throughput_bps)
- : bw_state(bw_state), estimated_throughput_bps(estimated_throughput_bps) {}
+ const absl::optional<DataRate>& estimated_throughput)
+ : bw_state(bw_state), estimated_throughput(estimated_throughput) {}
RateControlInput::~RateControlInput() = default;
diff --git a/modules/remote_bitrate_estimator/include/bwe_defines.h b/modules/remote_bitrate_estimator/include/bwe_defines.h
index 2098507..f6ba06c 100644
--- a/modules/remote_bitrate_estimator/include/bwe_defines.h
+++ b/modules/remote_bitrate_estimator/include/bwe_defines.h
@@ -51,11 +51,11 @@
struct RateControlInput {
RateControlInput(BandwidthUsage bw_state,
- const absl::optional<uint32_t>& estimated_throughput_bps);
+ const absl::optional<DataRate>& estimated_throughput);
~RateControlInput();
BandwidthUsage bw_state;
- absl::optional<uint32_t> estimated_throughput_bps;
+ absl::optional<DataRate> estimated_throughput;
};
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
index a7cfe4c..1ad35c7 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
@@ -22,6 +22,16 @@
#include "system_wrappers/include/metrics.h"
namespace webrtc {
+namespace {
+absl::optional<DataRate> OptionalRateFromOptionalBps(
+ absl::optional<int> bitrate_bps) {
+ if (bitrate_bps) {
+ return DataRate::bps(*bitrate_bps);
+ } else {
+ return absl::nullopt;
+ }
+}
+} // namespace
enum {
kTimestampGroupLengthMs = 5,
@@ -188,7 +198,8 @@
<< " bps. Mean send delta: " << best_it->send_mean_ms
<< " ms, mean recv delta: " << best_it->recv_mean_ms
<< " ms, num probes: " << best_it->count;
- remote_rate_.SetEstimate(probe_bitrate_bps, now_ms);
+ remote_rate_.SetEstimate(DataRate::bps(probe_bitrate_bps),
+ Timestamp::ms(now_ms));
return ProbeResult::kBitrateUpdated;
}
}
@@ -205,7 +216,7 @@
bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0;
bool bitrate_above_estimate =
remote_rate_.ValidEstimate() &&
- new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate());
+ new_bitrate_bps > remote_rate_.LatestEstimate().bps<int>();
return initial_probe || bitrate_above_estimate;
}
@@ -316,13 +327,14 @@
// Check if it's time for a periodic update or if we should update because
// of an over-use.
if (last_update_ms_ == -1 ||
- now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval()) {
+ now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval().ms()) {
update_estimate = true;
} else if (detector_.State() == BandwidthUsage::kBwOverusing) {
absl::optional<uint32_t> incoming_rate =
incoming_bitrate_.Rate(arrival_time_ms);
if (incoming_rate &&
- remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
+ remote_rate_.TimeToReduceFurther(Timestamp::ms(now_ms),
+ DataRate::bps(*incoming_rate))) {
update_estimate = true;
}
}
@@ -332,9 +344,11 @@
// The first overuse should immediately trigger a new estimate.
// We also have to update the estimate immediately if we are overusing
// and the target bitrate is too high compared to what we are receiving.
- const RateControlInput input(detector_.State(),
- incoming_bitrate_.Rate(arrival_time_ms));
- target_bitrate_bps = remote_rate_.Update(&input, now_ms);
+ const RateControlInput input(
+ detector_.State(),
+ OptionalRateFromOptionalBps(incoming_bitrate_.Rate(arrival_time_ms)));
+ target_bitrate_bps =
+ remote_rate_.Update(&input, Timestamp::ms(now_ms)).bps<uint32_t>();
update_estimate = remote_rate_.ValidEstimate();
ssrcs = Keys(ssrcs_);
}
@@ -374,7 +388,7 @@
void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t avg_rtt_ms,
int64_t max_rtt_ms) {
rtc::CritScope lock(&crit_);
- remote_rate_.SetRtt(avg_rtt_ms);
+ remote_rate_.SetRtt(TimeDelta::ms(avg_rtt_ms));
}
void RemoteBitrateEstimatorAbsSendTime::RemoveStream(uint32_t ssrc) {
@@ -399,7 +413,7 @@
if (ssrcs_.empty()) {
*bitrate_bps = 0;
} else {
- *bitrate_bps = remote_rate_.LatestEstimate();
+ *bitrate_bps = remote_rate_.LatestEstimate().bps<uint32_t>();
}
return true;
}
@@ -408,6 +422,6 @@
// Called from both the configuration thread and the network thread. Shouldn't
// be called from the network thread in the future.
rtc::CritScope lock(&crit_);
- remote_rate_.SetMinBitrate(min_bitrate_bps);
+ remote_rate_.SetMinBitrate(DataRate::bps(min_bitrate_bps));
}
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
index 1f0de47..a267051 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
@@ -27,6 +27,16 @@
#include "system_wrappers/include/metrics.h"
namespace webrtc {
+namespace {
+absl::optional<DataRate> OptionalRateFromOptionalBps(
+ absl::optional<int> bitrate_bps) {
+ if (bitrate_bps) {
+ return DataRate::bps(*bitrate_bps);
+ } else {
+ return absl::nullopt;
+ }
+}
+} // namespace
enum { kTimestampGroupLengthMs = 5 };
static const double kTimestampToMs = 1.0 / 90.0;
@@ -133,7 +143,8 @@
incoming_bitrate_.Rate(now_ms);
if (incoming_bitrate_bps &&
(prior_state != BandwidthUsage::kBwOverusing ||
- GetRemoteRate()->TimeToReduceFurther(now_ms, *incoming_bitrate_bps))) {
+ GetRemoteRate()->TimeToReduceFurther(
+ Timestamp::ms(now_ms), DataRate::bps(*incoming_bitrate_bps)))) {
// The first overuse should immediately trigger a new estimate.
// We also have to update the estimate immediately if we are overusing
// and the target bitrate is too high compared to what we are receiving.
@@ -187,10 +198,12 @@
}
AimdRateControl* remote_rate = GetRemoteRate();
- const RateControlInput input(bw_state, incoming_bitrate_.Rate(now_ms));
- uint32_t target_bitrate = remote_rate->Update(&input, now_ms);
+ const RateControlInput input(
+ bw_state, OptionalRateFromOptionalBps(incoming_bitrate_.Rate(now_ms)));
+ uint32_t target_bitrate =
+ remote_rate->Update(&input, Timestamp::ms(now_ms)).bps<uint32_t>();
if (remote_rate->ValidEstimate()) {
- process_interval_ms_ = remote_rate->GetFeedbackInterval();
+ process_interval_ms_ = remote_rate->GetFeedbackInterval().ms();
RTC_DCHECK_GT(process_interval_ms_, 0);
std::vector<uint32_t> ssrcs;
GetSsrcs(&ssrcs);
@@ -202,7 +215,7 @@
void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t avg_rtt_ms,
int64_t max_rtt_ms) {
rtc::CritScope cs(&crit_sect_);
- GetRemoteRate()->SetRtt(avg_rtt_ms);
+ GetRemoteRate()->SetRtt(TimeDelta::ms(avg_rtt_ms));
}
void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
@@ -226,7 +239,7 @@
if (ssrcs->empty())
*bitrate_bps = 0;
else
- *bitrate_bps = remote_rate_->LatestEstimate();
+ *bitrate_bps = remote_rate_->LatestEstimate().bps<uint32_t>();
return true;
}
@@ -249,7 +262,7 @@
void RemoteBitrateEstimatorSingleStream::SetMinBitrate(int min_bitrate_bps) {
rtc::CritScope cs(&crit_sect_);
- remote_rate_->SetMinBitrate(min_bitrate_bps);
+ remote_rate_->SetMinBitrate(DataRate::bps(min_bitrate_bps));
}
} // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
index 120db13..2a4ef06 100644
--- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
+++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc
@@ -55,7 +55,7 @@
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropThirteenStreamsWrap) {
- CapacityDropTestHelper(13, true, 733, 0);
+ CapacityDropTestHelper(13, true, 567, 0);
}
TEST_F(RemoteBitrateEstimatorSingleTest, CapacityDropNineteenStreamsWrap) {