Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc

Issue 2982233002: Added implementations for entering/exiting STARTUP, DRAIN, PROBE_BW, PROBE_RTT modes, also updated M (Closed)
Patch Set: Unittest fix Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 = 3;
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 // The least amount of rounds PROBE_RTT mode should last.
39 const int kProbeRttDurationRounds = 1;
40 // The least amount of milliseconds PROBE_RTT mode should last.
41 const int kProbeRttDurationMs = 200;
42 // Gain value for congestion window for assuming that network has no queues.
43 const float kTargetCongestionWindowGain = 1;
44 // Gain value for congestion window in PROBE_BW mode. In theory it should be
45 // equal to 1, but in practice because of delayed acks and the way networks
46 // work, it is nice to have some extra room in congestion window for full link
47 // utilization. Value chosen by observations on different tests.
48 const float kCruisingCongestionWindowGain = 1.5f;
49 // Expiration time for min_rtt sample, which is set to 10 seconds according to
50 // BBR design doc.
51 const int64_t kMinRttFilterSizeMs = 10000;
31 } // namespace 52 } // namespace
32 53
33 BbrBweSender::BbrBweSender(Clock* clock) 54 BbrBweSender::BbrBweSender(Clock* clock)
34 : BweSender(0), 55 : BweSender(0),
35 clock_(clock), 56 clock_(clock),
36 mode_(STARTUP), 57 mode_(STARTUP),
37 max_bandwidth_filter_(new MaxBandwidthFilter()), 58 max_bandwidth_filter_(new MaxBandwidthFilter()),
59 min_rtt_filter_(new MinRttFilter()),
60 congestion_window_(new CongestionWindow()),
61 rand_(new Random(time(NULL))),
38 round_count_(0), 62 round_count_(0),
39 last_packet_sent_(0), 63 last_packet_sent_(0),
40 round_trip_end_(0), 64 round_trip_end_(0),
41 full_bandwidth_reached_(false) { 65 full_bandwidth_reached_(false),
66 cycle_start_time_ms_(0),
67 cycle_index_(0),
68 prior_in_flight_(0),
69 probe_rtt_start_time_ms_(0),
70 minimum_congestion_window_start_time_ms_(),
71 minimum_congestion_window_start_round_(0) {
42 // Initially enter Startup mode. 72 // Initially enter Startup mode.
43 EnterStartup(); 73 EnterStartup();
44 } 74 }
45 75
46 BbrBweSender::~BbrBweSender() {} 76 BbrBweSender::~BbrBweSender() {}
47 77
48 int BbrBweSender::GetFeedbackIntervalMs() const { 78 int BbrBweSender::GetFeedbackIntervalMs() const {
49 return kFeedbackIntervalsMs; 79 return kFeedbackIntervalsMs;
50 } 80 }
51 81
(...skipping 22 matching lines...) Expand all
74 case STARTUP: 104 case STARTUP:
75 TryExitingStartup(); 105 TryExitingStartup();
76 break; 106 break;
77 case DRAIN: 107 case DRAIN:
78 TryExitingDrain(now_ms); 108 TryExitingDrain(now_ms);
79 break; 109 break;
80 case PROBE_BW: 110 case PROBE_BW:
81 TryUpdatingCyclePhase(now_ms); 111 TryUpdatingCyclePhase(now_ms);
82 break; 112 break;
83 case PROBE_RTT: 113 case PROBE_RTT:
84 TryExitingProbeRtt(now_ms); 114 TryExitingProbeRtt(now_ms, 0);
85 break; 115 break;
86 } 116 }
87 TryEnteringProbeRtt(now_ms); 117 TryEnteringProbeRtt(now_ms);
88 // TODO(gnish): implement functions updating congestion window and pacing rate 118 // TODO(gnish): implement functions updating congestion window and pacing rate
89 // controllers. 119 // controllers.
90 } 120 }
91 121
122 size_t BbrBweSender::TargetCongestionWindow(float gain) {
123 size_t target_congestion_window =
124 congestion_window_->GetTargetCongestionWindow(
125 max_bandwidth_filter_->max_bandwidth_estimate_bps(),
126 min_rtt_filter_->min_rtt_ms(), gain);
127 return target_congestion_window;
128 }
129
92 bool BbrBweSender::UpdateBandwidthAndMinRtt() { 130 bool BbrBweSender::UpdateBandwidthAndMinRtt() {
93 return false; 131 return false;
94 } 132 }
95 133
96 void BbrBweSender::EnterStartup() { 134 void BbrBweSender::EnterStartup() {
97 mode_ = STARTUP; 135 mode_ = STARTUP;
98 pacing_gain_ = kHighGain; 136 pacing_gain_ = kHighGain;
99 congestion_window_gain_ = kHighGain; 137 congestion_window_gain_ = kHighGain;
100 } 138 }
101 139
102 void BbrBweSender::TryExitingStartup() { 140 void BbrBweSender::TryExitingStartup() {
103 if (full_bandwidth_reached_) { 141 if (full_bandwidth_reached_) {
104 mode_ = DRAIN; 142 mode_ = DRAIN;
105 pacing_gain_ = kDrainGain; 143 pacing_gain_ = kDrainGain;
106 congestion_window_gain_ = kHighGain; 144 congestion_window_gain_ = kHighGain;
107 } 145 }
108 } 146 }
109 147
110 void BbrBweSender::TryExitingDrain(int64_t now_ms) {} 148 void BbrBweSender::TryExitingDrain(int64_t now_ms) {
149 if (congestion_window_->data_inflight() <=
150 TargetCongestionWindow(kTargetCongestionWindowGain))
151 EnterProbeBw(now_ms);
152 }
111 153
112 void BbrBweSender::EnterProbeBw(int64_t now_ms) {} 154 // Start probing with a random gain value, which is different form 0.75,
155 // starting with 0.75 doesn't offer any benefits as there are no queues to be
156 // drained.
157 void BbrBweSender::EnterProbeBw(int64_t now_ms) {
158 mode_ = PROBE_BW;
159 congestion_window_gain_ = kCruisingCongestionWindowGain;
160 int index = rand_->Rand(kGainCycleLength - 2);
161 if (index == 1)
162 index = kGainCycleLength - 1;
163 pacing_gain_ = kPacingGain[index];
164 cycle_start_time_ms_ = now_ms;
165 cycle_index_ = index;
166 }
113 167
114 void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {} 168 void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {
169 // Each phase should last rougly min_rtt ms time.
170 bool advance_cycle_phase = false;
171 if (min_rtt_filter_->min_rtt_ms())
172 advance_cycle_phase =
173 now_ms - cycle_start_time_ms_ > *min_rtt_filter_->min_rtt_ms();
174 // If BBR was probing and it couldn't increase data inflight sufficiently in
175 // one min_rtt time, continue probing. BBR design doc isn't clear about this,
176 // but condition helps in quicker ramp-up and performs better.
177 if (pacing_gain_ > 1.0 &&
178 prior_in_flight_ < TargetCongestionWindow(pacing_gain_))
179 advance_cycle_phase = false;
180 // If BBR has already drained queues there is no point in continuing draining
181 // phase.
182 if (pacing_gain_ < 1.0 && prior_in_flight_ <= TargetCongestionWindow(1))
183 advance_cycle_phase = true;
184 if (advance_cycle_phase) {
185 cycle_index_++;
186 cycle_index_ %= kGainCycleLength;
187 pacing_gain_ = kPacingGain[cycle_index_];
188 cycle_start_time_ms_ = now_ms;
189 }
190 }
115 191
116 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {} 192 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {
117 void BbrBweSender::TryExitingProbeRtt(int64_t now_ms) {} 193 if (min_rtt_filter_->min_rtt_expired(now_ms, kMinRttFilterSizeMs) &&
194 mode_ != PROBE_RTT) {
195 mode_ = PROBE_RTT;
196 pacing_gain_ = 1;
197 probe_rtt_start_time_ms_ = now_ms;
198 minimum_congestion_window_start_time_ms_.reset();
199 }
200 }
201
202 // minimum_congestion_window_start_time_'s value is set to the first moment when
203 // data inflight was less then kMinimumCongestionWindowBytes, we should make
204 // sure that BBR has been in PROBE_RTT mode for at least one round or 200ms.
205 void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, int64_t round) {
206 if (!minimum_congestion_window_start_time_ms_) {
207 if (congestion_window_->data_inflight() <=
208 CongestionWindow::kMinimumCongestionWindowBytes) {
209 *minimum_congestion_window_start_time_ms_ = now_ms;
210 minimum_congestion_window_start_round_ = round;
211 }
212 } else {
213 if (now_ms - *minimum_congestion_window_start_time_ms_ >=
214 kProbeRttDurationMs &&
215 round - minimum_congestion_window_start_round_ >=
216 kProbeRttDurationRounds)
217 EnterProbeBw(now_ms);
218 }
219 }
118 220
119 int64_t BbrBweSender::TimeUntilNextProcess() { 221 int64_t BbrBweSender::TimeUntilNextProcess() {
120 return 100; 222 return 100;
121 } 223 }
122 224
123 void BbrBweSender::OnPacketsSent(const Packets& packets) { 225 void BbrBweSender::OnPacketsSent(const Packets& packets) {
124 last_packet_sent_ = 226 last_packet_sent_ =
125 static_cast<const MediaPacket*>(packets.back())->sequence_number(); 227 static_cast<const MediaPacket*>(packets.back())->sequence_number();
126 } 228 }
127 229
128 void BbrBweSender::Process() {} 230 void BbrBweSender::Process() {}
129 231
130 BbrBweReceiver::BbrBweReceiver(int flow_id) 232 BbrBweReceiver::BbrBweReceiver(int flow_id)
131 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {} 233 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {}
132 234
133 BbrBweReceiver::~BbrBweReceiver() {} 235 BbrBweReceiver::~BbrBweReceiver() {}
134 236
135 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms, 237 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms,
136 const MediaPacket& media_packet) {} 238 const MediaPacket& media_packet) {}
137 239
138 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) { 240 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) {
139 return nullptr; 241 return nullptr;
140 } 242 }
141 } // namespace bwe 243 } // namespace bwe
142 } // namespace testing 244 } // namespace testing
143 } // namespace webrtc 245 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698