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/time_delta.h"
26 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
27 #include "modules/congestion_controller/goog_cc/alr_detector.h"
28 #include "modules/congestion_controller/goog_cc/probe_controller.h"
29 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
30 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
31 #include "rtc_base/checks.h"
32 #include "rtc_base/logging.h"
33
34 namespace webrtc {
35
36 namespace {
37 // From RTCPSender video report interval.
38 constexpr TimeDelta kLossUpdateInterval = TimeDelta::Millis(1000);
39
40 // Pacing-rate relative to our target send rate.
41 // Multiplicative factor that is applied to the target bitrate to calculate
42 // the number of bytes that can be transmitted per interval.
43 // Increasing this factor will result in lower delays in cases of bitrate
44 // overshoots from the encoder.
45 constexpr float kDefaultPaceMultiplier = 2.5f;
46
47 // If the probe result is far below the current throughput estimate
48 // it's unlikely that the probe is accurate, so we don't want to drop too far.
49 // However, if we actually are overusing, we want to drop to something slightly
50 // below the current throughput estimate to drain the network queues.
51 constexpr double kProbeDropThroughputFraction = 0.85;
52
GetBpsOrDefault(const absl::optional<DataRate> & rate,int64_t fallback_bps)53 int64_t GetBpsOrDefault(const absl::optional<DataRate>& rate,
54 int64_t fallback_bps) {
55 if (rate && rate->IsFinite()) {
56 return rate->bps();
57 } else {
58 return fallback_bps;
59 }
60 }
61
IsEnabled(const WebRtcKeyValueConfig * config,absl::string_view key)62 bool IsEnabled(const WebRtcKeyValueConfig* config, absl::string_view key) {
63 return absl::StartsWith(config->Lookup(key), "Enabled");
64 }
65
IsNotDisabled(const WebRtcKeyValueConfig * config,absl::string_view key)66 bool IsNotDisabled(const WebRtcKeyValueConfig* config, absl::string_view key) {
67 return !absl::StartsWith(config->Lookup(key), "Disabled");
68 }
69 } // namespace
70
GoogCcNetworkController(NetworkControllerConfig config,GoogCcConfig goog_cc_config)71 GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config,
72 GoogCcConfig goog_cc_config)
73 : key_value_config_(config.key_value_config ? config.key_value_config
74 : &trial_based_config_),
75 event_log_(config.event_log),
76 packet_feedback_only_(goog_cc_config.feedback_only),
77 safe_reset_on_route_change_("Enabled"),
78 safe_reset_acknowledged_rate_("ack"),
79 use_min_allocatable_as_lower_bound_(
80 IsNotDisabled(key_value_config_, "WebRTC-Bwe-MinAllocAsLowerBound")),
81 ignore_probes_lower_than_network_estimate_(IsNotDisabled(
82 key_value_config_,
83 "WebRTC-Bwe-IgnoreProbesLowerThanNetworkStateEstimate")),
84 limit_probes_lower_than_throughput_estimate_(
85 IsEnabled(key_value_config_,
86 "WebRTC-Bwe-LimitProbesLowerThanThroughputEstimate")),
87 rate_control_settings_(
88 RateControlSettings::ParseFromKeyValueConfig(key_value_config_)),
89 loss_based_stable_rate_(
90 IsEnabled(key_value_config_, "WebRTC-Bwe-LossBasedStableRate")),
91 probe_controller_(
92 new ProbeController(key_value_config_, config.event_log)),
93 congestion_window_pushback_controller_(
94 rate_control_settings_.UseCongestionWindowPushback()
95 ? std::make_unique<CongestionWindowPushbackController>(
96 key_value_config_)
97 : nullptr),
98 bandwidth_estimation_(
99 std::make_unique<SendSideBandwidthEstimation>(event_log_)),
100 alr_detector_(
101 std::make_unique<AlrDetector>(key_value_config_, config.event_log)),
102 probe_bitrate_estimator_(new ProbeBitrateEstimator(config.event_log)),
103 network_estimator_(std::move(goog_cc_config.network_state_estimator)),
104 network_state_predictor_(
105 std::move(goog_cc_config.network_state_predictor)),
106 delay_based_bwe_(new DelayBasedBwe(key_value_config_,
107 event_log_,
108 network_state_predictor_.get())),
109 acknowledged_bitrate_estimator_(
110 AcknowledgedBitrateEstimatorInterface::Create(key_value_config_)),
111 initial_config_(config),
112 last_loss_based_target_rate_(*config.constraints.starting_rate),
113 last_pushback_target_rate_(last_loss_based_target_rate_),
114 last_stable_target_rate_(last_loss_based_target_rate_),
115 pacing_factor_(config.stream_based_config.pacing_factor.value_or(
116 kDefaultPaceMultiplier)),
117 min_total_allocated_bitrate_(
118 config.stream_based_config.min_total_allocated_bitrate.value_or(
119 DataRate::Zero())),
120 max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
121 DataRate::Zero())),
122 max_total_allocated_bitrate_(DataRate::Zero()) {
123 RTC_DCHECK(config.constraints.at_time.IsFinite());
124 ParseFieldTrial(
125 {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
126 key_value_config_->Lookup("WebRTC-Bwe-SafeResetOnRouteChange"));
127 if (delay_based_bwe_)
128 delay_based_bwe_->SetMinBitrate(congestion_controller::GetMinBitrate());
129 }
130
~GoogCcNetworkController()131 GoogCcNetworkController::~GoogCcNetworkController() {}
132
OnNetworkAvailability(NetworkAvailability msg)133 NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability(
134 NetworkAvailability msg) {
135 NetworkControlUpdate update;
136 update.probe_cluster_configs = probe_controller_->OnNetworkAvailability(msg);
137 return update;
138 }
139
OnNetworkRouteChange(NetworkRouteChange msg)140 NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
141 NetworkRouteChange msg) {
142 if (safe_reset_on_route_change_) {
143 absl::optional<DataRate> estimated_bitrate;
144 if (safe_reset_acknowledged_rate_) {
145 estimated_bitrate = acknowledged_bitrate_estimator_->bitrate();
146 if (!estimated_bitrate)
147 estimated_bitrate = acknowledged_bitrate_estimator_->PeekRate();
148 } else {
149 estimated_bitrate = bandwidth_estimation_->target_rate();
150 }
151 if (estimated_bitrate) {
152 if (msg.constraints.starting_rate) {
153 msg.constraints.starting_rate =
154 std::min(*msg.constraints.starting_rate, *estimated_bitrate);
155 } else {
156 msg.constraints.starting_rate = estimated_bitrate;
157 }
158 }
159 }
160
161 acknowledged_bitrate_estimator_ =
162 AcknowledgedBitrateEstimatorInterface::Create(key_value_config_);
163 probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
164 if (network_estimator_)
165 network_estimator_->OnRouteChange(msg);
166 delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_,
167 network_state_predictor_.get()));
168 bandwidth_estimation_->OnRouteChange();
169 probe_controller_->Reset(msg.at_time.ms());
170 NetworkControlUpdate update;
171 update.probe_cluster_configs = ResetConstraints(msg.constraints);
172 MaybeTriggerOnNetworkChanged(&update, msg.at_time);
173 return update;
174 }
175
OnProcessInterval(ProcessInterval msg)176 NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
177 ProcessInterval msg) {
178 NetworkControlUpdate update;
179 if (initial_config_) {
180 update.probe_cluster_configs =
181 ResetConstraints(initial_config_->constraints);
182 update.pacer_config = GetPacingRates(msg.at_time);
183
184 if (initial_config_->stream_based_config.requests_alr_probing) {
185 probe_controller_->EnablePeriodicAlrProbing(
186 *initial_config_->stream_based_config.requests_alr_probing);
187 }
188 absl::optional<DataRate> total_bitrate =
189 initial_config_->stream_based_config.max_total_allocated_bitrate;
190 if (total_bitrate) {
191 auto probes = probe_controller_->OnMaxTotalAllocatedBitrate(
192 total_bitrate->bps(), msg.at_time.ms());
193 update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
194 probes.begin(), probes.end());
195
196 max_total_allocated_bitrate_ = *total_bitrate;
197 }
198 initial_config_.reset();
199 }
200 if (congestion_window_pushback_controller_ && msg.pacer_queue) {
201 congestion_window_pushback_controller_->UpdatePacingQueue(
202 msg.pacer_queue->bytes());
203 }
204 bandwidth_estimation_->UpdateEstimate(msg.at_time);
205 absl::optional<int64_t> start_time_ms =
206 alr_detector_->GetApplicationLimitedRegionStartTime();
207 probe_controller_->SetAlrStartTimeMs(start_time_ms);
208
209 auto probes = probe_controller_->Process(msg.at_time.ms());
210 update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
211 probes.begin(), probes.end());
212
213 if (rate_control_settings_.UseCongestionWindow() &&
214 last_packet_received_time_.IsFinite() && !feedback_max_rtts_.empty()) {
215 UpdateCongestionWindowSize();
216 }
217 if (congestion_window_pushback_controller_ && current_data_window_) {
218 congestion_window_pushback_controller_->SetDataWindow(
219 *current_data_window_);
220 } else {
221 update.congestion_window = current_data_window_;
222 }
223 MaybeTriggerOnNetworkChanged(&update, msg.at_time);
224 return update;
225 }
226
OnRemoteBitrateReport(RemoteBitrateReport msg)227 NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport(
228 RemoteBitrateReport msg) {
229 if (packet_feedback_only_) {
230 RTC_LOG(LS_ERROR) << "Received REMB for packet feedback only GoogCC";
231 return NetworkControlUpdate();
232 }
233 bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time,
234 msg.bandwidth);
235 BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
236 msg.bandwidth.bps() / 1000);
237 return NetworkControlUpdate();
238 }
239
OnRoundTripTimeUpdate(RoundTripTimeUpdate msg)240 NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate(
241 RoundTripTimeUpdate msg) {
242 if (packet_feedback_only_ || msg.smoothed)
243 return NetworkControlUpdate();
244 RTC_DCHECK(!msg.round_trip_time.IsZero());
245 if (delay_based_bwe_)
246 delay_based_bwe_->OnRttUpdate(msg.round_trip_time);
247 bandwidth_estimation_->UpdateRtt(msg.round_trip_time, msg.receive_time);
248 return NetworkControlUpdate();
249 }
250
OnSentPacket(SentPacket sent_packet)251 NetworkControlUpdate GoogCcNetworkController::OnSentPacket(
252 SentPacket sent_packet) {
253 alr_detector_->OnBytesSent(sent_packet.size.bytes(),
254 sent_packet.send_time.ms());
255 acknowledged_bitrate_estimator_->SetAlr(
256 alr_detector_->GetApplicationLimitedRegionStartTime().has_value());
257
258 if (!first_packet_sent_) {
259 first_packet_sent_ = true;
260 // Initialize feedback time to send time to allow estimation of RTT until
261 // first feedback is received.
262 bandwidth_estimation_->UpdatePropagationRtt(sent_packet.send_time,
263 TimeDelta::Zero());
264 }
265 bandwidth_estimation_->OnSentPacket(sent_packet);
266
267 if (congestion_window_pushback_controller_) {
268 congestion_window_pushback_controller_->UpdateOutstandingData(
269 sent_packet.data_in_flight.bytes());
270 NetworkControlUpdate update;
271 MaybeTriggerOnNetworkChanged(&update, sent_packet.send_time);
272 return update;
273 } else {
274 return NetworkControlUpdate();
275 }
276 }
277
OnReceivedPacket(ReceivedPacket received_packet)278 NetworkControlUpdate GoogCcNetworkController::OnReceivedPacket(
279 ReceivedPacket received_packet) {
280 last_packet_received_time_ = received_packet.receive_time;
281 return NetworkControlUpdate();
282 }
283
OnStreamsConfig(StreamsConfig msg)284 NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig(
285 StreamsConfig msg) {
286 NetworkControlUpdate update;
287 if (msg.requests_alr_probing) {
288 probe_controller_->EnablePeriodicAlrProbing(*msg.requests_alr_probing);
289 }
290 if (msg.max_total_allocated_bitrate &&
291 *msg.max_total_allocated_bitrate != max_total_allocated_bitrate_) {
292 if (rate_control_settings_.TriggerProbeOnMaxAllocatedBitrateChange()) {
293 update.probe_cluster_configs =
294 probe_controller_->OnMaxTotalAllocatedBitrate(
295 msg.max_total_allocated_bitrate->bps(), msg.at_time.ms());
296 } else {
297 probe_controller_->SetMaxBitrate(msg.max_total_allocated_bitrate->bps());
298 }
299 max_total_allocated_bitrate_ = *msg.max_total_allocated_bitrate;
300 }
301 bool pacing_changed = false;
302 if (msg.pacing_factor && *msg.pacing_factor != pacing_factor_) {
303 pacing_factor_ = *msg.pacing_factor;
304 pacing_changed = true;
305 }
306 if (msg.min_total_allocated_bitrate &&
307 *msg.min_total_allocated_bitrate != min_total_allocated_bitrate_) {
308 min_total_allocated_bitrate_ = *msg.min_total_allocated_bitrate;
309 pacing_changed = true;
310
311 if (use_min_allocatable_as_lower_bound_) {
312 ClampConstraints();
313 delay_based_bwe_->SetMinBitrate(min_data_rate_);
314 bandwidth_estimation_->SetMinMaxBitrate(min_data_rate_, max_data_rate_);
315 }
316 }
317 if (msg.max_padding_rate && *msg.max_padding_rate != max_padding_rate_) {
318 max_padding_rate_ = *msg.max_padding_rate;
319 pacing_changed = true;
320 }
321
322 if (pacing_changed)
323 update.pacer_config = GetPacingRates(msg.at_time);
324 return update;
325 }
326
OnTargetRateConstraints(TargetRateConstraints constraints)327 NetworkControlUpdate GoogCcNetworkController::OnTargetRateConstraints(
328 TargetRateConstraints constraints) {
329 NetworkControlUpdate update;
330 update.probe_cluster_configs = ResetConstraints(constraints);
331 MaybeTriggerOnNetworkChanged(&update, constraints.at_time);
332 return update;
333 }
334
ClampConstraints()335 void GoogCcNetworkController::ClampConstraints() {
336 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
337 // and that we don't try to set the min bitrate to 0 from any applications.
338 // The congestion controller should allow a min bitrate of 0.
339 min_data_rate_ =
340 std::max(min_target_rate_, congestion_controller::GetMinBitrate());
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_.bps(), GetBpsOrDefault(starting_rate_, -1),
371 max_data_rate_.bps_or(-1), new_constraints.at_time.ms());
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 = feedback.receive_time - max_recv_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 = std::accumulate(feedback_max_rtts_.begin(),
446 feedback_max_rtts_.end(), 0);
447 int64_t mean_rtt_ms = sum_rtt_ms / feedback_max_rtts_.size();
448 if (delay_based_bwe_)
449 delay_based_bwe_->OnRttUpdate(TimeDelta::Millis(mean_rtt_ms));
450 }
451
452 TimeDelta feedback_min_rtt = TimeDelta::PlusInfinity();
453 for (const auto& packet_feedback : feedbacks) {
454 TimeDelta pending_time = packet_feedback.receive_time - max_recv_time;
455 TimeDelta rtt = report.feedback_time -
456 packet_feedback.sent_packet.send_time - pending_time;
457 // Value used for predicting NACK round trip time in FEC controller.
458 feedback_min_rtt = std::min(rtt, feedback_min_rtt);
459 }
460 if (feedback_min_rtt.IsFinite()) {
461 bandwidth_estimation_->UpdateRtt(feedback_min_rtt, report.feedback_time);
462 }
463
464 expected_packets_since_last_loss_update_ +=
465 report.PacketsWithFeedback().size();
466 for (const auto& packet_feedback : report.PacketsWithFeedback()) {
467 if (packet_feedback.receive_time.IsInfinite())
468 lost_packets_since_last_loss_update_ += 1;
469 }
470 if (report.feedback_time > next_loss_update_) {
471 next_loss_update_ = report.feedback_time + kLossUpdateInterval;
472 bandwidth_estimation_->UpdatePacketsLost(
473 lost_packets_since_last_loss_update_,
474 expected_packets_since_last_loss_update_, report.feedback_time);
475 expected_packets_since_last_loss_update_ = 0;
476 lost_packets_since_last_loss_update_ = 0;
477 }
478 }
479 absl::optional<int64_t> alr_start_time =
480 alr_detector_->GetApplicationLimitedRegionStartTime();
481
482 if (previously_in_alr_ && !alr_start_time.has_value()) {
483 int64_t now_ms = report.feedback_time.ms();
484 acknowledged_bitrate_estimator_->SetAlrEndedTime(report.feedback_time);
485 probe_controller_->SetAlrEndedTimeMs(now_ms);
486 }
487 previously_in_alr_ = alr_start_time.has_value();
488 acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
489 report.SortedByReceiveTime());
490 auto acknowledged_bitrate = acknowledged_bitrate_estimator_->bitrate();
491 bandwidth_estimation_->SetAcknowledgedRate(acknowledged_bitrate,
492 report.feedback_time);
493 bandwidth_estimation_->IncomingPacketFeedbackVector(report);
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 }
512 }
513 absl::optional<DataRate> probe_bitrate =
514 probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate();
515 if (ignore_probes_lower_than_network_estimate_ && probe_bitrate &&
516 estimate_ && *probe_bitrate < delay_based_bwe_->last_estimate() &&
517 *probe_bitrate < estimate_->link_capacity_lower) {
518 probe_bitrate.reset();
519 }
520 if (limit_probes_lower_than_throughput_estimate_ && probe_bitrate &&
521 acknowledged_bitrate) {
522 // Limit the backoff to something slightly below the acknowledged
523 // bitrate. ("Slightly below" because we want to drain the queues
524 // if we are actually overusing.)
525 // The acknowledged bitrate shouldn't normally be higher than the delay
526 // based estimate, but it could happen e.g. due to packet bursts or
527 // encoder overshoot. We use std::min to ensure that a probe result
528 // below the current BWE never causes an increase.
529 DataRate limit =
530 std::min(delay_based_bwe_->last_estimate(),
531 *acknowledged_bitrate * kProbeDropThroughputFraction);
532 probe_bitrate = std::max(*probe_bitrate, limit);
533 }
534
535 NetworkControlUpdate update;
536 bool recovered_from_overuse = false;
537 bool backoff_in_alr = 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 // Update the estimate in the ProbeController, in case we want to probe.
554 MaybeTriggerOnNetworkChanged(&update, report.feedback_time);
555 }
556 recovered_from_overuse = result.recovered_from_overuse;
557 backoff_in_alr = result.backoff_in_alr;
558
559 if (recovered_from_overuse) {
560 probe_controller_->SetAlrStartTimeMs(alr_start_time);
561 auto probes = probe_controller_->RequestProbe(report.feedback_time.ms());
562 update.probe_cluster_configs.insert(update.probe_cluster_configs.end(),
563 probes.begin(), probes.end());
564 } else if (backoff_in_alr) {
565 // If we just backed off during ALR, request a new probe.
566 auto probes = probe_controller_->RequestProbe(report.feedback_time.ms());
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 if (loss_based_stable_rate_) {
645 stable_target_rate = std::min(stable_target_rate, loss_based_target_rate);
646 } else {
647 stable_target_rate = std::min(stable_target_rate, pushback_target_rate);
648 }
649
650 if ((loss_based_target_rate != last_loss_based_target_rate_) ||
651 (fraction_loss != last_estimated_fraction_loss_) ||
652 (round_trip_time != last_estimated_round_trip_time_) ||
653 (pushback_target_rate != last_pushback_target_rate_) ||
654 (stable_target_rate != last_stable_target_rate_)) {
655 last_loss_based_target_rate_ = loss_based_target_rate;
656 last_pushback_target_rate_ = pushback_target_rate;
657 last_estimated_fraction_loss_ = fraction_loss;
658 last_estimated_round_trip_time_ = round_trip_time;
659 last_stable_target_rate_ = stable_target_rate;
660
661 alr_detector_->SetEstimatedBitrate(loss_based_target_rate.bps());
662
663 TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod();
664
665 TargetTransferRate target_rate_msg;
666 target_rate_msg.at_time = at_time;
667 if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) {
668 target_rate_msg.target_rate = loss_based_target_rate;
669 target_rate_msg.cwnd_reduce_ratio = cwnd_reduce_ratio;
670 } else {
671 target_rate_msg.target_rate = pushback_target_rate;
672 }
673 target_rate_msg.stable_target_rate = stable_target_rate;
674 target_rate_msg.network_estimate.at_time = at_time;
675 target_rate_msg.network_estimate.round_trip_time = round_trip_time;
676 target_rate_msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0f;
677 target_rate_msg.network_estimate.bwe_period = bwe_period;
678
679 update->target_rate = target_rate_msg;
680
681 auto probes = probe_controller_->SetEstimatedBitrate(
682 loss_based_target_rate.bps(), at_time.ms());
683 update->probe_cluster_configs.insert(update->probe_cluster_configs.end(),
684 probes.begin(), probes.end());
685 update->pacer_config = GetPacingRates(at_time);
686
687 RTC_LOG(LS_VERBOSE) << "bwe " << at_time.ms() << " pushback_target_bps="
688 << last_pushback_target_rate_.bps()
689 << " estimate_bps=" << loss_based_target_rate.bps();
690 }
691 }
692
GetPacingRates(Timestamp at_time) const693 PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {
694 // Pacing rate is based on target rate before congestion window pushback,
695 // because we don't want to build queues in the pacer when pushback occurs.
696 DataRate pacing_rate =
697 std::max(min_total_allocated_bitrate_, last_loss_based_target_rate_) *
698 pacing_factor_;
699 DataRate padding_rate =
700 std::min(max_padding_rate_, last_pushback_target_rate_);
701 PacerConfig msg;
702 msg.at_time = at_time;
703 msg.time_window = TimeDelta::Seconds(1);
704 msg.data_window = pacing_rate * msg.time_window;
705 msg.pad_window = padding_rate * msg.time_window;
706 return msg;
707 }
708
709 } // namespace webrtc
710