diff --git a/doc/streamCompression.md b/doc/streamCompression.md
new file mode 100644
index 0000000..54c34ad
--- /dev/null
+++ b/doc/streamCompression.md
@@ -0,0 +1,248 @@
+# Stream-Komprimierung (MJPEG → H.264) — Abarbeitungsliste
+
+> **Status (2026-06-16):** Der H.264-Pfad ist **im Code vollständig vorhanden und
+> unit-getestet**, aber **noch nie auf dem Host scharf geschaltet oder gemessen**.
+> Diese Datei ist die ausführbare ToDo-Liste, um ihn in Betrieb zu nehmen — destilliert
+> aus [14_ReRender_roadmap.md](14_ReRender_roadmap.md) (Hintergrund/Entwurf),
+> [02_HardwareEncoding.md](02_HardwareEncoding.md), [03_Protocoll_roadmap.md](03_Protocoll_roadmap.md)
+> und [04_Delay_roadmap.md](04_Delay_roadmap.md).
+>
+> **Es ist also kein „von Null bauen".** Die offene Arbeit ist: *scharf schalten → messen →
+> tunen → ausrollen* — und zwar **auf dem Host gemessen, nicht vorhergesagt**
+> (Memory-Regel; alle Zahlen unten ohne Messung sind ausdrücklich **Hypothesen**).
+
+---
+
+## Ausgangslage in einem Satz
+
+Der Live-Stream geht heute als **MJPEG** raus (jedes Frame ein vollständiges JPEG). Das ist
+zwar pro Frame komprimiert, aber ohne Inter-Frame-Kompression → hohe Bitrate, und der Client
+muss jedes Frame einzeln dekodieren und in ein `
` schieben. Bei mehreren Kameras bringt
+das schwache Laptops an die Grenze. Mehr Kameras kommen → das Problem wächst.
+
+## Warum H.264 dem Laptop hilft (Motivation + eine Korrektur)
+
+„Unkomprimiert" trifft es nicht ganz — MJPEG **ist** komprimiert, nur eben **intra-frame**.
+Der Gewinn von H.264 ist trotzdem real und doppelt:
+
+1. **Inter-Frame-Kompression** (nur Bildänderungen übertragen) → deutlich weniger Bitrate
+ (Hypothese: ~2–5 MBit/s statt MJPEG-Bitrate; vor dem Umbau messen, siehe ToDo 0).
+2. **Hardware-Decode im Browser** — H.264 dekodiert der Client in der GPU; MJPEG dekodiert
+ er pro Frame auf der CPU/im Main-Thread und tauscht das `
`. Genau **das** ist die
+ Last, die mehrere Streams auf dem Laptop erzeugen. → H.264 entlastet primär den Client.
+
+> ⚠️ **Realität prüfen, nicht annehmen:** Alle Kameras laufen aktuell auf `liveSize`
+> **320×240** ([../cameras.json](../cameras.json)). `1920x1080` dort ist die `hiresSize`
+> (Einzelbild beim HD-Knopf), **kein** Dauerstream. Bei 320×240 ist die MJPEG-Bitrate schon
+> klein → der Bandbreiten-Gewinn könnte gering sein, der **Client-Decode-Gewinn** aber
+> trotzdem zählen. Das entscheidet ToDo 0.
+
+---
+
+## Was bereits im Code steckt (Datei-Pointer)
+
+| Baustein | Datei | Zustand |
+|---|---|---|
+| Encoder-Wahl (VAAPI/QSV/libx264) + MSE-Codec-String + FFmpeg-Args | [../src/hwencode.js](../src/hwencode.js) | ✅ + Unit-Test [../test/hwencode.test.js](../test/hwencode.test.js) |
+| fMP4-Box-Parser (Init-Segment + Fragmente) | [../src/fmp4Parser.js](../src/fmp4Parser.js) | ✅ + Unit-Test [../test/fmp4Parser.test.js](../test/fmp4Parser.test.js) |
+| `encode='h264'`-Zweig: Init-Cache, Fan-out, MJPEG-Nebenausgang (fd 3) für Snapshots | [../src/cameraSwitch.js](../src/cameraSwitch.js) | ✅ |
+| `video/mp4`-Route (Init-first Fan-out), `encode`/`mseCodec` in `/api/snapshot`+`/api/cameras` | [../src/snapshotService.js](../src/snapshotService.js) | ✅ |
+| MSE-`