Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 * | 9 * |
| 10 */ | 10 */ |
| 11 | 11 |
| 12 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" | 12 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" |
| 13 | 13 |
| 14 #include <stdlib.h> | |
| 15 | |
| 16 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_win dow.h" | |
| 14 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_ filter.h" | 17 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_ filter.h" |
| 18 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter .h" | |
| 15 | 19 |
| 16 namespace webrtc { | 20 namespace webrtc { |
| 17 namespace testing { | 21 namespace testing { |
| 18 namespace bwe { | 22 namespace bwe { |
| 19 namespace { | 23 namespace { |
| 20 const int kFeedbackIntervalsMs = 100; | 24 const int kFeedbackIntervalsMs = 100; |
| 21 // BBR uses this value to double sending rate each round trip. Design document | 25 // BBR uses this value to double sending rate each round trip. Design document |
| 22 // suggests using this value. | 26 // suggests using this value. |
| 23 const float kHighGain = 2.885f; | 27 const float kHighGain = 2.885f; |
| 24 // BBR uses this value to drain queues created during STARTUP in one round trip | 28 // BBR uses this value to drain queues created during STARTUP in one round trip |
| 25 // time. | 29 // time. |
| 26 const float kDrainGain = 1 / kHighGain; | 30 const float kDrainGain = 1 / kHighGain; |
| 27 // kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from | 31 // kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from |
| 28 // experiments, according to the design document. | 32 // experiments, according to the design document. |
| 29 const float kStartupGrowthTarget = 1.25f; | 33 const float kStartupGrowthTarget = 1.25f; |
| 30 const int kMaxRoundsWithoutGrowth = 3; | 34 const int kMaxRoundsWithoutGrowth = 3; |
| 35 // Pacing gain values for Probe Bandwidth mode. | |
| 36 const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1}; | |
| 37 const size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]); | |
| 38 const int kMinimumCongestionWindow = 4000; | |
|
philipel
2017/07/26 11:37:16
Is this in bytes? Why are there two kMinimumConges
gnish1
2017/07/27 08:38:37
Done.
| |
| 39 const int kProbeRttDurationRounds = 1; | |
|
philipel
2017/07/26 11:37:16
Comment what this value represent.
gnish1
2017/07/27 08:38:37
Done.
| |
| 40 const int kProbeRttDurationMs = 200; | |
|
philipel
2017/07/26 11:37:16
Comment what this value represent.
gnish1
2017/07/27 08:38:37
Done.
| |
| 31 } // namespace | 41 } // namespace |
| 32 | 42 |
| 33 BbrBweSender::BbrBweSender(Clock* clock) | 43 BbrBweSender::BbrBweSender(Clock* clock) |
| 34 : BweSender(0), | 44 : BweSender(0), |
| 35 clock_(clock), | 45 clock_(clock), |
| 36 mode_(STARTUP), | 46 mode_(STARTUP), |
| 37 max_bandwidth_filter_(new MaxBandwidthFilter()), | 47 max_bandwidth_filter_(new MaxBandwidthFilter()), |
| 48 min_rtt_filter_(new MinRttFilter()), | |
| 49 congestion_window_(new CongestionWindow()), | |
| 38 round_count_(0), | 50 round_count_(0), |
| 39 last_packet_sent_(0), | 51 last_packet_sent_(0), |
| 40 round_trip_end_(0), | 52 round_trip_end_(0), |
| 41 full_bandwidth_reached_(false) { | 53 full_bandwidth_reached_(false), |
| 54 cycle_start_time_ms_(0), | |
| 55 cycle_index_(0), | |
| 56 prior_in_flight_(0), | |
| 57 probe_rtt_start_time_ms_(0), | |
| 58 minimum_congestion_window_start_time_ms_(0), | |
| 59 minimum_congestion_window_start_round_(0) { | |
| 42 // Initially enter Startup mode. | 60 // Initially enter Startup mode. |
| 43 EnterStartup(); | 61 EnterStartup(); |
| 44 } | 62 } |
| 45 | 63 |
| 46 BbrBweSender::~BbrBweSender() {} | 64 BbrBweSender::~BbrBweSender() {} |
| 47 | 65 |
| 48 int BbrBweSender::GetFeedbackIntervalMs() const { | 66 int BbrBweSender::GetFeedbackIntervalMs() const { |
| 49 return kFeedbackIntervalsMs; | 67 return kFeedbackIntervalsMs; |
| 50 } | 68 } |
| 51 | 69 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 74 case STARTUP: | 92 case STARTUP: |
| 75 TryExitingStartup(); | 93 TryExitingStartup(); |
| 76 break; | 94 break; |
| 77 case DRAIN: | 95 case DRAIN: |
| 78 TryExitingDrain(now_ms); | 96 TryExitingDrain(now_ms); |
| 79 break; | 97 break; |
| 80 case PROBE_BW: | 98 case PROBE_BW: |
| 81 TryUpdatingCyclePhase(now_ms); | 99 TryUpdatingCyclePhase(now_ms); |
| 82 break; | 100 break; |
| 83 case PROBE_RTT: | 101 case PROBE_RTT: |
| 84 TryExitingProbeRtt(now_ms); | 102 TryExitingProbeRtt(now_ms, 0, false); |
| 85 break; | 103 break; |
| 86 } | 104 } |
| 87 TryEnteringProbeRtt(now_ms); | 105 TryEnteringProbeRtt(now_ms, false); |
| 88 // TODO(gnish): implement functions updating congestion window and pacing rate | 106 // TODO(gnish): implement functions updating congestion window and pacing rate |
| 89 // controllers. | 107 // controllers. |
| 90 } | 108 } |
| 91 | 109 |
| 110 size_t BbrBweSender::TargetCongestionWindow(float gain) { | |
| 111 size_t target_congestion_window = | |
| 112 congestion_window_->GetTargetCongestionWindow( | |
| 113 max_bandwidth_filter_->max_bandwidth_estimate_bps(), | |
| 114 min_rtt_filter_->min_rtt_ms(), gain); | |
| 115 return target_congestion_window; | |
| 116 } | |
| 117 | |
| 92 bool BbrBweSender::UpdateBandwidthAndMinRtt() { | 118 bool BbrBweSender::UpdateBandwidthAndMinRtt() { |
| 93 return false; | 119 return false; |
| 94 } | 120 } |
| 95 | 121 |
| 96 void BbrBweSender::EnterStartup() { | 122 void BbrBweSender::EnterStartup() { |
| 97 mode_ = STARTUP; | 123 mode_ = STARTUP; |
| 98 pacing_gain_ = kHighGain; | 124 pacing_gain_ = kHighGain; |
| 99 congestion_window_gain_ = kHighGain; | 125 congestion_window_gain_ = kHighGain; |
| 100 } | 126 } |
| 101 | 127 |
| 102 void BbrBweSender::TryExitingStartup() { | 128 void BbrBweSender::TryExitingStartup() { |
| 103 if (full_bandwidth_reached_) { | 129 if (full_bandwidth_reached_) { |
| 104 mode_ = DRAIN; | 130 mode_ = DRAIN; |
| 105 pacing_gain_ = kDrainGain; | 131 pacing_gain_ = kDrainGain; |
| 106 congestion_window_gain_ = kHighGain; | 132 congestion_window_gain_ = kHighGain; |
| 107 } | 133 } |
| 108 } | 134 } |
| 109 | 135 |
| 110 void BbrBweSender::TryExitingDrain(int64_t now_ms) {} | 136 void BbrBweSender::TryExitingDrain(int64_t now_ms) { |
| 137 if (congestion_window_->data_inflight() <= TargetCongestionWindow(1)) | |
|
philipel
2017/07/26 11:37:16
Create a variable for 1 which describes what it is
gnish1
2017/07/27 08:38:37
Done.
| |
| 138 EnterProbeBw(now_ms); | |
| 139 } | |
| 111 | 140 |
| 112 void BbrBweSender::EnterProbeBw(int64_t now_ms) {} | 141 // Start probing with a random gain value, which is different form 0.75, |
| 142 // starting with 0.75 doesn't offer any benefits as there are no queues to be | |
| 143 // drained. | |
| 144 void BbrBweSender::EnterProbeBw(int64_t now_ms) { | |
| 145 mode_ = PROBE_BW; | |
| 146 congestion_window_gain_ = 1.5f; | |
|
philipel
2017/07/26 11:37:16
Create a variable for 1.5 which describes what it
gnish1
2017/07/27 08:38:37
Done.
| |
| 147 unsigned int seed = time(NULL); | |
|
philipel
2017/07/26 11:37:16
Use webrtc::Random instead (in rc_base/random.h).
gnish1
2017/07/27 08:38:37
Done.
| |
| 148 int index = rand_r(&seed) % (kGainCycleLength - 1); | |
| 149 if (index == 1) | |
| 150 index = kGainCycleLength - 1; | |
| 151 pacing_gain_ = kPacingGain[index]; | |
| 152 cycle_start_time_ms_ = now_ms; | |
| 153 cycle_index_ = index; | |
| 154 } | |
| 113 | 155 |
| 114 void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {} | 156 void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) { |
| 157 // Each phase should last rougly min_rtt ms time. | |
| 158 bool advance_cycle_phase = | |
| 159 now_ms - cycle_start_time_ms_ > *min_rtt_filter_->min_rtt_ms(); | |
| 160 // If BBR was probing and it couldn't increase data inflight sufficiently in | |
| 161 // one min_rtt time, continue probing. | |
| 162 if (pacing_gain_ > 1.0 && | |
| 163 prior_in_flight_ < TargetCongestionWindow(pacing_gain_)) | |
| 164 advance_cycle_phase = false; | |
| 165 // If BBR has already drained queues there is no point in continuing draining | |
| 166 // phase. | |
| 167 if (pacing_gain_ < 1.0 && prior_in_flight_ <= TargetCongestionWindow(1)) | |
| 168 advance_cycle_phase = true; | |
| 169 if (advance_cycle_phase) { | |
| 170 cycle_index_++; | |
| 171 cycle_index_ %= kGainCycleLength; | |
| 172 pacing_gain_ = kPacingGain[cycle_index_]; | |
| 173 cycle_start_time_ms_ = now_ms; | |
| 174 } | |
| 175 } | |
| 115 | 176 |
| 116 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {} | 177 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms, bool min_rtt_expired) { |
| 117 void BbrBweSender::TryExitingProbeRtt(int64_t now_ms) {} | 178 if (min_rtt_expired && mode_ != PROBE_RTT) { |
| 179 mode_ = PROBE_RTT; | |
| 180 pacing_gain_ = 1; | |
| 181 probe_rtt_start_time_ms_ = now_ms; | |
| 182 minimum_congestion_window_start_time_ms_ = -1; | |
|
philipel
2017/07/26 11:37:16
I think using an rtc::Optional might be cleaner in
gnish1
2017/07/27 08:38:37
Done.
| |
| 183 } | |
| 184 } | |
| 185 | |
| 186 // minimum_congestion_window_start_time_'s value is set to the first moment when | |
| 187 // data inflight was less then kMinimumCongestionWindow, we should make sure | |
| 188 // that BBR has been in PROBE_RTT mode for at least one round or 200ms. | |
| 189 void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, | |
| 190 int64_t round, | |
| 191 bool min_rtt_expired) { | |
|
philipel
2017/07/26 11:37:16
|min_rtt_expired| is not used.
gnish1
2017/07/27 08:38:36
Done.
| |
| 192 if (minimum_congestion_window_start_time_ms_ == -1) { | |
| 193 if (congestion_window_->data_inflight() <= kMinimumCongestionWindow) { | |
| 194 minimum_congestion_window_start_time_ms_ = now_ms; | |
| 195 minimum_congestion_window_start_round_ = round; | |
| 196 } | |
| 197 } else { | |
| 198 if (now_ms - minimum_congestion_window_start_time_ms_ >= | |
| 199 kProbeRttDurationMs && | |
| 200 round - minimum_congestion_window_start_round_ >= | |
| 201 kProbeRttDurationRounds) | |
| 202 EnterProbeBw(now_ms); | |
| 203 } | |
| 204 } | |
| 118 | 205 |
| 119 int64_t BbrBweSender::TimeUntilNextProcess() { | 206 int64_t BbrBweSender::TimeUntilNextProcess() { |
| 120 return 100; | 207 return 100; |
| 121 } | 208 } |
| 122 | 209 |
| 123 void BbrBweSender::OnPacketsSent(const Packets& packets) { | 210 void BbrBweSender::OnPacketsSent(const Packets& packets) { |
| 124 last_packet_sent_ = | 211 last_packet_sent_ = |
| 125 static_cast<const MediaPacket*>(packets.back())->sequence_number(); | 212 static_cast<const MediaPacket*>(packets.back())->sequence_number(); |
| 126 } | 213 } |
| 127 | 214 |
| 128 void BbrBweSender::Process() {} | 215 void BbrBweSender::Process() {} |
| 129 | 216 |
| 130 BbrBweReceiver::BbrBweReceiver(int flow_id) | 217 BbrBweReceiver::BbrBweReceiver(int flow_id) |
| 131 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {} | 218 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {} |
| 132 | 219 |
| 133 BbrBweReceiver::~BbrBweReceiver() {} | 220 BbrBweReceiver::~BbrBweReceiver() {} |
| 134 | 221 |
| 135 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms, | 222 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms, |
| 136 const MediaPacket& media_packet) {} | 223 const MediaPacket& media_packet) {} |
| 137 | 224 |
| 138 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) { | 225 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) { |
| 139 return nullptr; | 226 return nullptr; |
| 140 } | 227 } |
| 141 } // namespace bwe | 228 } // namespace bwe |
| 142 } // namespace testing | 229 } // namespace testing |
| 143 } // namespace webrtc | 230 } // namespace webrtc |
| OLD | NEW |