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

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

Issue 2966403002: Added implementation of three classes in BBR,with unit-tests. (Closed)
Patch Set: Added logic for entering/exiting modes in BBR, added new bandwidth filter. Created 3 years, 5 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 = 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;
39 const int kProbeRttDurationRounds = 1;
40 const int kProbeRttDurationMs = 200;
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
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))
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;
147 unsigned int seed = time(NULL);
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;
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) {
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698