blob: c0a69266a0febeb8bba3388ae282eda639f2105b [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#ifndef MODULES_PACING_PACING_CONTROLLER_H_
12#define MODULES_PACING_PACING_CONTROLLER_H_
13
14#include <stddef.h>
15#include <stdint.h>
16
Henrik Boströmef241162022-06-06 16:19:11 +020017#include <array>
Erik Språngd05edec2019-08-14 10:43:47 +020018#include <atomic>
19#include <memory>
20#include <vector>
21
22#include "absl/types/optional.h"
Jonas Orelande62c2f22022-03-29 11:04:48 +020023#include "api/field_trials_view.h"
Erik Språngd05edec2019-08-14 10:43:47 +020024#include "api/function_view.h"
Erik Språngd05edec2019-08-14 10:43:47 +020025#include "api/transport/field_trial_based_config.h"
26#include "api/transport/network_types.h"
Erik Språngd05edec2019-08-14 10:43:47 +020027#include "modules/pacing/bitrate_prober.h"
28#include "modules/pacing/interval_budget.h"
Erik Språngd05edec2019-08-14 10:43:47 +020029#include "modules/pacing/rtp_packet_pacer.h"
30#include "modules/rtp_rtcp/include/rtp_packet_sender.h"
Björn Terelius31d0f7c2020-02-06 16:35:46 +010031#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Erik Språngd05edec2019-08-14 10:43:47 +020032#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Erik Språngd05edec2019-08-14 10:43:47 +020033#include "rtc_base/experiments/field_trial_parser.h"
34#include "rtc_base/thread_annotations.h"
35
36namespace webrtc {
37
Rikard Lundmark48be4822020-01-28 16:07:36 +010038// This class implements a leaky-bucket packet pacing algorithm. It handles the
Erik Språngd05edec2019-08-14 10:43:47 +020039// logic of determining which packets to send when, but the actual timing of
Jianhui Daic6942702021-11-10 12:58:27 +080040// the processing is done externally (e.g. RtpPacketPacer). Furthermore, the
Erik Språngd05edec2019-08-14 10:43:47 +020041// forwarding of packets when they are ready to be sent is also handled
Jianhui Daic6942702021-11-10 12:58:27 +080042// externally, via the PacingController::PacketSender interface.
Erik Språngd05edec2019-08-14 10:43:47 +020043class PacingController {
44 public:
45 class PacketSender {
46 public:
47 virtual ~PacketSender() = default;
Erik Språnged1fb192020-06-30 11:53:37 +000048 virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
49 const PacedPacketInfo& cluster_info) = 0;
Erik Språng1d50cb62020-07-02 17:41:32 +020050 // Should be called after each call to SendPacket().
51 virtual std::vector<std::unique_ptr<RtpPacketToSend>> FetchFec() = 0;
Erik Språngd05edec2019-08-14 10:43:47 +020052 virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
53 DataSize size) = 0;
Erik Språngd05edec2019-08-14 10:43:47 +020054 };
55
Erik Språngcb568272022-04-27 12:33:02 +020056 // Interface for class hanlding storage of and prioritization of packets
57 // pending to be sent by the pacer.
58 // Note that for the methods taking a Timestamp as parameter, the parameter
59 // will never decrease between two subsequent calls.
60 class PacketQueue {
61 public:
62 virtual ~PacketQueue() = default;
63
64 virtual void Push(Timestamp enqueue_time,
65 std::unique_ptr<RtpPacketToSend> packet) = 0;
66 virtual std::unique_ptr<RtpPacketToSend> Pop() = 0;
67
Erik Språngb73c0582022-05-02 21:18:08 +020068 virtual int SizeInPackets() const = 0;
Erik Språngcb568272022-04-27 12:33:02 +020069 bool Empty() const { return SizeInPackets() == 0; }
70 virtual DataSize SizeInPayloadBytes() const = 0;
71
Henrik Boströmef241162022-06-06 16:19:11 +020072 // Total packets in the queue per media type (RtpPacketMediaType values are
73 // used as lookup index).
74 virtual const std::array<int, kNumMediaTypes>&
75 SizeInPacketsPerRtpPacketMediaType() const = 0;
76
Erik Språngcb568272022-04-27 12:33:02 +020077 // If the next packet, that would be returned by Pop() if called
78 // now, is an audio packet this method returns the enqueue time
79 // of that packet. If queue is empty or top packet is not audio,
80 // returns Timestamp::MinusInfinity().
81 virtual Timestamp LeadingAudioPacketEnqueueTime() const = 0;
82
83 // Enqueue time of the oldest packet in the queue,
84 // Timestamp::MinusInfinity() if queue is empty.
85 virtual Timestamp OldestEnqueueTime() const = 0;
86
87 // Average queue time for the packets currently in the queue.
88 // The queuing time is calculated from Push() to the last UpdateQueueTime()
89 // call - with any time spent in a paused state subtracted.
Erik Språngb73c0582022-05-02 21:18:08 +020090 // Returns TimeDelta::Zero() for an empty queue.
Erik Språngcb568272022-04-27 12:33:02 +020091 virtual TimeDelta AverageQueueTime() const = 0;
92
93 // Called during packet processing or when pause stats changes. Since the
94 // AverageQueueTime() method does not look at the wall time, this method
95 // needs to be called before querying queue time.
96 virtual void UpdateAverageQueueTime(Timestamp now) = 0;
97
98 // Set the pause state, while `paused` is true queuing time is not counted.
99 virtual void SetPauseState(bool paused, Timestamp now) = 0;
100 };
101
Erik Språngd05edec2019-08-14 10:43:47 +0200102 // Expected max pacer delay. If ExpectedQueueTime() is higher than
103 // this value, the packet producers should wait (eg drop frames rather than
104 // encoding them). Bitrate sent may temporarily exceed target set by
105 // UpdateBitrate() so that this limit will be upheld.
106 static const TimeDelta kMaxExpectedQueueLength;
107 // Pacing-rate relative to our target send rate.
108 // Multiplicative factor that is applied to the target bitrate to calculate
109 // the number of bytes that can be transmitted per interval.
110 // Increasing this factor will result in lower delays in cases of bitrate
111 // overshoots from the encoder.
112 static const float kDefaultPaceMultiplier;
Artem Titovee3e3fd2021-07-28 20:28:28 +0200113 // If no media or paused, wake up at least every `kPausedProcessIntervalMs` in
Erik Språngd05edec2019-08-14 10:43:47 +0200114 // order to send a keep-alive packet so we don't get stuck in a bad state due
115 // to lack of feedback.
116 static const TimeDelta kPausedProcessInterval;
117
Erik Språngeb487992019-11-14 14:15:15 +0100118 static const TimeDelta kMinSleepTime;
119
Jianhui Daidf59e532022-03-19 15:38:51 +0800120 // Allow probes to be processed slightly ahead of inteded send time. Currently
121 // set to 1ms as this is intended to allow times be rounded down to the
122 // nearest millisecond.
123 static const TimeDelta kMaxEarlyProbeProcessing;
124
Erik Språngd05edec2019-08-14 10:43:47 +0200125 PacingController(Clock* clock,
126 PacketSender* packet_sender,
Erik Språng6aa5cea2022-05-16 13:20:36 +0200127 const FieldTrialsView& field_trials);
128
Erik Språngd05edec2019-08-14 10:43:47 +0200129 ~PacingController();
130
Erik Språngd05edec2019-08-14 10:43:47 +0200131 // Adds the packet to the queue and calls PacketRouter::SendPacket() when
132 // it's time to send.
133 void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
134
Per Kjellander88af2032022-05-16 19:58:40 +0200135 // ABSL_DEPRECATED("Use CreateProbeClusters instead")
Erik Språngd05edec2019-08-14 10:43:47 +0200136 void CreateProbeCluster(DataRate bitrate, int cluster_id);
Per Kjellander88af2032022-05-16 19:58:40 +0200137 void CreateProbeClusters(
138 rtc::ArrayView<const ProbeClusterConfig> probe_cluster_configs);
Erik Språngd05edec2019-08-14 10:43:47 +0200139
140 void Pause(); // Temporarily pause all sending.
141 void Resume(); // Resume sending packets.
142 bool IsPaused() const;
143
Erik Språng66734372022-03-16 14:20:49 +0100144 void SetCongested(bool congested);
Erik Språngd05edec2019-08-14 10:43:47 +0200145
146 // Sets the pacing rates. Must be called once before packets can be sent.
147 void SetPacingRates(DataRate pacing_rate, DataRate padding_rate);
Erik Språngdf9e51a2022-06-10 11:42:15 +0200148 DataRate pacing_rate() const { return adjusted_media_rate_; }
Erik Språngd05edec2019-08-14 10:43:47 +0200149
150 // Currently audio traffic is not accounted by pacer and passed through.
151 // With the introduction of audio BWE audio traffic will be accounted for
152 // the pacer budget calculation. The audio traffic still will be injected
153 // at high priority.
154 void SetAccountForAudioPackets(bool account_for_audio);
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100155 void SetIncludeOverhead();
Erik Språngd05edec2019-08-14 10:43:47 +0200156
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000157 void SetTransportOverhead(DataSize overhead_per_packet);
Per Kjellander8d847f02022-06-01 20:21:58 +0200158 // The pacer is allowed to send enqued packets in bursts and can build up a
159 // packet "debt" that correspond to approximately the send rate during
160 // 'burst_interval'.
161 void SetSendBurstInterval(TimeDelta burst_interval);
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000162
Jianhui Dai94457792021-12-07 19:34:36 +0800163 // Returns the time when the oldest packet was queued.
164 Timestamp OldestPacketEnqueueTime() const;
Erik Språngd05edec2019-08-14 10:43:47 +0200165
Erik Språng4314a492019-11-26 17:48:49 +0100166 // Number of packets in the pacer queue.
Erik Språngd05edec2019-08-14 10:43:47 +0200167 size_t QueueSizePackets() const;
Henrik Boströmef241162022-06-06 16:19:11 +0200168 // Number of packets in the pacer queue per media type (RtpPacketMediaType
169 // values are used as lookup index).
170 const std::array<int, kNumMediaTypes>& SizeInPacketsPerRtpPacketMediaType()
171 const;
Erik Språng4314a492019-11-26 17:48:49 +0100172 // Totals size of packets in the pacer queue.
Erik Språngd05edec2019-08-14 10:43:47 +0200173 DataSize QueueSizeData() const;
174
Erik Språng4314a492019-11-26 17:48:49 +0100175 // Current buffer level, i.e. max of media and padding debt.
176 DataSize CurrentBufferLevel() const;
177
Jianhui Dai94457792021-12-07 19:34:36 +0800178 // Returns the time when the first packet was sent.
Erik Språngd05edec2019-08-14 10:43:47 +0200179 absl::optional<Timestamp> FirstSentPacketTime() const;
180
181 // Returns the number of milliseconds it will take to send the current
182 // packets in the queue, given the current size and bitrate, ignoring prio.
183 TimeDelta ExpectedQueueTime() const;
184
185 void SetQueueTimeLimit(TimeDelta limit);
186
187 // Enable bitrate probing. Enabled by default, mostly here to simplify
188 // testing. Must be called before any packets are being sent to have an
189 // effect.
190 void SetProbingEnabled(bool enabled);
191
Erik Språngeb487992019-11-14 14:15:15 +0100192 // Returns the next time we expect ProcessPackets() to be called.
193 Timestamp NextSendTime() const;
Erik Språngd05edec2019-08-14 10:43:47 +0200194
195 // Check queue of pending packets and send them or padding packets, if budget
196 // is available.
197 void ProcessPackets();
198
Erik Språng4ab61cb2020-05-19 17:40:58 +0200199 bool IsProbing() const;
200
Erik Språngd05edec2019-08-14 10:43:47 +0200201 private:
202 TimeDelta UpdateTimeAndGetElapsed(Timestamp now);
203 bool ShouldSendKeepalive(Timestamp now) const;
204
205 // Updates the number of bytes that can be sent for the next time interval.
206 void UpdateBudgetWithElapsedTime(TimeDelta delta);
207 void UpdateBudgetWithSentData(DataSize size);
Jianhui Daidf59e532022-03-19 15:38:51 +0800208 void UpdatePaddingBudgetWithSentData(DataSize size);
Erik Språngd05edec2019-08-14 10:43:47 +0200209
Erik Språngb9d38092020-07-17 12:06:12 +0200210 DataSize PaddingToAdd(DataSize recommended_probe_size,
Erik Språngeb487992019-11-14 14:15:15 +0100211 DataSize data_sent) const;
Erik Språngd05edec2019-08-14 10:43:47 +0200212
Erik Språngb0df5932019-11-18 13:40:24 +0100213 std::unique_ptr<RtpPacketToSend> GetPendingPacket(
Erik Språngeb487992019-11-14 14:15:15 +0100214 const PacedPacketInfo& pacing_info,
215 Timestamp target_send_time,
216 Timestamp now);
Björn Terelius31d0f7c2020-02-06 16:35:46 +0100217 void OnPacketSent(RtpPacketMediaType packet_type,
Erik Språngb0df5932019-11-18 13:40:24 +0100218 DataSize packet_size,
Erik Språngeb487992019-11-14 14:15:15 +0100219 Timestamp send_time);
Erik Språngdf9e51a2022-06-10 11:42:15 +0200220 void MaybeUpdateMediaRateDueToLongQueue(Timestamp now);
Erik Språngd05edec2019-08-14 10:43:47 +0200221
222 Timestamp CurrentTime() const;
223
224 Clock* const clock_;
225 PacketSender* const packet_sender_;
Jonas Orelande62c2f22022-03-29 11:04:48 +0200226 const FieldTrialsView& field_trials_;
Erik Språngd05edec2019-08-14 10:43:47 +0200227
228 const bool drain_large_queues_;
229 const bool send_padding_if_silent_;
230 const bool pace_audio_;
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000231 const bool ignore_transport_overhead_;
Erik Språngeb487992019-11-14 14:15:15 +0100232
Erik Språngd05edec2019-08-14 10:43:47 +0200233 TimeDelta min_packet_limit_;
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000234 DataSize transport_overhead_per_packet_;
Per Kjellander8d847f02022-06-01 20:21:58 +0200235 TimeDelta send_burst_interval_;
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000236
Erik Språngd05edec2019-08-14 10:43:47 +0200237 // TODO(webrtc:9716): Remove this when we are certain clocks are monotonic.
Artem Titovee3e3fd2021-07-28 20:28:28 +0200238 // The last millisecond timestamp returned by `clock_`.
Erik Språngd05edec2019-08-14 10:43:47 +0200239 mutable Timestamp last_timestamp_;
240 bool paused_;
Erik Språngeb487992019-11-14 14:15:15 +0100241
Erik Språngdf9e51a2022-06-10 11:42:15 +0200242 // Amount of outstanding data for media and padding.
Erik Språngeb487992019-11-14 14:15:15 +0100243 DataSize media_debt_;
244 DataSize padding_debt_;
Erik Språngdf9e51a2022-06-10 11:42:15 +0200245
246 // The target pacing rate, signaled via SetPacingRates().
247 DataRate pacing_rate_;
248 // The media send rate, which might adjusted from pacing_rate_, e.g. if the
249 // pacing queue is growing too long.
250 DataRate adjusted_media_rate_;
251 // The padding target rate. We aim to fill up to this rate with padding what
252 // is not already used by media.
Erik Språngeb487992019-11-14 14:15:15 +0100253 DataRate padding_rate_;
254
Erik Språngd05edec2019-08-14 10:43:47 +0200255 BitrateProber prober_;
256 bool probing_send_failure_;
Erik Språngd05edec2019-08-14 10:43:47 +0200257
Erik Språngeb487992019-11-14 14:15:15 +0100258 Timestamp last_process_time_;
Erik Språngd05edec2019-08-14 10:43:47 +0200259 Timestamp last_send_time_;
260 absl::optional<Timestamp> first_sent_packet_time_;
Erik Språngcb568272022-04-27 12:33:02 +0200261 bool seen_first_packet_;
Erik Språngd05edec2019-08-14 10:43:47 +0200262
Erik Språngcb568272022-04-27 12:33:02 +0200263 std::unique_ptr<PacketQueue> packet_queue_;
Erik Språngd05edec2019-08-14 10:43:47 +0200264
Erik Språng66734372022-03-16 14:20:49 +0100265 bool congested_;
Erik Språngd05edec2019-08-14 10:43:47 +0200266
Jianhui Daidf59e532022-03-19 15:38:51 +0800267 TimeDelta queue_time_limit_;
Erik Språngd05edec2019-08-14 10:43:47 +0200268 bool account_for_audio_;
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100269 bool include_overhead_;
Erik Språngd05edec2019-08-14 10:43:47 +0200270};
271} // namespace webrtc
272
273#endif // MODULES_PACING_PACING_CONTROLLER_H_