CI / Build + Clippy + Test (pull_request) Failing after 30s
CI / Security audit (RUSTSEC) (pull_request) Failing after 30s
Oracle audit of all 5 `unsafe impl Send` in src/avhw/ found soundness
intact but reasoning wrong in 3 of 5:
- AvHwDevCtx: claimed '&mut self ensures exclusive access' — false,
ref_clone() hands raw pointers to other threads / FFmpeg-internal
codec workers. Real basis is AVBufferRef atomic_uint refcount +
libva VADisplay thread safety.
- AvHwFrameCtx: claimed 'send/receive pattern is thread-safe' —
misdirection. Real basis is AVBufferPool atomic get/put.
- EncState: claimed 'raw pointers not shared across threads' — false
when FFmpeg frame/slice threading is enabled. Real basis is the
hw device/frames contexts being designed for such sharing.
SwEncState and SwEncEncode comments were acceptable; improved for
clarity (note that contained FFmpeg handles are non-thread-safe but
Send-sound under exclusive access, and that crossbeam/Arc fields are
already Send by design).
Added module-level convention doc to src/avhw/mod.rs centralizing
the C-API-level justification rule and explicitly calling out the
'&mut self as Send basis' anti-pattern so future contributors don't
repeat the category error.
Fixed AGENTS.md:
- Stale claim that Cargo.toml 'only warns' on undocumented_unsafe_blocks
(it's been 'deny' for a while)
- Stale path src/avhw.rs → src/avhw/ (split in d53e881)
- Stale 'avoid moving wrappers across threads' guidance — Send is sound,
the audit just confirmed why
No code behavior change. Verified: cargo build --release,
cargo clippy --release --all-targets (0 warnings),
cargo test --release (79 unit + 3 integration, 1 ignored).
4.1 KiB
4.1 KiB
AGENTS.md
Sources of truth
- Trust current Rust source,
Cargo.toml,shell.nix, and tests overdocs/superpowers/*oranalysis.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.nixprovides FFmpeg/Wayland/libdrm/Mesa/libva/clang andLIBCLANG_PATH, but does not currently list PipeWire. - Normal build:
cargo build. Release binary required by README and integration tests:cargo build --release. Cargo.tomlsetsclippy::undocumented_unsafe_blocks = "deny"; everyunsafeblock andunsafe implmust carry a// SAFETY:comment or the build fails. Forunsafe impl Sendon FFmpeg wrappers, see the convention insrc/avhw/mod.rs— justification must be at the C-API level (atomic refcounts, libvaVADisplaythread 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 testincludestests/integration_test.rs, which shells out totarget/release/wl-webrtc; runcargo build --releasefirst 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 --helpand invalid-argument rejection. Real capture needs Wayland plus either wlr-screencopy or XDG Portal/PipeWire. - The README CLI table is stale for
--backendand--no-persist;src/args.rsis authoritative for flags.
Runtime architecture
src/main.rsis the real entrypoint: parseArgs, initialize tracing fromRUST_LOGor-v, reject non-H.264, require--outputor--port, detect backend, then run one of two loops.- Backend detection in
src/backend_detect.rs: explicit--backend portal|screencopywins; otherwise wlr-screencopy is preferred when the Wayland globalzwlr_screencopy_manager_v1exists, else Portal/PipeWire is used if D-Bus ScreenCast is available. - Do not use
ashpdfor backend availability checks;backend_detect.rsintentionally uses rawzbusbecauseashpdcaches azbus::Connectionin a global and can hang after its owning Tokio runtime is dropped. src/state.rsdrives the wlroots path using a mio Wayland fd loop andState<CapWlrScreencopy>;src/state_portal.rsdrives the Portal/PipeWire path throughCapPortalframe channels.src/webrtc.rsis a small embedded HTTP/WebRTC signaling server usingstr0m;--port 0means file-output mode,--port > 0enables WebRTC mode.
Unsafe and FFI work
- FFmpeg/VAAPI/PipeWire code relies on raw FFI and many
unsafeblocks. Preserve nearby// SAFETY:explanations and add one for any new unsafe block. src/avhw/(split from the formersrc/avhw.rsin commitd53e881) owns FFmpegAVBufferRef/ frame / codec contexts. Five types (AvHwDevCtx,AvHwFrameCtx,EncState,SwEncState,SwEncEncode) carryunsafe 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 — seesrc/avhw/mod.rsfor the full convention.CapPortalstores the portal restore token under the user cache directory (wl-webrtc/portal-restore-token); use--no-persistwhen 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.mp4andcargo run --bin sw_encode_bench -- --output /tmp/bench_test.mp4.