diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md index 8f22923..680028d 100644 --- a/docs/RUNBOOK.md +++ b/docs/RUNBOOK.md @@ -133,8 +133,10 @@ Optional flags: `--port`, `--peer HOST[:PORT]`, `--bitrate KBPS`, Notes: the encoder runs a VBV that caps keyframe bursts to roughly two frame periods of bytes, and the receiver requests a 4MB UDP receive -buffer (clamped by `net.core.rmem_max`). For very high `--bitrate` -values, raise `net.core.rmem_max` on the receiver machine. +buffer (clamped by `net.core.rmem_max`; the install script raises it to +4 MB and persists the change). The remaining bottleneck on Wi-Fi-only +boards is the wireless link itself — lower `--bitrate` until the stream +is stable. The headless equivalent runs as part of `meson test` (`udp loopback` test): synthetic frames → encode → packetize → localhost UDP → depacketize → diff --git a/scripts/install-receiver.sh b/scripts/install-receiver.sh index 0dd9b63..287a7fd 100755 --- a/scripts/install-receiver.sh +++ b/scripts/install-receiver.sh @@ -145,6 +145,16 @@ install -m 755 "${BUILD_DIR}/src/app/screencast" "${INSTALL_DIR}/screencast" systemctl enable --now avahi-daemon 2>/dev/null || true +# UDP receive buffers clamp to net.core.rmem_max (stock Debian: ~208 KB). +# A keyframe burst at higher bitrates is larger than that, and the packet +# loss it causes makes every keyframe undecodable (black screen). Applied +# idempotently; buffers are allocated lazily, so this costs no RAM at rest. +if [ "$(cat /proc/sys/net/core/rmem_max)" -lt 4194304 ]; then + log "raising net.core.rmem_max to 4 MB for RTP burst absorption" + sysctl -w net.core.rmem_max=4194304 >/dev/null + printf 'net.core.rmem_max=4194304\n' > /etc/sysctl.d/99-screencast-rmem.conf +fi + # --- systemd autostart -------------------------------------------------------- if [ "${ENABLE_SERVICE}" = "1" ] && command -v systemctl >/dev/null 2>&1; then log "installing the systemd service (autostart on boot)"