fix(useWebcamFrames): drop JPEG quality 0.6 → 0.25 for emulator preview

The ESP32-CAM + ILI9341 example was rendering grey-X "decode failed"
rectangles. Serial showed:

    E (53868) esp_jpg_decode: JPG Decompression Failed!
                              Data format error

Root cause: the QEMU emulation delivers up to 8 KiB of JPEG bytes per
frame (8 EOFs × 1024 = 8192) plus a 2-byte FF D9 EOI injection at the
end of that window. Real webcam frames at quality 0.6 are ~11 KiB —
they get truncated mid-Huffman-scan in the firmware framebuffer.
cam_verify_jpeg_eoi accepts the frame (it found FF D9), but the
upstream jpg2rgb565() actually parses the JPEG and rejects the
truncated structure.

Quality 0.25 produces ~3-5 KiB JPEGs that fit the budget entirely.
The decoder finds the natural EOI well before our injection point,
parses cleanly, and renders to the TFT. Visual quality is fine for
an emulator preview — the user is seeing their webcam, not editing
print-quality photos.

Long-term fix is a smarter QEMU walker that ring-wraps to deliver
bigger JPEGs (>16 KiB possible by reusing descriptors mid-frame),
but that's a separate change in qemu-lcgamboa. This frontend tweak
unblocks the demo without another DLL rebuild cycle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Montero Crespo 2026-05-03 00:08:17 -03:00
parent 6d56fe9a90
commit c4c446cf39
1 changed files with 16 additions and 1 deletions

View File

@ -44,7 +44,22 @@ export interface UseWebcamFramesResult {
const FRAME_WIDTH = 320;
const FRAME_HEIGHT = 240;
const FRAME_INTERVAL_MS = 100; // 10 fps
const JPEG_QUALITY = 0.6;
// Keep JPEGs comfortably under the QEMU emulator's 8 KiB-per-frame
// deliverable budget (8 EOFs × 1024 bytes from the cam_hal default
// 16-descriptor ring). Quality 0.6 produces ~10-12 KiB which gets
// truncated mid-stream in the firmware framebuffer — cam_verify_jpeg_eoi
// accepts the frame because we inject FF D9 at byte 8190, but
// jpg2rgb565() (the upstream decoder) rejects the truncated JPEG with
// "JPG Decompression Failed! Data format error".
//
// Quality 0.25 produces ~3-5 KiB JPEGs that fit the budget entirely
// AND decode cleanly because the natural EOI marker lands well before
// our injection point. Visual quality is roughly equivalent to a
// VGA-era webcam capture — totally serviceable for an emulator preview.
//
// See test/test-esp32-cam/autosearch/14_complete_emulation.md "Bug #9"
// for the full forensic trace of the truncation issue.
const JPEG_QUALITY = 0.25;
export function useWebcamFrames(): UseWebcamFramesResult {
const [status, setStatus] = useState<WebcamStatus>('idle');