fix(useWebcamFrames): JPEG quality 0.35 → 0.28 — intermittent decode fails

User reported "JPG Decompression Failed! Data format error" hitting
intermittently with quality 0.35. Worker log showed actual JPEG
payloads at 7959-8123 bytes per frame — right at the QEMU emulator's
8192-byte deliverable budget (8 EOFs × 1024 bytes from cam_hal's
default 16-descriptor ring).

The webcam JPEG encoder produces variable-size output: simple uniform
scenes compress to ~6 KiB, complex/textured/moving frames bloat to
~9-10 KiB. Anything over 8192 gets truncated mid-Huffman-scan in the
firmware framebuffer, my walker injects FF D9 at byte 8190 to keep
cam_verify_jpeg_eoi happy, but the upstream jpg2rgb565 actually
parses the structure and chokes on the truncated stream.

Quality 0.28 keeps even the worst-case complex frame comfortably
under 8 KiB. Visual quality is still much better than the 0.25
fallback — fine for a 160×120 preview where the user cares about
"is my face there" not "did the JPEG quantization tables converge".

Real long-term fix would be to bump EOFS_PER_FRAME and lift the 8 KiB
ceiling — but that touches the QEMU walker (DLL rebuild cycle) and
risks breaking the descriptor-ring math. Doing this frontend tweak
first to unblock the demo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Montero Crespo 2026-05-03 00:32:46 -03:00
parent 977308ef80
commit 2c08e84fc6
1 changed files with 6 additions and 5 deletions

View File

@ -46,11 +46,12 @@ const FRAME_HEIGHT = 240;
const FRAME_INTERVAL_MS = 100; // 10 fps
// JPEG must fit in the QEMU emulator's 8 KiB-per-frame deliverable
// budget (8 EOFs × 1024 bytes from the cam_hal default 16-descriptor
// ring) — beyond that the firmware sees a truncated JPEG and
// jpg2rgb565() rejects it with "Data format error". 0.35 produces
// ~6-7 KiB JPEGs at QVGA which fit comfortably, with clearly more
// detail than the 0.25 fallback we used pre-batching.
const JPEG_QUALITY = 0.35;
// ring). Anything bigger gets truncated and jpg2rgb565() rejects it
// with "Data format error" — observed intermittently at 0.35 because
// complex scenes encode larger than the average. 0.28 keeps the worst
// case well under 8 KiB while staying noticeably sharper than the
// 0.25 fallback we used before SPI batching landed.
const JPEG_QUALITY = 0.28;
export function useWebcamFrames(): UseWebcamFramesResult {
const [status, setStatus] = useState<WebcamStatus>('idle');