• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "net/quic/congestion_control/inter_arrival_sender.h"
6 
7 namespace net {
8 
9 namespace {
10 const int64 kProbeBitrateKBytesPerSecond = 1200;  // 9.6 Mbit/s
11 const float kPacketLossBitrateReduction = 0.7f;
12 const float kUncertainSafetyMargin = 0.7f;
13 const float kMaxBitrateReduction = 0.9f;
14 const float kMinBitrateReduction = 0.05f;
15 const uint64 kMinBitrateKbit = 10;
16 const int kInitialRttMs = 60;  // At a typical RTT 60 ms.
17 const float kAlpha = 0.125f;
18 const float kOneMinusAlpha = 1 - kAlpha;
19 
20 static const int kBitrateSmoothingPeriodMs = 1000;
21 static const int kMinBitrateSmoothingPeriodMs = 500;
22 
23 }  // namespace
24 
InterArrivalSender(const QuicClock * clock)25 InterArrivalSender::InterArrivalSender(const QuicClock* clock)
26     : probing_(true),
27       max_segment_size_(kDefaultMaxPacketSize),
28       current_bandwidth_(QuicBandwidth::Zero()),
29       smoothed_rtt_(QuicTime::Delta::Zero()),
30       channel_estimator_(new ChannelEstimator()),
31       bitrate_ramp_up_(new InterArrivalBitrateRampUp(clock)),
32       overuse_detector_(new InterArrivalOveruseDetector()),
33       probe_(new InterArrivalProbe(max_segment_size_)),
34       state_machine_(new InterArrivalStateMachine(clock)),
35       paced_sender_(new PacedSender(QuicBandwidth::FromKBytesPerSecond(
36           kProbeBitrateKBytesPerSecond), max_segment_size_)),
37       accumulated_number_of_lost_packets_(0),
38       bandwidth_usage_state_(kBandwidthSteady),
39       back_down_time_(QuicTime::Zero()),
40       back_down_bandwidth_(QuicBandwidth::Zero()),
41       back_down_congestion_delay_(QuicTime::Delta::Zero()) {
42 }
43 
~InterArrivalSender()44 InterArrivalSender::~InterArrivalSender() {
45 }
46 
SetFromConfig(const QuicConfig & config,bool is_server)47 void InterArrivalSender::SetFromConfig(const QuicConfig& config,
48                                        bool is_server) {
49 }
50 
SetMaxPacketSize(QuicByteCount max_packet_size)51 void InterArrivalSender::SetMaxPacketSize(QuicByteCount max_packet_size) {
52   max_segment_size_ = max_packet_size;
53   paced_sender_->set_max_segment_size(max_segment_size_);
54   probe_->set_max_segment_size(max_segment_size_);
55 }
56 
57 // TODO(pwestin): this is really inefficient (4% CPU on the GFE loadtest).
58 // static
CalculateSentBandwidth(const SendAlgorithmInterface::SentPacketsMap & sent_packets_map,QuicTime feedback_receive_time)59 QuicBandwidth InterArrivalSender::CalculateSentBandwidth(
60     const SendAlgorithmInterface::SentPacketsMap& sent_packets_map,
61     QuicTime feedback_receive_time) {
62   const QuicTime::Delta kBitrateSmoothingPeriod =
63       QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs);
64   const QuicTime::Delta kMinBitrateSmoothingPeriod =
65       QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs);
66 
67   QuicByteCount sum_bytes_sent = 0;
68 
69   // Sum packet from new until they are kBitrateSmoothingPeriod old.
70   SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit =
71       sent_packets_map.rbegin();
72 
73   QuicTime::Delta max_diff = QuicTime::Delta::Zero();
74   for (; history_rit != sent_packets_map.rend(); ++history_rit) {
75     QuicTime::Delta diff =
76         feedback_receive_time.Subtract(history_rit->second->send_timestamp());
77     if (diff > kBitrateSmoothingPeriod) {
78       break;
79     }
80     sum_bytes_sent += history_rit->second->bytes_sent();
81     max_diff = diff;
82   }
83   if (max_diff < kMinBitrateSmoothingPeriod) {
84     // No estimate.
85     return QuicBandwidth::Zero();
86   }
87   return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff);
88 }
89 
OnIncomingQuicCongestionFeedbackFrame(const QuicCongestionFeedbackFrame & feedback,QuicTime feedback_receive_time,const SentPacketsMap & sent_packets)90 void InterArrivalSender::OnIncomingQuicCongestionFeedbackFrame(
91     const QuicCongestionFeedbackFrame& feedback,
92     QuicTime feedback_receive_time,
93     const SentPacketsMap& sent_packets) {
94   DCHECK(feedback.type == kInterArrival);
95 
96   if (feedback.type != kInterArrival) {
97     return;
98   }
99 
100   QuicBandwidth sent_bandwidth = CalculateSentBandwidth(sent_packets,
101                                                         feedback_receive_time);
102 
103   TimeMap::const_iterator received_it;
104   for (received_it = feedback.inter_arrival.received_packet_times.begin();
105       received_it != feedback.inter_arrival.received_packet_times.end();
106       ++received_it) {
107     QuicPacketSequenceNumber sequence_number = received_it->first;
108 
109     SentPacketsMap::const_iterator sent_it = sent_packets.find(sequence_number);
110     if (sent_it == sent_packets.end()) {
111       // Too old data; ignore and move forward.
112       DVLOG(1) << "Too old feedback move forward, sequence_number:"
113                  << sequence_number;
114       continue;
115     }
116     QuicTime time_received = received_it->second;
117     QuicTime time_sent = sent_it->second->send_timestamp();
118     QuicByteCount bytes_sent = sent_it->second->bytes_sent();
119 
120     channel_estimator_->OnAcknowledgedPacket(
121         sequence_number, bytes_sent, time_sent, time_received);
122     if (probing_) {
123       probe_->OnIncomingFeedback(
124           sequence_number, bytes_sent, time_sent, time_received);
125     } else {
126       bool last_of_send_time = false;
127       SentPacketsMap::const_iterator next_sent_it = ++sent_it;
128       if (next_sent_it == sent_packets.end()) {
129         // No more sent packets; hence this must be the last.
130         last_of_send_time = true;
131       } else {
132         if (time_sent != next_sent_it->second->send_timestamp()) {
133           // Next sent packet have a different send time.
134           last_of_send_time = true;
135         }
136       }
137       overuse_detector_->OnAcknowledgedPacket(
138           sequence_number, time_sent, last_of_send_time, time_received);
139     }
140   }
141   if (probing_) {
142     probing_ = ProbingPhase(feedback_receive_time);
143     return;
144   }
145 
146   bool packet_loss_event = false;
147   if (accumulated_number_of_lost_packets_ !=
148       feedback.inter_arrival.accumulated_number_of_lost_packets) {
149     accumulated_number_of_lost_packets_ =
150         feedback.inter_arrival.accumulated_number_of_lost_packets;
151     packet_loss_event = true;
152   }
153   InterArrivalState state = state_machine_->GetInterArrivalState();
154 
155   if (state == kInterArrivalStatePacketLoss ||
156       state == kInterArrivalStateCompetingTcpFLow) {
157     if (packet_loss_event) {
158       if (!state_machine_->PacketLossEvent()) {
159         // Less than one RTT since last PacketLossEvent.
160         return;
161       }
162       EstimateBandwidthAfterLossEvent(feedback_receive_time);
163     } else {
164       EstimateNewBandwidth(feedback_receive_time, sent_bandwidth);
165     }
166     return;
167   }
168   EstimateDelayBandwidth(feedback_receive_time, sent_bandwidth);
169 }
170 
ProbingPhase(QuicTime feedback_receive_time)171 bool InterArrivalSender::ProbingPhase(QuicTime feedback_receive_time) {
172   QuicBandwidth available_channel_estimate = QuicBandwidth::Zero();
173   if (!probe_->GetEstimate(&available_channel_estimate)) {
174     // Continue probing phase.
175     return true;
176   }
177   QuicBandwidth channel_estimate = QuicBandwidth::Zero();
178   ChannelEstimateState channel_estimator_state =
179       channel_estimator_->GetChannelEstimate(&channel_estimate);
180 
181   QuicBandwidth new_rate =
182       available_channel_estimate.Scale(kUncertainSafetyMargin);
183 
184   switch (channel_estimator_state) {
185     case kChannelEstimateUnknown:
186       channel_estimate = available_channel_estimate;
187       break;
188     case kChannelEstimateUncertain:
189       channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin);
190       break;
191     case kChannelEstimateGood:
192       // Do nothing.
193       break;
194   }
195   new_rate = std::max(new_rate,
196                        QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit));
197 
198   bitrate_ramp_up_->Reset(new_rate, available_channel_estimate,
199                           channel_estimate);
200 
201   current_bandwidth_ = new_rate;
202   paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, new_rate);
203   DVLOG(1) << "Probe result; new rate:"
204              << new_rate.ToKBitsPerSecond() << " Kbits/s "
205              << " available estimate:"
206              << available_channel_estimate.ToKBitsPerSecond() << " Kbits/s "
207              << " channel estimate:"
208              << channel_estimate.ToKBitsPerSecond() << " Kbits/s ";
209   return false;
210 }
211 
OnPacketAcked(QuicPacketSequenceNumber,QuicByteCount acked_bytes,QuicTime::Delta rtt)212 void InterArrivalSender::OnPacketAcked(
213     QuicPacketSequenceNumber /*acked_sequence_number*/,
214     QuicByteCount acked_bytes,
215     QuicTime::Delta rtt) {
216   // RTT can't be negative.
217   DCHECK_LE(0, rtt.ToMicroseconds());
218 
219   if (probing_) {
220     probe_->OnAcknowledgedPacket(acked_bytes);
221   }
222 
223   if (rtt.IsInfinite()) {
224     return;
225   }
226 
227   if (smoothed_rtt_.IsZero()) {
228     smoothed_rtt_ = rtt;
229   } else {
230     smoothed_rtt_ = QuicTime::Delta::FromMicroseconds(
231         kOneMinusAlpha * smoothed_rtt_.ToMicroseconds() +
232         kAlpha * rtt.ToMicroseconds());
233   }
234   state_machine_->set_rtt(smoothed_rtt_);
235 }
236 
OnPacketLost(QuicPacketSequenceNumber,QuicTime ack_receive_time)237 void InterArrivalSender::OnPacketLost(
238     QuicPacketSequenceNumber /*sequence_number*/,
239     QuicTime ack_receive_time) {
240   // Packet loss was reported.
241   if (!probing_) {
242     if (!state_machine_->PacketLossEvent()) {
243       // Less than one RTT since last PacketLossEvent.
244       return;
245     }
246     // Calculate new pace rate.
247     EstimateBandwidthAfterLossEvent(ack_receive_time);
248   }
249 }
250 
OnPacketSent(QuicTime sent_time,QuicPacketSequenceNumber sequence_number,QuicByteCount bytes,TransmissionType,HasRetransmittableData)251 bool InterArrivalSender::OnPacketSent(
252     QuicTime sent_time,
253     QuicPacketSequenceNumber sequence_number,
254     QuicByteCount bytes,
255     TransmissionType /*transmission_type*/,
256     HasRetransmittableData /*has_retransmittable_data*/) {
257   if (probing_) {
258     probe_->OnPacketSent(bytes);
259   }
260   paced_sender_->OnPacketSent(sent_time, bytes);
261   return true;
262 }
263 
OnRetransmissionTimeout()264 void InterArrivalSender::OnRetransmissionTimeout() {
265   // TODO(ianswett): Decrease the available bandwidth.
266 }
267 
OnPacketAbandoned(QuicPacketSequenceNumber,QuicByteCount abandoned_bytes)268 void InterArrivalSender::OnPacketAbandoned(
269     QuicPacketSequenceNumber /*sequence_number*/,
270     QuicByteCount abandoned_bytes) {
271   // TODO(pwestin): use for out outer_congestion_window_ logic.
272   if (probing_) {
273     probe_->OnAcknowledgedPacket(abandoned_bytes);
274   }
275 }
276 
TimeUntilSend(QuicTime now,TransmissionType,HasRetransmittableData has_retransmittable_data,IsHandshake)277 QuicTime::Delta InterArrivalSender::TimeUntilSend(
278     QuicTime now,
279     TransmissionType /*transmission_type*/,
280     HasRetransmittableData has_retransmittable_data,
281     IsHandshake /*handshake*/) {
282   // TODO(pwestin): implement outer_congestion_window_ logic.
283   QuicTime::Delta outer_window = QuicTime::Delta::Zero();
284 
285   if (probing_) {
286     if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA &&
287         probe_->GetAvailableCongestionWindow() == 0) {
288       outer_window = QuicTime::Delta::Infinite();
289     }
290   }
291   return paced_sender_->TimeUntilSend(now, outer_window);
292 }
293 
EstimateDelayBandwidth(QuicTime feedback_receive_time,QuicBandwidth sent_bandwidth)294 void InterArrivalSender::EstimateDelayBandwidth(QuicTime feedback_receive_time,
295                                                 QuicBandwidth sent_bandwidth) {
296   QuicTime::Delta estimated_congestion_delay = QuicTime::Delta::Zero();
297   BandwidthUsage new_bandwidth_usage_state =
298       overuse_detector_->GetState(&estimated_congestion_delay);
299 
300   switch (new_bandwidth_usage_state) {
301     case kBandwidthDraining:
302     case kBandwidthUnderUsing:
303       // Hold our current bitrate.
304       break;
305     case kBandwidthOverUsing:
306       if (!state_machine_->IncreasingDelayEvent()) {
307         // Less than one RTT since last IncreasingDelayEvent.
308         return;
309       }
310       EstimateBandwidthAfterDelayEvent(feedback_receive_time,
311                                        estimated_congestion_delay);
312       break;
313     case kBandwidthSteady:
314       // Calculate new pace rate.
315       if (bandwidth_usage_state_ == kBandwidthDraining ||
316           bandwidth_usage_state_ == kBandwidthOverUsing) {
317         EstimateNewBandwidthAfterDraining(feedback_receive_time,
318                                           estimated_congestion_delay);
319       } else {
320         EstimateNewBandwidth(feedback_receive_time, sent_bandwidth);
321       }
322       break;
323   }
324   bandwidth_usage_state_ = new_bandwidth_usage_state;
325 }
326 
BandwidthEstimate() const327 QuicBandwidth InterArrivalSender::BandwidthEstimate() const {
328   return current_bandwidth_;
329 }
330 
SmoothedRtt() const331 QuicTime::Delta InterArrivalSender::SmoothedRtt() const {
332   if (smoothed_rtt_.IsZero()) {
333     return QuicTime::Delta::FromMilliseconds(kInitialRttMs);
334   }
335   return smoothed_rtt_;
336 }
337 
RetransmissionDelay() const338 QuicTime::Delta InterArrivalSender::RetransmissionDelay() const {
339   // TODO(pwestin): Calculate and return retransmission delay.
340   // Use 2 * the smoothed RTT for now.
341   return smoothed_rtt_.Add(smoothed_rtt_);
342 }
343 
GetCongestionWindow() const344 QuicByteCount InterArrivalSender::GetCongestionWindow() const {
345   return 0;
346 }
347 
EstimateNewBandwidth(QuicTime feedback_receive_time,QuicBandwidth sent_bandwidth)348 void InterArrivalSender::EstimateNewBandwidth(QuicTime feedback_receive_time,
349                                               QuicBandwidth sent_bandwidth) {
350   QuicBandwidth new_bandwidth = bitrate_ramp_up_->GetNewBitrate(sent_bandwidth);
351   if (current_bandwidth_ == new_bandwidth) {
352     return;
353   }
354   current_bandwidth_ = new_bandwidth;
355   state_machine_->IncreaseBitrateDecision();
356 
357   QuicBandwidth channel_estimate = QuicBandwidth::Zero();
358   ChannelEstimateState channel_estimator_state =
359       channel_estimator_->GetChannelEstimate(&channel_estimate);
360 
361   if (channel_estimator_state == kChannelEstimateGood) {
362     bitrate_ramp_up_->UpdateChannelEstimate(channel_estimate);
363   }
364   paced_sender_->UpdateBandwidthEstimate(feedback_receive_time,
365                                          current_bandwidth_);
366   DVLOG(1) << "New bandwidth estimate in steady state:"
367              << current_bandwidth_.ToKBitsPerSecond()
368              << " Kbits/s";
369 }
370 
371 // Did we drain the network buffers in our expected pace?
EstimateNewBandwidthAfterDraining(QuicTime feedback_receive_time,QuicTime::Delta estimated_congestion_delay)372 void InterArrivalSender::EstimateNewBandwidthAfterDraining(
373     QuicTime feedback_receive_time,
374     QuicTime::Delta estimated_congestion_delay) {
375   if (current_bandwidth_ > back_down_bandwidth_) {
376     // Do nothing, our current bandwidth is higher than our bandwidth at the
377     // previous back down.
378     DVLOG(1) << "Current bandwidth estimate is higher than before draining";
379     return;
380   }
381   if (estimated_congestion_delay >= back_down_congestion_delay_) {
382     // Do nothing, our estimated delay have increased.
383     DVLOG(1) << "Current delay estimate is higher than before draining";
384     return;
385   }
386   DCHECK(back_down_time_.IsInitialized());
387   QuicTime::Delta buffer_reduction =
388       back_down_congestion_delay_.Subtract(estimated_congestion_delay);
389   QuicTime::Delta elapsed_time =
390       feedback_receive_time.Subtract(back_down_time_).Subtract(SmoothedRtt());
391 
392   QuicBandwidth new_estimate = QuicBandwidth::Zero();
393   if (buffer_reduction >= elapsed_time) {
394     // We have drained more than the elapsed time... go back to our old rate.
395     new_estimate = back_down_bandwidth_;
396   } else {
397     float fraction_of_rate =
398         static_cast<float>(buffer_reduction.ToMicroseconds()) /
399             elapsed_time.ToMicroseconds();  // < 1.0
400 
401     QuicBandwidth draining_rate = back_down_bandwidth_.Scale(fraction_of_rate);
402     QuicBandwidth max_estimated_draining_rate =
403         back_down_bandwidth_.Subtract(current_bandwidth_);
404     if (draining_rate > max_estimated_draining_rate) {
405       // We drained faster than our old send rate, go back to our old rate.
406       new_estimate = back_down_bandwidth_;
407     } else {
408       // Use our drain rate and our kMinBitrateReduction to go to our
409       // new estimate.
410       new_estimate = std::max(current_bandwidth_,
411                               current_bandwidth_.Add(draining_rate).Scale(
412                                   1.0f - kMinBitrateReduction));
413       DVLOG(1) << "Draining calculation; current rate:"
414                  << current_bandwidth_.ToKBitsPerSecond() << " Kbits/s "
415                  << "draining rate:"
416                  << draining_rate.ToKBitsPerSecond() << " Kbits/s "
417                  << "new estimate:"
418                  << new_estimate.ToKBitsPerSecond() << " Kbits/s "
419                  << " buffer reduction:"
420                  << buffer_reduction.ToMicroseconds() << " us "
421                  << " elapsed time:"
422                  << elapsed_time.ToMicroseconds()  << " us ";
423     }
424   }
425   if (new_estimate == current_bandwidth_) {
426     return;
427   }
428 
429   QuicBandwidth channel_estimate = QuicBandwidth::Zero();
430   ChannelEstimateState channel_estimator_state =
431       channel_estimator_->GetChannelEstimate(&channel_estimate);
432 
433   // TODO(pwestin): we need to analyze channel_estimate too.
434   switch (channel_estimator_state) {
435     case kChannelEstimateUnknown:
436       channel_estimate = current_bandwidth_;
437       break;
438     case kChannelEstimateUncertain:
439       channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin);
440       break;
441     case kChannelEstimateGood:
442       // Do nothing, estimate is accurate.
443       break;
444   }
445   bitrate_ramp_up_->Reset(new_estimate, back_down_bandwidth_, channel_estimate);
446   state_machine_->IncreaseBitrateDecision();
447   paced_sender_->UpdateBandwidthEstimate(feedback_receive_time, new_estimate);
448   current_bandwidth_ = new_estimate;
449   DVLOG(1) << "New bandwidth estimate after draining:"
450              << new_estimate.ToKBitsPerSecond() << " Kbits/s";
451 }
452 
EstimateBandwidthAfterDelayEvent(QuicTime feedback_receive_time,QuicTime::Delta estimated_congestion_delay)453 void InterArrivalSender::EstimateBandwidthAfterDelayEvent(
454     QuicTime feedback_receive_time,
455     QuicTime::Delta estimated_congestion_delay) {
456   QuicByteCount estimated_byte_buildup =
457       current_bandwidth_.ToBytesPerPeriod(estimated_congestion_delay);
458 
459   // To drain all build up buffer within one RTT we need to reduce the
460   // bitrate with the following.
461   // TODO(pwestin): this is a crude first implementation.
462   int64 draining_rate_per_rtt = (estimated_byte_buildup *
463       kNumMicrosPerSecond) / SmoothedRtt().ToMicroseconds();
464 
465   float decrease_factor =
466       draining_rate_per_rtt / current_bandwidth_.ToBytesPerSecond();
467 
468   decrease_factor = std::max(decrease_factor, kMinBitrateReduction);
469   decrease_factor = std::min(decrease_factor, kMaxBitrateReduction);
470   back_down_congestion_delay_ = estimated_congestion_delay;
471   QuicBandwidth new_target_bitrate =
472       current_bandwidth_.Scale(1.0f - decrease_factor);
473 
474   // While in delay sensing mode send at least one packet per RTT.
475   QuicBandwidth min_delay_bitrate =
476       QuicBandwidth::FromBytesAndTimeDelta(max_segment_size_, SmoothedRtt());
477   new_target_bitrate = std::max(new_target_bitrate, min_delay_bitrate);
478 
479   ResetCurrentBandwidth(feedback_receive_time, new_target_bitrate);
480 
481   DVLOG(1) << "New bandwidth estimate after delay event:"
482       << current_bandwidth_.ToKBitsPerSecond()
483       << " Kbits/s min delay bitrate:"
484       << min_delay_bitrate.ToKBitsPerSecond()
485       << " Kbits/s RTT:"
486       << SmoothedRtt().ToMicroseconds()
487       << " us";
488 }
489 
EstimateBandwidthAfterLossEvent(QuicTime feedback_receive_time)490 void InterArrivalSender::EstimateBandwidthAfterLossEvent(
491     QuicTime feedback_receive_time) {
492   ResetCurrentBandwidth(feedback_receive_time,
493                         current_bandwidth_.Scale(kPacketLossBitrateReduction));
494   DVLOG(1) << "New bandwidth estimate after loss event:"
495              << current_bandwidth_.ToKBitsPerSecond()
496              << " Kbits/s";
497 }
498 
ResetCurrentBandwidth(QuicTime feedback_receive_time,QuicBandwidth new_rate)499 void InterArrivalSender::ResetCurrentBandwidth(QuicTime feedback_receive_time,
500                                                QuicBandwidth new_rate) {
501   new_rate = std::max(new_rate,
502                       QuicBandwidth::FromKBitsPerSecond(kMinBitrateKbit));
503   QuicBandwidth channel_estimate = QuicBandwidth::Zero();
504   ChannelEstimateState channel_estimator_state =
505       channel_estimator_->GetChannelEstimate(&channel_estimate);
506 
507   switch (channel_estimator_state) {
508     case kChannelEstimateUnknown:
509       channel_estimate = current_bandwidth_;
510       break;
511     case kChannelEstimateUncertain:
512       channel_estimate = channel_estimate.Scale(kUncertainSafetyMargin);
513       break;
514     case kChannelEstimateGood:
515       // Do nothing.
516       break;
517   }
518   back_down_time_ = feedback_receive_time;
519   back_down_bandwidth_ = current_bandwidth_;
520   bitrate_ramp_up_->Reset(new_rate, current_bandwidth_, channel_estimate);
521   if (new_rate != current_bandwidth_) {
522     current_bandwidth_ = new_rate;
523     paced_sender_->UpdateBandwidthEstimate(feedback_receive_time,
524                                            current_bandwidth_);
525     state_machine_->DecreaseBitrateDecision();
526   }
527 }
528 
529 }  // namespace net
530