Phase 1 MVP implementation of wl-webrtc: Wayland screen capture tool with hardware-accelerated VAAPI H.264 encoding and WebTransport output. Includes all 9 runtime bug fixes from code audit (fix-audit-issues plan): CRITICAL: - C2: h264_metadata BSF with repeat_sps/repeat_pps in encode pipeline - C4: FpsLimit wired as timing gate in on_copy_complete HIGH: - C3+A2: DRM device discovery via dmabuf feedback MainDevice event, unified resolve_drm_path() helper (CLI > compositor > auto > fallback) - H2: Separate physical_size (mm) from mode_size (pixels) in wl_output - H1+A3: Multi-output warning + named-output-not-found error MEDIUM: - M5: tv_sec u32->u64 to avoid Y2106 timestamp truncation - M4: Guard against SHM Buffer event (DMA-BUF only) Key components: - src/avhw.rs: FFmpeg VAAPI encoder + filter graph + BSF pipeline - src/state.rs: Wayland event loop + output negotiation + screencopy - src/cap_wlr_screencopy.rs: wlr-screencopy capture source - src/fps_limit.rs: Frame rate limiting with configurable target - src/transform.rs: Frame format conversion utilities
104 lines
3.0 KiB
Rust
104 lines
3.0 KiB
Rust
use std::process::Command;
|
|
|
|
/// Helper: get the binary path. Uses the release build if available.
|
|
fn bin_path() -> &'static str {
|
|
"target/release/wl-webrtc"
|
|
}
|
|
|
|
#[test]
|
|
fn test_help_flag() {
|
|
let output = Command::new(bin_path())
|
|
.arg("--help")
|
|
.output()
|
|
.expect("failed to execute wl-webrtc --help");
|
|
|
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
assert!(output.status.success(), "--help should exit 0");
|
|
assert!(
|
|
stdout.contains("output"),
|
|
"help output should mention 'output'"
|
|
);
|
|
assert!(stdout.contains("fps"), "help output should mention 'fps'");
|
|
assert!(
|
|
stdout.contains("codec"),
|
|
"help output should mention 'codec'"
|
|
);
|
|
assert!(
|
|
stdout.contains("bitrate"),
|
|
"help output should mention 'bitrate'"
|
|
);
|
|
assert!(
|
|
stdout.contains("gop-size"),
|
|
"help output should mention 'gop-size'"
|
|
);
|
|
assert!(
|
|
stdout.contains("drm-device"),
|
|
"help output should mention 'drm-device'"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_rejects_invalid_args() {
|
|
let output = Command::new(bin_path())
|
|
.arg("--nonexistent-flag-xyz")
|
|
.output()
|
|
.expect("failed to execute wl-webrtc with invalid args");
|
|
|
|
assert!(
|
|
!output.status.success(),
|
|
"should reject unrecognized flag"
|
|
);
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
assert!(
|
|
stderr.to_lowercase().contains("error")
|
|
|| stderr.to_lowercase().contains("unexpected")
|
|
|| stderr.to_lowercase().contains("unrecognized"),
|
|
"stderr should mention the error, got: {stderr}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_rejects_hevc_codec() {
|
|
let output = Command::new(bin_path())
|
|
.arg("--output")
|
|
.arg("/dev/null")
|
|
.arg("--codec")
|
|
.arg("hevc")
|
|
.output()
|
|
.expect("failed to execute wl-webrtc --codec hevc");
|
|
|
|
// MVP only supports h264; hevc should be rejected.
|
|
assert!(
|
|
!output.status.success(),
|
|
"should reject hevc codec in MVP"
|
|
);
|
|
}
|
|
|
|
/// Tests requiring a live Wayland compositor and VAAPI hardware.
|
|
/// Run with: cargo test -- --ignored
|
|
#[test]
|
|
#[ignore]
|
|
fn test_capture_starts_with_valid_output() {
|
|
// This test requires:
|
|
// - A running Wayland compositor
|
|
// - VAAPI-compatible GPU hardware
|
|
// - A writable output path
|
|
let output = Command::new(bin_path())
|
|
.arg("--output")
|
|
.arg("/tmp/wl-webrtc-test-capture.mp4")
|
|
.arg("--fps")
|
|
.arg("10")
|
|
.output()
|
|
.expect("failed to start wl-webrtc");
|
|
|
|
// If we get here, the process ran and exited.
|
|
// In a real test, we'd give it time to capture a few frames
|
|
// and then send SIGINT, but for now just check it didn't
|
|
// immediately fail with an argument error.
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
assert!(
|
|
!stderr.contains("error: unexpected") && !stderr.contains("error: invalid"),
|
|
"should not have argument parsing errors, got: {stderr}"
|
|
);
|
|
}
|