• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
32 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
33 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
34 #include "rtc_base/experiments/field_trial_parser.h"
35 #include "rtc_base/thread_annotations.h"
36 
37 namespace webrtc {
38 
39 // This class implements a leaky-bucket packet pacing algorithm. It handles the
40 // 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 //
45 class PacingController {
46  public:
47   // 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 
54   class PacketSender {
55    public:
56     virtual ~PacketSender() = default;
57     virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
58                             const PacedPacketInfo& cluster_info) = 0;
59     // Should be called after each call to SendPacket().
60     virtual std::vector<std::unique_ptr<RtpPacketToSend>> FetchFec() = 0;
61     virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
62         DataSize size) = 0;
63   };
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 
81   static const TimeDelta kMinSleepTime;
82 
83   PacingController(Clock* clock,
84                    PacketSender* packet_sender,
85                    RtcEventLog* event_log,
86                    const WebRtcKeyValueConfig* field_trials,
87                    ProcessMode mode);
88 
89   ~PacingController();
90 
91   // 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);
112   void SetIncludeOverhead();
113 
114   void SetTransportOverhead(DataSize overhead_per_packet);
115 
116   // Returns the time since the oldest queued packet was enqueued.
117   TimeDelta OldestPacketWaitTime() const;
118 
119   // Number of packets in the pacer queue.
120   size_t QueueSizePackets() const;
121   // Totals size of packets in the pacer queue.
122   DataSize QueueSizeData() const;
123 
124   // Current buffer level, i.e. max of media and padding debt.
125   DataSize CurrentBufferLevel() const;
126 
127   // 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 
141   // Returns the next time we expect ProcessPackets() to be called.
142   Timestamp NextSendTime() const;
143 
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 
150   bool IsProbing() const;
151 
152  private:
153   void EnqueuePacketInternal(std::unique_ptr<RtpPacketToSend> packet,
154                              int priority);
155   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 
162   DataSize PaddingToAdd(DataSize recommended_probe_size,
163                         DataSize data_sent) const;
164 
165   std::unique_ptr<RtpPacketToSend> GetPendingPacket(
166       const PacedPacketInfo& pacing_info,
167       Timestamp target_send_time,
168       Timestamp now);
169   void OnPacketSent(RtpPacketMediaType packet_type,
170                     DataSize packet_size,
171                     Timestamp send_time);
172   void OnPaddingSent(DataSize padding_sent);
173 
174   Timestamp CurrentTime() const;
175 
176   const ProcessMode mode_;
177   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_;
185   const bool small_first_probe_packet_;
186   const bool ignore_transport_overhead_;
187   // In dynamic mode, indicates the target size when requesting padding,
188   // expressed as a duration in order to adjust for varying padding rate.
189   const TimeDelta padding_target_duration_;
190 
191   TimeDelta min_packet_limit_;
192 
193   DataSize transport_overhead_per_packet_;
194 
195   // TODO(webrtc:9716): Remove this when we are certain clocks are monotonic.
196   // The last millisecond timestamp returned by |clock_|.
197   mutable Timestamp last_timestamp_;
198   bool paused_;
199 
200   // If |use_interval_budget_| is true, |media_budget_| and |padding_budget_|
201   // will be used to track when packets can be sent. Otherwise the media and
202   // padding debt counters will be used together with the target rates.
203 
204   // This is the media budget, keeping track of how many bits of media
205   // we can pace out during the current interval.
206   IntervalBudget media_budget_;
207   // This is the padding budget, keeping track of how many bits of padding we're
208   // allowed to send out during the current interval. This budget will be
209   // utilized when there's no media to send.
210   IntervalBudget padding_budget_;
211 
212   DataSize media_debt_;
213   DataSize padding_debt_;
214   DataRate media_rate_;
215   DataRate padding_rate_;
216 
217   BitrateProber prober_;
218   bool probing_send_failure_;
219 
220   DataRate pacing_bitrate_;
221 
222   Timestamp last_process_time_;
223   Timestamp last_send_time_;
224   absl::optional<Timestamp> first_sent_packet_time_;
225 
226   RoundRobinPacketQueue packet_queue_;
227   uint64_t packet_counter_;
228 
229   DataSize congestion_window_size_;
230   DataSize outstanding_data_;
231 
232   TimeDelta queue_time_limit;
233   bool account_for_audio_;
234   bool include_overhead_;
235 };
236 }  // namespace webrtc
237 
238 #endif  // MODULES_PACING_PACING_CONTROLLER_H_
239