# AGENTS.md ## Sources of truth - Trust current Rust source, `Cargo.toml`, `shell.nix`, and tests over `docs/superpowers/*` or `analysis.md`; those docs contain historical/aspirational modules that are not in the tree. - Crate edition is 2021, not the default Rust 2024. The package exposes a library, three binaries (`wl-webrtc`, `vaapi_import_bench`, `sw_encode_bench`), and two examples (`list_globals`, `test_portal`). ## Setup and build - Native prerequisites are FFmpeg 6+ dev libs with VAAPI, Wayland protocols/libs, libdrm, PipeWire, and libclang. `shell.nix` provides FFmpeg/Wayland/libdrm/Mesa/libva/clang and `LIBCLANG_PATH`, but does not currently list PipeWire. - Normal build: `cargo build`. Release binary required by README and integration tests: `cargo build --release`. - `Cargo.toml` only warns on `clippy::undocumented_unsafe_blocks`; do not assume a broader clippy policy exists unless you add one. ## Testing and verification - Unit/focused tests can run with filters, e.g. `cargo test transform`, `cargo test fps_limit`, `cargo test backend_detect`. - Full `cargo test` includes `tests/integration_test.rs`, which shells out to `target/release/wl-webrtc`; run `cargo build --release` first or those tests fail before reaching code behavior. - Hardware/live tests are marked ignored; run them only on a Wayland session with VAAPI-capable GPU and writable output: `cargo test -- --ignored`. - CLI smoke test surface: `target/release/wl-webrtc --help` and invalid-argument rejection. Real capture needs Wayland plus either wlr-screencopy or XDG Portal/PipeWire. - The README CLI table is stale for `--backend` and `--no-persist`; `src/args.rs` is authoritative for flags. ## Runtime architecture - `src/main.rs` is the real entrypoint: parse `Args`, initialize tracing from `RUST_LOG` or `-v`, reject non-H.264, require `--output` or `--port`, detect backend, then run one of two loops. - Backend detection in `src/backend_detect.rs`: explicit `--backend portal|screencopy` wins; otherwise wlr-screencopy is preferred when the Wayland global `zwlr_screencopy_manager_v1` exists, else Portal/PipeWire is used if D-Bus ScreenCast is available. - Do not use `ashpd` for backend availability checks; `backend_detect.rs` intentionally uses raw `zbus` because `ashpd` caches a `zbus::Connection` in a global and can hang after its owning Tokio runtime is dropped. - `src/state.rs` drives the wlroots path using a mio Wayland fd loop and `State`; `src/state_portal.rs` drives the Portal/PipeWire path through `CapPortal` frame channels. - `src/webrtc.rs` is a small embedded HTTP/WebRTC signaling server using `str0m`; `--port 0` means file-output mode, `--port > 0` enables WebRTC mode. ## Unsafe and FFI work - FFmpeg/VAAPI/PipeWire code relies on raw FFI and many `unsafe` blocks. Preserve nearby `// SAFETY:` explanations and add one for any new unsafe block. - `src/avhw.rs` owns FFmpeg `AVBufferRef`/frame contexts and has explicit `unsafe impl Send`; avoid moving those wrappers across threads without rechecking the documented exclusivity assumptions. - `CapPortal` stores the portal restore token under the user cache directory (`wl-webrtc/portal-restore-token`); use `--no-persist` when manually testing fresh authorization behavior. ## Useful manual commands - List Wayland globals: `cargo run --example list_globals`. - Portal permission smoke test: `cargo run --example test_portal`. - Portal/VAAPI benchmarks require a screen-share dialog and hardware: `cargo run --bin vaapi_import_bench -- --output /tmp/vaapi_bench.mp4` and `cargo run --bin sw_encode_bench -- --output /tmp/bench_test.mp4`.