src.nth.io/

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Hoersten <[email protected]>2026-07-17 20:27:50 -0500
committerLuke Hoersten <[email protected]>2026-07-17 20:27:50 -0500
commit8eebc0ea5b6001be6735cf679fb3b94757d0de02 (patch)
tree64356f69baaade8d23c64e22160f3a23e2c3a3bf
parent482d8f45f18c6cc880bf2dfbbb70e3a4d704ac44 (diff)
docs: mark M9 verified — live stream shipped as raw TCP :81, not POST /stream
M9 still carried the abandoned chunked-HTTP design and a pending status long after the raw TCP data-socket stream was verified at painted = sent = 24 fps (recv/decode task split d1c8d45 + TCP window/EMAC tuning). Rewrite the milestone to describe what shipped, flip it ✅, and bump the README's "M1 – M8" line to M9.
-rw-r--r--README.md2
-rw-r--r--TESTING.md12
2 files changed, 8 insertions, 6 deletions
diff --git a/README.md b/README.md
index afd5b92..d7a53d3 100644
--- a/README.md
+++ b/README.md
@@ -589,7 +589,7 @@ Every endpoint is idempotent; every failure leaves the device in a sane state.
## What's next
-M1 – M8 are all ✅ on hardware (see [`TESTING.md`](TESTING.md) for verification details). End-to-end Scrypted streaming via ffmpeg + the zero-copy `JPEG → BGR888 → DSI` hot path now sustains **painted = sent = 24 fps** at the Unifi medium substream rate, sub-50 ms glass-to-glass, no source-side backpressure.
+M1 – M9 are all ✅ on hardware (see [`TESTING.md`](TESTING.md) for verification details). End-to-end Scrypted streaming via ffmpeg + the zero-copy `JPEG → BGR888 → DSI` hot path now sustains **painted = sent = 24 fps** at the Unifi medium substream rate, sub-50 ms glass-to-glass, no source-side backpressure.
### Measured per-frame budget
diff --git a/TESTING.md b/TESTING.md
index 4b1a0a2..5046ad3 100644
--- a/TESTING.md
+++ b/TESTING.md
@@ -34,7 +34,7 @@ Status legend:
| M6 | State + Idle Timer (`POST /state`, 409 guard) | ✅ | ✅ |
| M7 | Touch + Outbound `/state` POST | ✅ | ✅ |
| M8 | Local Screens + touch long-press | ✅ | ✅ |
-| M9 | Live Stream (`POST /stream`) | ⬜ | ⬜ |
+| M9 | Live Stream (raw TCP data socket `:81`) | ✅ | ✅ |
---
@@ -590,13 +590,15 @@ Tap rapidly (faster than the receiver can ack) and confirm the receiver only see
---
-## M9 — Live Stream (`POST /stream`)
+## M9 — Live Stream (raw TCP data socket `:81`)
-**Acceptance**: ≥ 10 fps multipart MJPEG over a single chunked POST.
+**Acceptance** (as designed: ≥ 10 fps): sustained live video from a real camera through Scrypted to the panel.
-**How to verify**: ffmpeg-driven test stream from a host, measure fps from the device's frame counter.
+**What shipped** (the design changed from the original `POST /stream` chunked-HTTP idea): a long-lived raw TCP connection to port 81 carrying length-prefixed JPEGs (16-byte `VPRT` v1 header — magic, length, seq, event-timestamp), received by a dedicated recv-task and handed to a decode/paint task through a 3-buffer PSRAM ring with drop-oldest semantics. See the README's *Measured per-frame budget* and *TCP window + EMAC tuning* sections for the architecture and numbers.
-**Status**: ⬜ pending.
+**How to verify**: trigger a camera event (or tap the panel) with the Scrypted script installed; watch the script's 10 s stream-health log and `curl http://<ip>/state | jq .stream` for the firmware's 30-frame windows.
+
+**Status**: ✅ verified on hardware (stream server `d1c8d45` recv/decode task split; TCP window + EMAC RX pool tuning follow-up). Steady state at the Unifi medium substream: **painted = sent = 24 fps**, wire 74 Mbps avg, glass-to-glass ~40–100 ms, no drops/flushes, `decode_errors=0` across thousands of frames. Re-confirmed 2026-07-18 during the v1.4.0 verification (24 fps painted, g2g ~100 ms on the first windows of a cold start).
---