blob: 0439c1d567bdbf98626e67521116e0ab7b67d1e1 [file] [log] [blame]
nisse559af382017-03-21 06:41:12 -07001/*
2 * Copyright (c) 2012 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/congestion_controller/include/send_side_congestion_controller.h"
nisse559af382017-03-21 06:41:12 -070012
13#include <algorithm>
Sebastian Janssonea86bb72018-02-14 16:53:38 +000014#include <cstdio>
Mirko Bonadeie32bb502018-04-11 14:59:08 +020015#include <iterator>
nisse559af382017-03-21 06:41:12 -070016#include <memory>
17#include <vector>
Sebastian Janssonea86bb72018-02-14 16:53:38 +000018
Karl Wiberg918f50c2018-07-05 11:40:33 +020019#include "absl/memory/memory.h"
Sebastian Janssonea86bb72018-02-14 16:53:38 +000020#include "modules/bitrate_controller/include/bitrate_controller.h"
Ying Wange1d7b232018-07-17 16:01:25 +020021#include "modules/congestion_controller/congestion_window_pushback_controller.h"
Sebastian Jansson172fd852018-05-24 14:17:06 +020022#include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +020023#include "modules/congestion_controller/goog_cc/probe_controller.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
25#include "rtc_base/checks.h"
26#include "rtc_base/format_macros.h"
27#include "rtc_base/logging.h"
Oleh Prypina40f8242017-12-21 13:32:23 +010028#include "rtc_base/numerics/safe_conversions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/rate_limiter.h"
30#include "rtc_base/socket.h"
31#include "rtc_base/timeutils.h"
32#include "system_wrappers/include/field_trial.h"
Ilya Nikolaevskiy2ffe3e82018-01-17 19:57:24 +000033#include "system_wrappers/include/runtime_enabled_features.h"
nisse559af382017-03-21 06:41:12 -070034
35namespace webrtc {
36namespace {
37
Sebastian Janssonea86bb72018-02-14 16:53:38 +000038const char kCwndExperiment[] = "WebRTC-CwndExperiment";
39const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
Ying Wange1d7b232018-07-17 16:01:25 +020040
41// When CongestionWindowPushback is enabled, the pacer is oblivious to
42// the congestion window. The relation between outstanding data and
43// the congestion window affects encoder allocations directly.
44const char kCongestionPushbackExperiment[] = "WebRTC-CongestionWindowPushback";
45
Sebastian Janssonea86bb72018-02-14 16:53:38 +000046const int64_t kDefaultAcceptedQueueMs = 250;
47
48bool CwndExperimentEnabled() {
49 std::string experiment_string =
50 webrtc::field_trial::FindFullName(kCwndExperiment);
51 // The experiment is enabled iff the field trial string begins with "Enabled".
52 return experiment_string.find("Enabled") == 0;
53}
54
55bool ReadCwndExperimentParameter(int64_t* accepted_queue_ms) {
56 RTC_DCHECK(accepted_queue_ms);
57 std::string experiment_string =
58 webrtc::field_trial::FindFullName(kCwndExperiment);
59 int parsed_values =
60 sscanf(experiment_string.c_str(), "Enabled-%" PRId64, accepted_queue_ms);
61 if (parsed_values == 1) {
62 RTC_CHECK_GE(*accepted_queue_ms, 0)
63 << "Accepted must be greater than or equal to 0.";
64 return true;
65 }
66 return false;
67}
68
Ying Wange1d7b232018-07-17 16:01:25 +020069bool IsCongestionWindowPushbackExperimentEnabled() {
70 return webrtc::field_trial::IsEnabled(kCongestionPushbackExperiment) &&
71 webrtc::field_trial::IsEnabled(kCwndExperiment);
72}
73
74std::unique_ptr<CongestionWindowPushbackController>
75MaybeCreateCongestionWindowPushbackController() {
76 return IsCongestionWindowPushbackExperimentEnabled()
77 ? absl::make_unique<CongestionWindowPushbackController>()
78 : nullptr;
79}
80
nisse559af382017-03-21 06:41:12 -070081static const int64_t kRetransmitWindowSizeMs = 500;
82
Sebastian Janssonea86bb72018-02-14 16:53:38 +000083// Makes sure that the bitrate and the min, max values are in valid range.
84static void ClampBitrates(int* bitrate_bps,
85 int* min_bitrate_bps,
86 int* max_bitrate_bps) {
87 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
88 // and that we don't try to set the min bitrate to 0 from any applications.
89 // The congestion controller should allow a min bitrate of 0.
90 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps())
91 *min_bitrate_bps = congestion_controller::GetMinBitrateBps();
92 if (*max_bitrate_bps > 0)
93 *max_bitrate_bps = std::max(*min_bitrate_bps, *max_bitrate_bps);
94 if (*bitrate_bps > 0)
95 *bitrate_bps = std::max(*min_bitrate_bps, *bitrate_bps);
nisse559af382017-03-21 06:41:12 -070096}
97
Sebastian Janssonea86bb72018-02-14 16:53:38 +000098std::vector<webrtc::PacketFeedback> ReceivedPacketFeedbackVector(
99 const std::vector<webrtc::PacketFeedback>& input) {
100 std::vector<PacketFeedback> received_packet_feedback_vector;
101 auto is_received = [](const webrtc::PacketFeedback& packet_feedback) {
102 return packet_feedback.arrival_time_ms !=
103 webrtc::PacketFeedback::kNotReceived;
104 };
105 std::copy_if(input.begin(), input.end(),
106 std::back_inserter(received_packet_feedback_vector),
107 is_received);
108 return received_packet_feedback_vector;
tschumim3fae6282017-06-11 23:57:17 -0700109}
110
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000111void SortPacketFeedbackVector(
112 std::vector<webrtc::PacketFeedback>* const input) {
113 RTC_DCHECK(input);
tschumim3fae6282017-06-11 23:57:17 -0700114 std::sort(input->begin(), input->end(), PacketFeedbackComparator());
115}
116
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000117bool IsPacerPushbackExperimentEnabled() {
Yves Gerey665174f2018-06-19 15:03:05 +0200118 return webrtc::field_trial::IsEnabled(kPacerPushbackExperiment) ||
119 (!webrtc::field_trial::IsDisabled(kPacerPushbackExperiment) &&
120 webrtc::runtime_enabled_features::IsFeatureEnabled(
121 webrtc::runtime_enabled_features::kDualStreamModeFeatureName));
Ilya Nikolaevskiy2ffe3e82018-01-17 19:57:24 +0000122}
123
nisse559af382017-03-21 06:41:12 -0700124} // namespace
125
126SendSideCongestionController::SendSideCongestionController(
127 const Clock* clock,
128 Observer* observer,
129 RtcEventLog* event_log,
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200130 PacedSender* pacer)
nisse559af382017-03-21 06:41:12 -0700131 : clock_(clock),
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000132 observer_(observer),
133 event_log_(event_log),
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200134 pacer_(pacer),
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000135 bitrate_controller_(
136 BitrateController::CreateBitrateController(clock_, event_log)),
137 acknowledged_bitrate_estimator_(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200138 absl::make_unique<AcknowledgedBitrateEstimator>()),
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200139 probe_controller_(new ProbeController()),
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000140 retransmission_rate_limiter_(
141 new RateLimiter(clock, kRetransmitWindowSizeMs)),
nisse559af382017-03-21 06:41:12 -0700142 transport_feedback_adapter_(clock_),
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000143 last_reported_bitrate_bps_(0),
144 last_reported_fraction_loss_(0),
145 last_reported_rtt_(0),
146 network_state_(kNetworkUp),
147 pause_pacer_(false),
148 pacer_paused_(false),
149 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
Sebastian Jansson04b18cb2018-07-02 09:25:25 +0200150 delay_based_bwe_(new DelayBasedBwe(event_log_)),
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000151 in_cwnd_experiment_(CwndExperimentEnabled()),
152 accepted_queue_ms_(kDefaultAcceptedQueueMs),
153 was_in_alr_(false),
Stefan Holmer4dbc7e42018-01-26 15:09:41 +0100154 send_side_bwe_with_overhead_(
155 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
156 transport_overhead_bytes_per_packet_(0),
Ying Wange1d7b232018-07-17 16:01:25 +0200157 pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()),
158 congestion_window_pushback_controller_(
159 MaybeCreateCongestionWindowPushbackController()) {
Per Kjellanderdd3eae52018-05-18 07:12:15 +0000160 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000161 if (in_cwnd_experiment_ &&
162 !ReadCwndExperimentParameter(&accepted_queue_ms_)) {
163 RTC_LOG(LS_WARNING) << "Failed to parse parameters for CwndExperiment "
164 "from field trial string. Experiment disabled.";
165 in_cwnd_experiment_ = false;
166 }
Sebastian Jansson65792c52018-02-14 16:50:17 +0000167}
Danil Chapovalov4e849f62018-02-14 08:28:02 +0000168
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000169SendSideCongestionController::~SendSideCongestionController() {}
170
elad.alond12a8e12017-03-23 11:04:48 -0700171void SendSideCongestionController::RegisterPacketFeedbackObserver(
172 PacketFeedbackObserver* observer) {
173 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer);
174}
175
176void SendSideCongestionController::DeRegisterPacketFeedbackObserver(
177 PacketFeedbackObserver* observer) {
178 transport_feedback_adapter_.DeRegisterPacketFeedbackObserver(observer);
179}
180
nisse23425f92017-04-03 04:54:25 -0700181void SendSideCongestionController::RegisterNetworkObserver(Observer* observer) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000182 rtc::CritScope cs(&observer_lock_);
183 RTC_DCHECK(observer_ == nullptr);
184 observer_ = observer;
nisse23425f92017-04-03 04:54:25 -0700185}
186
187void SendSideCongestionController::DeRegisterNetworkObserver(
188 Observer* observer) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000189 rtc::CritScope cs(&observer_lock_);
190 RTC_DCHECK_EQ(observer_, observer);
191 observer_ = nullptr;
nisse23425f92017-04-03 04:54:25 -0700192}
193
nisse559af382017-03-21 06:41:12 -0700194void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps,
195 int start_bitrate_bps,
196 int max_bitrate_bps) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000197 ClampBitrates(&start_bitrate_bps, &min_bitrate_bps, &max_bitrate_bps);
198 bitrate_controller_->SetBitrates(start_bitrate_bps, min_bitrate_bps,
199 max_bitrate_bps);
200
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200201 {
202 rtc::CritScope cs(&probe_lock_);
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200203 SendProbes(probe_controller_->SetBitrates(
204 min_bitrate_bps, start_bitrate_bps, max_bitrate_bps,
205 clock_->TimeInMilliseconds()));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200206 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000207
208 {
209 rtc::CritScope cs(&bwe_lock_);
210 if (start_bitrate_bps > 0)
211 delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
212 min_bitrate_bps_ = min_bitrate_bps;
Per Kjellanderdd3eae52018-05-18 07:12:15 +0000213 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000214 }
215 MaybeTriggerOnNetworkChanged();
nisse559af382017-03-21 06:41:12 -0700216}
217
Sebastian Jansson68ee4652018-03-13 11:40:34 +0100218void SendSideCongestionController::SetAllocatedSendBitrateLimits(
219 int64_t min_send_bitrate_bps,
220 int64_t max_padding_bitrate_bps,
221 int64_t max_total_bitrate_bps) {
222 pacer_->SetSendBitrateLimits(min_send_bitrate_bps, max_padding_bitrate_bps);
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200223
224 rtc::CritScope cs(&probe_lock_);
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200225 SendProbes(probe_controller_->OnMaxTotalAllocatedBitrate(
226 max_total_bitrate_bps, clock_->TimeInMilliseconds()));
philipeldb4fa4b2018-03-06 18:29:22 +0100227}
228
nisse559af382017-03-21 06:41:12 -0700229// TODO(holmer): Split this up and use SetBweBitrates in combination with
230// OnNetworkRouteChanged.
231void SendSideCongestionController::OnNetworkRouteChanged(
232 const rtc::NetworkRoute& network_route,
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000233 int bitrate_bps,
nisse559af382017-03-21 06:41:12 -0700234 int min_bitrate_bps,
235 int max_bitrate_bps) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000236 ClampBitrates(&bitrate_bps, &min_bitrate_bps, &max_bitrate_bps);
237 // TODO(honghaiz): Recreate this object once the bitrate controller is
238 // no longer exposed outside SendSideCongestionController.
239 bitrate_controller_->ResetBitrates(bitrate_bps, min_bitrate_bps,
240 max_bitrate_bps);
241
nisse559af382017-03-21 06:41:12 -0700242 transport_feedback_adapter_.SetNetworkIds(network_route.local_network_id,
243 network_route.remote_network_id);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000244 {
245 rtc::CritScope cs(&bwe_lock_);
Sebastian Jansson3c24ea82018-02-23 18:30:26 +0100246 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000247 min_bitrate_bps_ = min_bitrate_bps;
Sebastian Jansson04b18cb2018-07-02 09:25:25 +0200248 delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000249 acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator());
250 delay_based_bwe_->SetStartBitrate(bitrate_bps);
Per Kjellanderdd3eae52018-05-18 07:12:15 +0000251 delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000252 }
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200253 {
254 rtc::CritScope cs(&probe_lock_);
255 probe_controller_->Reset(clock_->TimeInMilliseconds());
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200256 SendProbes(probe_controller_->SetBitrates(min_bitrate_bps, bitrate_bps,
257 max_bitrate_bps,
258 clock_->TimeInMilliseconds()));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200259 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000260
261 MaybeTriggerOnNetworkChanged();
262}
263
264BitrateController* SendSideCongestionController::GetBitrateController() const {
265 return bitrate_controller_.get();
nisse559af382017-03-21 06:41:12 -0700266}
267
srtea6092a92017-11-22 19:37:43 +0100268bool SendSideCongestionController::AvailableBandwidth(
269 uint32_t* bandwidth) const {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000270 return bitrate_controller_->AvailableBandwidth(bandwidth);
srtea6092a92017-11-22 19:37:43 +0100271}
272
Sebastian Jansson98e01112018-02-28 16:47:29 +0100273RtcpBandwidthObserver* SendSideCongestionController::GetBandwidthObserver() {
274 return bitrate_controller_.get();
275}
276
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000277RtcpBandwidthObserver* SendSideCongestionController::GetBandwidthObserver()
278 const {
279 return bitrate_controller_.get();
Sebastian Jansson8d9c5402017-11-15 17:22:16 +0100280}
281
nisse559af382017-03-21 06:41:12 -0700282RateLimiter* SendSideCongestionController::GetRetransmissionRateLimiter() {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000283 return retransmission_rate_limiter_.get();
nisse559af382017-03-21 06:41:12 -0700284}
285
Sebastian Jansson1d430f72018-03-21 12:47:10 +0100286void SendSideCongestionController::SetPerPacketFeedbackAvailable(
287 bool available) {}
288
nisse559af382017-03-21 06:41:12 -0700289void SendSideCongestionController::EnablePeriodicAlrProbing(bool enable) {
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200290 rtc::CritScope cs(&probe_lock_);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000291 probe_controller_->EnablePeriodicAlrProbing(enable);
nisse559af382017-03-21 06:41:12 -0700292}
293
nisse559af382017-03-21 06:41:12 -0700294int64_t SendSideCongestionController::GetPacerQueuingDelayMs() const {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000295 return IsNetworkDown() ? 0 : pacer_->QueueInMs();
nisse559af382017-03-21 06:41:12 -0700296}
297
asaperssonfc5e81c2017-04-19 23:28:53 -0700298int64_t SendSideCongestionController::GetFirstPacketTimeMs() const {
299 return pacer_->FirstSentPacketTimeMs();
300}
301
nisse76e62b02017-05-31 02:24:52 -0700302TransportFeedbackObserver*
303SendSideCongestionController::GetTransportFeedbackObserver() {
304 return this;
305}
306
nisse559af382017-03-21 06:41:12 -0700307void SendSideCongestionController::SignalNetworkState(NetworkState state) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100308 RTC_LOG(LS_INFO) << "SignalNetworkState "
309 << (state == kNetworkUp ? "Up" : "Down");
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000310 {
311 rtc::CritScope cs(&network_state_lock_);
312 pause_pacer_ = state == kNetworkDown;
313 network_state_ = state;
314 }
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200315
316 {
317 rtc::CritScope cs(&probe_lock_);
318 NetworkAvailability msg;
319 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
320 msg.network_available = state == kNetworkUp;
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200321 SendProbes(probe_controller_->OnNetworkAvailability(msg));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200322 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000323 MaybeTriggerOnNetworkChanged();
nisse559af382017-03-21 06:41:12 -0700324}
325
326void SendSideCongestionController::SetTransportOverhead(
327 size_t transport_overhead_bytes_per_packet) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000328 rtc::CritScope cs(&bwe_lock_);
Stefan Holmer4dbc7e42018-01-26 15:09:41 +0100329 transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
nisse559af382017-03-21 06:41:12 -0700330}
331
332void SendSideCongestionController::OnSentPacket(
333 const rtc::SentPacket& sent_packet) {
334 // We're not interested in packets without an id, which may be stun packets,
335 // etc, sent on the same transport.
336 if (sent_packet.packet_id == -1)
337 return;
338 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
339 sent_packet.send_time_ms);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000340 if (in_cwnd_experiment_)
341 LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
nisse559af382017-03-21 06:41:12 -0700342}
343
344void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
345 int64_t max_rtt_ms) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000346 rtc::CritScope cs(&bwe_lock_);
Sebastian Jansson04b18cb2018-07-02 09:25:25 +0200347 delay_based_bwe_->OnRttUpdate(avg_rtt_ms);
nisse559af382017-03-21 06:41:12 -0700348}
349
350int64_t SendSideCongestionController::TimeUntilNextProcess() {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000351 return bitrate_controller_->TimeUntilNextProcess();
nisse559af382017-03-21 06:41:12 -0700352}
353
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200354void SendSideCongestionController::SendProbes(
355 std::vector<ProbeClusterConfig> probe_configs) {
356 for (auto probe_config : probe_configs) {
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200357 pacer_->CreateProbeCluster(probe_config.target_data_rate.bps());
358 }
359}
360
nisse559af382017-03-21 06:41:12 -0700361void SendSideCongestionController::Process() {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000362 bool pause_pacer;
363 // TODO(holmer): Once this class is running on a task queue we should
364 // replace this with a task instead.
stefan9e117c5e12017-08-16 08:16:25 -0700365 {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000366 rtc::CritScope lock(&network_state_lock_);
367 pause_pacer = pause_pacer_;
stefan9e117c5e12017-08-16 08:16:25 -0700368 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000369 if (pause_pacer && !pacer_paused_) {
370 pacer_->Pause();
371 pacer_paused_ = true;
372 } else if (!pause_pacer && pacer_paused_) {
373 pacer_->Resume();
374 pacer_paused_ = false;
stefan9e117c5e12017-08-16 08:16:25 -0700375 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000376 bitrate_controller_->Process();
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200377
378 {
379 rtc::CritScope cs(&probe_lock_);
380 probe_controller_->SetAlrStartTimeMs(
381 pacer_->GetApplicationLimitedRegionStartTime());
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200382 SendProbes(probe_controller_->Process(clock_->TimeInMilliseconds()));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200383 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000384 MaybeTriggerOnNetworkChanged();
nisse559af382017-03-21 06:41:12 -0700385}
386
387void SendSideCongestionController::AddPacket(
elad.alond12a8e12017-03-23 11:04:48 -0700388 uint32_t ssrc,
nisse559af382017-03-21 06:41:12 -0700389 uint16_t sequence_number,
390 size_t length,
391 const PacedPacketInfo& pacing_info) {
Stefan Holmer4dbc7e42018-01-26 15:09:41 +0100392 if (send_side_bwe_with_overhead_) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000393 rtc::CritScope cs(&bwe_lock_);
Stefan Holmer4dbc7e42018-01-26 15:09:41 +0100394 length += transport_overhead_bytes_per_packet_;
395 }
elad.alond12a8e12017-03-23 11:04:48 -0700396 transport_feedback_adapter_.AddPacket(ssrc, sequence_number, length,
397 pacing_info);
nisse559af382017-03-21 06:41:12 -0700398}
399
400void SendSideCongestionController::OnTransportFeedback(
401 const rtcp::TransportFeedback& feedback) {
erikvargabf5a2fc2017-06-16 05:02:05 -0700402 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_);
nisse559af382017-03-21 06:41:12 -0700403 transport_feedback_adapter_.OnTransportFeedback(feedback);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000404 std::vector<PacketFeedback> feedback_vector = ReceivedPacketFeedbackVector(
405 transport_feedback_adapter_.GetTransportFeedbackVector());
tschumim3fae6282017-06-11 23:57:17 -0700406 SortPacketFeedbackVector(&feedback_vector);
tschumim9d117642017-07-17 01:41:41 -0700407
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000408 bool currently_in_alr =
409 pacer_->GetApplicationLimitedRegionStartTime().has_value();
410 if (was_in_alr_ && !currently_in_alr) {
411 int64_t now_ms = rtc::TimeMillis();
412 acknowledged_bitrate_estimator_->SetAlrEndedTimeMs(now_ms);
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200413 rtc::CritScope cs(&probe_lock_);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000414 probe_controller_->SetAlrEndedTimeMs(now_ms);
tschumim9d117642017-07-17 01:41:41 -0700415 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000416 was_in_alr_ = currently_in_alr;
417
418 acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
419 feedback_vector);
420 DelayBasedBwe::Result result;
421 {
422 rtc::CritScope cs(&bwe_lock_);
423 result = delay_based_bwe_->IncomingPacketFeedbackVector(
Sebastian Jansson04b18cb2018-07-02 09:25:25 +0200424 feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(),
425 clock_->TimeInMilliseconds());
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000426 }
427 if (result.updated) {
428 bitrate_controller_->OnDelayBasedBweResult(result);
429 // Update the estimate in the ProbeController, in case we want to probe.
430 MaybeTriggerOnNetworkChanged();
431 }
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200432 if (result.recovered_from_overuse) {
433 rtc::CritScope cs(&probe_lock_);
434 probe_controller_->SetAlrStartTimeMs(
435 pacer_->GetApplicationLimitedRegionStartTime());
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200436 SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds()));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200437 }
Ying Wange1d7b232018-07-17 16:01:25 +0200438 if (in_cwnd_experiment_) {
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000439 LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes());
Ying Wange1d7b232018-07-17 16:01:25 +0200440 }
stefan9e117c5e12017-08-16 08:16:25 -0700441}
442
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000443void SendSideCongestionController::LimitOutstandingBytes(
444 size_t num_outstanding_bytes) {
445 RTC_DCHECK(in_cwnd_experiment_);
446 rtc::CritScope lock(&network_state_lock_);
Danil Chapovalov0040b662018-06-18 10:48:16 +0200447 absl::optional<int64_t> min_rtt_ms =
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000448 transport_feedback_adapter_.GetMinFeedbackLoopRtt();
449 // No valid RTT. Could be because send-side BWE isn't used, in which case
450 // we don't try to limit the outstanding packets.
451 if (!min_rtt_ms)
452 return;
453 const size_t kMinCwndBytes = 2 * 1500;
454 size_t max_outstanding_bytes =
455 std::max<size_t>((*min_rtt_ms + accepted_queue_ms_) *
456 last_reported_bitrate_bps_ / 1000 / 8,
457 kMinCwndBytes);
458 RTC_LOG(LS_INFO) << clock_->TimeInMilliseconds()
459 << " Outstanding bytes: " << num_outstanding_bytes
460 << " pacer queue: " << pacer_->QueueInMs()
461 << " max outstanding: " << max_outstanding_bytes;
462 RTC_LOG(LS_INFO) << "Feedback rtt: " << *min_rtt_ms
463 << " Bitrate: " << last_reported_bitrate_bps_;
Ying Wange1d7b232018-07-17 16:01:25 +0200464 if (congestion_window_pushback_controller_) {
465 congestion_window_pushback_controller_->UpdateOutstandingData(
466 num_outstanding_bytes);
467 congestion_window_pushback_controller_->UpdateMaxOutstandingData(
468 max_outstanding_bytes);
469 } else {
470 pause_pacer_ = num_outstanding_bytes > max_outstanding_bytes;
471 }
nisse559af382017-03-21 06:41:12 -0700472}
473
474std::vector<PacketFeedback>
475SendSideCongestionController::GetTransportFeedbackVector() const {
erikvargabf5a2fc2017-06-16 05:02:05 -0700476 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_);
nisse559af382017-03-21 06:41:12 -0700477 return transport_feedback_adapter_.GetTransportFeedbackVector();
478}
479
Sebastian Jansson68ee4652018-03-13 11:40:34 +0100480void SendSideCongestionController::SetPacingFactor(float pacing_factor) {
481 pacer_->SetPacingFactor(pacing_factor);
482}
483
Alex Narestbcf91802018-06-25 16:08:36 +0200484void SendSideCongestionController::SetAllocatedBitrateWithoutFeedback(
485 uint32_t bitrate_bps) {
486 acknowledged_bitrate_estimator_->SetAllocatedBitrateWithoutFeedback(
487 bitrate_bps);
488}
489
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000490void SendSideCongestionController::MaybeTriggerOnNetworkChanged() {
491 uint32_t bitrate_bps;
492 uint8_t fraction_loss;
493 int64_t rtt;
494 bool estimate_changed = bitrate_controller_->GetNetworkParameters(
495 &bitrate_bps, &fraction_loss, &rtt);
496 if (estimate_changed) {
497 pacer_->SetEstimatedBitrate(bitrate_bps);
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200498 {
499 rtc::CritScope cs(&probe_lock_);
Sebastian Janssonda2ec402018-08-02 16:27:28 +0200500 SendProbes(probe_controller_->SetEstimatedBitrate(
501 bitrate_bps, clock_->TimeInMilliseconds()));
Sebastian Janssonb2ecc3d2018-07-13 17:22:01 +0200502 }
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000503 retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
Danil Chapovalov4e849f62018-02-14 08:28:02 +0000504 }
505
Ying Wange1d7b232018-07-17 16:01:25 +0200506 if (IsNetworkDown()) {
507 bitrate_bps = 0;
508 } else if (congestion_window_pushback_controller_) {
509 rtc::CritScope lock(&network_state_lock_);
510 bitrate_bps = congestion_window_pushback_controller_->UpdateTargetBitrate(
511 bitrate_bps);
512 } else if (!pacer_pushback_experiment_) {
513 bitrate_bps = IsSendQueueFull() ? 0 : bitrate_bps;
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000514 } else {
Ying Wange1d7b232018-07-17 16:01:25 +0200515 int64_t queue_length_ms = pacer_->ExpectedQueueTimeMs();
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000516
Ying Wange1d7b232018-07-17 16:01:25 +0200517 if (queue_length_ms == 0) {
518 encoding_rate_ = 1.0;
519 } else if (queue_length_ms > 50) {
520 float encoding_rate = 1.0 - queue_length_ms / 1000.0;
521 encoding_rate_ = std::min(encoding_rate_, encoding_rate);
522 encoding_rate_ = std::max(encoding_rate_, 0.0f);
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000523 }
Ying Wange1d7b232018-07-17 16:01:25 +0200524
525 bitrate_bps *= encoding_rate_;
526 bitrate_bps = bitrate_bps < 50000 ? 0 : bitrate_bps;
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000527 }
528
529 if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
530 int64_t probing_interval_ms;
531 {
532 rtc::CritScope cs(&bwe_lock_);
533 probing_interval_ms = delay_based_bwe_->GetExpectedBwePeriodMs();
534 }
535 {
536 rtc::CritScope cs(&observer_lock_);
537 if (observer_) {
538 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt,
539 probing_interval_ms);
540 }
541 }
542 }
nisse559af382017-03-21 06:41:12 -0700543}
Sebastian Janssonea86bb72018-02-14 16:53:38 +0000544
545bool SendSideCongestionController::HasNetworkParametersToReportChanged(
546 uint32_t bitrate_bps,
547 uint8_t fraction_loss,
548 int64_t rtt) {
549 rtc::CritScope cs(&network_state_lock_);
550 bool changed =
551 last_reported_bitrate_bps_ != bitrate_bps ||
552 (bitrate_bps > 0 && (last_reported_fraction_loss_ != fraction_loss ||
553 last_reported_rtt_ != rtt));
554 if (changed && (last_reported_bitrate_bps_ == 0 || bitrate_bps == 0)) {
555 RTC_LOG(LS_INFO) << "Bitrate estimate state changed, BWE: " << bitrate_bps
556 << " bps.";
557 }
558 last_reported_bitrate_bps_ = bitrate_bps;
559 last_reported_fraction_loss_ = fraction_loss;
560 last_reported_rtt_ = rtt;
561 return changed;
562}
563
564bool SendSideCongestionController::IsSendQueueFull() const {
565 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs;
566}
567
568bool SendSideCongestionController::IsNetworkDown() const {
569 rtc::CritScope cs(&network_state_lock_);
570 return network_state_ == kNetworkDown;
571}
572
nisse559af382017-03-21 06:41:12 -0700573} // namespace webrtc