Chromium Code Reviews| Index: webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
| diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
| index a2463fc872e89df01e3260f738a39cf770eb3b23..21d343548ec1dc5f0842db91c77e578cadc07ce1 100644 |
| --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
| +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc |
| @@ -11,7 +11,12 @@ |
| #include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" |
| +#include <stdlib.h> |
| + |
| +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h" |
| #include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h" |
| +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h" |
| +#include "webrtc/rtc_base/random.h" |
| namespace webrtc { |
| namespace testing { |
| @@ -28,6 +33,20 @@ const float kDrainGain = 1 / kHighGain; |
| // experiments, according to the design document. |
| const float kStartupGrowthTarget = 1.25f; |
| const int kMaxRoundsWithoutGrowth = 3; |
| +// Pacing gain values for Probe Bandwidth mode. |
| +const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1}; |
| +const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]); |
| +// The least amount of rounds PROBE_RTT mode should last. |
| +const int kProbeRttDurationRounds = 1; |
| +// The least amount of milliseconds PROBE_RTT mode should last. |
| +const int kProbeRttDurationMs = 200; |
| +// Gain value for congestion window for assuming that network has no queues. |
| +const float kTargetCongestionWindowGain = 1; |
| +// Gain value for congestion window in PROBE_BW mode. In theory it should be |
| +// equal to 1, but in practice because of delayed acks and the way networks |
| +// work, it is nice to have some extra room in congestion window for full link |
| +// utilization. Value chosen by observations on different tests. |
| +const float kCruisingCongestionWindowGain = 1.5f; |
| } // namespace |
| BbrBweSender::BbrBweSender(Clock* clock) |
| @@ -35,10 +54,18 @@ BbrBweSender::BbrBweSender(Clock* clock) |
| clock_(clock), |
| mode_(STARTUP), |
| max_bandwidth_filter_(new MaxBandwidthFilter()), |
| + min_rtt_filter_(new MinRttFilter()), |
| + congestion_window_(new CongestionWindow()), |
| round_count_(0), |
| last_packet_sent_(0), |
| round_trip_end_(0), |
| - full_bandwidth_reached_(false) { |
| + full_bandwidth_reached_(false), |
| + cycle_start_time_ms_(0), |
| + cycle_index_(0), |
| + prior_in_flight_(0), |
| + probe_rtt_start_time_ms_(0), |
| + minimum_congestion_window_start_time_ms_(), |
| + minimum_congestion_window_start_round_(0) { |
| // Initially enter Startup mode. |
| EnterStartup(); |
| } |
| @@ -81,14 +108,22 @@ void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) { |
| TryUpdatingCyclePhase(now_ms); |
| break; |
| case PROBE_RTT: |
| - TryExitingProbeRtt(now_ms); |
| + TryExitingProbeRtt(now_ms, 0); |
| break; |
| } |
| - TryEnteringProbeRtt(now_ms); |
| + TryEnteringProbeRtt(now_ms, false); |
| // TODO(gnish): implement functions updating congestion window and pacing rate |
| // controllers. |
| } |
| +size_t BbrBweSender::TargetCongestionWindow(float gain) { |
| + size_t target_congestion_window = |
| + congestion_window_->GetTargetCongestionWindow( |
| + max_bandwidth_filter_->max_bandwidth_estimate_bps(), |
| + min_rtt_filter_->min_rtt_ms(), gain); |
|
philipel
2017/07/27 09:15:27
Before calling this function you need to determine
gnish1
2017/07/27 11:24:25
GetTargetCongestionWindow() checks if the value is
|
| + return target_congestion_window; |
| +} |
| + |
| bool BbrBweSender::UpdateBandwidthAndMinRtt() { |
| return false; |
| } |
| @@ -107,14 +142,75 @@ void BbrBweSender::TryExitingStartup() { |
| } |
| } |
| -void BbrBweSender::TryExitingDrain(int64_t now_ms) {} |
| +void BbrBweSender::TryExitingDrain(int64_t now_ms) { |
| + if (congestion_window_->data_inflight() <= |
| + TargetCongestionWindow(kTargetCongestionWindowGain)) |
| + EnterProbeBw(now_ms); |
| +} |
| -void BbrBweSender::EnterProbeBw(int64_t now_ms) {} |
| +// Start probing with a random gain value, which is different form 0.75, |
| +// starting with 0.75 doesn't offer any benefits as there are no queues to be |
| +// drained. |
| +void BbrBweSender::EnterProbeBw(int64_t now_ms) { |
| + mode_ = PROBE_BW; |
| + congestion_window_gain_ = kCruisingCongestionWindowGain; |
| + Random* rand = new Random(time(NULL)); |
|
philipel
2017/07/27 09:15:27
Every time you call this function you will leak on
gnish1
2017/07/27 11:24:25
Done.
|
| + int index = rand->Rand(kGainCycleLength - 2); |
| + if (index == 1) |
| + index = kGainCycleLength - 1; |
| + pacing_gain_ = kPacingGain[index]; |
| + cycle_start_time_ms_ = now_ms; |
| + cycle_index_ = index; |
| +} |
| -void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {} |
| +void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) { |
| + // Each phase should last rougly min_rtt ms time. |
| + bool advance_cycle_phase = |
| + now_ms - cycle_start_time_ms_ > *min_rtt_filter_->min_rtt_ms(); |
| + // If BBR was probing and it couldn't increase data inflight sufficiently in |
| + // one min_rtt time, continue probing. |
| + if (pacing_gain_ > 1.0 && |
|
philipel
2017/07/27 09:15:27
Is this according to the BBR design or is this som
gnish1
2017/07/27 11:24:25
Done.
|
| + prior_in_flight_ < TargetCongestionWindow(pacing_gain_)) |
| + advance_cycle_phase = false; |
| + // If BBR has already drained queues there is no point in continuing draining |
| + // phase. |
| + if (pacing_gain_ < 1.0 && prior_in_flight_ <= TargetCongestionWindow(1)) |
| + advance_cycle_phase = true; |
| + if (advance_cycle_phase) { |
| + cycle_index_++; |
| + cycle_index_ %= kGainCycleLength; |
| + pacing_gain_ = kPacingGain[cycle_index_]; |
| + cycle_start_time_ms_ = now_ms; |
| + } |
| +} |
| -void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {} |
| -void BbrBweSender::TryExitingProbeRtt(int64_t now_ms) {} |
| +void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms, bool min_rtt_expired) { |
|
philipel
2017/07/27 09:15:27
Remove |min_rtt_expired| and use |min_rtt_filter_|
gnish1
2017/07/27 11:24:25
Done.
|
| + if (min_rtt_expired && mode_ != PROBE_RTT) { |
| + mode_ = PROBE_RTT; |
| + pacing_gain_ = 1; |
| + probe_rtt_start_time_ms_ = now_ms; |
| + minimum_congestion_window_start_time_ms_.reset(); |
| + } |
| +} |
| + |
| +// minimum_congestion_window_start_time_'s value is set to the first moment when |
| +// data inflight was less then kMinimumCongestionWindowBytes, we should make |
| +// sure that BBR has been in PROBE_RTT mode for at least one round or 200ms. |
| +void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, int64_t round) { |
| + if (!minimum_congestion_window_start_time_ms_) { |
| + if (congestion_window_->data_inflight() <= |
| + CongestionWindow::kMinimumCongestionWindowBytes) { |
| + *minimum_congestion_window_start_time_ms_ = now_ms; |
| + minimum_congestion_window_start_round_ = round; |
| + } |
| + } else { |
| + if (now_ms - *minimum_congestion_window_start_time_ms_ >= |
| + kProbeRttDurationMs && |
| + round - minimum_congestion_window_start_round_ >= |
| + kProbeRttDurationRounds) |
| + EnterProbeBw(now_ms); |
| + } |
| +} |
| int64_t BbrBweSender::TimeUntilNextProcess() { |
| return 100; |