| 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 namespace net { |
| 8 |
| 7 namespace { | 9 namespace { |
| 8 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s | 10 const int64 kProbeBitrateKBytesPerSecond = 1200; // 9.6 Mbit/s |
| 9 const float kPacketLossBitrateReduction = 0.7f; | 11 const float kPacketLossBitrateReduction = 0.7f; |
| 10 const float kUncertainSafetyMargin = 0.7f; | 12 const float kUncertainSafetyMargin = 0.7f; |
| 11 const float kMaxBitrateReduction = 0.9f; | 13 const float kMaxBitrateReduction = 0.9f; |
| 12 const float kMinBitrateReduction = 0.05f; | 14 const float kMinBitrateReduction = 0.05f; |
| 13 const uint64 kMinBitrateKbit = 10; | 15 const uint64 kMinBitrateKbit = 10; |
| 14 const int kInitialRttMs = 60; // At a typical RTT 60 ms. | 16 const int kInitialRttMs = 60; // At a typical RTT 60 ms. |
| 15 } | |
| 16 | 17 |
| 17 namespace net { | 18 static const int kBitrateSmoothingPeriodMs = 1000; |
| 19 static const int kMinBitrateSmoothingPeriodMs = 500; |
| 20 |
| 21 } // namespace |
| 18 | 22 |
| 19 InterArrivalSender::InterArrivalSender(const QuicClock* clock) | 23 InterArrivalSender::InterArrivalSender(const QuicClock* clock) |
| 20 : probing_(true), | 24 : probing_(true), |
| 21 current_bandwidth_(QuicBandwidth::Zero()), | 25 current_bandwidth_(QuicBandwidth::Zero()), |
| 22 smoothed_rtt_(QuicTime::Delta::Zero()), | 26 smoothed_rtt_(QuicTime::Delta::Zero()), |
| 23 channel_estimator_(new ChannelEstimator()), | 27 channel_estimator_(new ChannelEstimator()), |
| 24 bitrate_ramp_up_(new InterArrivalBitrateRampUp(clock)), | 28 bitrate_ramp_up_(new InterArrivalBitrateRampUp(clock)), |
| 25 overuse_detector_(new InterArrivalOveruseDetector()), | 29 overuse_detector_(new InterArrivalOveruseDetector()), |
| 26 probe_(new InterArrivalProbe()), | 30 probe_(new InterArrivalProbe()), |
| 27 state_machine_(new InterArrivalStateMachine(clock)), | 31 state_machine_(new InterArrivalStateMachine(clock)), |
| 28 paced_sender_(new PacedSender(QuicBandwidth::FromKBytesPerSecond( | 32 paced_sender_(new PacedSender(QuicBandwidth::FromKBytesPerSecond( |
| 29 kProbeBitrateKBytesPerSecond))), | 33 kProbeBitrateKBytesPerSecond))), |
| 30 accumulated_number_of_lost_packets_(0), | 34 accumulated_number_of_lost_packets_(0), |
| 31 bandwidth_usage_state_(kBandwidthSteady), | 35 bandwidth_usage_state_(kBandwidthSteady), |
| 32 back_down_time_(QuicTime::Zero()), | 36 back_down_time_(QuicTime::Zero()), |
| 33 back_down_bandwidth_(QuicBandwidth::Zero()), | 37 back_down_bandwidth_(QuicBandwidth::Zero()), |
| 34 back_down_congestion_delay_(QuicTime::Delta::Zero()) { | 38 back_down_congestion_delay_(QuicTime::Delta::Zero()) { |
| 35 } | 39 } |
| 36 | 40 |
| 37 InterArrivalSender::~InterArrivalSender() { | 41 InterArrivalSender::~InterArrivalSender() { |
| 38 } | 42 } |
| 39 | 43 |
| 44 // TODO(pwestin): this is really inefficient (4% CPU on the GFE loadtest). |
| 45 // static |
| 46 QuicBandwidth InterArrivalSender::CalculateSentBandwidth( |
| 47 const SendAlgorithmInterface::SentPacketsMap& sent_packets_map, |
| 48 QuicTime feedback_receive_time) { |
| 49 const QuicTime::Delta kBitrateSmoothingPeriod = |
| 50 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs); |
| 51 const QuicTime::Delta kMinBitrateSmoothingPeriod = |
| 52 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs); |
| 53 |
| 54 QuicByteCount sum_bytes_sent = 0; |
| 55 |
| 56 // Sum packet from new until they are kBitrateSmoothingPeriod old. |
| 57 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit = |
| 58 sent_packets_map.rbegin(); |
| 59 |
| 60 QuicTime::Delta max_diff = QuicTime::Delta::Zero(); |
| 61 for (; history_rit != sent_packets_map.rend(); ++history_rit) { |
| 62 QuicTime::Delta diff = |
| 63 feedback_receive_time.Subtract(history_rit->second->SendTimestamp()); |
| 64 if (diff > kBitrateSmoothingPeriod) { |
| 65 break; |
| 66 } |
| 67 sum_bytes_sent += history_rit->second->BytesSent(); |
| 68 max_diff = diff; |
| 69 } |
| 70 if (max_diff < kMinBitrateSmoothingPeriod) { |
| 71 // No estimate. |
| 72 return QuicBandwidth::Zero(); |
| 73 } |
| 74 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff); |
| 75 } |
| 76 |
| 40 void InterArrivalSender::OnIncomingQuicCongestionFeedbackFrame( | 77 void InterArrivalSender::OnIncomingQuicCongestionFeedbackFrame( |
| 41 const QuicCongestionFeedbackFrame& feedback, | 78 const QuicCongestionFeedbackFrame& feedback, |
| 42 QuicTime feedback_receive_time, | 79 QuicTime feedback_receive_time, |
| 43 QuicBandwidth sent_bandwidth, | |
| 44 const SentPacketsMap& sent_packets) { | 80 const SentPacketsMap& sent_packets) { |
| 45 DCHECK(feedback.type == kInterArrival); | 81 DCHECK(feedback.type == kInterArrival); |
| 46 | 82 |
| 47 if (feedback.type != kInterArrival) { | 83 if (feedback.type != kInterArrival) { |
| 48 return; | 84 return; |
| 49 } | 85 } |
| 86 |
| 87 QuicBandwidth sent_bandwidth = CalculateSentBandwidth(sent_packets, |
| 88 feedback_receive_time); |
| 89 |
| 50 TimeMap::const_iterator received_it; | 90 TimeMap::const_iterator received_it; |
| 51 for (received_it = feedback.inter_arrival.received_packet_times.begin(); | 91 for (received_it = feedback.inter_arrival.received_packet_times.begin(); |
| 52 received_it != feedback.inter_arrival.received_packet_times.end(); | 92 received_it != feedback.inter_arrival.received_packet_times.end(); |
| 53 ++received_it) { | 93 ++received_it) { |
| 54 QuicPacketSequenceNumber sequence_number = received_it->first; | 94 QuicPacketSequenceNumber sequence_number = received_it->first; |
| 55 | 95 |
| 56 SentPacketsMap::const_iterator sent_it = sent_packets.find(sequence_number); | 96 SentPacketsMap::const_iterator sent_it = sent_packets.find(sequence_number); |
| 57 if (sent_it == sent_packets.end()) { | 97 if (sent_it == sent_packets.end()) { |
| 58 // Too old data; ignore and move forward. | 98 // Too old data; ignore and move forward. |
| 59 DLOG(INFO) << "Too old feedback move forward, sequence_number:" | 99 DLOG(INFO) << "Too old feedback move forward, sequence_number:" |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 bitrate_ramp_up_->Reset(new_rate, current_bandwidth_, channel_estimate); | 480 bitrate_ramp_up_->Reset(new_rate, current_bandwidth_, channel_estimate); |
| 441 if (new_rate != current_bandwidth_) { | 481 if (new_rate != current_bandwidth_) { |
| 442 current_bandwidth_ = new_rate; | 482 current_bandwidth_ = new_rate; |
| 443 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, | 483 paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, |
| 444 current_bandwidth_); | 484 current_bandwidth_); |
| 445 state_machine_->DecreaseBitrateDecision(); | 485 state_machine_->DecreaseBitrateDecision(); |
| 446 } | 486 } |
| 447 } | 487 } |
| 448 | 488 |
| 449 } // namespace net | 489 } // namespace net |
| OLD | NEW |