mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
_capture_mjpeg_frame returned the very first JPEG it found in the
bytes stream, but many MJPEG sources — go2rtc most notably, and
several IP cameras — emit a warm-up frame on the byte that follows
connection accept: usually the last keyframe held in the encoder,
typically black or stale until the encoder catches up to live
content. Subsequent frames on the same connection are fine.
Result: every code path that opened a fresh capture (snapshot UX,
finish photos in notifications, timelapse, plate-detection CV,
Obico ML inference, Settings → Test button) returned a black image
on go2rtc-fronted cameras.
Reporter's support log showed every black frame was 11095 bytes
(pure-black 1280x720 JPEG ≈ 10-15 KB) while real-content frames
from the same source were 30-45 KB.
Fix:
- Read past the first complete JPEG, return the second.
- Fall back to the first frame if the connection closes / times out /
hits the 5 MB buffer cap before a second arrives. Without that
fallback, slow / single-frame streams that pre-fix returned the
warm-up would post-fix return None — a regression. The fallback
guarantees we never do worse than current behaviour.
- Inner while-loop now drains every complete frame already in the
buffer before pulling the next chunk so high-FPS sources that
pack multiple frames per chunk are handled correctly.
Untouched: snapshot / rtsp / usb capture paths, generate_mjpeg_stream
(live-view fan-out).
7 new regression tests in TestCaptureMjpegFrameWarmupSkip cover
two-frames-in-two-chunks, two-frames-in-one-chunk, partial-frame-
split-across-chunks, single-frame fallback, timeout fallback, zero-
frame stream returns None, non-200 returns None.
Latency penalty: at most one frame interval (typically 50 ms - 1 s
on a steady stream), well within every caller's tolerance window.