The Raspberry Pi Zero 2 W (512 MB RAM) ran out of memory compiling signaling.cpp — nlohmann/json peaks well above available RAM at -O3, and ninja runs 6 parallel jobs on a quad-core — so the OOM killer terminated the compiler with 'Killed signal terminated program cc1plus'. When less than 1.5 GB RAM is detected, the install script now adds 1 GB of temporary build-time swap (fallocate with a dd fallback, removed on exit; some filesystems such as btrfs refuse swapfiles outright, in which case it warns and continues) and compiles with a single job. The cleanup trap also covers the SDL3 source directory. The swap mechanics were live-tested with a small swapfile (swapon/ swapoff lifecycle); this dev machine's filesystem rejects swapfiles, which is what exposed the need for the warning fallback. The Pi's ext4 rootfs accepts them.
screen_cast
A native Linux peer-to-peer screencast application.
- Send your desktop or a window to another Linux machine.
- Receive a stream and render it in a window.
- Discover receivers on the LAN via mDNS/Avahi; negotiate sessions with JSON signaling; stream H.264 over RTP/UDP.
Built with C++20, Meson, PipeWire, FFmpeg, and SDL3.
Quick start
Requirements:
- C++20 compiler with
<format>(GCC 13+, Clang 18+) - Meson >= 0.63, Ninja
- FFmpeg development packages (
libavcodec,libavutil,libswscale) - SDL3 development package (
sdl3) - nlohmann JSON (
nlohmann_json) and Avahi client (avahi-client) - For the sender only: PipeWire dev (
libpipewire-0.3) and libportal
Build and run tests:
meson setup build
meson compile -C build
meson test -C build --print-errorlogs
Stream between two machines:
screencast --receive # machine A: announces itself, opens a window
screencast --send # machine B: discovers A, negotiates, streams
See docs/RUNBOOK.md for all modes, flags, and validation procedures.
Receiver on a small ARM board (e.g. Raspberry Pi Zero 2 W)
The receiver does not need the sender's PipeWire/portal capture stack. On the board, run:
sudo ./scripts/install-receiver.sh
screencast --receive
The script installs the dependencies, builds a receiver-only binary
(-Dsender=false), runs the test suite, and installs to /usr/local/bin
(override with SC_RECEIVER_INSTALL_DIR). It needs Raspberry Pi OS Trixie
or newer (GCC 13+ for C++20 <format>), builds SDL3 from source when the
distribution does not package it, and enables avahi-daemon. It also
installs and enables a systemd service so the receiver starts at boot —
systemctl status screencast-receiver to check on it.
Performance note: decoding is software H.264; on very small boards expect smooth playback for modest resolutions and reduced frame rates at high resolutions. Hardware decode is planned for Phase 7. On a headless console the receiver runs fullscreen automatically with aspect-preserving letterboxing.
Architecture
See docs/ARCHITECTURE.md for module boundaries and design rules.
Roadmap
Development is split into phases in docs/PHASES.md.
Current phase: Phase 7 — Resilience and polish.
License
MIT — see LICENSE (to be added).