• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/congestion_controller/goog_cc/goog_cc_network_control.h"
12 
13 #include <inttypes.h>
14 #include <stdio.h>
15 
16 #include <algorithm>
17 #include <cstdint>
18 #include <memory>
19 #include <numeric>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "absl/strings/match.h"
25 #include "api/units/data_rate.h"
26 #include "api/units/time_delta.h"
27 #include "api/units/timestamp.h"
28 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
29 #include "modules/congestion_controller/goog_cc/alr_detector.h"
30 #include "modules/congestion_controller/goog_cc/loss_based_bwe_v2.h"
31 #include "modules/congestion_controller/goog_cc/probe_controller.h"
32 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
33 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
34 #include "rtc_base/checks.h"
35 #include "rtc_base/logging.h"
36 
37 namespace webrtc {
38 
39 namespace {
40 // From RTCPSender video report interval.
41 constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis(1000);
42 
43 // Pacing-rate relative to our target send rate.
44 // Multiplicative factor that is applied to the target bitrate to calculate
45 // the number of bytes that can be transmitted per interval.
46 // Increasing this factor will result in lower delays in cases of bitrate
47 // overshoots from the encoder.
48 constexpr float kDefaultPaceMultiplier = 2.5f;
49 
50 // If the probe result is far below the current throughput estimate
51 // it's unlikely that the probe is accurate, so we don't want to drop too far.
52 // However, if we actually are overusing, we want to drop to something slightly
53 // below the current throughput estimate to drain the network queues.
54 constexpr double kProbeDropThroughputFraction = 0.85;
55 
IsEnabled(const FieldTrialsView * config,absl::string_view key)56 bool IsEnabled(const FieldTrialsView* config, absl::string_view key) {
57   return absl::StartsWith(config->Lookup(key), "Enabled");
58 }
59 
IsNotDisabled(const FieldTrialsView * config,absl::string_view key)60 bool IsNotDisabled(const FieldTrialsView* config, absl::string_view key) {
61   return !absl::StartsWith(config->Lookup(key), "Disabled");
62 }
63 
GetBandwidthLimitedCause(LossBasedState loss_based_state)64 BandwidthLimitedCause GetBandwidthLimitedCause(
65     LossBasedState loss_based_state) {
66   switch (loss_based_state) {
67     case LossBasedState::kDecreasing:
68       return BandwidthLimitedCause::kLossLimitedBweDecreasing;
69     case LossBasedState::kIncreasing:
70       return BandwidthLimitedCause::kLossLimitedBweIncreasing;
71     default:
72       return BandwidthLimitedCause::kDelayBasedLimited;
73   }
74 }
75 
76 }  // namespace
77 
GoogCcNetworkController(NetworkControllerConfig config,GoogCcConfig goog_cc_config)78 GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config,
79                                                  GoogCcConfig goog_cc_config)
80     : key_value_config_(config.key_value_config ? config.key_value_config
81                                                 : &trial_based_config_),
82       event_log_(config.event_log),
83       packet_feedback_only_(goog_cc_config.feedback_only),
84       safe_reset_on_route_change_("Enabled"),
85       safe_reset_acknowledged_rate_("ack"),
86       use_min_allocatable_as_lower_bound_(
87           IsNotDisabled(key_value_config_, "WebRTC-Bwe-MinAllocAsLowerBound")),
88       ignore_probes_lower_than_network_estimate_(IsNotDisabled(
89           key_value_config_,
90           "WebRTC-Bwe-IgnoreProbesLowerThanNetworkStateEstimate")),
91       limit_probes_lower_than_throughput_estimate_(
92           IsEnabled(key_value_config_,
93                     "WebRTC-Bwe-LimitProbesLowerThanThroughputEstimate")),
94       rate_control_settings_(
95           RateControlSettings::ParseFromKeyValueConfig(key_value_config_)),
96       pace_at_max_of_bwe_and_lower_link_capacity_(
97           IsEnabled(key_value_config_,
98                     "WebRTC-Bwe-PaceAtMaxOfBweAndLowerLinkCapacity")),
99       probe_controller_(
100           new ProbeController(key_value_config_, config.event_log)),
101       congestion_window_pushback_controller_(
102           rate_control_settings_.UseCongestionWindowPushback()
103               ? std::make_unique<CongestionWindowPushbackController>(
104                     key_value_config_)
105               : nullptr),
106       bandwidth_estimation_(
107           std::make_unique<SendSideBandwidthEstimation>(key_value_config_,
108                                                         event_log_)),
109       alr_detector_(
110           std::make_unique<AlrDetector>(key_value_config_, config.event_log)),
111       probe_bitrate_estimator_(new ProbeBitrateEstimator(config.event_log)),
112       network_estimator_(std::move(goog_cc_config.network_state_estimator)),
113       network_state_predictor_(
114           std::move(goog_cc_config.network_state_predictor)),
115       delay_based_bwe_(new DelayBasedBwe(key_value_config_,
116                                          event_log_,
117                                          network_state_predictor_.get())),
118       acknowledged_bitrate_estimator_(
119           AcknowledgedBitrateEstimatorInterface::Create(key_value_config_)),
120       initial_config_(config),
121       last_loss_based_target_rate_(*config.constraints.starting_rate),
122       last_pushback_target_rate_(last_loss_based_target_rate_),
123       last_stable_target_rate_(last_loss_based_target_rate_),
124       pacing_factor_(config.stream_based_config.pacing_factor.value_or(
125           kDefaultPaceMultiplier)),
126       min_total_allocated_bitrate_(
127           config.stream_based_config.min_total_allocated_bitrate.value_or(
128               DataRate::Zero())),
129       max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
130           DataRate::Zero())) {
131   RTC_DCHECK(config.constraints.at_time.IsFinite());
132   ParseFieldTrial(
133       {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
134       key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
135   if (delay_based_bwe_)
136     delay_based_bwe_->SetMinBitrate(kCongestionControllerMinBitrate);
137 }
138 
~GoogCcNetworkController()139 GoogCcNetworkController::~GoogCcNetworkController() {}
140 
OnNetworkAvailability(NetworkAvailability msg)141 NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability(
142     NetworkAvailability msg) {
143   NetworkControlUpdate update;
144   update.probe_cluster_configs = probe_controller_->OnNetworkAvailability(msg);
145   return update;
146 }
147 
OnNetworkRouteChange(NetworkRouteChange msg)148 NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
149     NetworkRouteChange msg) {
150   if (safe_reset_on_route_change_) {
151     absl::optional<DataRate> estimated_bitrate;
152     if (safe_reset_acknowledged_rate_) {
153       estimated_bitrate = acknowledged_bitrate_estimator_->bitrate();
154       if (!estimated_bitrate)
155         estimated_bitrate = acknowledged_bitrate_estimator_->PeekRate();
156     } else {
157       estimated_bitrate = bandwidth_estimation_->target_rate();
158     }
159     if (estimated_bitrate) {
160       if (msg.constraints.starting_rate) {
161         msg.constraints.starting_rate =
162             std::min(*msg.constraints.starting_rate, *estimated_bitrate);
163       } else {
164         msg.constraints.starting_rate = estimated_bitrate;
165       }
166     }
167   }
168 
169   acknowledged_bitrate_estimator_ =
170       AcknowledgedBitrateEstimatorInterface::Create(key_value_config_);
171   probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
172   if (network_estimator_)
173     network_estimator_->OnRouteChange(msg);
174   delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_,
175                                            network_state_predictor_.get()));
176   bandwidth_estimation_->OnRouteChange();
177   probe_controller_->Reset(msg.at_time);
178   NetworkControlUpdate update;
179   update.probe_cluster_configs = ResetConstraints(msg.constraints);
180   MaybeTriggerOnNetworkChanged(&update, msg.at_time);
181   return update;
182 }
183 
OnProcessInterval(ProcessInterval msg)184 NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
185     ProcessInterval msg) {
186   NetworkControlUpdate update;
187   if (initial_config_) {
188     update.probe_cluster_configs =
189         ResetConstraints(initial_config_->constraints);
190     update.pacer_config = GetPacingRates(msg.at_time);
191 
192     if (initial_config_->stream_based_config.requests_alr_probing) {
193       probe_controller_->EnablePeriodicAlrProbing(
194           *initial_config_->stream_based_config.requests_alr_probing);
195     }
196     absl::optional<DataRate> total_bitrate =
197         initial_config_->stream_based_config.max_total_allocated_bitrate;
198     if (total_bitrate) {
199       auto probes = probe_controller_->OnMaxTotalAllocatedBitrate(
200           *total_bitrate, msg.at_time);
201       update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
202                                           probes.begin(), probes.end());
203     }
204     initial_config_.reset();
205   }
206   if (congestion_window_pushback_controller_ && msg.pacer_queue) {
207     congestion_window_pushback_controller_->UpdatePacingQueue(
208         msg.pacer_queue->bytes());
209   }
210   bandwidth_estimation_->UpdateEstimate(msg.at_time);
211   absl::optional<int64_t> start_time_ms =
212       alr_detector_->GetApplicationLimitedRegionStartTime();
213   probe_controller_->SetAlrStartTimeMs(start_time_ms);
214 
215   auto probes = probe_controller_->Process(msg.at_time);
216   update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
217                                       probes.begin(), probes.end());
218 
219   if (rate_control_settings_.UseCongestionWindow() &&
220       last_packet_received_time_.IsFinite() && !feedback_max_rtts_.empty()) {
221     UpdateCongestionWindowSize();
222   }
223   if (congestion_window_pushback_controller_ && current_data_window_) {
224     congestion_window_pushback_controller_->SetDataWindow(
225         *current_data_window_);
226   } else {
227     update.congestion_window = current_data_window_;
228   }
229   MaybeTriggerOnNetworkChanged(&update, msg.at_time);
230   return update;
231 }
232 
OnRemoteBitrateReport(RemoteBitrateReport msg)233 NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport(
234     RemoteBitrateReport msg) {
235   if (packet_feedback_only_) {
236     RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
237     return NetworkControlUpdate();
238   }
239   bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time,
240                                                 msg.bandwidth);
241   BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
242                         msg.bandwidth.bps() / 1000);
243   return NetworkControlUpdate();
244 }
245 
OnRoundTripTimeUpdate(RoundTripTimeUpdate msg)246 NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate(
247     RoundTripTimeUpdate msg) {
248   if (packet_feedback_only_ || msg.smoothed)
249     return NetworkControlUpdate();
250   RTC_DCHECK(!msg.round_trip_time.IsZero());
251   if (delay_based_bwe_)
252     delay_based_bwe_->OnRttUpdate(msg.round_trip_time);
253   bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time);
254   return NetworkControlUpdate();
255 }
256 
OnSentPacket(SentPacket sent_packet)257 NetworkControlUpdate GoogCcNetworkController::OnSentPacket(
258     SentPacket sent_packet) {
259   alr_detector_->OnBytesSent(sent_packet.size.bytes(),
260                              sent_packet.send_time.ms());
261   acknowledged_bitrate_estimator_->SetAlr(
262       alr_detector_->GetApplicationLimitedRegionStartTime().has_value());
263 
264   if (!first_packet_sent_) {
265     first_packet_sent_ = true;
266     // Initialize feedback time to send time to allow estimation of RTT until
267     // first feedback is received.
268     bandwidth_estimation_->UpdatePropagationRtt(sent_packet.send_time,
269                                                 TimeDelta::Zero());
270   }
271   bandwidth_estimation_->OnSentPacket(sent_packet);
272 
273   if (congestion_window_pushback_controller_) {
274     congestion_window_pushback_controller_->UpdateOutstandingData(
275         sent_packet.data_in_flight.bytes());
276     NetworkControlUpdate update;
277     MaybeTriggerOnNetworkChanged(&update, sent_packet.send_time);
278     return update;
279   } else {
280     return NetworkControlUpdate();
281   }
282 }
283 
OnReceivedPacket(ReceivedPacket received_packet)284 NetworkControlUpdate GoogCcNetworkController::OnReceivedPacket(
285     ReceivedPacket received_packet) {
286   last_packet_received_time_ = received_packet.receive_time;
287   return NetworkControlUpdate();
288 }
289 
OnStreamsConfig(StreamsConfig msg)290 NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig(
291     StreamsConfig msg) {
292   NetworkControlUpdate update;
293   if (msg.requests_alr_probing) {
294     probe_controller_->EnablePeriodicAlrProbing(*msg.requests_alr_probing);
295   }
296   if (msg.max_total_allocated_bitrate) {
297     update.probe_cluster_configs =
298         probe_controller_->OnMaxTotalAllocatedBitrate(
299             *msg.max_total_allocated_bitrate, msg.at_time);
300   }
301 
302   bool pacing_changed = false;
303   if (msg.pacing_factor && *msg.pacing_factor != pacing_factor_) {
304     pacing_factor_ = *msg.pacing_factor;
305     pacing_changed = true;
306   }
307   if (msg.min_total_allocated_bitrate &&
308       *msg.min_total_allocated_bitrate != min_total_allocated_bitrate_) {
309     min_total_allocated_bitrate_ = *msg.min_total_allocated_bitrate;
310     pacing_changed = true;
311 
312     if (use_min_allocatable_as_lower_bound_) {
313       ClampConstraints();
314       delay_based_bwe_->SetMinBitrate(min_data_rate_);
315       bandwidth_estimation_->SetMinMaxBitrate(min_data_rate_, max_data_rate_);
316     }
317   }
318   if (msg.max_padding_rate && *msg.max_padding_rate != max_padding_rate_) {
319     max_padding_rate_ = *msg.max_padding_rate;
320     pacing_changed = true;
321   }
322 
323   if (pacing_changed)
324     update.pacer_config = GetPacingRates(msg.at_time);
325   return update;
326 }
327 
OnTargetRateConstraints(TargetRateConstraints constraints)328 NetworkControlUpdate GoogCcNetworkController::OnTargetRateConstraints(
329     TargetRateConstraints constraints) {
330   NetworkControlUpdate update;
331   update.probe_cluster_configs = ResetConstraints(constraints);
332   MaybeTriggerOnNetworkChanged(&update, constraints.at_time);
333   return update;
334 }
335 
ClampConstraints()336 void GoogCcNetworkController::ClampConstraints() {
337   // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
338   // and that we don't try to set the min bitrate to 0 from any applications.
339   // The congestion controller should allow a min bitrate of 0.
340   min_data_rate_ = std::max(min_target_rate_, kCongestionControllerMinBitrate);
341   if (use_min_allocatable_as_lower_bound_) {
342     min_data_rate_ = std::max(min_data_rate_, min_total_allocated_bitrate_);
343   }
344   if (max_data_rate_ < min_data_rate_) {
345     RTC_LOG(LS_WARNING) << "max bitrate smaller than min bitrate";
346     max_data_rate_ = min_data_rate_;
347   }
348   if (starting_rate_ && starting_rate_ < min_data_rate_) {
349     RTC_LOG(LS_WARNING) << "start bitrate smaller than min bitrate";
350     starting_rate_ = min_data_rate_;
351   }
352 }
353 
ResetConstraints(TargetRateConstraints new_constraints)354 std::vector<ProbeClusterConfig> GoogCcNetworkController::ResetConstraints(
355     TargetRateConstraints new_constraints) {
356   min_target_rate_ = new_constraints.min_data_rate.value_or(DataRate::Zero());
357   max_data_rate_ =
358       new_constraints.max_data_rate.value_or(DataRate::PlusInfinity());
359   starting_rate_ = new_constraints.starting_rate;
360   ClampConstraints();
361 
362   bandwidth_estimation_->SetBitrates(starting_rate_, min_data_rate_,
363                                      max_data_rate_, new_constraints.at_time);
364 
365   if (starting_rate_)
366     delay_based_bwe_->SetStartBitrate(*starting_rate_);
367   delay_based_bwe_->SetMinBitrate(min_data_rate_);
368 
369   return probe_controller_->SetBitrates(
370       min_data_rate_, starting_rate_.value_or(DataRate::Zero()), max_data_rate_,
371       new_constraints.at_time);
372 }
373 
OnTransportLossReport(TransportLossReport msg)374 NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport(
375     TransportLossReport msg) {
376   if (packet_feedback_only_)
377     return NetworkControlUpdate();
378   int64_t total_packets_delta =
379       msg.packets_received_delta + msg.packets_lost_delta;
380   bandwidth_estimation_->UpdatePacketsLost(
381       msg.packets_lost_delta, total_packets_delta, msg.receive_time);
382   return NetworkControlUpdate();
383 }
384 
UpdateCongestionWindowSize()385 void GoogCcNetworkController::UpdateCongestionWindowSize() {
386   TimeDelta min_feedback_max_rtt = TimeDelta::Millis(
387       *std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end()));
388 
389   const DataSize kMinCwnd = DataSize::Bytes(2 * 1500);
390   TimeDelta time_window =
391       min_feedback_max_rtt +
392       TimeDelta::Millis(
393           rate_control_settings_.GetCongestionWindowAdditionalTimeMs());
394 
395   DataSize data_window = last_loss_based_target_rate_ * time_window;
396   if (current_data_window_) {
397     data_window =
398         std::max(kMinCwnd, (data_window + current_data_window_.value()) / 2);
399   } else {
400     data_window = std::max(kMinCwnd, data_window);
401   }
402   current_data_window_ = data_window;
403 }
404 
OnTransportPacketsFeedback(TransportPacketsFeedback report)405 NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
406     TransportPacketsFeedback report) {
407   if (report.packet_feedbacks.empty()) {
408     // TODO(bugs.webrtc.org/10125): Design a better mechanism to safe-guard
409     // against building very large network queues.
410     return NetworkControlUpdate();
411   }
412 
413   if (congestion_window_pushback_controller_) {
414     congestion_window_pushback_controller_->UpdateOutstandingData(
415         report.data_in_flight.bytes());
416   }
417   TimeDelta max_feedback_rtt = TimeDelta::MinusInfinity();
418   TimeDelta min_propagation_rtt = TimeDelta::PlusInfinity();
419   Timestamp max_recv_time = Timestamp::MinusInfinity();
420 
421   std::vector<PacketResult> feedbacks = report.ReceivedWithSendInfo();
422   for (const auto& feedback : feedbacks)
423     max_recv_time = std::max(max_recv_time, feedback.receive_time);
424 
425   for (const auto& feedback : feedbacks) {
426     TimeDelta feedback_rtt =
427         report.feedback_time - feedback.sent_packet.send_time;
428     TimeDelta min_pending_time = max_recv_time - feedback.receive_time;
429     TimeDelta propagation_rtt = feedback_rtt - min_pending_time;
430     max_feedback_rtt = std::max(max_feedback_rtt, feedback_rtt);
431     min_propagation_rtt = std::min(min_propagation_rtt, propagation_rtt);
432   }
433 
434   if (max_feedback_rtt.IsFinite()) {
435     feedback_max_rtts_.push_back(max_feedback_rtt.ms());
436     const size_t kMaxFeedbackRttWindow = 32;
437     if (feedback_max_rtts_.size() > kMaxFeedbackRttWindow)
438       feedback_max_rtts_.pop_front();
439     // TODO(srte): Use time since last unacknowledged packet.
440     bandwidth_estimation_->UpdatePropagationRtt(report.feedback_time,
441                                                 min_propagation_rtt);
442   }
443   if (packet_feedback_only_) {
444     if (!feedback_max_rtts_.empty()) {
445       int64_t sum_rtt_ms =
446           std::accumulate(feedback_max_rtts_.begin(), feedback_max_rtts_.end(),
447                           static_cast<int64_t>(0));
448       int64_t mean_rtt_ms = sum_rtt_ms / feedback_max_rtts_.size();
449       if (delay_based_bwe_)
450         delay_based_bwe_->OnRttUpdate(TimeDelta::Millis(mean_rtt_ms));
451     }
452 
453     TimeDelta feedback_min_rtt = TimeDelta::PlusInfinity();
454     for (const auto& packet_feedback : feedbacks) {
455       TimeDelta pending_time = packet_feedback.receive_time - max_recv_time;
456       TimeDelta rtt = report.feedback_time -
457                       packet_feedback.sent_packet.send_time - pending_time;
458       // Value used for predicting NACK round trip time in FEC controller.
459       feedback_min_rtt = std::min(rtt, feedback_min_rtt);
460     }
461     if (feedback_min_rtt.IsFinite()) {
462       bandwidth_estimation_->UpdateRtt(feedback_min_rtt, report.feedback_time);
463     }
464 
465     expected_packets_since_last_loss_update_ +=
466         report.PacketsWithFeedback().size();
467     for (const auto& packet_feedback : report.PacketsWithFeedback()) {
468       if (!packet_feedback.IsReceived())
469         lost_packets_since_last_loss_update_ += 1;
470     }
471     if (report.feedback_time > next_loss_update_) {
472       next_loss_update_ = report.feedback_time + kLossUpdateInterval;
473       bandwidth_estimation_->UpdatePacketsLost(
474           lost_packets_since_last_loss_update_,
475           expected_packets_since_last_loss_update_, report.feedback_time);
476       expected_packets_since_last_loss_update_ = 0;
477       lost_packets_since_last_loss_update_ = 0;
478     }
479   }
480   absl::optional<int64_t> alr_start_time =
481       alr_detector_->GetApplicationLimitedRegionStartTime();
482 
483   if (previously_in_alr_ && !alr_start_time.has_value()) {
484     int64_t now_ms = report.feedback_time.ms();
485     acknowledged_bitrate_estimator_->SetAlrEndedTime(report.feedback_time);
486     probe_controller_->SetAlrEndedTimeMs(now_ms);
487   }
488   previously_in_alr_ = alr_start_time.has_value();
489   acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
490       report.SortedByReceiveTime());
491   auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate();
492   bandwidth_estimation_->SetAcknowledgedRate(acknowledged_bitrate,
493                                              report.feedback_time);
494   for (const auto& feedback : report.SortedByReceiveTime()) {
495     if (feedback.sent_packet.pacing_info.probe_cluster_id !=
496         PacedPacketInfo::kNotAProbe) {
497       probe_bitrate_estimator_->HandleProbeAndEstimateBitrate(feedback);
498     }
499   }
500 
501   if (network_estimator_) {
502     network_estimator_->OnTransportPacketsFeedback(report);
503     auto prev_estimate = estimate_;
504     estimate_ = network_estimator_->GetCurrentEstimate();
505     // TODO(srte): Make OnTransportPacketsFeedback signal whether the state
506     // changed to avoid the need for this check.
507     if (estimate_ && (!prev_estimate || estimate_->last_feed_time !=
508                                             prev_estimate->last_feed_time)) {
509       event_log_->Log(std::make_unique<RtcEventRemoteEstimate>(
510           estimate_->link_capacity_lower, estimate_->link_capacity_upper));
511       probe_controller_->SetNetworkStateEstimate(*estimate_);
512     }
513   }
514   absl::optional<DataRate> probe_bitrate =
515       probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate();
516   if (ignore_probes_lower_than_network_estimate_ && probe_bitrate &&
517       estimate_ && *probe_bitrate < delay_based_bwe_->last_estimate() &&
518       *probe_bitrate < estimate_->link_capacity_lower) {
519     probe_bitrate.reset();
520   }
521   if (limit_probes_lower_than_throughput_estimate_ && probe_bitrate &&
522       acknowledged_bitrate) {
523     // Limit the backoff to something slightly below the acknowledged
524     // bitrate. ("Slightly below" because we want to drain the queues
525     // if we are actually overusing.)
526     // The acknowledged bitrate shouldn't normally be higher than the delay
527     // based estimate, but it could happen e.g. due to packet bursts or
528     // encoder overshoot. We use std::min to ensure that a probe result
529     // below the current BWE never causes an increase.
530     DataRate limit =
531         std::min(delay_based_bwe_->last_estimate(),
532                  *acknowledged_bitrate * kProbeDropThroughputFraction);
533     probe_bitrate = std::max(*probe_bitrate, limit);
534   }
535 
536   NetworkControlUpdate update;
537   bool recovered_from_overuse = false;
538 
539   DelayBasedBwe::Result result;
540   result = delay_based_bwe_->IncomingPacketFeedbackVector(
541       report, acknowledged_bitrate, probe_bitrate, estimate_,
542       alr_start_time.has_value());
543 
544   if (result.updated) {
545     if (result.probe) {
546       bandwidth_estimation_->SetSendBitrate(result.target_bitrate,
547                                             report.feedback_time);
548     }
549     // Since SetSendBitrate now resets the delay-based estimate, we have to
550     // call UpdateDelayBasedEstimate after SetSendBitrate.
551     bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time,
552                                                     result.target_bitrate);
553   }
554   bandwidth_estimation_->UpdateLossBasedEstimator(
555       report, result.delay_detector_state, probe_bitrate,
556       estimate_ ? estimate_->link_capacity_upper : DataRate::PlusInfinity());
557   if (result.updated) {
558     // Update the estimate in the ProbeController, in case we want to probe.
559     MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
560   }
561 
562   recovered_from_overuse = result.recovered_from_overuse;
563 
564   if (recovered_from_overuse) {
565     probe_controller_->SetAlrStartTimeMs(alr_start_time);
566     auto probes = probe_controller_->RequestProbe(report.feedback_time);
567     update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
568                                         probes.begin(), probes.end());
569   }
570 
571   // No valid RTT could be because send-side BWE isn't used, in which case
572   // we don't try to limit the outstanding packets.
573   if (rate_control_settings_.UseCongestionWindow() &&
574       max_feedback_rtt.IsFinite()) {
575     UpdateCongestionWindowSize();
576   }
577   if (congestion_window_pushback_controller_ && current_data_window_) {
578     congestion_window_pushback_controller_->SetDataWindow(
579         *current_data_window_);
580   } else {
581     update.congestion_window = current_data_window_;
582   }
583 
584   return update;
585 }
586 
OnNetworkStateEstimate(NetworkStateEstimate msg)587 NetworkControlUpdate GoogCcNetworkController::OnNetworkStateEstimate(
588     NetworkStateEstimate msg) {
589   estimate_ = msg;
590   return NetworkControlUpdate();
591 }
592 
GetNetworkState(Timestamp at_time) const593 NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
594     Timestamp at_time) const {
595   NetworkControlUpdate update;
596   update.target_rate = TargetTransferRate();
597   update.target_rate->network_estimate.at_time = at_time;
598   update.target_rate->network_estimate.loss_rate_ratio =
599       last_estimated_fraction_loss_.value_or(0) / 255.0;
600   update.target_rate->network_estimate.round_trip_time =
601       last_estimated_round_trip_time_;
602   update.target_rate->network_estimate.bwe_period =
603       delay_based_bwe_->GetExpectedBwePeriod();
604 
605   update.target_rate->at_time = at_time;
606   update.target_rate->target_rate = last_pushback_target_rate_;
607   update.target_rate->stable_target_rate =
608       bandwidth_estimation_->GetEstimatedLinkCapacity();
609   update.pacer_config = GetPacingRates(at_time);
610   update.congestion_window = current_data_window_;
611   return update;
612 }
613 
MaybeTriggerOnNetworkChanged(NetworkControlUpdate * update,Timestamp at_time)614 void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
615     NetworkControlUpdate* update,
616     Timestamp at_time) {
617   uint8_t fraction_loss = bandwidth_estimation_->fraction_loss();
618   TimeDelta round_trip_time = bandwidth_estimation_->round_trip_time();
619   DataRate loss_based_target_rate = bandwidth_estimation_->target_rate();
620   DataRate pushback_target_rate = loss_based_target_rate;
621 
622   BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", at_time.ms(),
623                         (fraction_loss * 100) / 256);
624   BWE_TEST_LOGGING_PLOT(1, "rtt_ms", at_time.ms(), round_trip_time.ms());
625   BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", at_time.ms(),
626                         loss_based_target_rate.kbps());
627 
628   double cwnd_reduce_ratio = 0.0;
629   if (congestion_window_pushback_controller_) {
630     int64_t pushback_rate =
631         congestion_window_pushback_controller_->UpdateTargetBitrate(
632             loss_based_target_rate.bps());
633     pushback_rate = std::max<int64_t>(bandwidth_estimation_->GetMinBitrate(),
634                                       pushback_rate);
635     pushback_target_rate = DataRate::BitsPerSec(pushback_rate);
636     if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) {
637       cwnd_reduce_ratio = static_cast<double>(loss_based_target_rate.bps() -
638                                               pushback_target_rate.bps()) /
639                           loss_based_target_rate.bps();
640     }
641   }
642   DataRate stable_target_rate =
643       bandwidth_estimation_->GetEstimatedLinkCapacity();
644   stable_target_rate = std::min(stable_target_rate, pushback_target_rate);
645 
646   if ((loss_based_target_rate != last_loss_based_target_rate_) ||
647       (fraction_loss != last_estimated_fraction_loss_) ||
648       (round_trip_time != last_estimated_round_trip_time_) ||
649       (pushback_target_rate != last_pushback_target_rate_) ||
650       (stable_target_rate != last_stable_target_rate_)) {
651     last_loss_based_target_rate_ = loss_based_target_rate;
652     last_pushback_target_rate_ = pushback_target_rate;
653     last_estimated_fraction_loss_ = fraction_loss;
654     last_estimated_round_trip_time_ = round_trip_time;
655     last_stable_target_rate_ = stable_target_rate;
656 
657     alr_detector_->SetEstimatedBitrate(loss_based_target_rate.bps());
658 
659     TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod();
660 
661     TargetTransferRate target_rate_msg;
662     target_rate_msg.at_time = at_time;
663     if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) {
664       target_rate_msg.target_rate = loss_based_target_rate;
665       target_rate_msg.cwnd_reduce_ratio = cwnd_reduce_ratio;
666     } else {
667       target_rate_msg.target_rate = pushback_target_rate;
668     }
669     target_rate_msg.stable_target_rate = stable_target_rate;
670     target_rate_msg.network_estimate.at_time = at_time;
671     target_rate_msg.network_estimate.round_trip_time = round_trip_time;
672     target_rate_msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0f;
673     target_rate_msg.network_estimate.bwe_period = bwe_period;
674 
675     update->target_rate = target_rate_msg;
676 
677     auto probes = probe_controller_->SetEstimatedBitrate(
678         loss_based_target_rate,
679         GetBandwidthLimitedCause(bandwidth_estimation_->loss_based_state()),
680         at_time);
681     update->probe_cluster_configs.insert(update->probe_cluster_configs.end(),
682                                          probes.begin(), probes.end());
683     update->pacer_config = GetPacingRates(at_time);
684     RTC_LOG(LS_VERBOSE) << "bwe " << at_time.ms() << " pushback_target_bps="
685                         << last_pushback_target_rate_.bps()
686                         << " estimate_bps=" << loss_based_target_rate.bps();
687   }
688 }
689 
GetPacingRates(Timestamp at_time) const690 PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {
691   // Pacing rate is based on target rate before congestion window pushback,
692   // because we don't want to build queues in the pacer when pushback occurs.
693   DataRate pacing_rate = DataRate::Zero();
694   if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_) {
695     pacing_rate =
696         std::max({min_total_allocated_bitrate_, estimate_->link_capacity_lower,
697                   last_loss_based_target_rate_}) *
698         pacing_factor_;
699   } else {
700     pacing_rate =
701         std::max(min_total_allocated_bitrate_, last_loss_based_target_rate_) *
702         pacing_factor_;
703   }
704   DataRate padding_rate =
705       std::min(max_padding_rate_, last_pushback_target_rate_);
706   PacerConfig msg;
707   msg.at_time = at_time;
708   msg.time_window = TimeDelta::Seconds(1);
709   msg.data_window = pacing_rate * msg.time_window;
710   msg.pad_window = padding_rate * msg.time_window;
711   return msg;
712 }
713 
714 }  // namespace webrtc
715