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