From bba40948edccd4ac6c4a661c8f16c6469b212985 Mon Sep 17 00:00:00 2001 From: Luke Hoersten Date: Mon, 15 Jun 2026 09:18:57 -0500 Subject: scrypted: distinguish backpressure vs source-limited stream rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The single warning conflated two unrelated symptoms: - HTTP/POST backpressure (drops accumulating because the firmware or network can't keep up) — fix is to raise frame_interval_ms. - Source-limited rate (ffmpeg's fps filter or the camera substream produces fewer frames than requested) — raising the interval makes this worse, not better. Now: drops > 25% of target prints "backpressure" advice; otherwise delivered < 60% of target prints "source-limited" with the correct hint that the camera/filter is the limit, not the firmware. The 600ms-interval case where we get 1.5 fps delivered with zero drops no longer prints the (wrong) "raise interval" suggestion. --- scrypted/scrypted-viewport.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'scrypted') diff --git a/scrypted/scrypted-viewport.ts b/scrypted/scrypted-viewport.ts index 2e46ab3..66f89dc 100644 --- a/scrypted/scrypted-viewport.ts +++ b/scrypted/scrypted-viewport.ts @@ -797,9 +797,18 @@ class ScryptedViewportProvider extends ScryptedDeviceBase if (window > 0 && (sentFrames > 0 || droppedFrames > 0)) { const sentRate = sentFrames / window; const targetRate = 1000 / v.frameIntervalMs; - if (sentRate < targetRate * 0.75) { - const dropRate = droppedFrames / window; - this.console.log(`"${v.name}": delivered ~${sentRate.toFixed(1)} fps vs target ${targetRate.toFixed(1)} fps over the last ${window.toFixed(1)}s (dropped ~${dropRate.toFixed(1)} fps — in-flight HTTP POST hadn't returned when ffmpeg emitted the next frame; raise frame_interval_ms slightly to flatten this)`); + const dropRate = droppedFrames / window; + // Two distinct symptoms to call out: + // - drops > 25% of target → backpressure: HTTP POST or + // panel is the bottleneck, advice is to raise interval. + // - delivered < 60% AND drops are negligible → ffmpeg's + // fps filter / camera substream simply isn't producing + // the requested rate. Raising interval won't help; + // surface a different message. + if (dropRate > targetRate * 0.25) { + this.console.log(`"${v.name}": backpressure — delivered ~${sentRate.toFixed(1)} fps vs target ${targetRate.toFixed(1)} fps, dropped ~${dropRate.toFixed(1)} fps over ${window.toFixed(1)}s (POST stack can't keep up; raise frame_interval_ms slightly to flatten this)`); + } else if (sentRate < targetRate * 0.6 && sentRate > 0) { + this.console.log(`"${v.name}": source-limited — delivered ~${sentRate.toFixed(1)} fps vs target ${targetRate.toFixed(1)} fps over ${window.toFixed(1)}s (camera substream / ffmpeg fps filter producing below requested rate; raising frame_interval_ms won't help)`); } droppedFrames = 0; sentFrames = 0; -- cgit v1.2.3