From caad1565b84e14c6bab833377d2e107096d66af6 Mon Sep 17 00:00:00 2001 From: mikael-lovqvists-claude-agent Date: Wed, 25 Mar 2026 22:53:34 +0000 Subject: [PATCH] Clarify ingest scanner scope: opaque pipe vs well-formed V4L2 vs weird sources V4L2 with proper node: driver guarantees per-buffer framing, no scan needed. Opaque pipe (dd|nc): buffer boundaries lost, EOI scanner is the correct tool. Weird containers (RIFF-wrapped USB cams, IP cameras, RTSP): route via ffmpeg, not a custom parser. Scanner is an option only for constrained raw-stream cases. Co-Authored-By: Claude Sonnet 4.6 --- architecture.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/architecture.md b/architecture.md index d0fa96f..52f2aa7 100644 --- a/architecture.md +++ b/architecture.md @@ -90,6 +90,25 @@ The Pi runs only: Everything else happens on machines with adequate resources. +### Frame Boundaries and the Ingest Scanner + +When the V4L2 driver is well-behaved and delivers `V4L2_PIX_FMT_MJPEG`, each dequeued buffer contains exactly one complete MJPEG frame — the driver guarantees this boundary. If the Pi runs a proper node process that dequeues buffers and sends each one as an encapsulated frame, boundaries are preserved across the wire and no scanning is needed at the ingest end. + +When the Pi uses a raw pipe (`dd | nc`), the buffer boundaries are discarded at the source. What arrives at the ingest node is a concatenated MJPEG byte stream with no framing. The ingest module's two-pass EOI state machine exists specifically for this case: it scans the incoming bytes for JPEG SOI (`0xFF 0xD8`) and EOI (`0xFF 0xD9`) markers to recover frame boundaries from the raw stream and re-emit discrete frames into the encapsulated transport. + +This is the **primary and planned** ingest path for the Pi forwarding scenario. It is not a hack — it is the correct tool when the source is an opaque byte stream carrying concatenated MJPEG. + +### Fallback: Non-Standard and Containerised Sources + +Some sources produce MJPEG in unexpected ways: +- Cheap USB webcams with firmware that wraps frames in an AVI or RIFF container even on the V4L2 interface +- IP/network cameras streaming via HTTP multipart MIME (`multipart/x-mixed-replace`) or RTSP with unusual packetisation +- Any source where the JPEG payload is embedded inside another container format + +For these cases the preferred fallback is to route through **ffmpeg**, which handles essentially any container format and emits clean decoded frames or re-muxed output. A custom parser for every quirky format is not a worthwhile investment. + +The EOI scanner in the ingest module is kept as a secondary option for sources that are known to produce a raw concatenated MJPEG byte stream but where spawning ffmpeg is undesirable (resource constraints, startup latency, etc.). It is not the general solution for malformed or unusual sources. + --- ## Transport Protocol