blob: cdd908c9f898b2c6e7d1d8f36770c1055442b5c2 [file] [log] [blame]
Erik Språngd05edec2019-08-14 10:43:47 +02001/*
2 * Copyright (c) 2019 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/pacing/pacing_controller.h"
12
13#include <algorithm>
Mirko Bonadei317a1f02019-09-17 17:06:18 +020014#include <memory>
Erik Språngd05edec2019-08-14 10:43:47 +020015#include <utility>
16#include <vector>
17
Mirko Bonadei06d35592020-04-01 13:43:08 +020018#include "absl/strings/match.h"
Erik Språngd05edec2019-08-14 10:43:47 +020019#include "modules/pacing/bitrate_prober.h"
20#include "modules/pacing/interval_budget.h"
Erik Språngb73c0582022-05-02 21:18:08 +020021#include "modules/pacing/prioritized_packet_queue.h"
Erik Språngcb568272022-04-27 12:33:02 +020022#include "modules/pacing/round_robin_packet_queue.h"
Erik Språngd05edec2019-08-14 10:43:47 +020023#include "rtc_base/checks.h"
Erik Språng9acc18d2020-04-16 19:41:07 +020024#include "rtc_base/experiments/field_trial_parser.h"
Erik Språngd05edec2019-08-14 10:43:47 +020025#include "rtc_base/logging.h"
26#include "rtc_base/time_utils.h"
27#include "system_wrappers/include/clock.h"
28
29namespace webrtc {
30namespace {
31// Time limit in milliseconds between packet bursts.
Danil Chapovalov55284022020-02-07 14:53:52 +010032constexpr TimeDelta kDefaultMinPacketLimit = TimeDelta::Millis(5);
33constexpr TimeDelta kCongestedPacketInterval = TimeDelta::Millis(500);
Erik Språngeb487992019-11-14 14:15:15 +010034// TODO(sprang): Consider dropping this limit.
35// The maximum debt level, in terms of time, capped when sending packets.
Danil Chapovalov55284022020-02-07 14:53:52 +010036constexpr TimeDelta kMaxDebtInTime = TimeDelta::Millis(500);
37constexpr TimeDelta kMaxElapsedTime = TimeDelta::Seconds(2);
Erik Språngc52e6272022-07-07 12:41:57 +020038constexpr TimeDelta kTargetPaddingDuration = TimeDelta::Millis(5);
Erik Språngd05edec2019-08-14 10:43:47 +020039
Jonas Orelande62c2f22022-03-29 11:04:48 +020040bool IsDisabled(const FieldTrialsView& field_trials, absl::string_view key) {
Mirko Bonadei06d35592020-04-01 13:43:08 +020041 return absl::StartsWith(field_trials.Lookup(key), "Disabled");
Erik Språngd05edec2019-08-14 10:43:47 +020042}
43
Jonas Orelande62c2f22022-03-29 11:04:48 +020044bool IsEnabled(const FieldTrialsView& field_trials, absl::string_view key) {
Mirko Bonadei06d35592020-04-01 13:43:08 +020045 return absl::StartsWith(field_trials.Lookup(key), "Enabled");
Erik Språngd05edec2019-08-14 10:43:47 +020046}
47
Erik Språngb73c0582022-05-02 21:18:08 +020048std::unique_ptr<PacingController::PacketQueue> CreatePacketQueue(
49 const FieldTrialsView& field_trials,
50 Timestamp creation_time) {
Erik Språng06a6f3f2022-07-25 15:00:18 +020051 if (field_trials.IsDisabled("WebRTC-Pacer-UsePrioritizedPacketQueue")) {
52 return std::make_unique<RoundRobinPacketQueue>(creation_time);
Erik Språngb73c0582022-05-02 21:18:08 +020053 }
Erik Språng06a6f3f2022-07-25 15:00:18 +020054 return std::make_unique<PrioritizedPacketQueue>(creation_time);
Erik Språngb73c0582022-05-02 21:18:08 +020055}
56
Erik Språngd05edec2019-08-14 10:43:47 +020057} // namespace
58
59const TimeDelta PacingController::kMaxExpectedQueueLength =
Danil Chapovalov55284022020-02-07 14:53:52 +010060 TimeDelta::Millis(2000);
Erik Språngd05edec2019-08-14 10:43:47 +020061const float PacingController::kDefaultPaceMultiplier = 2.5f;
62const TimeDelta PacingController::kPausedProcessInterval =
63 kCongestedPacketInterval;
Danil Chapovalov55284022020-02-07 14:53:52 +010064const TimeDelta PacingController::kMinSleepTime = TimeDelta::Millis(1);
Jianhui Daidf59e532022-03-19 15:38:51 +080065const TimeDelta PacingController::kMaxEarlyProbeProcessing =
66 TimeDelta::Millis(1);
Erik Språngd05edec2019-08-14 10:43:47 +020067
68PacingController::PacingController(Clock* clock,
69 PacketSender* packet_sender,
Erik Språng6aa5cea2022-05-16 13:20:36 +020070 const FieldTrialsView& field_trials)
71 : clock_(clock),
Erik Språngd05edec2019-08-14 10:43:47 +020072 packet_sender_(packet_sender),
Erik Språnge486a7b2022-03-15 15:13:25 +010073 field_trials_(field_trials),
Erik Språngd05edec2019-08-14 10:43:47 +020074 drain_large_queues_(
Erik Språnge486a7b2022-03-15 15:13:25 +010075 !IsDisabled(field_trials_, "WebRTC-Pacer-DrainQueue")),
Erik Språngd05edec2019-08-14 10:43:47 +020076 send_padding_if_silent_(
Erik Språnge486a7b2022-03-15 15:13:25 +010077 IsEnabled(field_trials_, "WebRTC-Pacer-PadInSilence")),
78 pace_audio_(IsEnabled(field_trials_, "WebRTC-Pacer-BlockAudio")),
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +000079 ignore_transport_overhead_(
Erik Språnge486a7b2022-03-15 15:13:25 +010080 IsEnabled(field_trials_, "WebRTC-Pacer-IgnoreTransportOverhead")),
Erik Språngd05edec2019-08-14 10:43:47 +020081 min_packet_limit_(kDefaultMinPacketLimit),
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +000082 transport_overhead_per_packet_(DataSize::Zero()),
Per Kjellander8d847f02022-06-01 20:21:58 +020083 send_burst_interval_(TimeDelta::Zero()),
Erik Språngd05edec2019-08-14 10:43:47 +020084 last_timestamp_(clock_->CurrentTime()),
85 paused_(false),
Erik Språngeb487992019-11-14 14:15:15 +010086 media_debt_(DataSize::Zero()),
87 padding_debt_(DataSize::Zero()),
Erik Språngdf9e51a2022-06-10 11:42:15 +020088 pacing_rate_(DataRate::Zero()),
89 adjusted_media_rate_(DataRate::Zero()),
Erik Språngeb487992019-11-14 14:15:15 +010090 padding_rate_(DataRate::Zero()),
Erik Språnge486a7b2022-03-15 15:13:25 +010091 prober_(field_trials_),
Erik Språngd05edec2019-08-14 10:43:47 +020092 probing_send_failure_(false),
Erik Språngeb487992019-11-14 14:15:15 +010093 last_process_time_(clock->CurrentTime()),
94 last_send_time_(last_process_time_),
Erik Språngcb568272022-04-27 12:33:02 +020095 seen_first_packet_(false),
Erik Språngb73c0582022-05-02 21:18:08 +020096 packet_queue_(CreatePacketQueue(field_trials_, last_process_time_)),
Erik Språng66734372022-03-16 14:20:49 +010097 congested_(false),
Jianhui Daidf59e532022-03-19 15:38:51 +080098 queue_time_limit_(kMaxExpectedQueueLength),
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +010099 account_for_audio_(false),
100 include_overhead_(false) {
Erik Språngd05edec2019-08-14 10:43:47 +0200101 if (!drain_large_queues_) {
102 RTC_LOG(LS_WARNING) << "Pacer queues will not be drained,"
103 "pushback experiment must be enabled.";
104 }
105 FieldTrialParameter<int> min_packet_limit_ms("", min_packet_limit_.ms());
106 ParseFieldTrial({&min_packet_limit_ms},
Erik Språnge486a7b2022-03-15 15:13:25 +0100107 field_trials_.Lookup("WebRTC-Pacer-MinPacketLimitMs"));
Danil Chapovalov55284022020-02-07 14:53:52 +0100108 min_packet_limit_ = TimeDelta::Millis(min_packet_limit_ms.Get());
Erik Språngd05edec2019-08-14 10:43:47 +0200109 UpdateBudgetWithElapsedTime(min_packet_limit_);
110}
111
112PacingController::~PacingController() = default;
113
114void PacingController::CreateProbeCluster(DataRate bitrate, int cluster_id) {
Per Kjellander88af2032022-05-16 19:58:40 +0200115 prober_.CreateProbeCluster({.at_time = CurrentTime(),
116 .target_data_rate = bitrate,
117 .target_duration = TimeDelta::Millis(15),
118 .target_probe_count = 5,
119 .id = cluster_id});
120}
121
122void PacingController::CreateProbeClusters(
123 rtc::ArrayView<const ProbeClusterConfig> probe_cluster_configs) {
124 for (const ProbeClusterConfig probe_cluster_config : probe_cluster_configs) {
125 prober_.CreateProbeCluster(probe_cluster_config);
126 }
Erik Språngd05edec2019-08-14 10:43:47 +0200127}
128
129void PacingController::Pause() {
130 if (!paused_)
131 RTC_LOG(LS_INFO) << "PacedSender paused.";
132 paused_ = true;
Erik Språngcb568272022-04-27 12:33:02 +0200133 packet_queue_->SetPauseState(true, CurrentTime());
Erik Språngd05edec2019-08-14 10:43:47 +0200134}
135
136void PacingController::Resume() {
137 if (paused_)
138 RTC_LOG(LS_INFO) << "PacedSender resumed.";
139 paused_ = false;
Erik Språngcb568272022-04-27 12:33:02 +0200140 packet_queue_->SetPauseState(false, CurrentTime());
Erik Språngd05edec2019-08-14 10:43:47 +0200141}
142
143bool PacingController::IsPaused() const {
144 return paused_;
145}
146
Erik Språng66734372022-03-16 14:20:49 +0100147void PacingController::SetCongested(bool congested) {
148 if (congested_ && !congested) {
149 UpdateBudgetWithElapsedTime(UpdateTimeAndGetElapsed(CurrentTime()));
Erik Språngeb487992019-11-14 14:15:15 +0100150 }
Erik Språng66734372022-03-16 14:20:49 +0100151 congested_ = congested;
Erik Språngd05edec2019-08-14 10:43:47 +0200152}
153
Erik Språng4ab61cb2020-05-19 17:40:58 +0200154bool PacingController::IsProbing() const {
155 return prober_.is_probing();
156}
157
Erik Språngd05edec2019-08-14 10:43:47 +0200158Timestamp PacingController::CurrentTime() const {
159 Timestamp time = clock_->CurrentTime();
160 if (time < last_timestamp_) {
161 RTC_LOG(LS_WARNING)
162 << "Non-monotonic clock behavior observed. Previous timestamp: "
163 << last_timestamp_.ms() << ", new timestamp: " << time.ms();
164 RTC_DCHECK_GE(time, last_timestamp_);
165 time = last_timestamp_;
166 }
167 last_timestamp_ = time;
168 return time;
169}
170
171void PacingController::SetProbingEnabled(bool enabled) {
Erik Språngcb568272022-04-27 12:33:02 +0200172 RTC_CHECK(!seen_first_packet_);
Erik Språngd05edec2019-08-14 10:43:47 +0200173 prober_.SetEnabled(enabled);
174}
175
176void PacingController::SetPacingRates(DataRate pacing_rate,
177 DataRate padding_rate) {
Erik Språnged21d962022-04-20 17:42:35 +0200178 static constexpr DataRate kMaxRate = DataRate::KilobitsPerSec(100'000);
179 RTC_CHECK_GT(pacing_rate, DataRate::Zero());
180 RTC_CHECK_GE(padding_rate, DataRate::Zero());
Erik Språng6aa5cea2022-05-16 13:20:36 +0200181 if (padding_rate > pacing_rate) {
182 RTC_LOG(LS_WARNING) << "Padding rate " << padding_rate.kbps()
183 << "kbps is higher than the pacing rate "
184 << pacing_rate.kbps() << "kbps, capping.";
185 padding_rate = pacing_rate;
186 }
187
Erik Språnged21d962022-04-20 17:42:35 +0200188 if (pacing_rate > kMaxRate || padding_rate > kMaxRate) {
189 RTC_LOG(LS_WARNING) << "Very high pacing rates ( > " << kMaxRate.kbps()
190 << " kbps) configured: pacing = " << pacing_rate.kbps()
191 << " kbps, padding = " << padding_rate.kbps()
192 << " kbps.";
193 }
Erik Språngdf9e51a2022-06-10 11:42:15 +0200194 pacing_rate_ = pacing_rate;
Erik Språngeb487992019-11-14 14:15:15 +0100195 padding_rate_ = padding_rate;
Erik Språngdf9e51a2022-06-10 11:42:15 +0200196 MaybeUpdateMediaRateDueToLongQueue(CurrentTime());
Erik Språngd05edec2019-08-14 10:43:47 +0200197
Erik Språngdf9e51a2022-06-10 11:42:15 +0200198 RTC_LOG(LS_VERBOSE) << "bwe:pacer_updated pacing_kbps=" << pacing_rate_.kbps()
Erik Språngd05edec2019-08-14 10:43:47 +0200199 << " padding_budget_kbps=" << padding_rate.kbps();
200}
201
Erik Språngd05edec2019-08-14 10:43:47 +0200202void PacingController::EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet) {
Erik Språngdf9e51a2022-06-10 11:42:15 +0200203 RTC_DCHECK(pacing_rate_ > DataRate::Zero())
Erik Språngd05edec2019-08-14 10:43:47 +0200204 << "SetPacingRate must be called before InsertPacket.";
Erik Språngd05edec2019-08-14 10:43:47 +0200205 RTC_CHECK(packet->packet_type());
Erik Språng8b749e42022-04-25 13:21:27 +0200206
207 prober_.OnIncomingPacket(DataSize::Bytes(packet->payload_size()));
208
Erik Språngdf9e51a2022-06-10 11:42:15 +0200209 const Timestamp now = CurrentTime();
Erik Språng6aa5cea2022-05-16 13:20:36 +0200210 if (packet_queue_->Empty()) {
Erik Språng8b749e42022-04-25 13:21:27 +0200211 // If queue is empty, we need to "fast-forward" the last process time,
212 // so that we don't use passed time as budget for sending the first new
213 // packet.
214 Timestamp target_process_time = now;
215 Timestamp next_send_time = NextSendTime();
216 if (next_send_time.IsFinite()) {
217 // There was already a valid planned send time, such as a keep-alive.
218 // Use that as last process time only if it's prior to now.
219 target_process_time = std::min(now, next_send_time);
220 }
221 UpdateBudgetWithElapsedTime(UpdateTimeAndGetElapsed(target_process_time));
222 }
Erik Språngcb568272022-04-27 12:33:02 +0200223 packet_queue_->Push(now, std::move(packet));
224 seen_first_packet_ = true;
Erik Språngdf9e51a2022-06-10 11:42:15 +0200225
226 // Queue length has increased, check if we need to change the pacing rate.
227 MaybeUpdateMediaRateDueToLongQueue(now);
Erik Språngd05edec2019-08-14 10:43:47 +0200228}
229
230void PacingController::SetAccountForAudioPackets(bool account_for_audio) {
231 account_for_audio_ = account_for_audio;
232}
233
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100234void PacingController::SetIncludeOverhead() {
235 include_overhead_ = true;
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100236}
237
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000238void PacingController::SetTransportOverhead(DataSize overhead_per_packet) {
239 if (ignore_transport_overhead_)
240 return;
241 transport_overhead_per_packet_ = overhead_per_packet;
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000242}
243
Per Kjellander8d847f02022-06-01 20:21:58 +0200244void PacingController::SetSendBurstInterval(TimeDelta burst_interval) {
245 send_burst_interval_ = burst_interval;
246}
247
Erik Språngd05edec2019-08-14 10:43:47 +0200248TimeDelta PacingController::ExpectedQueueTime() const {
Erik Språngdf9e51a2022-06-10 11:42:15 +0200249 RTC_DCHECK_GT(adjusted_media_rate_, DataRate::Zero());
250 return QueueSizeData() / adjusted_media_rate_;
Erik Språngd05edec2019-08-14 10:43:47 +0200251}
252
253size_t PacingController::QueueSizePackets() const {
Erik Språngb73c0582022-05-02 21:18:08 +0200254 return rtc::checked_cast<size_t>(packet_queue_->SizeInPackets());
Erik Språngd05edec2019-08-14 10:43:47 +0200255}
256
Henrik Boströmef241162022-06-06 16:19:11 +0200257const std::array<int, kNumMediaTypes>&
258PacingController::SizeInPacketsPerRtpPacketMediaType() const {
259 return packet_queue_->SizeInPacketsPerRtpPacketMediaType();
260}
261
Erik Språngd05edec2019-08-14 10:43:47 +0200262DataSize PacingController::QueueSizeData() const {
Erik Språngcb568272022-04-27 12:33:02 +0200263 DataSize size = packet_queue_->SizeInPayloadBytes();
264 if (include_overhead_) {
265 size += static_cast<int64_t>(packet_queue_->SizeInPackets()) *
266 transport_overhead_per_packet_;
267 }
268 return size;
Erik Språngd05edec2019-08-14 10:43:47 +0200269}
270
Erik Språng4314a492019-11-26 17:48:49 +0100271DataSize PacingController::CurrentBufferLevel() const {
272 return std::max(media_debt_, padding_debt_);
273}
274
Erik Språngd05edec2019-08-14 10:43:47 +0200275absl::optional<Timestamp> PacingController::FirstSentPacketTime() const {
276 return first_sent_packet_time_;
277}
278
Jianhui Dai94457792021-12-07 19:34:36 +0800279Timestamp PacingController::OldestPacketEnqueueTime() const {
Erik Språngcb568272022-04-27 12:33:02 +0200280 return packet_queue_->OldestEnqueueTime();
Erik Språngd05edec2019-08-14 10:43:47 +0200281}
282
283TimeDelta PacingController::UpdateTimeAndGetElapsed(Timestamp now) {
Erik Språng7d0cde52020-07-19 12:48:16 +0200284 // If no previous processing, or last process was "in the future" because of
285 // early probe processing, then there is no elapsed time to add budget for.
286 if (last_process_time_.IsMinusInfinity() || now < last_process_time_) {
Erik Språngeb487992019-11-14 14:15:15 +0100287 return TimeDelta::Zero();
288 }
289 TimeDelta elapsed_time = now - last_process_time_;
290 last_process_time_ = now;
Erik Språngd05edec2019-08-14 10:43:47 +0200291 if (elapsed_time > kMaxElapsedTime) {
292 RTC_LOG(LS_WARNING) << "Elapsed time (" << elapsed_time.ms()
293 << " ms) longer than expected, limiting to "
294 << kMaxElapsedTime.ms();
295 elapsed_time = kMaxElapsedTime;
296 }
297 return elapsed_time;
298}
299
300bool PacingController::ShouldSendKeepalive(Timestamp now) const {
Erik Språngcb568272022-04-27 12:33:02 +0200301 if (send_padding_if_silent_ || paused_ || congested_ || !seen_first_packet_) {
Erik Språngd05edec2019-08-14 10:43:47 +0200302 // We send a padding packet every 500 ms to ensure we won't get stuck in
303 // congested state due to no feedback being received.
Jianhui Daidf59e532022-03-19 15:38:51 +0800304 if (now - last_send_time_ >= kCongestedPacketInterval) {
Erik Språngeb487992019-11-14 14:15:15 +0100305 return true;
Erik Språngd05edec2019-08-14 10:43:47 +0200306 }
307 }
308 return false;
309}
310
Erik Språngeb487992019-11-14 14:15:15 +0100311Timestamp PacingController::NextSendTime() const {
Erik Språngb9d38092020-07-17 12:06:12 +0200312 const Timestamp now = CurrentTime();
Jianhui Daidf59e532022-03-19 15:38:51 +0800313 Timestamp next_send_time = Timestamp::PlusInfinity();
Erik Språngeb487992019-11-14 14:15:15 +0100314
Erik Språngae100292019-12-17 17:49:49 +0100315 if (paused_) {
316 return last_send_time_ + kPausedProcessInterval;
317 }
318
Erik Språngeb487992019-11-14 14:15:15 +0100319 // If probing is active, that always takes priority.
Jianhui Daidf59e532022-03-19 15:38:51 +0800320 if (prober_.is_probing() && !probing_send_failure_) {
Erik Språngeb487992019-11-14 14:15:15 +0100321 Timestamp probe_time = prober_.NextProbeTime(now);
Jianhui Daidf59e532022-03-19 15:38:51 +0800322 if (!probe_time.IsPlusInfinity()) {
323 return probe_time.IsMinusInfinity() ? now : probe_time;
Erik Språngeb487992019-11-14 14:15:15 +0100324 }
Erik Språngd05edec2019-08-14 10:43:47 +0200325 }
326
Jianhui Daidf59e532022-03-19 15:38:51 +0800327 // Not pacing audio, if leading packet is audio its target send
328 // time is the time at which it was enqueued.
Erik Språngcb568272022-04-27 12:33:02 +0200329 Timestamp unpaced_audio_time =
330 pace_audio_ ? Timestamp::PlusInfinity()
331 : packet_queue_->LeadingAudioPacketEnqueueTime();
332 if (unpaced_audio_time.IsFinite()) {
333 return unpaced_audio_time;
Erik Språng9cb58d52020-03-28 17:15:54 +0100334 }
Erik Språngeb487992019-11-14 14:15:15 +0100335
Erik Språngcb568272022-04-27 12:33:02 +0200336 if (congested_ || !seen_first_packet_) {
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000337 // We need to at least send keep-alive packets with some interval.
Erik Språngeb487992019-11-14 14:15:15 +0100338 return last_send_time_ + kCongestedPacketInterval;
339 }
340
Erik Språngdf9e51a2022-06-10 11:42:15 +0200341 if (adjusted_media_rate_ > DataRate::Zero() && !packet_queue_->Empty()) {
Per Kjellander8d847f02022-06-01 20:21:58 +0200342 // If packets are allowed to be sent in a burst, the
343 // debt is allowed to grow up to one packet more than what can be sent
344 // during 'send_burst_period_'.
Erik Språngdf9e51a2022-06-10 11:42:15 +0200345 TimeDelta drain_time = media_debt_ / adjusted_media_rate_;
Per Kjellander8d847f02022-06-01 20:21:58 +0200346 next_send_time =
347 last_process_time_ +
348 ((send_burst_interval_ > drain_time) ? TimeDelta::Zero() : drain_time);
Erik Språngcb568272022-04-27 12:33:02 +0200349 } else if (padding_rate_ > DataRate::Zero() && packet_queue_->Empty()) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800350 // If we _don't_ have pending packets, check how long until we have
351 // bandwidth for padding packets. Both media and padding debts must
352 // have been drained to do this.
Erik Språngdf9e51a2022-06-10 11:42:15 +0200353 RTC_DCHECK_GT(adjusted_media_rate_, DataRate::Zero());
354 TimeDelta drain_time = std::max(media_debt_ / adjusted_media_rate_,
355 padding_debt_ / padding_rate_);
Erik Språngb844dd82022-04-22 12:18:17 +0200356
357 if (drain_time.IsZero() &&
358 (!media_debt_.IsZero() || !padding_debt_.IsZero())) {
359 // We have a non-zero debt, but drain time is smaller than tick size of
360 // TimeDelta, round it up to the smallest possible non-zero delta.
361 drain_time = TimeDelta::Micros(1);
362 }
Jianhui Daidf59e532022-03-19 15:38:51 +0800363 next_send_time = last_process_time_ + drain_time;
364 } else {
365 // Nothing to do.
366 next_send_time = last_process_time_ + kPausedProcessInterval;
Erik Språngeb487992019-11-14 14:15:15 +0100367 }
368
Erik Språngb1ccae22019-11-25 18:22:09 +0100369 if (send_padding_if_silent_) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800370 next_send_time =
371 std::min(next_send_time, last_send_time_ + kPausedProcessInterval);
Erik Språngb1ccae22019-11-25 18:22:09 +0100372 }
Jianhui Daidf59e532022-03-19 15:38:51 +0800373
374 return next_send_time;
Erik Språngd05edec2019-08-14 10:43:47 +0200375}
376
377void PacingController::ProcessPackets() {
Erik Språngdf9e51a2022-06-10 11:42:15 +0200378 const Timestamp now = CurrentTime();
Erik Språngeb487992019-11-14 14:15:15 +0100379 Timestamp target_send_time = now;
Erik Språngeb487992019-11-14 14:15:15 +0100380
381 if (ShouldSendKeepalive(now)) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800382 DataSize keepalive_data_sent = DataSize::Zero();
Erik Språngeb487992019-11-14 14:15:15 +0100383 // We can not send padding unless a normal packet has first been sent. If
384 // we do, timestamps get messed up.
Erik Språngcb568272022-04-27 12:33:02 +0200385 if (seen_first_packet_) {
Erik Språngeb487992019-11-14 14:15:15 +0100386 std::vector<std::unique_ptr<RtpPacketToSend>> keepalive_packets =
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100387 packet_sender_->GeneratePadding(DataSize::Bytes(1));
Erik Språngeb487992019-11-14 14:15:15 +0100388 for (auto& packet : keepalive_packets) {
389 keepalive_data_sent +=
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100390 DataSize::Bytes(packet->payload_size() + packet->padding_size());
Erik Språnged1fb192020-06-30 11:53:37 +0000391 packet_sender_->SendPacket(std::move(packet), PacedPacketInfo());
Erik Språng1d50cb62020-07-02 17:41:32 +0200392 for (auto& packet : packet_sender_->FetchFec()) {
393 EnqueuePacket(std::move(packet));
394 }
Erik Språngeb487992019-11-14 14:15:15 +0100395 }
Erik Språngeb487992019-11-14 14:15:15 +0100396 }
Jianhui Daidf59e532022-03-19 15:38:51 +0800397 OnPacketSent(RtpPacketMediaType::kPadding, keepalive_data_sent, now);
Erik Språngeb487992019-11-14 14:15:15 +0100398 }
399
400 if (paused_) {
Erik Språngd05edec2019-08-14 10:43:47 +0200401 return;
Erik Språngeb487992019-11-14 14:15:15 +0100402 }
Erik Språngd05edec2019-08-14 10:43:47 +0200403
Per Kjellander8d847f02022-06-01 20:21:58 +0200404 TimeDelta early_execute_margin =
405 prober_.is_probing() ? kMaxEarlyProbeProcessing : TimeDelta::Zero();
Jianhui Daidf59e532022-03-19 15:38:51 +0800406
Per Kjellander8d847f02022-06-01 20:21:58 +0200407 target_send_time = NextSendTime();
408 if (now + early_execute_margin < target_send_time) {
409 // We are too early, but if queue is empty still allow draining some debt.
410 // Probing is allowed to be sent up to kMinSleepTime early.
411 UpdateBudgetWithElapsedTime(UpdateTimeAndGetElapsed(now));
412 return;
413 }
Jianhui Daidf59e532022-03-19 15:38:51 +0800414
415 TimeDelta elapsed_time = UpdateTimeAndGetElapsed(target_send_time);
416
Erik Språngd05edec2019-08-14 10:43:47 +0200417 if (elapsed_time > TimeDelta::Zero()) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800418 UpdateBudgetWithElapsedTime(elapsed_time);
Erik Språngd05edec2019-08-14 10:43:47 +0200419 }
420
Erik Språngd05edec2019-08-14 10:43:47 +0200421 PacedPacketInfo pacing_info;
Erik Språngb9d38092020-07-17 12:06:12 +0200422 DataSize recommended_probe_size = DataSize::Zero();
423 bool is_probing = prober_.is_probing();
Erik Språngd05edec2019-08-14 10:43:47 +0200424 if (is_probing) {
Erik Språngb9d38092020-07-17 12:06:12 +0200425 // Probe timing is sensitive, and handled explicitly by BitrateProber, so
426 // use actual send time rather than target.
427 pacing_info = prober_.CurrentCluster(now).value_or(PacedPacketInfo());
428 if (pacing_info.probe_cluster_id != PacedPacketInfo::kNotAProbe) {
Erik Språngb9d38092020-07-17 12:06:12 +0200429 recommended_probe_size = prober_.RecommendedMinProbeSize();
430 RTC_DCHECK_GT(recommended_probe_size, DataSize::Zero());
431 } else {
432 // No valid probe cluster returned, probe might have timed out.
433 is_probing = false;
434 }
Erik Språngd05edec2019-08-14 10:43:47 +0200435 }
436
Erik Språngacded162022-04-22 15:59:06 +0000437 DataSize data_sent = DataSize::Zero();
Erik Språnged21d962022-04-20 17:42:35 +0200438 // Circuit breaker, making sure main loop isn't forever.
439 static constexpr int kMaxIterations = 1 << 16;
440 int iteration = 0;
441 int packets_sent = 0;
442 int padding_packets_generated = 0;
443 for (; iteration < kMaxIterations; ++iteration) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800444 // Fetch packet, so long as queue is not empty or budget is not
Erik Språngeb487992019-11-14 14:15:15 +0100445 // exhausted.
Erik Språngb0df5932019-11-18 13:40:24 +0100446 std::unique_ptr<RtpPacketToSend> rtp_packet =
447 GetPendingPacket(pacing_info, target_send_time, now);
Erik Språngb0df5932019-11-18 13:40:24 +0100448 if (rtp_packet == nullptr) {
Erik Språngd05edec2019-08-14 10:43:47 +0200449 // No packet available to send, check if we should send padding.
Erik Språngf5815fa2019-08-21 14:27:31 +0200450 DataSize padding_to_add = PaddingToAdd(recommended_probe_size, data_sent);
451 if (padding_to_add > DataSize::Zero()) {
452 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
453 packet_sender_->GeneratePadding(padding_to_add);
Jianhui Daidf59e532022-03-19 15:38:51 +0800454 if (!padding_packets.empty()) {
Erik Språnged21d962022-04-20 17:42:35 +0200455 padding_packets_generated += padding_packets.size();
Jianhui Daidf59e532022-03-19 15:38:51 +0800456 for (auto& packet : padding_packets) {
457 EnqueuePacket(std::move(packet));
458 }
459 // Continue loop to send the padding that was just added.
460 continue;
461 } else {
462 // Can't generate padding, still update padding budget for next send
463 // time.
464 UpdatePaddingBudgetWithSentData(padding_to_add);
Erik Språngd05edec2019-08-14 10:43:47 +0200465 }
466 }
Erik Språngd05edec2019-08-14 10:43:47 +0200467 // Can't fetch new packet and no padding to send, exit send loop.
468 break;
Jianhui Daidf59e532022-03-19 15:38:51 +0800469 } else {
Erik Språngacded162022-04-22 15:59:06 +0000470 RTC_DCHECK(rtp_packet);
471 RTC_DCHECK(rtp_packet->packet_type().has_value());
472 const RtpPacketMediaType packet_type = *rtp_packet->packet_type();
473 DataSize packet_size = DataSize::Bytes(rtp_packet->payload_size() +
474 rtp_packet->padding_size());
475
476 if (include_overhead_) {
477 packet_size += DataSize::Bytes(rtp_packet->headers_size()) +
478 transport_overhead_per_packet_;
479 }
480
481 packet_sender_->SendPacket(std::move(rtp_packet), pacing_info);
482 for (auto& packet : packet_sender_->FetchFec()) {
483 EnqueuePacket(std::move(packet));
484 }
485 data_sent += packet_size;
Erik Språnged21d962022-04-20 17:42:35 +0200486 ++packets_sent;
Erik Språnga1888ae2020-07-02 12:02:36 +0000487
Erik Språngacded162022-04-22 15:59:06 +0000488 // Send done, update send time.
489 OnPacketSent(packet_type, packet_size, now);
490
Erik Språnge65d05d2022-04-24 15:10:59 +0200491 if (is_probing) {
492 pacing_info.probe_cluster_bytes_sent += packet_size.bytes();
493 // If we are currently probing, we need to stop the send loop when we
494 // have reached the send target.
495 if (data_sent >= recommended_probe_size) {
496 break;
497 }
Erik Språngd0909522022-04-21 11:24:18 +0000498 }
499
Erik Språngeb487992019-11-14 14:15:15 +0100500 // Update target send time in case that are more packets that we are late
501 // in processing.
Erik Språng6aa5cea2022-05-16 13:20:36 +0200502 target_send_time = NextSendTime();
503 if (target_send_time > now) {
504 // Exit loop if not probing.
505 if (!is_probing) {
506 break;
Jianhui Daidf59e532022-03-19 15:38:51 +0800507 }
Erik Språng6aa5cea2022-05-16 13:20:36 +0200508 target_send_time = now;
Erik Språngeb487992019-11-14 14:15:15 +0100509 }
Erik Språng6aa5cea2022-05-16 13:20:36 +0200510 UpdateBudgetWithElapsedTime(UpdateTimeAndGetElapsed(target_send_time));
Erik Språngeb487992019-11-14 14:15:15 +0100511 }
Erik Språngd05edec2019-08-14 10:43:47 +0200512 }
513
Erik Språnged21d962022-04-20 17:42:35 +0200514 if (iteration >= kMaxIterations) {
515 // Circuit break activated. Log warning, adjust send time and return.
516 // TODO(sprang): Consider completely clearing state.
517 RTC_LOG(LS_ERROR) << "PacingController exceeded max iterations in "
518 "send-loop: packets sent = "
519 << packets_sent << ", padding packets generated = "
520 << padding_packets_generated
521 << ", bytes sent = " << data_sent.bytes();
522 last_send_time_ = now;
523 last_process_time_ = now;
524 return;
525 }
526
Erik Språngd05edec2019-08-14 10:43:47 +0200527 if (is_probing) {
528 probing_send_failure_ = data_sent == DataSize::Zero();
529 if (!probing_send_failure_) {
Erik Språngb9d38092020-07-17 12:06:12 +0200530 prober_.ProbeSent(CurrentTime(), data_sent);
Erik Språngd05edec2019-08-14 10:43:47 +0200531 }
532 }
Erik Språngdf9e51a2022-06-10 11:42:15 +0200533
534 // Queue length has probably decreased, check if pacing rate needs to updated.
535 // Poll the time again, since we might have enqueued new fec/padding packets
536 // with a later timestamp than `now`.
537 MaybeUpdateMediaRateDueToLongQueue(CurrentTime());
Erik Språngd05edec2019-08-14 10:43:47 +0200538}
539
Erik Språngb9d38092020-07-17 12:06:12 +0200540DataSize PacingController::PaddingToAdd(DataSize recommended_probe_size,
541 DataSize data_sent) const {
Erik Språngcb568272022-04-27 12:33:02 +0200542 if (!packet_queue_->Empty()) {
Erik Språngd05edec2019-08-14 10:43:47 +0200543 // Actual payload available, no need to add padding.
544 return DataSize::Zero();
545 }
546
Erik Språng66734372022-03-16 14:20:49 +0100547 if (congested_) {
Erik Språngd05edec2019-08-14 10:43:47 +0200548 // Don't add padding if congested, even if requested for probing.
549 return DataSize::Zero();
550 }
551
Erik Språngcb568272022-04-27 12:33:02 +0200552 if (!seen_first_packet_) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800553 // We can not send padding unless a normal packet has first been sent. If
554 // we do, timestamps get messed up.
Erik Språngd05edec2019-08-14 10:43:47 +0200555 return DataSize::Zero();
556 }
557
Erik Språngb9d38092020-07-17 12:06:12 +0200558 if (!recommended_probe_size.IsZero()) {
559 if (recommended_probe_size > data_sent) {
560 return recommended_probe_size - data_sent;
Erik Språngd05edec2019-08-14 10:43:47 +0200561 }
562 return DataSize::Zero();
563 }
564
Erik Språng6aa5cea2022-05-16 13:20:36 +0200565 if (padding_rate_ > DataRate::Zero() && padding_debt_ == DataSize::Zero()) {
Erik Språngc52e6272022-07-07 12:41:57 +0200566 return kTargetPaddingDuration * padding_rate_;
Erik Språngeb487992019-11-14 14:15:15 +0100567 }
568 return DataSize::Zero();
Erik Språngd05edec2019-08-14 10:43:47 +0200569}
570
Erik Språngb0df5932019-11-18 13:40:24 +0100571std::unique_ptr<RtpPacketToSend> PacingController::GetPendingPacket(
Erik Språngeb487992019-11-14 14:15:15 +0100572 const PacedPacketInfo& pacing_info,
573 Timestamp target_send_time,
574 Timestamp now) {
Erik Språnge65d05d2022-04-24 15:10:59 +0200575 const bool is_probe =
576 pacing_info.probe_cluster_id != PacedPacketInfo::kNotAProbe;
577 // If first packet in probe, insert a small padding packet so we have a
578 // more reliable start window for the rate estimation.
579 if (is_probe && pacing_info.probe_cluster_bytes_sent == 0) {
580 auto padding = packet_sender_->GeneratePadding(DataSize::Bytes(1));
581 // If no RTP modules sending media are registered, we may not get a
582 // padding packet back.
583 if (!padding.empty()) {
584 // We should never get more than one padding packets with a requested
585 // size of 1 byte.
586 RTC_DCHECK_EQ(padding.size(), 1u);
587 return std::move(padding[0]);
588 }
589 }
590
Erik Språngcb568272022-04-27 12:33:02 +0200591 if (packet_queue_->Empty()) {
Erik Språngf660e812019-09-01 12:26:44 +0000592 return nullptr;
593 }
594
Erik Språngeb487992019-11-14 14:15:15 +0100595 // First, check if there is any reason _not_ to send the next queued packet.
596
597 // Unpaced audio packets and probes are exempted from send checks.
Erik Språngb571ff42020-04-04 17:20:37 +0200598 bool unpaced_audio_packet =
Erik Språngcb568272022-04-27 12:33:02 +0200599 !pace_audio_ && packet_queue_->LeadingAudioPacketEnqueueTime().IsFinite();
Erik Språngeb487992019-11-14 14:15:15 +0100600 if (!unpaced_audio_packet && !is_probe) {
Erik Språng66734372022-03-16 14:20:49 +0100601 if (congested_) {
Evan Shrubsole6ef59d12020-01-08 16:45:08 +0100602 // Don't send anything if congested.
Erik Språngeb487992019-11-14 14:15:15 +0100603 return nullptr;
604 }
605
Per Kjellander8d847f02022-06-01 20:21:58 +0200606 if (now <= target_send_time && send_burst_interval_.IsZero()) {
607 // We allow sending slightly early if we think that we would actually
608 // had been able to, had we been right on time - i.e. the current debt
609 // is not more than would be reduced to zero at the target sent time.
610 // If we allow packets to be sent in a burst, packet are allowed to be
611 // sent early.
Erik Språngdf9e51a2022-06-10 11:42:15 +0200612 TimeDelta flush_time = media_debt_ / adjusted_media_rate_;
Per Kjellander8d847f02022-06-01 20:21:58 +0200613 if (now + flush_time > target_send_time) {
614 return nullptr;
Erik Språngeb487992019-11-14 14:15:15 +0100615 }
Per Kjellander8d847f02022-06-01 20:21:58 +0200616 }
Erik Språngf660e812019-09-01 12:26:44 +0000617 }
Erik Språngeb487992019-11-14 14:15:15 +0100618
Erik Språngcb568272022-04-27 12:33:02 +0200619 return packet_queue_->Pop();
Erik Språngf660e812019-09-01 12:26:44 +0000620}
621
Björn Terelius31d0f7c2020-02-06 16:35:46 +0100622void PacingController::OnPacketSent(RtpPacketMediaType packet_type,
Erik Språngb0df5932019-11-18 13:40:24 +0100623 DataSize packet_size,
Erik Språngeb487992019-11-14 14:15:15 +0100624 Timestamp send_time) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800625 if (!first_sent_packet_time_ && packet_type != RtpPacketMediaType::kPadding) {
Erik Språngeb487992019-11-14 14:15:15 +0100626 first_sent_packet_time_ = send_time;
Erik Språngf660e812019-09-01 12:26:44 +0000627 }
Jianhui Daidf59e532022-03-19 15:38:51 +0800628
Björn Terelius31d0f7c2020-02-06 16:35:46 +0100629 bool audio_packet = packet_type == RtpPacketMediaType::kAudio;
Jianhui Daidf59e532022-03-19 15:38:51 +0800630 if ((!audio_packet || account_for_audio_) && packet_size > DataSize::Zero()) {
Erik Språngb0df5932019-11-18 13:40:24 +0100631 UpdateBudgetWithSentData(packet_size);
Erik Språngf660e812019-09-01 12:26:44 +0000632 }
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000633
Jianhui Daidf59e532022-03-19 15:38:51 +0800634 last_send_time_ = send_time;
Erik Språngd05edec2019-08-14 10:43:47 +0200635}
636
637void PacingController::UpdateBudgetWithElapsedTime(TimeDelta delta) {
Erik Språngdf9e51a2022-06-10 11:42:15 +0200638 media_debt_ -= std::min(media_debt_, adjusted_media_rate_ * delta);
Erik Språng6aa5cea2022-05-16 13:20:36 +0200639 padding_debt_ -= std::min(padding_debt_, padding_rate_ * delta);
Erik Språngd05edec2019-08-14 10:43:47 +0200640}
641
642void PacingController::UpdateBudgetWithSentData(DataSize size) {
Erik Språng6aa5cea2022-05-16 13:20:36 +0200643 media_debt_ += size;
Erik Språngdf9e51a2022-06-10 11:42:15 +0200644 media_debt_ = std::min(media_debt_, adjusted_media_rate_ * kMaxDebtInTime);
Jianhui Daidf59e532022-03-19 15:38:51 +0800645 UpdatePaddingBudgetWithSentData(size);
646}
647
648void PacingController::UpdatePaddingBudgetWithSentData(DataSize size) {
Erik Språng6aa5cea2022-05-16 13:20:36 +0200649 padding_debt_ += size;
650 padding_debt_ = std::min(padding_debt_, padding_rate_ * kMaxDebtInTime);
Erik Språngd05edec2019-08-14 10:43:47 +0200651}
652
653void PacingController::SetQueueTimeLimit(TimeDelta limit) {
Jianhui Daidf59e532022-03-19 15:38:51 +0800654 queue_time_limit_ = limit;
Erik Språngd05edec2019-08-14 10:43:47 +0200655}
656
Erik Språngdf9e51a2022-06-10 11:42:15 +0200657void PacingController::MaybeUpdateMediaRateDueToLongQueue(Timestamp now) {
658 adjusted_media_rate_ = pacing_rate_;
659 if (!drain_large_queues_) {
660 return;
661 }
662
663 DataSize queue_size_data = QueueSizeData();
664 if (queue_size_data > DataSize::Zero()) {
665 // Assuming equal size packets and input/output rate, the average packet
666 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if
667 // time constraint shall be met. Determine bitrate needed for that.
668 packet_queue_->UpdateAverageQueueTime(now);
669 TimeDelta avg_time_left =
670 std::max(TimeDelta::Millis(1),
671 queue_time_limit_ - packet_queue_->AverageQueueTime());
672 DataRate min_rate_needed = queue_size_data / avg_time_left;
673 if (min_rate_needed > pacing_rate_) {
674 adjusted_media_rate_ = min_rate_needed;
675 RTC_LOG(LS_VERBOSE) << "bwe:large_pacing_queue pacing_rate_kbps="
676 << pacing_rate_.kbps();
677 }
678 }
679}
680
Erik Språngd05edec2019-08-14 10:43:47 +0200681} // namespace webrtc