From 1b4f3ef9a130a8f16952809af8e49ba3003bba00 Mon Sep 17 00:00:00 2001 From: YuLi Date: Fri, 10 Jul 2026 17:19:43 -0700 Subject: [PATCH] Bound paced sender cache by frame count (#4776) ### Motivation - Prevent unbounded memory growth in `FramePacedSender` when many frames share identical or tightly clustered DTS values by restoring an insertion-time frame-count guard independent of DTS-span-based pressure. ### Description - Add a `kMaxCacheSize` constant and force a cache `flushCache(...)` when `_cache.size()` exceeds `kMaxCacheSize`, keeping paced-sender buffering bounded even if `buf_ms` remains small; the guard is applied immediately after `_cache.emplace(...)` in `FramePacedSender::inputFrame`. ### Testing - Performed static discovery of call sites and symbols with `rg`/`sed` to verify the paced sender is created when `_option.paced_sender_ms` is nonzero and that frames are routed to `_paced_sender->inputFrame(...)`; this succeeded. - Attempted to configure and build with `cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j2` and `cmake --build build -j2`, both failed during configuration or build due to missing third-party artifacts (`3rdpart/ZLToolKit/CMakeLists.txt`) or no existing `build` directory in the checkout, so no binary tests were executed. ------ [Codex Task](https://chatgpt.com/codex/cloud/tasks/task_e_6a512c4481a883209d56b8e7109a91ba) --- src/Common/MultiMediaSourceMuxer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index 48e4b5f0..68ff1a0a 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -44,6 +44,8 @@ public: // Speed bounds static constexpr float kMinSpeed = 0.5f; static constexpr float kMaxSpeed = 1.5f; + // Keep the cache bounded even when publisher timestamps are identical or tightly clustered. + static constexpr size_t kMaxCacheSize = 25 * 5; FramePacedSender(uint32_t paced_sender_ms, OnFrame cb) : _paced_sender_ms(paced_sender_ms), _cb(std::move(cb)) {} @@ -74,6 +76,10 @@ public: } _cache.emplace(frame->dts(), Frame::getCacheAbleFrame(frame)); last_dts = frame->dts(); + if (_cache.size() > kMaxCacheSize) { + WarnL << "Force flush paced sender cache: size=" << _cache.size(); + flushCache(frame->dts()); + } return true; }