Files
screen_cast/docs/PHASES.md
T
fegger b5e8d7174c feat(network): implement Phase 4 RTP framing with FU-A fragmentation
Add the sc_network library: RFC 3550 RtpHeader/RtpPacket serialize and
parse (the receiver tolerates CSRC lists, extension headers, and
padding by skipping/stripping them) and RFC 6184 H.264 payloading via
H264Packetizer/H264Depacketizer.

The packetizer splits Annex-B frames into NAL units (3- and 4-byte
start codes), emitting single-NAL packets or FU-A fragments within the
configured MTU, with the marker bit closing each frame and randomized
SSRC/sequence by default. The depacketizer reassembles access units
with 3-byte start codes, so both start-code widths round-trip
byte-exactly; frames damaged by sequence gaps or missing fragments
are dropped until the Phase 7 loss-recovery work.

test_rtp covers header and packet round-trips, malformed-input
rejections, splitter behavior, FU-A chunk bounds, full packetize ->
depacketize round-trip, gap dropping, marker-only frame separation,
sequence wrap, and empty inputs. meson test 3/3, valgrind clean.
2026-09-07 10:48:17 +02:00

3.2 KiB

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.

  • Meson build files (meson.build, meson_options.txt).
  • Public module headers with namespace sc.
  • Unit test that exercises a trivial utility function.
  • 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.

  • Add libavcodec, libavutil, libswscale dependencies.
  • Implement EncoderFactory::create() and Encoder::encode().
  • Implement DecoderFactory::create() and Decoder::decode().
  • 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.

  • Add libpipewire-0.3 dependency.
  • Implement CaptureFactory::create() using the xdg-desktop-portal.
  • 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.

  • Implement RtpHeader and RtpPacket serialize/parse.
  • Add H.264 NAL splitting and FU-A fragmentation.
  • 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.

  • Implement RtpTransport with ASIO or raw UDP sockets.
  • Wire sender pipeline: capture → encode → RTP → localhost UDP.
  • Wire receiver pipeline: localhost UDP → RTP → decode → renderer.
  • Add SDL2/3 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.

  • Implement mDNS/DNS-SD discovery with Avahi.
  • Implement JSON WebSocket signaling.
  • Extend CLI with --peer-address or --discover.

Validation: two machines on the same LAN connect without hard-coded IP addresses.

Phase 7 — Resilience and Polish

Goal: loss recovery, hardware acceleration, and packaging.

  • NACK / PLI feedback loop.
  • Jitter buffer on the receiver.
  • VAAPI/NVENC hardware encode probes and fallback.
  • Optional GUI target behind meson -Dgui=true.
  • .desktop file, icon, packaging notes.

Validation: sustained streaming under packet loss; hardware accel smoke where available.

Current phase

Phase 5 — Local UDP Sender → Receiver Loopback.