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

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

Issue 2990163002: Almost full implementation of BBR's core. (Closed)
Patch Set: Updated according to comments. 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> 14 #include <stdlib.h>
15 #include <algorithm>
15 16
16 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_win dow.h" 17 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_win dow.h"
17 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_ filter.h" 18 #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" 19 #include "webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter .h"
19 20
20 namespace webrtc { 21 namespace webrtc {
21 namespace testing { 22 namespace testing {
22 namespace bwe { 23 namespace bwe {
23 namespace { 24 namespace {
24 const int kFeedbackIntervalsMs = 3; 25 const int kFeedbackIntervalsMs = 5;
25 // BBR uses this value to double sending rate each round trip. Design document 26 // BBR uses this value to double sending rate each round trip. Design document
26 // suggests using this value. 27 // suggests using this value.
27 const float kHighGain = 2.885f; 28 const float kHighGain = 2.885f;
28 // BBR uses this value to drain queues created during STARTUP in one round trip 29 // BBR uses this value to drain queues created during STARTUP in one round trip
29 // time. 30 // time.
30 const float kDrainGain = 1 / kHighGain; 31 const float kDrainGain = 1 / kHighGain;
31 // kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from 32 // kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from
32 // experiments, according to the design document. 33 // experiments, according to the design document.
33 const float kStartupGrowthTarget = 1.25f; 34 const float kStartupGrowthTarget = 1.25f;
34 const int kMaxRoundsWithoutGrowth = 3; 35 const int kMaxRoundsWithoutGrowth = 3;
35 // Pacing gain values for Probe Bandwidth mode. 36 // Pacing gain values for Probe Bandwidth mode.
36 const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1}; 37 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 size_t kGainCycleLength = sizeof(kPacingGain) / sizeof(kPacingGain[0]);
38 // The least amount of rounds PROBE_RTT mode should last. 39 // Least amount number of rounds PROBE_RTT should last.
39 const int kProbeRttDurationRounds = 1; 40 const int kProbeRttDurationRounds = 1;
40 // The least amount of milliseconds PROBE_RTT mode should last. 41 // The least amount of milliseconds PROBE_RTT mode should last.
41 const int kProbeRttDurationMs = 200; 42 const int kProbeRttDurationMs = 200;
42 // Gain value for congestion window for assuming that network has no queues. 43 // Gain value for congestion window for assuming that network has no queues.
43 const float kTargetCongestionWindowGain = 1; 44 const float kTargetCongestionWindowGain = 1;
44 // Gain value for congestion window in PROBE_BW mode. In theory it should be 45 // 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 // 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 // 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 // utilization. Value chosen by observations on different tests.
48 const float kCruisingCongestionWindowGain = 1.5f; 49 const float kCruisingCongestionWindowGain = 1.5f;
49 // Expiration time for min_rtt sample, which is set to 10 seconds according to 50 // Pacing gain specific for Recovery mode. Chosen by experiments in simulation
50 // BBR design doc. 51 // tool.
51 const int64_t kMinRttFilterSizeMs = 10000; 52 const float kRecoveryPacingGain = 0.5f;
53 // Congestion window gain specific for Recovery mode. Chosen by experiments in
54 // simulation tool.
55 const float kRecoveryCongestionWindowGain = 1.5f;
56 // Number of rounds over which average rtt is stored for Recovery mode.
57 const size_t kPastRttsFilterSize = 1;
58 // Threshold to assume average rtt has increased for a round. Chosen by
59 // experiments in simulation tool.
60 const float kRttIncreaseThreshold = 3;
61 // Threshold to assume average rtt has decreased for a round. Chosen by
62 // experiments in simulation tool.
63 const float kRttDecreaseThreshold = 1.5f;
52 } // namespace 64 } // namespace
53 65
54 BbrBweSender::BbrBweSender(Clock* clock) 66 BbrBweSender::BbrBweSender(Clock* clock)
55 : BweSender(0), 67 : BweSender(0),
56 clock_(clock), 68 clock_(clock),
57 mode_(STARTUP), 69 mode_(STARTUP),
58 max_bandwidth_filter_(new MaxBandwidthFilter()), 70 max_bandwidth_filter_(new MaxBandwidthFilter()),
59 min_rtt_filter_(new MinRttFilter()), 71 min_rtt_filter_(new MinRttFilter()),
60 congestion_window_(new CongestionWindow()), 72 congestion_window_(new CongestionWindow()),
61 rand_(new Random(time(NULL))), 73 rand_(new Random(time(NULL))),
62 round_count_(0), 74 round_count_(0),
63 last_packet_sent_(0),
64 round_trip_end_(0), 75 round_trip_end_(0),
65 full_bandwidth_reached_(false), 76 full_bandwidth_reached_(false),
66 cycle_start_time_ms_(0), 77 cycle_start_time_ms_(0),
67 cycle_index_(0), 78 cycle_index_(0),
79 bytes_acked_(0),
68 prior_in_flight_(0), 80 prior_in_flight_(0),
69 probe_rtt_start_time_ms_(0), 81 probe_rtt_start_time_ms_(0),
70 minimum_congestion_window_start_time_ms_(), 82 minimum_congestion_window_start_time_ms_(0),
71 minimum_congestion_window_start_round_(0) { 83 minimum_congestion_window_start_round_(0),
84 bytes_sent_(0),
85 last_packet_sent_sequence_number_(0),
86 last_packet_acked_sequence_number_(0),
87 last_packet_ack_time_(0),
88 last_packet_send_time_(0),
89 pacing_rate_bps_(0),
90 last_packet_send_time_during_high_gain_ms_(-1),
91 data_sent_before_high_gain_started_bytes_(-1),
92 data_sent_before_high_gain_ended_bytes_(-1),
93 first_packet_ack_time_during_high_gain_ms_(-1),
94 last_packet_ack_time_during_high_gain_ms_(-1),
95 data_acked_before_high_gain_started_bytes_(-1),
96 data_acked_before_high_gain_ended_bytes_(-1),
97 first_packet_seq_num_during_high_gain_(-1),
98 last_packet_seq_num_during_high_gain_(-1),
99 high_gain_over_(false),
100 packet_stats_(),
101 past_rtts_() {
72 // Initially enter Startup mode. 102 // Initially enter Startup mode.
73 EnterStartup(); 103 EnterStartup();
74 } 104 }
75 105
76 BbrBweSender::~BbrBweSender() {} 106 BbrBweSender::~BbrBweSender() {}
77 107
78 int BbrBweSender::GetFeedbackIntervalMs() const { 108 int BbrBweSender::GetFeedbackIntervalMs() const {
79 return kFeedbackIntervalsMs; 109 return kFeedbackIntervalsMs;
80 } 110 }
81 111
112 void BbrBweSender::CalculatePacingRate() {
113 pacing_rate_bps_ =
114 max_bandwidth_filter_->max_bandwidth_estimate_bps() * pacing_gain_;
115 }
116
117 void BbrBweSender::HandleLoss(uint64_t last_acked_packet,
118 uint64_t recently_acked_packet) {
119 // Logic specific to wrapping sequence numbers.
120 if (!last_acked_packet)
121 return;
122 for (uint16_t i = last_acked_packet + 1;
123 AheadOrAt<uint64_t>(recently_acked_packet - 1, i); i++)
124 congestion_window_->AckReceived(packet_stats_[i].payload_size_bytes);
125 }
126
127 void BbrBweSender::AddToPastRtts(int64_t rtt_sample_ms) {
128 uint64_t last_round = 0;
129 if (!past_rtts_.empty())
130 last_round = past_rtts_.back().round;
131
132 // Try to add the sample to the last round.
133 if (last_round == round_count_ && !past_rtts_.empty()) {
134 past_rtts_.back().sum_of_rtts_ms += rtt_sample_ms;
135 past_rtts_.back().num_samples++;
136 } else {
137 // If the sample belongs to a new round, keep number of rounds in the window
138 // equal to |kPastRttsFilterSize|.
139 if (past_rtts_.size() == kPastRttsFilterSize)
140 past_rtts_.pop_front();
141 past_rtts_.push_back(
142 BbrBweSender::AverageRtt(rtt_sample_ms, 1, round_count_));
143 }
144 }
145
82 void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) { 146 void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) {
147 int64_t now_ms = clock_->TimeInMilliseconds();
148 last_packet_ack_time_ = now_ms;
149 prior_in_flight_ = bytes_acked_;
83 const BbrBweFeedback& fb = static_cast<const BbrBweFeedback&>(feedback); 150 const BbrBweFeedback& fb = static_cast<const BbrBweFeedback&>(feedback);
84 // feedback_vector holds values of acknowledged packets' sequence numbers. 151 // feedback_vector holds values of acknowledged packets' sequence numbers.
85 const std::vector<uint64_t>& feedback_vector = fb.packet_feedback_vector(); 152 const std::vector<uint64_t>& feedback_vector = fb.packet_feedback_vector();
86 // Check if new round started for the connection. Round is the period of time 153 // Go through all the packets acked, update variables/containers accordingly.
87 // from sending packet to its acknowledgement. 154 for (uint64_t f : feedback_vector) {
155 // Completing packet information with a recently received ack.
156 PacketStats* packet = &packet_stats_[f];
157 bytes_acked_ += packet->payload_size_bytes;
158 packet->data_sent_bytes = bytes_sent_;
159 packet->last_sent_packet_send_time_ms = last_packet_send_time_;
160 packet->data_acked_bytes = bytes_acked_;
161 packet->ack_time_ms = now_ms;
162 // Logic specific to applying "bucket" to high gain, in order to have
163 // quicker ramp-up. We check if we started receiving acks for the packets
164 // sent during high gain phase.
165 if (packet->sequence_number == first_packet_seq_num_during_high_gain_) {
166 first_packet_ack_time_during_high_gain_ms_ = now_ms;
167 data_acked_before_high_gain_started_bytes_ = bytes_acked_;
168 }
169 // If the last packet of high gain phase has been acked, high gain phase is
170 // over.
171 if (packet->sequence_number == last_packet_seq_num_during_high_gain_) {
172 last_packet_ack_time_during_high_gain_ms_ = now_ms;
173 data_acked_before_high_gain_ended_bytes_ = bytes_acked_;
174 high_gain_over_ = true;
175 }
176 // Notify pacer that an ack was received, to adjust data inflight.
177 // TODO(gnish): Add implementation for BitrateObserver class, to notify
178 // pacer about incoming acks.
179 congestion_window_->AckReceived(packet->payload_size_bytes);
180 HandleLoss(last_packet_acked_sequence_number_, packet->sequence_number);
181 last_packet_acked_sequence_number_ = packet->sequence_number;
182 // Logic for wrapping sequence numbers. If round started with packet number
183 // x, it can never end on y, if x > y. That could happen when sequence
184 // numbers are wrapped after some point.
185 if (packet->sequence_number == 0)
186 round_trip_end_ = 0;
187 }
188 // Check if new round started for the connection.
88 bool new_round_started = false; 189 bool new_round_started = false;
89 if (!feedback_vector.empty()) { 190 if (!feedback_vector.empty()) {
90 uint64_t last_acked_packet = *feedback_vector.rbegin(); 191 if (last_packet_acked_sequence_number_ > round_trip_end_) {
91 if (last_acked_packet > round_trip_end_) {
92 new_round_started = true; 192 new_round_started = true;
93 round_count_++; 193 round_count_++;
94 round_trip_end_ = last_packet_sent_; 194 round_trip_end_ = last_packet_sent_sequence_number_;
95 } 195 }
96 } 196 }
197 bool min_rtt_expired = false;
198 min_rtt_expired =
199 UpdateBandwidthAndMinRtt(now_ms, feedback_vector, bytes_acked_);
97 if (new_round_started && !full_bandwidth_reached_) { 200 if (new_round_started && !full_bandwidth_reached_) {
98 full_bandwidth_reached_ = max_bandwidth_filter_->FullBandwidthReached( 201 full_bandwidth_reached_ = max_bandwidth_filter_->FullBandwidthReached(
99 kStartupGrowthTarget, kMaxRoundsWithoutGrowth); 202 kStartupGrowthTarget, kMaxRoundsWithoutGrowth);
100 } 203 }
101 int now_ms = clock_->TimeInMilliseconds();
102 switch (mode_) { 204 switch (mode_) {
103 break; 205 break;
104 case STARTUP: 206 case STARTUP:
105 TryExitingStartup(); 207 TryExitingStartup();
106 break; 208 break;
107 case DRAIN: 209 case DRAIN:
108 TryExitingDrain(now_ms); 210 TryExitingDrain(now_ms);
109 break; 211 break;
110 case PROBE_BW: 212 case PROBE_BW:
111 TryUpdatingCyclePhase(now_ms); 213 TryUpdatingCyclePhase(now_ms);
112 break; 214 break;
113 case PROBE_RTT: 215 case PROBE_RTT:
114 TryExitingProbeRtt(now_ms, 0); 216 TryExitingProbeRtt(now_ms, round_count_);
217 break;
218 case RECOVERY:
219 TryExitingRecovery(new_round_started);
115 break; 220 break;
116 } 221 }
117 TryEnteringProbeRtt(now_ms); 222 TryEnteringProbeRtt(now_ms);
118 // TODO(gnish): implement functions updating congestion window and pacing rate 223 TryEnteringRecovery(new_round_started); // Comment this line to disable
119 // controllers. 224 // entering Recovery mode.
225 for (uint64_t f : feedback_vector)
226 AddToPastRtts(packet_stats_[f].ack_time_ms - packet_stats_[f].send_time_ms);
227 CalculatePacingRate();
228 // Make sure we don't get stuck when pacing_rate is 0, because of simulation
229 // tool specifics.
230 if (!pacing_rate_bps_)
231 pacing_rate_bps_ = 100;
232 BWE_TEST_LOGGING_PLOT(1, "SendRate", now_ms, pacing_rate_bps_ / 1000);
233 // TODO(gnish): Add implementation for BitrateObserver class to update pacing
234 // rate for the pacer and the encoder.
120 } 235 }
121 236
122 size_t BbrBweSender::TargetCongestionWindow(float gain) { 237 size_t BbrBweSender::TargetCongestionWindow(float gain) {
123 size_t target_congestion_window = 238 size_t target_congestion_window =
124 congestion_window_->GetTargetCongestionWindow( 239 congestion_window_->GetTargetCongestionWindow(
125 max_bandwidth_filter_->max_bandwidth_estimate_bps(), 240 max_bandwidth_filter_->max_bandwidth_estimate_bps(),
126 min_rtt_filter_->min_rtt_ms(), gain); 241 min_rtt_filter_->min_rtt_ms(), gain);
127 return target_congestion_window; 242 return target_congestion_window;
128 } 243 }
129 244
130 bool BbrBweSender::UpdateBandwidthAndMinRtt() { 245 rtc::Optional<int64_t> BbrBweSender::CalculateBandwidthSample(
131 return false; 246 size_t data_sent_bytes,
247 int64_t send_time_delta_ms,
248 size_t data_acked_bytes,
249 int64_t ack_time_delta_ms) {
250 rtc::Optional<int64_t> bandwidth_sample;
251 if (send_time_delta_ms > 0)
252 *bandwidth_sample = data_sent_bytes * 8000 / send_time_delta_ms;
253 rtc::Optional<int64_t> ack_rate;
254 if (ack_time_delta_ms > 0)
255 *ack_rate = data_acked_bytes * 8000 / ack_time_delta_ms;
256 // If send rate couldn't be calculated automaticaly set |bandwidth_sample| to
257 // ack_rate.
258 if (!bandwidth_sample)
259 bandwidth_sample = ack_rate;
260 if (bandwidth_sample && ack_rate)
261 *bandwidth_sample = std::min(*bandwidth_sample, *ack_rate);
262 return bandwidth_sample;
263 }
264
265 void BbrBweSender::AddSampleForHighGain() {
266 if (!high_gain_over_)
267 return;
268 high_gain_over_ = false;
269 // Calculate data sent/acked and time elapsed only for packets sent during
270 // high gain phase.
271 size_t data_sent_bytes = data_sent_before_high_gain_ended_bytes_ -
272 data_sent_before_high_gain_started_bytes_;
273 int64_t send_time_delta_ms = last_packet_send_time_during_high_gain_ms_ -
274 *first_packet_send_time_during_high_gain_ms_;
275 size_t data_acked_bytes = data_acked_before_high_gain_ended_bytes_ -
276 data_acked_before_high_gain_started_bytes_;
277 int64_t ack_time_delta_ms = last_packet_ack_time_during_high_gain_ms_ -
278 first_packet_ack_time_during_high_gain_ms_;
279 rtc::Optional<int64_t> bandwidth_sample = CalculateBandwidthSample(
280 data_sent_bytes, send_time_delta_ms, data_acked_bytes, ack_time_delta_ms);
281 if (bandwidth_sample)
282 max_bandwidth_filter_->AddBandwidthSample(*bandwidth_sample, round_count_);
283 first_packet_send_time_during_high_gain_ms_.reset();
284 }
285
286 bool BbrBweSender::UpdateBandwidthAndMinRtt(
287 int64_t now_ms,
288 const std::vector<uint64_t>& feedback_vector,
289 int64_t bytes_acked) {
290 rtc::Optional<int64_t> min_rtt_sample_ms;
291 for (uint64_t f : feedback_vector) {
292 PacketStats packet = packet_stats_[f];
293 size_t data_sent_bytes =
294 packet.data_sent_bytes - packet.data_sent_before_last_sent_packet_bytes;
295 int64_t send_time_delta_ms =
296 packet.last_sent_packet_send_time_ms - packet.send_time_ms;
297 size_t data_acked_bytes = packet.data_acked_bytes -
298 packet.data_acked_before_last_acked_packet_bytes;
299 int64_t ack_time_delta_ms =
300 packet.ack_time_ms - packet.last_acked_packet_ack_time_ms;
301 rtc::Optional<int64_t> bandwidth_sample =
302 CalculateBandwidthSample(data_sent_bytes, send_time_delta_ms,
303 data_acked_bytes, ack_time_delta_ms);
304 if (bandwidth_sample)
305 max_bandwidth_filter_->AddBandwidthSample(*bandwidth_sample,
306 round_count_);
307 AddSampleForHighGain(); // Comment to disable bucket for high gain.
308 if (!min_rtt_sample_ms)
309 *min_rtt_sample_ms = packet.ack_time_ms - packet.send_time_ms;
310 else
311 *min_rtt_sample_ms = std::min(*min_rtt_sample_ms,
312 packet.ack_time_ms - packet.send_time_ms);
313 BWE_TEST_LOGGING_PLOT(1, "MinRtt", now_ms,
314 packet.ack_time_ms - packet.send_time_ms);
315 }
316 if (!min_rtt_sample_ms)
317 return false;
318 bool min_rtt_expired = min_rtt_filter_->MinRttExpired(now_ms);
319 min_rtt_filter_->AddRttSample(*min_rtt_sample_ms, now_ms);
philipel 2017/08/08 11:54:54 Don't you want to reverse line 318 and 319?
gnish1 2017/08/08 13:19:56 Done.
320 return min_rtt_expired;
132 } 321 }
133 322
134 void BbrBweSender::EnterStartup() { 323 void BbrBweSender::EnterStartup() {
135 mode_ = STARTUP; 324 mode_ = STARTUP;
136 pacing_gain_ = kHighGain; 325 pacing_gain_ = kHighGain;
137 congestion_window_gain_ = kHighGain; 326 congestion_window_gain_ = kHighGain;
138 } 327 }
139 328
140 void BbrBweSender::TryExitingStartup() { 329 void BbrBweSender::TryExitingStartup() {
141 if (full_bandwidth_reached_) { 330 if (full_bandwidth_reached_) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 advance_cycle_phase = true; 372 advance_cycle_phase = true;
184 if (advance_cycle_phase) { 373 if (advance_cycle_phase) {
185 cycle_index_++; 374 cycle_index_++;
186 cycle_index_ %= kGainCycleLength; 375 cycle_index_ %= kGainCycleLength;
187 pacing_gain_ = kPacingGain[cycle_index_]; 376 pacing_gain_ = kPacingGain[cycle_index_];
188 cycle_start_time_ms_ = now_ms; 377 cycle_start_time_ms_ = now_ms;
189 } 378 }
190 } 379 }
191 380
192 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) { 381 void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {
193 if (min_rtt_filter_->min_rtt_expired(now_ms, kMinRttFilterSizeMs) && 382 if (min_rtt_filter_->MinRttExpired(now_ms) && mode_ != PROBE_RTT) {
194 mode_ != PROBE_RTT) {
195 mode_ = PROBE_RTT; 383 mode_ = PROBE_RTT;
196 pacing_gain_ = 1; 384 pacing_gain_ = 1;
197 probe_rtt_start_time_ms_ = now_ms; 385 probe_rtt_start_time_ms_ = now_ms;
198 minimum_congestion_window_start_time_ms_.reset(); 386 minimum_congestion_window_start_time_ms_.reset();
199 } 387 }
200 } 388 }
201 389
202 // minimum_congestion_window_start_time_'s value is set to the first moment when 390 // |minimum_congestion_window_start_time_|'s value is set to the first moment
203 // data inflight was less then kMinimumCongestionWindowBytes, we should make 391 // when data inflight was less then
204 // sure that BBR has been in PROBE_RTT mode for at least one round or 200ms. 392 // |CongestionWindow::kMinimumCongestionWindowBytes|, we should make sure that
393 // 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) { 394 void BbrBweSender::TryExitingProbeRtt(int64_t now_ms, int64_t round) {
206 if (!minimum_congestion_window_start_time_ms_) { 395 if (!minimum_congestion_window_start_time_ms_) {
207 if (congestion_window_->data_inflight() <= 396 if (congestion_window_->data_inflight() <=
208 CongestionWindow::kMinimumCongestionWindowBytes) { 397 CongestionWindow::kMinimumCongestionWindowBytes) {
209 *minimum_congestion_window_start_time_ms_ = now_ms; 398 *minimum_congestion_window_start_time_ms_ = now_ms;
210 minimum_congestion_window_start_round_ = round; 399 minimum_congestion_window_start_round_ = round;
211 } 400 }
212 } else { 401 } else {
213 if (now_ms - *minimum_congestion_window_start_time_ms_ >= 402 if (now_ms - *minimum_congestion_window_start_time_ms_ >=
214 kProbeRttDurationMs && 403 kProbeRttDurationMs &&
215 round - minimum_congestion_window_start_round_ >= 404 round - minimum_congestion_window_start_round_ >=
216 kProbeRttDurationRounds) 405 kProbeRttDurationRounds)
217 EnterProbeBw(now_ms); 406 EnterProbeBw(now_ms);
218 } 407 }
219 } 408 }
220 409
410 void BbrBweSender::TryEnteringRecovery(bool new_round_started) {
411 // If we are already in Recovery don't try to enter.
412 if (mode_ == RECOVERY || !new_round_started || !full_bandwidth_reached_)
413 return;
414 uint64_t increased_rtt_round_counter = 0;
415 // If average rtt for past |kPastRttsFilterSize| rounds has been more than
416 // some multiplier of min_rtt_ms enter Recovery.
417 for (BbrBweSender::AverageRtt i : past_rtts_) {
418 if (i.sum_of_rtts_ms / (int64_t)i.num_samples >=
419 *min_rtt_filter_->min_rtt_ms() * kRttIncreaseThreshold)
420 increased_rtt_round_counter++;
421 }
422 if (increased_rtt_round_counter < kPastRttsFilterSize)
423 return;
424 mode_ = RECOVERY;
425 pacing_gain_ = kRecoveryPacingGain;
426 congestion_window_gain_ = kRecoveryCongestionWindowGain;
427 }
428
429 void BbrBweSender::TryExitingRecovery(bool new_round_started) {
430 if (mode_ != RECOVERY || !new_round_started || !full_bandwidth_reached_)
431 return;
432 // If average rtt for the past round has decreased sufficiently exit Recovery.
433 if (!past_rtts_.empty()) {
434 BbrBweSender::AverageRtt last_round_sample = past_rtts_.back();
435 if (last_round_sample.sum_of_rtts_ms / last_round_sample.num_samples <=
436 *min_rtt_filter_->min_rtt_ms() * kRttDecreaseThreshold) {
437 EnterProbeBw(clock_->TimeInMilliseconds());
438 }
439 }
440 }
441
221 int64_t BbrBweSender::TimeUntilNextProcess() { 442 int64_t BbrBweSender::TimeUntilNextProcess() {
222 return 100; 443 return 50;
223 } 444 }
224 445
225 void BbrBweSender::OnPacketsSent(const Packets& packets) { 446 void BbrBweSender::OnPacketsSent(const Packets& packets) {
226 last_packet_sent_ = 447 for (Packet* packet : packets) {
227 static_cast<const MediaPacket*>(packets.back())->sequence_number(); 448 if (packet->GetPacketType() == Packet::kMedia) {
449 MediaPacket* media_packet = static_cast<MediaPacket*>(packet);
450 bytes_sent_ += media_packet->payload_size();
451 PacketStats packet_stats = PacketStats(
452 media_packet->sequence_number(), 0,
453 media_packet->sender_timestamp_ms(), 0, last_packet_ack_time_,
454 media_packet->payload_size(), 0, bytes_sent_, 0, bytes_acked_);
455 packet_stats_[media_packet->sequence_number()] = packet_stats;
456 last_packet_send_time_ = media_packet->sender_timestamp_ms();
457 last_packet_sent_sequence_number_ = media_packet->sequence_number();
458 // If this is the first packet sent for high gain phase, save data for it.
459 if (!first_packet_send_time_during_high_gain_ms_ && pacing_gain_ > 1) {
460 *first_packet_send_time_during_high_gain_ms_ = last_packet_send_time_;
461 data_sent_before_high_gain_started_bytes_ = bytes_sent_;
462 first_packet_seq_num_during_high_gain_ =
463 media_packet->sequence_number();
464 }
465 // This condition ensures that |last_packet_seq_num_during_high_gain_|
466 // will contain a sequence number of the last packet sent during high gain
467 // phase.
468 if (pacing_gain_ > 1) {
469 last_packet_send_time_during_high_gain_ms_ = last_packet_send_time_;
470 data_sent_before_high_gain_ended_bytes_ = bytes_sent_;
471 last_packet_seq_num_during_high_gain_ = media_packet->sequence_number();
472 }
473 congestion_window_->PacketSent(media_packet->payload_size());
474 }
475 }
228 } 476 }
229 477
230 void BbrBweSender::Process() {} 478 void BbrBweSender::Process() {}
231 479
232 BbrBweReceiver::BbrBweReceiver(int flow_id) 480 BbrBweReceiver::BbrBweReceiver(int flow_id)
233 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {} 481 : BweReceiver(flow_id, kReceivingRateTimeWindowMs), clock_(0) {}
234 482
235 BbrBweReceiver::~BbrBweReceiver() {} 483 BbrBweReceiver::~BbrBweReceiver() {}
236 484
237 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms, 485 void BbrBweReceiver::ReceivePacket(int64_t arrival_time_ms,
238 const MediaPacket& media_packet) {} 486 const MediaPacket& media_packet) {}
239 487
240 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) { 488 FeedbackPacket* BbrBweReceiver::GetFeedback(int64_t now_ms) {
241 return nullptr; 489 return nullptr;
242 } 490 }
243 } // namespace bwe 491 } // namespace bwe
244 } // namespace testing 492 } // namespace testing
245 } // namespace webrtc 493 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698