# Development Phases This file breaks the project into incremental milestones. Each phase produces a working, testable slice of functionality. Do not start a phase until the previous one is validated. ## Phase 1 — Project Skeleton **Goal**: configure, compile, and run tests with no real dependencies. - [x] Meson build files (`meson.build`, `meson_options.txt`). - [x] Public module headers with `namespace sc`. - [x] Unit test that exercises a trivial utility function. - [x] `README.md` with build instructions. **Validation**: `meson setup build && meson compile -C build && meson test -C build`. ## Phase 2 — Software H.264 Encode / Decode **Goal**: encode raw pixel buffers to H.264 and decode them back, purely with FFmpeg software paths. - [x] Add `libavcodec`, `libavutil`, `libswscale` dependencies. - [x] Implement `EncoderFactory::create()` and `Encoder::encode()`. - [x] Implement `DecoderFactory::create()` and `Decoder::decode()`. - [x] Round-trip test: synthetic RGB frames → H.264 → decoded RGB. **Validation**: unit test produces visually/structurally correct round-trip frames. ## Phase 3 — PipeWire Screen Capture **Goal**: capture the desktop and feed frames into the encoder. - [x] Add `libpipewire-0.3` dependency. - [x] Implement `CaptureFactory::create()` using the xdg-desktop-portal. - [x] Wire `CaptureSession::next_frame()` → `Encoder::encode()` in a local smoke test that just writes a few encoded frames to disk. **Validation**: manual run on a real Linux desktop session produces a valid H.264 bitstream. ## Phase 4 — RTP Framing **Goal**: packetize NAL units into RTP and depacketize them. - [x] Implement `RtpHeader` and `RtpPacket` serialize/parse. - [x] Add H.264 NAL splitting and FU-A fragmentation. - [x] Unit test for serialization, fragmentation, and reassembly. **Validation**: unit tests cover single-NAL and fragmented packet paths. ## Phase 5 — Local UDP Sender → Receiver Loopback **Goal**: send RTP packets over UDP and render the result locally. - [x] Implement `RtpTransport` with ASIO or raw UDP sockets. - [x] Wire sender pipeline: capture → encode → RTP → localhost UDP. - [x] Wire receiver pipeline: localhost UDP → RTP → decode → renderer. - [x] Add SDL2/SDL3 dependency and a minimal `Renderer`. **Validation**: `screencast --send` and `screencast --receive` on the same machine show the captured desktop in a window. ## Phase 6 — LAN Signaling and Discovery **Goal**: two peers on the same LAN can find each other and negotiate a session. - [x] Implement mDNS/DNS-SD discovery with Avahi. - [x] Implement JSON signaling (newline-delimited JSON over TCP for now; the WebSocket transport is deferred to Phase 7 with its dependency). - [x] Extend CLI with `--peer` and `--discover`. **Validation**: two peers connect without hard-coded IP addresses. Validated over loopback AND on real two-machine hardware: a Raspberry Pi Zero 2 W (Wi-Fi, headless KMSDRM, systemd autostart) was discovered, negotiated with, and streamed to from the desktop; the receiver rendered a synthetic feed fullscreen on its display. On that network the LAN's 6to4 addresses are unreachable between peers, so senders try all discovered addresses in reachability order (private IPv4 first). ## Phase 7 — Resilience and Polish **Goal**: loss recovery, hardware acceleration, and polish. - [x] PLI keyframe feedback over signaling (receiver asks, sender re-encodes a keyframe; validated end-to-end with an induced loss). - [x] Jitter/reorder window on the receiver (16 packets / 60 ms). - [x] Hardware H.264 decode probe with software fallback (h264_v4l2m2m — the Pi's VideoCore path; --swdecode opts out). - [x] GTK4 sender GUI behind `meson -Dgui=true` (gtkmm; receiver list, bitrate, start/stop) plus a waybar widget (`screencast waybar`, click-to-toggle, right-click opens the panel; state shared via $XDG_RUNTIME_DIR/screencast/sender.json). - [ ] VAAPI hardware encode probe on the sender (deferred: software encode is not the bottleneck). - Deferred: .desktop file, packaging. **Validation**: sustained streaming under packet loss; hardware accel smoke where available. PLI + jitter validated on the desktop (induced-loss probe); hardware decode validated as clean-fallback on the desktop, hardware path pending a run on the Pi. ## Current phase Phase 7 — Resilience and Polish.