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