OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/congestion_control/inter_arrival_sender.h" | 5 #include "net/quic/congestion_control/inter_arrival_sender.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
| 9 using std::max; |
| 10 using std::min; |
| 11 |
7 namespace net { | 12 namespace net { |
8 | 13 |
9 namespace { | 14 namespace { |
10 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s | 15 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s |
11 const float kPacketLossBitrateReduction = 0.7f; | 16 const float kPacketLossBitrateReduction = 0.7f; |
12 const float kUncertainSafetyMargin = 0.7f; | 17 const float kUncertainSafetyMargin = 0.7f; |
13 const float kMaxBitrateReduction = 0.9f; | 18 const float kMaxBitrateReduction = 0.9f; |
14 const float kMinBitrateReduction = 0.05f; | 19 const float kMinBitrateReduction = 0.05f; |
15 const uint64 kMinBitrateKbit = 10; | 20 const uint64 kMinBitrateKbit = 10; |
16 const int kInitialRttMs = 60; // At a typical RTT 60 ms. | 21 const int kInitialRttMs = 60; // At a typical RTT 60 ms. |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 case kChannelEstimateUnknown: | 190 case kChannelEstimateUnknown: |
186 channel_estimate = available_channel_estimate; | 191 channel_estimate = available_channel_estimate; |
187 break; | 192 break; |
188 case kChannelEstimateUncertain: | 193 case kChannelEstimateUncertain: |
189 channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin); | 194 channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin); |
190 break; | 195 break; |
191 case kChannelEstimateGood: | 196 case kChannelEstimateGood: |
192 // Do nothing. | 197 // Do nothing. |
193 break; | 198 break; |
194 } | 199 } |
195 new_rate = std::max(new_rate, | 200 new_rate = max(new_rate, |
196 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); | 201 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); |
197 | 202 |
198 bitrate_ramp_up_->Reset(new_rate, available_channel_estimate, | 203 bitrate_ramp_up_->Reset(new_rate, available_channel_estimate, |
199 channel_estimate); | 204 channel_estimate); |
200 | 205 |
201 current_bandwidth_ = new_rate; | 206 current_bandwidth_ = new_rate; |
202 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, new_rate); | 207 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, new_rate); |
203 DVLOG(1) << "Probe result; new rate:" | 208 DVLOG(1) << "Probe result; new rate:" |
204 << new_rate.ToKBitsPerSecond() << " Kbits/s " | 209 << new_rate.ToKBitsPerSecond() << " Kbits/s " |
205 << " available estimate:" | 210 << " available estimate:" |
206 << available_channel_estimate.ToKBitsPerSecond() << " Kbits/s " | 211 << available_channel_estimate.ToKBitsPerSecond() << " Kbits/s " |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 | 405 |
401 QuicBandwidth draining_rate = back_down_bandwidth_.Scale(fraction_of_rate); | 406 QuicBandwidth draining_rate = back_down_bandwidth_.Scale(fraction_of_rate); |
402 QuicBandwidth max_estimated_draining_rate = | 407 QuicBandwidth max_estimated_draining_rate = |
403 back_down_bandwidth_.Subtract(current_bandwidth_); | 408 back_down_bandwidth_.Subtract(current_bandwidth_); |
404 if (draining_rate > max_estimated_draining_rate) { | 409 if (draining_rate > max_estimated_draining_rate) { |
405 // We drained faster than our old send rate, go back to our old rate. | 410 // We drained faster than our old send rate, go back to our old rate. |
406 new_estimate = back_down_bandwidth_; | 411 new_estimate = back_down_bandwidth_; |
407 } else { | 412 } else { |
408 // Use our drain rate and our kMinBitrateReduction to go to our | 413 // Use our drain rate and our kMinBitrateReduction to go to our |
409 // new estimate. | 414 // new estimate. |
410 new_estimate = std::max(current_bandwidth_, | 415 new_estimate = max(current_bandwidth_, |
411 current_bandwidth_.Add(draining_rate).Scale( | 416 current_bandwidth_.Add(draining_rate).Scale( |
412 1.0f - kMinBitrateReduction)); | 417 1.0f - kMinBitrateReduction)); |
413 DVLOG(1) << "Draining calculation; current rate:" | 418 DVLOG(1) << "Draining calculation; current rate:" |
414 << current_bandwidth_.ToKBitsPerSecond() << " Kbits/s " | 419 << current_bandwidth_.ToKBitsPerSecond() << " Kbits/s " |
415 << "draining rate:" | 420 << "draining rate:" |
416 << draining_rate.ToKBitsPerSecond() << " Kbits/s " | 421 << draining_rate.ToKBitsPerSecond() << " Kbits/s " |
417 << "new estimate:" | 422 << "new estimate:" |
418 << new_estimate.ToKBitsPerSecond() << " Kbits/s " | 423 << new_estimate.ToKBitsPerSecond() << " Kbits/s " |
419 << " buffer reduction:" | 424 << " buffer reduction:" |
420 << buffer_reduction.ToMicroseconds() << " us " | 425 << buffer_reduction.ToMicroseconds() << " us " |
421 << " elapsed time:" | 426 << " elapsed time:" |
422 << elapsed_time.ToMicroseconds() << " us "; | 427 << elapsed_time.ToMicroseconds() << " us "; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 463 |
459 // To drain all build up buffer within one RTT we need to reduce the | 464 // To drain all build up buffer within one RTT we need to reduce the |
460 // bitrate with the following. | 465 // bitrate with the following. |
461 // TODO(pwestin): this is a crude first implementation. | 466 // TODO(pwestin): this is a crude first implementation. |
462 int64 draining_rate_per_rtt = (estimated_byte_buildup * | 467 int64 draining_rate_per_rtt = (estimated_byte_buildup * |
463 kNumMicrosPerSecond) / SmoothedRtt().ToMicroseconds(); | 468 kNumMicrosPerSecond) / SmoothedRtt().ToMicroseconds(); |
464 | 469 |
465 float decrease_factor = | 470 float decrease_factor = |
466 draining_rate_per_rtt / current_bandwidth_.ToBytesPerSecond(); | 471 draining_rate_per_rtt / current_bandwidth_.ToBytesPerSecond(); |
467 | 472 |
468 decrease_factor = std::max(decrease_factor, kMinBitrateReduction); | 473 decrease_factor = max(decrease_factor, kMinBitrateReduction); |
469 decrease_factor = std::min(decrease_factor, kMaxBitrateReduction); | 474 decrease_factor = min(decrease_factor, kMaxBitrateReduction); |
470 back_down_congestion_delay_ = estimated_congestion_delay; | 475 back_down_congestion_delay_ = estimated_congestion_delay; |
471 QuicBandwidth new_target_bitrate = | 476 QuicBandwidth new_target_bitrate = |
472 current_bandwidth_.Scale(1.0f - decrease_factor); | 477 current_bandwidth_.Scale(1.0f - decrease_factor); |
473 | 478 |
474 // While in delay sensing mode send at least one packet per RTT. | 479 // While in delay sensing mode send at least one packet per RTT. |
475 QuicBandwidth min_delay_bitrate = | 480 QuicBandwidth min_delay_bitrate = |
476 QuicBandwidth::FromBytesAndTimeDelta(max_segment_size_, SmoothedRtt()); | 481 QuicBandwidth::FromBytesAndTimeDelta(max_segment_size_, SmoothedRtt()); |
477 new_target_bitrate = std::max(new_target_bitrate, min_delay_bitrate); | 482 new_target_bitrate = max(new_target_bitrate, min_delay_bitrate); |
478 | 483 |
479 ResetCurrentBandwidth(feedback_receive_time, new_target_bitrate); | 484 ResetCurrentBandwidth(feedback_receive_time, new_target_bitrate); |
480 | 485 |
481 DVLOG(1) << "New bandwidth estimate after delay event:" | 486 DVLOG(1) << "New bandwidth estimate after delay event:" |
482 << current_bandwidth_.ToKBitsPerSecond() | 487 << current_bandwidth_.ToKBitsPerSecond() |
483 << " Kbits/s min delay bitrate:" | 488 << " Kbits/s min delay bitrate:" |
484 << min_delay_bitrate.ToKBitsPerSecond() | 489 << min_delay_bitrate.ToKBitsPerSecond() |
485 << " Kbits/s RTT:" | 490 << " Kbits/s RTT:" |
486 << SmoothedRtt().ToMicroseconds() | 491 << SmoothedRtt().ToMicroseconds() |
487 << " us"; | 492 << " us"; |
488 } | 493 } |
489 | 494 |
490 void InterArrivalSender::EstimateBandwidthAfterLossEvent( | 495 void InterArrivalSender::EstimateBandwidthAfterLossEvent( |
491 QuicTime feedback_receive_time) { | 496 QuicTime feedback_receive_time) { |
492 ResetCurrentBandwidth(feedback_receive_time, | 497 ResetCurrentBandwidth(feedback_receive_time, |
493 current_bandwidth_.Scale(kPacketLossBitrateReduction)); | 498 current_bandwidth_.Scale(kPacketLossBitrateReduction)); |
494 DVLOG(1) << "New bandwidth estimate after loss event:" | 499 DVLOG(1) << "New bandwidth estimate after loss event:" |
495 << current_bandwidth_.ToKBitsPerSecond() | 500 << current_bandwidth_.ToKBitsPerSecond() |
496 << " Kbits/s"; | 501 << " Kbits/s"; |
497 } | 502 } |
498 | 503 |
499 void InterArrivalSender::ResetCurrentBandwidth(QuicTime feedback_receive_time, | 504 void InterArrivalSender::ResetCurrentBandwidth(QuicTime feedback_receive_time, |
500 QuicBandwidth new_rate) { | 505 QuicBandwidth new_rate) { |
501 new_rate = std::max(new_rate, | 506 new_rate = max(new_rate, |
502 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); | 507 QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit)); |
503 QuicBandwidth channel_estimate = QuicBandwidth::Zero(); | 508 QuicBandwidth channel_estimate = QuicBandwidth::Zero(); |
504 ChannelEstimateState channel_estimator_state = | 509 ChannelEstimateState channel_estimator_state = |
505 channel_estimator_->GetChannelEstimate(&channel_estimate); | 510 channel_estimator_->GetChannelEstimate(&channel_estimate); |
506 | 511 |
507 switch (channel_estimator_state) { | 512 switch (channel_estimator_state) { |
508 case kChannelEstimateUnknown: | 513 case kChannelEstimateUnknown: |
509 channel_estimate = current_bandwidth_; | 514 channel_estimate = current_bandwidth_; |
510 break; | 515 break; |
511 case kChannelEstimateUncertain: | 516 case kChannelEstimateUncertain: |
512 channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin); | 517 channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin); |
513 break; | 518 break; |
514 case kChannelEstimateGood: | 519 case kChannelEstimateGood: |
515 // Do nothing. | 520 // Do nothing. |
516 break; | 521 break; |
517 } | 522 } |
518 back_down_time_ = feedback_receive_time; | 523 back_down_time_ = feedback_receive_time; |
519 back_down_bandwidth_ = current_bandwidth_; | 524 back_down_bandwidth_ = current_bandwidth_; |
520 bitrate_ramp_up_->Reset(new_rate, current_bandwidth_, channel_estimate); | 525 bitrate_ramp_up_->Reset(new_rate, current_bandwidth_, channel_estimate); |
521 if (new_rate != current_bandwidth_) { | 526 if (new_rate != current_bandwidth_) { |
522 current_bandwidth_ = new_rate; | 527 current_bandwidth_ = new_rate; |
523 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, | 528 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, |
524 current_bandwidth_); | 529 current_bandwidth_); |
525 state_machine_->DecreaseBitrateDecision(); | 530 state_machine_->DecreaseBitrateDecision(); |
526 } | 531 } |
527 } | 532 } |
528 | 533 |
529 } // namespace net | 534 } // namespace net |
OLD | NEW |