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' (33 padding bytes, where 1 is optimal). Optimal fields order: clock_, packet_sender_, 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_, 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 -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_call_call_gn0.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/third_party/libwebrtc/call/call_gn -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/libwebrtc/call/call_gn -resource-dir /usr/lib/llvm-23/lib/clang/23 -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 -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D ABSL_ALLOCATOR_NOTHROW=1 -D PROTOBUF_ENABLE_DEBUG_LOGGING_MAY_LEAK_PII=0 -D RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY -D RTC_ENABLE_VP9 -D WEBRTC_DEPRECATE_PLAN_B -D WEBRTC_ENABLE_PROTOBUF=0 -D WEBRTC_ENCODER_PSNR_STATS -D WEBRTC_LIBRARY_IMPL -D WEBRTC_MOZILLA_BUILD -D WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0 -D WEBRTC_STRICT_FIELD_TRIALS=0 -D WEBRTC_WITHOUT_RUST -D DYNAMIC_ANNOTATIONS_ENABLED=1 -D USE_AURA=1 -D USE_GLIB=1 -D USE_OZONE=1 -D USE_UDEV -D WEBRTC_LINUX -D WEBRTC_POSIX -D _FILE_OFFSET_BITS=64 -D _LARGEFILE64_SOURCE -D _LARGEFILE_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D WEBRTC_ENABLE_AVX2 -D _DEBUG -D _GNU_SOURCE -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/third_party/libwebrtc/call/call_gn -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/libwebrtc/call/call_gn -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/libwebrtc_overrides -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/libwebrtc/gen -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/third_party/libwebrtc -I /root/firefox-clang/tools/profiler/public -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -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-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 -Wno-character-conversion -std=gnu++20 -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 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ Unified_cpp_call_call_gn0.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 <span>
21#include <vector>
22
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' (33 padding bytes, where 1 is optimal). Optimal fields order: clock_, packet_sender_, 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_, 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 std::span<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 kMaxExpectedQueueLength = TimeDelta::Millis(2000);
92
93 struct Configuration {
94 // If the pacer queue grows longer than the configured max queue limit,
95 // pacer sends at the minimum rate needed to keep the max queue limit and
96 // ignore the current bandwidth estimate.
97 bool drain_large_queues = true;
98 // Expected max pacer delay. If ExpectedQueueTime() is higher than
99 // this value, the packet producers should wait (eg drop frames rather than
100 // encoding them). Bitrate sent may temporarily exceed target set by
101 // SetPacingRates() so that this limit will be upheld if
102 // `drain_large_queues` is set.
103 TimeDelta queue_time_limit = kMaxExpectedQueueLength;
104 // Audio retransmission is prioritized before video retransmission packets.
105 bool prioritize_audio_retransmission = false;
106 // Configure separate timeouts per priority. After a timeout, a packet of
107 // that sort will not be paced and instead dropped.
108 // Note: to set TTL on audio retransmission,
109 // `prioritize_audio_retransmission` must be true.
110 PacketQueueTTL packet_queue_ttl;
111 // The pacer is allowed to send enqueued packets in bursts and can build up
112 // a packet "debt" that correspond to approximately the send rate during the
113 // burst interval.
114 TimeDelta send_burst_interval = PacerConfig::kDefaultTimeInterval;
115 std::optional<PacerConfig> initial_pacer_config;
116 };
117
118 static Configuration DefaultConfiguration() { return Configuration{}; }
119
120 PacingController(Clock* clock,
121 PacketSender* packet_sender,
122 const FieldTrialsView& field_trials,
123 Configuration configuration = DefaultConfiguration());
124
125 ~PacingController();
126
127 // Adds the packet to the queue and calls PacketRouter::SendPacket() when
128 // it's time to send.
129 void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
130
131 void CreateProbeClusters(
132 std::span<const ProbeClusterConfig> probe_cluster_configs);
133
134 void Pause(); // Temporarily pause all sending.
135 void Resume(); // Resume sending packets.
136 bool IsPaused() const;
137
138 void SetCongested(bool congested);
139
140 // Sets the pacing rates. Must be called once before packets can be sent.
141 [[deprecated("Use SetPacerConfig")]]
142 void SetPacingRates(DataRate pacing_rate, DataRate padding_rate);
143 void SetPacerConfig(PacerConfig pacer_config);
144
145 DataRate pacing_rate() const { return adjusted_media_rate_; }
146
147 // Currently audio traffic is not accounted by pacer and passed through.
148 // With the introduction of audio BWE audio traffic will be accounted for
149 // the pacer budget calculation. The audio traffic still will be injected
150 // at high priority.
151 void SetAccountForAudioPackets(bool account_for_audio);
152 void SetIncludeOverhead();
153
154 void SetTransportOverhead(DataSize overhead_per_packet);
155 // The pacer is allowed to send enqued packets in bursts and can build up a
156 // packet "debt" that correspond to approximately the send rate during
157 // 'burst_interval'.
158 [[deprecated("Use SetPacerConfig")]]
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
242 const bool drain_large_queues_;
243 const bool send_padding_if_silent_;
244 const bool pace_audio_;
245 const bool ignore_transport_overhead_;
246 const bool fast_retransmissions_;
247 DataSize transport_overhead_per_packet_;
248 TimeDelta send_burst_interval_;
249
250 // TODO(webrtc:9716): Remove this when we are certain clocks are monotonic.
251 // The last millisecond timestamp returned by `clock_`.
252 mutable Timestamp last_timestamp_;
253 bool paused_;
254
255 // Amount of outstanding data for media and padding.
256 DataSize media_debt_;
257 DataSize padding_debt_;
258
259 // The target pacing rate, signaled via SetPacingRates().
260 DataRate pacing_rate_;
261 // The media send rate, which might adjusted from pacing_rate_, e.g. if the
262 // pacing queue is growing too long.
263 DataRate adjusted_media_rate_;
264 // The padding target rate. We aim to fill up to this rate with padding what
265 // is not already used by media.
266 DataRate padding_rate_;
267
268 BitrateProber prober_;
269 bool probing_send_failure_;
270
271 Timestamp last_process_time_;
272 Timestamp last_send_time_;
273 std::optional<Timestamp> first_sent_packet_time_;
274 bool seen_first_packet_;
275
276 PrioritizedPacketQueue packet_queue_;
277
278 bool congested_;
279
280 TimeDelta queue_time_limit_;
281 bool account_for_audio_;
282 bool include_overhead_;
283
284 int circuit_breaker_threshold_;
285};
286} // namespace webrtc
287
288#endif // MODULES_PACING_PACING_CONTROLLER_H_