blob: b0bdfb2e4264d05aa4bcebbd1fd6075821f6e685 [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
17#include <atomic>
18#include <memory>
19#include <vector>
20
21#include "absl/types/optional.h"
22#include "api/function_view.h"
23#include "api/rtc_event_log/rtc_event_log.h"
24#include "api/transport/field_trial_based_config.h"
25#include "api/transport/network_types.h"
26#include "api/transport/webrtc_key_value_config.h"
27#include "modules/pacing/bitrate_prober.h"
28#include "modules/pacing/interval_budget.h"
29#include "modules/pacing/round_robin_packet_queue.h"
30#include "modules/pacing/rtp_packet_pacer.h"
31#include "modules/rtp_rtcp/include/rtp_packet_sender.h"
Björn Terelius31d0f7c2020-02-06 16:35:46 +010032#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Erik Språngd05edec2019-08-14 10:43:47 +020033#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Erik Språngd05edec2019-08-14 10:43:47 +020034#include "rtc_base/experiments/field_trial_parser.h"
35#include "rtc_base/thread_annotations.h"
36
37namespace webrtc {
38
Rikard Lundmark48be4822020-01-28 16:07:36 +010039// This class implements a leaky-bucket packet pacing algorithm. It handles the
Erik Språngd05edec2019-08-14 10:43:47 +020040// logic of determining which packets to send when, but the actual timing of
41// the processing is done externally (e.g. PacedSender). Furthermore, the
42// forwarding of packets when they are ready to be sent is also handled
43// externally, via the PacedSendingController::PacketSender interface.
44//
45class PacingController {
46 public:
Erik Språngeb487992019-11-14 14:15:15 +010047 // Periodic mode uses the IntervalBudget class for tracking bitrate
48 // budgets, and expected ProcessPackets() to be called a fixed rate,
49 // e.g. every 5ms as implemented by PacedSender.
50 // Dynamic mode allows for arbitrary time delta between calls to
51 // ProcessPackets.
52 enum class ProcessMode { kPeriodic, kDynamic };
53
Erik Språngd05edec2019-08-14 10:43:47 +020054 class PacketSender {
55 public:
56 virtual ~PacketSender() = default;
Erik Språnged1fb192020-06-30 11:53:37 +000057 virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
58 const PacedPacketInfo& cluster_info) = 0;
Erik Språng1d50cb62020-07-02 17:41:32 +020059 // Should be called after each call to SendPacket().
60 virtual std::vector<std::unique_ptr<RtpPacketToSend>> FetchFec() = 0;
Erik Språngd05edec2019-08-14 10:43:47 +020061 virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
62 DataSize size) = 0;
Erik Språngd05edec2019-08-14 10:43:47 +020063 };
64
65 // Expected max pacer delay. If ExpectedQueueTime() is higher than
66 // this value, the packet producers should wait (eg drop frames rather than
67 // encoding them). Bitrate sent may temporarily exceed target set by
68 // UpdateBitrate() so that this limit will be upheld.
69 static const TimeDelta kMaxExpectedQueueLength;
70 // Pacing-rate relative to our target send rate.
71 // Multiplicative factor that is applied to the target bitrate to calculate
72 // the number of bytes that can be transmitted per interval.
73 // Increasing this factor will result in lower delays in cases of bitrate
74 // overshoots from the encoder.
75 static const float kDefaultPaceMultiplier;
76 // If no media or paused, wake up at least every |kPausedProcessIntervalMs| in
77 // order to send a keep-alive packet so we don't get stuck in a bad state due
78 // to lack of feedback.
79 static const TimeDelta kPausedProcessInterval;
80
Erik Språngeb487992019-11-14 14:15:15 +010081 static const TimeDelta kMinSleepTime;
82
Erik Språngd05edec2019-08-14 10:43:47 +020083 PacingController(Clock* clock,
84 PacketSender* packet_sender,
85 RtcEventLog* event_log,
Erik Språngeb487992019-11-14 14:15:15 +010086 const WebRtcKeyValueConfig* field_trials,
87 ProcessMode mode);
Erik Språngd05edec2019-08-14 10:43:47 +020088
89 ~PacingController();
90
Erik Språngd05edec2019-08-14 10:43:47 +020091 // Adds the packet to the queue and calls PacketRouter::SendPacket() when
92 // it's time to send.
93 void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
94
95 void CreateProbeCluster(DataRate bitrate, int cluster_id);
96
97 void Pause(); // Temporarily pause all sending.
98 void Resume(); // Resume sending packets.
99 bool IsPaused() const;
100
101 void SetCongestionWindow(DataSize congestion_window_size);
102 void UpdateOutstandingData(DataSize outstanding_data);
103
104 // Sets the pacing rates. Must be called once before packets can be sent.
105 void SetPacingRates(DataRate pacing_rate, DataRate padding_rate);
106
107 // Currently audio traffic is not accounted by pacer and passed through.
108 // With the introduction of audio BWE audio traffic will be accounted for
109 // the pacer budget calculation. The audio traffic still will be injected
110 // at high priority.
111 void SetAccountForAudioPackets(bool account_for_audio);
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100112 void SetIncludeOverhead();
Erik Språngd05edec2019-08-14 10:43:47 +0200113
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000114 void SetTransportOverhead(DataSize overhead_per_packet);
115
Erik Språngd05edec2019-08-14 10:43:47 +0200116 // Returns the time since the oldest queued packet was enqueued.
117 TimeDelta OldestPacketWaitTime() const;
118
Erik Språng4314a492019-11-26 17:48:49 +0100119 // Number of packets in the pacer queue.
Erik Språngd05edec2019-08-14 10:43:47 +0200120 size_t QueueSizePackets() const;
Erik Språng4314a492019-11-26 17:48:49 +0100121 // Totals size of packets in the pacer queue.
Erik Språngd05edec2019-08-14 10:43:47 +0200122 DataSize QueueSizeData() const;
123
Erik Språng4314a492019-11-26 17:48:49 +0100124 // Current buffer level, i.e. max of media and padding debt.
125 DataSize CurrentBufferLevel() const;
126
Erik Språngd05edec2019-08-14 10:43:47 +0200127 // Returns the time when the first packet was sent;
128 absl::optional<Timestamp> FirstSentPacketTime() const;
129
130 // Returns the number of milliseconds it will take to send the current
131 // packets in the queue, given the current size and bitrate, ignoring prio.
132 TimeDelta ExpectedQueueTime() const;
133
134 void SetQueueTimeLimit(TimeDelta limit);
135
136 // Enable bitrate probing. Enabled by default, mostly here to simplify
137 // testing. Must be called before any packets are being sent to have an
138 // effect.
139 void SetProbingEnabled(bool enabled);
140
Erik Språngeb487992019-11-14 14:15:15 +0100141 // Returns the next time we expect ProcessPackets() to be called.
142 Timestamp NextSendTime() const;
Erik Språngd05edec2019-08-14 10:43:47 +0200143
144 // Check queue of pending packets and send them or padding packets, if budget
145 // is available.
146 void ProcessPackets();
147
148 bool Congested() const;
149
Erik Språng4ab61cb2020-05-19 17:40:58 +0200150 bool IsProbing() const;
151
Erik Språngd05edec2019-08-14 10:43:47 +0200152 private:
Erik Språng78c82a42019-10-03 18:46:04 +0200153 void EnqueuePacketInternal(std::unique_ptr<RtpPacketToSend> packet,
154 int priority);
Erik Språngd05edec2019-08-14 10:43:47 +0200155 TimeDelta UpdateTimeAndGetElapsed(Timestamp now);
156 bool ShouldSendKeepalive(Timestamp now) const;
157
158 // Updates the number of bytes that can be sent for the next time interval.
159 void UpdateBudgetWithElapsedTime(TimeDelta delta);
160 void UpdateBudgetWithSentData(DataSize size);
161
Erik Språngb9d38092020-07-17 12:06:12 +0200162 DataSize PaddingToAdd(DataSize recommended_probe_size,
Erik Språngeb487992019-11-14 14:15:15 +0100163 DataSize data_sent) const;
Erik Språngd05edec2019-08-14 10:43:47 +0200164
Erik Språngb0df5932019-11-18 13:40:24 +0100165 std::unique_ptr<RtpPacketToSend> GetPendingPacket(
Erik Språngeb487992019-11-14 14:15:15 +0100166 const PacedPacketInfo& pacing_info,
167 Timestamp target_send_time,
168 Timestamp now);
Björn Terelius31d0f7c2020-02-06 16:35:46 +0100169 void OnPacketSent(RtpPacketMediaType packet_type,
Erik Språngb0df5932019-11-18 13:40:24 +0100170 DataSize packet_size,
Erik Språngeb487992019-11-14 14:15:15 +0100171 Timestamp send_time);
Erik Språngd05edec2019-08-14 10:43:47 +0200172 void OnPaddingSent(DataSize padding_sent);
173
174 Timestamp CurrentTime() const;
175
Erik Språngeb487992019-11-14 14:15:15 +0100176 const ProcessMode mode_;
Erik Språngd05edec2019-08-14 10:43:47 +0200177 Clock* const clock_;
178 PacketSender* const packet_sender_;
179 const std::unique_ptr<FieldTrialBasedConfig> fallback_field_trials_;
180 const WebRtcKeyValueConfig* field_trials_;
181
182 const bool drain_large_queues_;
183 const bool send_padding_if_silent_;
184 const bool pace_audio_;
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000185 const bool ignore_transport_overhead_;
Erik Språng9acc18d2020-04-16 19:41:07 +0200186 // In dynamic mode, indicates the target size when requesting padding,
187 // expressed as a duration in order to adjust for varying padding rate.
188 const TimeDelta padding_target_duration_;
Erik Språngeb487992019-11-14 14:15:15 +0100189
Erik Språngd05edec2019-08-14 10:43:47 +0200190 TimeDelta min_packet_limit_;
191
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000192 DataSize transport_overhead_per_packet_;
193
Erik Språngd05edec2019-08-14 10:43:47 +0200194 // TODO(webrtc:9716): Remove this when we are certain clocks are monotonic.
195 // The last millisecond timestamp returned by |clock_|.
196 mutable Timestamp last_timestamp_;
197 bool paused_;
Erik Språngeb487992019-11-14 14:15:15 +0100198
199 // If |use_interval_budget_| is true, |media_budget_| and |padding_budget_|
200 // will be used to track when packets can be sent. Otherwise the media and
201 // padding debt counters will be used together with the target rates.
202
Erik Språngd05edec2019-08-14 10:43:47 +0200203 // This is the media budget, keeping track of how many bits of media
204 // we can pace out during the current interval.
205 IntervalBudget media_budget_;
206 // This is the padding budget, keeping track of how many bits of padding we're
207 // allowed to send out during the current interval. This budget will be
208 // utilized when there's no media to send.
209 IntervalBudget padding_budget_;
210
Erik Språngeb487992019-11-14 14:15:15 +0100211 DataSize media_debt_;
212 DataSize padding_debt_;
213 DataRate media_rate_;
214 DataRate padding_rate_;
215
Erik Språngd05edec2019-08-14 10:43:47 +0200216 BitrateProber prober_;
217 bool probing_send_failure_;
Erik Språngd05edec2019-08-14 10:43:47 +0200218
219 DataRate pacing_bitrate_;
220
Erik Språngeb487992019-11-14 14:15:15 +0100221 Timestamp last_process_time_;
Erik Språngd05edec2019-08-14 10:43:47 +0200222 Timestamp last_send_time_;
223 absl::optional<Timestamp> first_sent_packet_time_;
224
225 RoundRobinPacketQueue packet_queue_;
226 uint64_t packet_counter_;
227
228 DataSize congestion_window_size_;
229 DataSize outstanding_data_;
230
231 TimeDelta queue_time_limit;
232 bool account_for_audio_;
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100233 bool include_overhead_;
Erik Språngd05edec2019-08-14 10:43:47 +0200234};
235} // namespace webrtc
236
237#endif // MODULES_PACING_PACING_CONTROLLER_H_