Bug Summary

File:root/firefox-clang/third_party/libwebrtc/modules/pacing/pacing_controller.h
Warning:line 43, column 7
Excessive padding in 'class webrtc::PacingController' (32 padding bytes, where 0 is optimal). Optimal fields order: clock_, packet_sender_, field_trials_, max_rate, transport_overhead_per_packet_, send_burst_interval_, last_timestamp_, media_debt_, padding_debt_, pacing_rate_, adjusted_media_rate_, padding_rate_, last_process_time_, last_send_time_, queue_time_limit_, first_sent_packet_time_, prober_, packet_queue_, circuit_breaker_threshold_, drain_large_queues_, send_padding_if_silent_, pace_audio_, ignore_transport_overhead_, fast_retransmissions_, keyframe_flushing_, paused_, probing_send_failure_, seen_first_packet_, congested_, account_for_audio_, include_overhead_, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_libwebrtcglue0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/libwebrtcglue -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/libwebrtcglue -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D HAVE_UINT64_T -D WEBRTC_MOZILLA_BUILD -D RTC_ENABLE_VP9 -D WEBRTC_POSIX -D WEBRTC_BUILD_LIBEVENT -D WEBRTC_LINUX -D WEBRTC_USE_PIPEWIRE -D WEBRTC_USE_X11 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media/webrtc/libwebrtcglue -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/libwebrtcglue -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/dom/media/gmp -I /root/firefox-clang/dom/media/systemservices -I /root/firefox-clang/dom/media/webrtc -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/media/libyuv/libyuv/include -I /root/firefox-clang/media/webrtc -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/third_party/libsrtp/src/include -I /root/firefox-clang/third_party/libwebrtc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ Unified_cpp_libwebrtcglue0.cpp
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 <array>
18#include <memory>
19#include <optional>
20#include <vector>
21
22#include "api/array_view.h"
23#include "api/field_trials_view.h"
24#include "api/rtp_packet_sender.h"
25#include "api/transport/network_types.h"
26#include "api/units/data_rate.h"
27#include "api/units/data_size.h"
28#include "api/units/time_delta.h"
29#include "api/units/timestamp.h"
30#include "modules/pacing/bitrate_prober.h"
31#include "modules/pacing/prioritized_packet_queue.h"
32#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
33#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
34#include "system_wrappers/include/clock.h"
35
36namespace webrtc {
37
38// This class implements a leaky-bucket packet pacing algorithm. It handles the
39// logic of determining which packets to send when, but the actual timing of
40// the processing is done externally (e.g. RtpPacketPacer). Furthermore, the
41// forwarding of packets when they are ready to be sent is also handled
42// externally, via the PacingController::PacketSender interface.
43class PacingController {
Excessive padding in 'class webrtc::PacingController' (32 padding bytes, where 0 is optimal). Optimal fields order: clock_, packet_sender_, field_trials_, max_rate, transport_overhead_per_packet_, send_burst_interval_, last_timestamp_, media_debt_, padding_debt_, pacing_rate_, adjusted_media_rate_, padding_rate_, last_process_time_, last_send_time_, queue_time_limit_, first_sent_packet_time_, prober_, packet_queue_, circuit_breaker_threshold_, drain_large_queues_, send_padding_if_silent_, pace_audio_, ignore_transport_overhead_, fast_retransmissions_, keyframe_flushing_, paused_, probing_send_failure_, seen_first_packet_, congested_, account_for_audio_, include_overhead_, consider reordering the fields or adding explicit padding members
44 public:
45 class PacketSender {
46 public:
47 virtual ~PacketSender() = default;
48 virtual void SendPacket(std::unique_ptr<RtpPacketToSend> packet,
49 const PacedPacketInfo& cluster_info) = 0;
50 // Should be called after each call to SendPacket().
51 virtual std::vector<std::unique_ptr<RtpPacketToSend>> FetchFec() = 0;
52 virtual std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
53 DataSize size) = 0;
54 // TODO(bugs.webrtc.org/1439830): Make pure virtual once subclasses adapt.
55 virtual void OnBatchComplete() {}
56
57 // TODO(bugs.webrtc.org/11340): Make pure virtual once downstream projects
58 // have been updated.
59 virtual void OnAbortedRetransmissions(
60 uint32_t /* ssrc */,
61 rtc::ArrayView<const uint16_t> /* sequence_numbers */) {}
62 virtual std::optional<uint32_t> GetRtxSsrcForMedia(
63 uint32_t /* ssrc */) const {
64 return std::nullopt;
65 }
66 };
67
68 // If no media or paused, wake up at least every `kPausedProcessIntervalMs` in
69 // order to send a keep-alive packet so we don't get stuck in a bad state due
70 // to lack of feedback.
71 static const TimeDelta kPausedProcessInterval;
72 // The default minimum time that should elapse calls to `ProcessPackets()`.
73 static const TimeDelta kMinSleepTime;
74 // When padding should be generated, add packets to the buffer with a size
75 // corresponding to this duration times the current padding rate.
76 static const TimeDelta kTargetPaddingDuration;
77 // The maximum time that the pacer can use when "replaying" passed time where
78 // padding should have been generated.
79 static const TimeDelta kMaxPaddingReplayDuration;
80 // Allow probes to be processed slightly ahead of inteded send time. Currently
81 // set to 1ms as this is intended to allow times be rounded down to the
82 // nearest millisecond.
83 static const TimeDelta kMaxEarlyProbeProcessing;
84 // Max total size of packets expected to be sent in a burst in order to not
85 // risk loosing packets due to too small send socket buffers. It upper limits
86 // the send burst interval.
87 // Ex: max send burst interval = 63Kb / 10Mbit/s = 50ms.
88 static constexpr DataSize kMaxBurstSize = DataSize::Bytes(63 * 1000);
89
90 // Configuration default values.
91 static constexpr TimeDelta kDefaultBurstInterval = TimeDelta::Millis(40);
92 static constexpr TimeDelta kMaxExpectedQueueLength = TimeDelta::Millis(2000);
93
94 struct Configuration {
95 // If the pacer queue grows longer than the configured max queue limit,
96 // pacer sends at the minimum rate needed to keep the max queue limit and
97 // ignore the current bandwidth estimate.
98 bool drain_large_queues = true;
99 // Expected max pacer delay. If ExpectedQueueTime() is higher than
100 // this value, the packet producers should wait (eg drop frames rather than
101 // encoding them). Bitrate sent may temporarily exceed target set by
102 // SetPacingRates() so that this limit will be upheld if
103 // `drain_large_queues` is set.
104 TimeDelta queue_time_limit = kMaxExpectedQueueLength;
105 // If the first packet of a keyframe is enqueued on a RTP stream, pacer
106 // skips forward to that packet and drops other enqueued packets on that
107 // stream, unless a keyframe is already being paced.
108 bool keyframe_flushing = false;
109 // Audio retransmission is prioritized before video retransmission packets.
110 bool prioritize_audio_retransmission = false;
111 // Configure separate timeouts per priority. After a timeout, a packet of
112 // that sort will not be paced and instead dropped.
113 // Note: to set TTL on audio retransmission,
114 // `prioritize_audio_retransmission` must be true.
115 PacketQueueTTL packet_queue_ttl;
116 // The pacer is allowed to send enqueued packets in bursts and can build up
117 // a packet "debt" that correspond to approximately the send rate during the
118 // burst interval.
119 TimeDelta send_burst_interval = kDefaultBurstInterval;
120 };
121
122 static Configuration DefaultConfiguration() { return Configuration{}; }
123
124 PacingController(Clock* clock,
125 PacketSender* packet_sender,
126 const FieldTrialsView& field_trials,
127 Configuration configuration = DefaultConfiguration());
128
129 ~PacingController();
130
131 // 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
135 void CreateProbeClusters(
136 rtc::ArrayView<const ProbeClusterConfig> probe_cluster_configs);
137
138 void Pause(); // Temporarily pause all sending.
139 void Resume(); // Resume sending packets.
140 bool IsPaused() const;
141
142 void SetCongested(bool congested);
143
144 // Sets the pacing rates. Must be called once before packets can be sent.
145 void SetPacingRates(DataRate pacing_rate, DataRate padding_rate);
146 DataRate pacing_rate() const { return adjusted_media_rate_; }
147
148 // Currently audio traffic is not accounted by pacer and passed through.
149 // With the introduction of audio BWE audio traffic will be accounted for
150 // the pacer budget calculation. The audio traffic still will be injected
151 // at high priority.
152 void SetAccountForAudioPackets(bool account_for_audio);
153 void SetIncludeOverhead();
154
155 void SetTransportOverhead(DataSize overhead_per_packet);
156 // The pacer is allowed to send enqued packets in bursts and can build up a
157 // packet "debt" that correspond to approximately the send rate during
158 // 'burst_interval'.
159 void SetSendBurstInterval(TimeDelta burst_interval);
160
161 // A probe may be sent without first waing for a media packet.
162 void SetAllowProbeWithoutMediaPacket(bool allow);
163
164 // Returns the time when the oldest packet was queued.
165 Timestamp OldestPacketEnqueueTime() const;
166
167 // Number of packets in the pacer queue.
168 size_t QueueSizePackets() const;
169 // Number of packets in the pacer queue per media type (RtpPacketMediaType
170 // values are used as lookup index).
171 const std::array<int, kNumMediaTypes>& SizeInPacketsPerRtpPacketMediaType()
172 const;
173 // Totals size of packets in the pacer queue.
174 DataSize QueueSizeData() const;
175
176 // Current buffer level, i.e. max of media and padding debt.
177 DataSize CurrentBufferLevel() const;
178
179 // Returns the time when the first packet was sent.
180 std::optional<Timestamp> FirstSentPacketTime() const;
181
182 // Returns the number of milliseconds it will take to send the current
183 // packets in the queue, given the current size and bitrate, ignoring prio.
184 TimeDelta ExpectedQueueTime() const;
185
186 void SetQueueTimeLimit(TimeDelta limit);
187
188 // Enable bitrate probing. Enabled by default, mostly here to simplify
189 // testing. Must be called before any packets are being sent to have an
190 // effect.
191 void SetProbingEnabled(bool enabled);
192
193 // Returns the next time we expect ProcessPackets() to be called.
194 Timestamp NextSendTime() const;
195
196 // Check queue of pending packets and send them or padding packets, if budget
197 // is available.
198 void ProcessPackets();
199
200 bool IsProbing() const;
201
202 // Note: Intended for debugging purposes only, will be removed.
203 // Sets the number of iterations of the main loop in `ProcessPackets()` that
204 // is considered erroneous to exceed.
205 void SetCircuitBreakerThreshold(int num_iterations);
206
207 // Remove any pending packets matching this SSRC from the packet queue.
208 void RemovePacketsForSsrc(uint32_t ssrc);
209
210 private:
211 TimeDelta UpdateTimeAndGetElapsed(Timestamp now);
212 bool ShouldSendKeepalive(Timestamp now) const;
213
214 // Updates the number of bytes that can be sent for the next time interval.
215 void UpdateBudgetWithElapsedTime(TimeDelta delta);
216 void UpdateBudgetWithSentData(DataSize size);
217 void UpdatePaddingBudgetWithSentData(DataSize size);
218
219 DataSize PaddingToAdd(DataSize recommended_probe_size,
220 DataSize data_sent) const;
221
222 std::unique_ptr<RtpPacketToSend> GetPendingPacket(
223 const PacedPacketInfo& pacing_info,
224 Timestamp target_send_time,
225 Timestamp now);
226 void OnPacketSent(RtpPacketMediaType packet_type,
227 DataSize packet_size,
228 Timestamp send_time);
229 void MaybeUpdateMediaRateDueToLongQueue(Timestamp now);
230
231 Timestamp CurrentTime() const;
232
233 // Helper methods for packet that may not be paced. Returns a finite Timestamp
234 // if a packet type is configured to not be paced and the packet queue has at
235 // least one packet of that type. Otherwise returns
236 // Timestamp::MinusInfinity().
237 Timestamp NextUnpacedSendTime() const;
238
239 Clock* const clock_;
240 PacketSender* const packet_sender_;
241 const FieldTrialsView& field_trials_;
242
243 const bool drain_large_queues_;
244 const bool send_padding_if_silent_;
245 const bool pace_audio_;
246 const bool ignore_transport_overhead_;
247 const bool fast_retransmissions_;
248 const bool keyframe_flushing_;
249 DataRate max_rate = DataRate::BitsPerSec(100'000'000);
250 DataSize transport_overhead_per_packet_;
251 TimeDelta send_burst_interval_;
252
253 // TODO(webrtc:9716): Remove this when we are certain clocks are monotonic.
254 // The last millisecond timestamp returned by `clock_`.
255 mutable Timestamp last_timestamp_;
256 bool paused_;
257
258 // Amount of outstanding data for media and padding.
259 DataSize media_debt_;
260 DataSize padding_debt_;
261
262 // The target pacing rate, signaled via SetPacingRates().
263 DataRate pacing_rate_;
264 // The media send rate, which might adjusted from pacing_rate_, e.g. if the
265 // pacing queue is growing too long.
266 DataRate adjusted_media_rate_;
267 // The padding target rate. We aim to fill up to this rate with padding what
268 // is not already used by media.
269 DataRate padding_rate_;
270
271 BitrateProber prober_;
272 bool probing_send_failure_;
273
274 Timestamp last_process_time_;
275 Timestamp last_send_time_;
276 std::optional<Timestamp> first_sent_packet_time_;
277 bool seen_first_packet_;
278
279 PrioritizedPacketQueue packet_queue_;
280
281 bool congested_;
282
283 TimeDelta queue_time_limit_;
284 bool account_for_audio_;
285 bool include_overhead_;
286
287 int circuit_breaker_threshold_;
288};
289} // namespace webrtc
290
291#endif // MODULES_PACING_PACING_CONTROLLER_H_