diff options
| author | Luke Hoersten <[email protected]> | 2026-06-20 12:11:54 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-20 12:11:54 -0500 |
| commit | 439dadb24c4e07eb11f1aa9804cf7a973518e539 (patch) | |
| tree | 000492fb7928d1ae0c7e42769080f8c5043fd9f6 | |
| parent | a7fbd013f2bfabcb7a18a7878a959c24ed838110 (diff) | |
scrypted: log node_buf in stream window — confirms script-side buffering
Adds two values to the unified stream log line:
node_buf=NKB≈Mms
node_buf bytes is sock.writableLength — bytes that socket.write()
accepted from us but the kernel send buffer hasn't pulled yet, so
they sit in Node's internal queue. These have NOT been sent over the
wire; the firmware can't have them.
Dividing by the current send rate (bytes/sec computed from the same
window's bytesSent) gives the buffer depth in milliseconds: how many
seconds of already-extracted-from-ffmpeg frames are stalled at the
script. When g2g shows 7s steady state and node_buf shows e.g.
5000-6000KB ≈ 6500ms, the conclusion is obvious — the buffering
isn't in the firmware or on the wire, it's in Scrypted's Node
process.
No behavior change; pure diagnostic.
| -rw-r--r-- | scrypted/scrypted-viewport.ts | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/scrypted/scrypted-viewport.ts b/scrypted/scrypted-viewport.ts index 747d3c0..7cf5faa 100644 --- a/scrypted/scrypted-viewport.ts +++ b/scrypted/scrypted-viewport.ts @@ -6,7 +6,7 @@ // short git hash of the commit that added this constant — if the // hash in the log doesn't match the HEAD this file came from, the // Scrypted Script editor is still on stale code. -const SCRIPT_VERSION = "28f39bf"; +const SCRIPT_VERSION = "pending"; // // Architecture // ------------ @@ -1022,11 +1022,24 @@ class ScryptedViewportProvider extends ScryptedDeviceBase } catch { /* keep the local stats; firmware-side just shows ? */ } const skipped = paintedNum >= 0 ? Math.max(0, sentRate - paintedNum).toFixed(1) : "?"; + // node_buf = bytes Scrypted has handed to socket.write but + // the kernel send buffer hasn't accepted yet — they sit in + // Node's internal queue, NOT on the wire. Divide by the + // current send rate to estimate how many seconds of + // already-emitted frames are waiting at the source. This + // is the load-bearing piece of the g2g "buffer depth" + // story: when this is large, the firmware can't possibly + // be showing the freshest bytes because we haven't even + // sent them yet. + const nodeBufBytes = sock?.writableLength ?? 0; + const sentBps = mbPerSec * 1024 * 1024; + const nodeBufMs = sentBps > 0 ? (nodeBufBytes / sentBps * 1000).toFixed(0) : "?"; this.console.log( `stream "${v.name}": sent=${sentRate.toFixed(1)}fps painted=${painted}fps ` + `(fw-skipped=${skipped}fps, drops=${droppedFrames}) ` + `${mbPerSec.toFixed(2)}MB/s sent / ${paintedMb}MB/s painted | ` + - `socket.write p50=${p50}ms p95=${p95}ms max=${max}ms backpressured=${socketBackpressured} | ` + + `socket.write p50=${p50}ms p95=${p95}ms max=${max}ms backpressured=${socketBackpressured} ` + + `node_buf=${(nodeBufBytes / 1024).toFixed(0)}KB≈${nodeBufMs}ms | ` + `recv=${recvStr}us dec=${decStr}us paint=${paintStr}us idle=${idleStr}us | g2g=${g2g}`); droppedFrames = 0; |
