CI / Security audit (RUSTSEC) (pull_request) Has been cancelled
CI / Build + Clippy + Test (pull_request) Has been cancelled
Update the 'Runtime architecture' section to reflect that state.rs /
cap_portal.rs / state_portal.rs / webrtc.rs are now parent modules of
directory trees:
- src/state.rs -> src/state/mod.rs (+ src/state/dispatch/ for the 13
Wayland Dispatch impls)
- src/state_portal.rs still exists; helpers split into
src/state_portal/{bitrate,threads}.rs
- src/cap_portal.rs holds the struct; setup/token_fs/pipewire_thread
split into src/cap_portal/
- src/webrtc.rs gains src/webrtc/html_page.rs sibling
No content changes beyond the path references; the rest of AGENTS.md
remains accurate.
41 lines
4.5 KiB
Markdown
41 lines
4.5 KiB
Markdown
# 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` sets `clippy::undocumented_unsafe_blocks = "deny"`; every `unsafe` block and `unsafe impl` must carry a `// SAFETY:` comment or the build fails. For `unsafe impl Send` on FFmpeg wrappers, see the convention in `src/avhw/mod.rs` — justification must be at the C-API level (atomic refcounts, libva `VADisplay` thread safety), not Rust borrow level.
|
|
|
|
## 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/mod.rs` drives the wlroots path using a mio Wayland fd loop and `State<CapWlrScreencopy>` (Wayland `Dispatch` impls live under `src/state/dispatch/`); `src/state_portal.rs` drives the Portal/PipeWire path through `CapPortal` frame channels (bitrate helpers and encode/webrtc thread loops are split into `src/state_portal/{bitrate,threads}.rs`). `src/cap_portal.rs` holds the `CapPortal` struct itself; its setup logic, token filesystem helpers, and PipeWire capture thread live under `src/cap_portal/`.
|
|
- `src/webrtc.rs` is a small embedded HTTP/WebRTC signaling server using `str0m`; the embedded HTML test page is in `src/webrtc/html_page.rs`. `--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/` (split from the former `src/avhw.rs` in commit d53e881) owns FFmpeg `AVBufferRef` / frame / codec contexts. Five types (`AvHwDevCtx`, `AvHwFrameCtx`, `EncState`, `SwEncState`, `SwEncEncode`) carry `unsafe impl Send`; soundness was Oracle-audited on 2026-07-09 against FFmpeg/libva threading semantics. Moving them across threads is sound *because the C APIs use atomic refcounts*, not because of any Rust-side exclusivity — see `src/avhw/mod.rs` for the full convention.
|
|
- `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`.
|