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)
This commit is contained in:
YuLi
2026-07-10 17:19:43 -07:00
committed by GitHub
parent a485d89063
commit 1b4f3ef9a1

View File

@@ -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;
}