diff options
| author | Luke Hoersten <[email protected]> | 2026-06-15 08:49:34 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-15 08:49:34 -0500 |
| commit | fd3faa934999ee3953d66d9db84f67b699e81548 (patch) | |
| tree | f507d639dc54fa124c145159a47b41d01909b3d1 | |
| parent | 2429179eaf1a62af770fe6de3b25b276db3ce401 (diff) | |
scrypted: rotate-before-scale so portrait JPEGs report 800x480
The portrait filter chain was scale=480:800,transpose=1. Output frame
dimensions came out 800x480 (correct) but the mjpeg encoder was
occasionally writing the pre-transpose 480x800 into the JPEG SOF
marker, so the firmware's dimension check rejected the frame:
expected 800x480, got 480x800
Reordering to transpose=1,scale=800:480,setsar=1 makes the post-filter
dims explicit and unambiguous — transpose first changes the frame to
800x480, scale re-asserts it, setsar clears any leftover non-1:1
aspect ratio metadata. The encoder now writes 800x480 into SOF every
frame.
| -rw-r--r-- | scrypted/scrypted-viewport.ts | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/scrypted/scrypted-viewport.ts b/scrypted/scrypted-viewport.ts index 7b69a75..22f233a 100644 --- a/scrypted/scrypted-viewport.ts +++ b/scrypted/scrypted-viewport.ts @@ -614,9 +614,17 @@ class ScryptedViewportProvider extends ScryptedDeviceBase // panel is already in the right rotation. The firmware never // touches pixels — the hardware JPEG decoder writes BGR888 // straight into a DMA buffer that gets handed to the DSI engine. + // Filter order matters here. Earlier we did + // scale=480:800,transpose=1 + // which intermittently produced a JPEG with a SOF marker + // reporting 480x800 — the firmware then rejected it with + // "expected 800x480, got 480x800". Rotating *first* and then + // scaling to an EXPLICIT panelWxpanelH (with setsar to clear + // any leftover aspect-ratio metadata) makes the final encoded + // dimensions deterministic regardless of source resolution. const vf = v.orientation === "portrait" - ? `scale=${panelH}:${panelW}:flags=lanczos,transpose=1` // 90° CW → panelW x panelH - : `scale=${panelW}:${panelH}:flags=lanczos`; + ? `transpose=1,scale=${panelW}:${panelH}:flags=lanczos,setsar=1` + : `scale=${panelW}:${panelH}:flags=lanczos,setsar=1`; const fps = Math.max(1, Math.round(1000 / v.frameIntervalMs)); // Pull the camera's video stream, convert to ffmpeg input args, and |
