- commit
- 4e16190dd5f1233173ac2fc7bb7f791a615b7722
- parent
- 54a4b7d2868822bf3fd00aac68a2f99a8c8b98da
- author
- FelineStateMachine <dami.etoile@gmail.com>
| M | README.md | 16 | +++-- |
| M | crates/ | 47 | +++++++++++++ |
| A | crates/ | 107 | ++++++++++++++++++++++++++++++ |
| M | scripts/ | 2 | + |
@@ -37,15 +37,19 @@ Steam and games.
3737 input messages, limits, and ALPNs.3838 - The Linux host is the pure Rust `sigil` binary with no Tauri or webview3939 dependency.40-- The Bazzite path captures the exact Gamescope PipeWire node, derives the41- encoded size from its bounded native caps by default, and uses AMD GstVA42- H.264. An explicit width/height pair remains available for downscale proofs;43- 1280×800/60 is the first measured target, not a product constraint.40+- The core host captures the standard upstream Gamescope PipeWire video source,41+ derives the encoded size from its bounded native caps by default, and uses42+ AMD GstVA H.264. An explicit width/height pair remains available for43+ downscale proofs; 1280×800/60 is the first measured target, not a product44+ constraint. Bazzite remains the only packaged and hardware-proven appliance;45+ SteamOS packaging, cold boot, encoder availability, and hardware UAT remain46+ unproven.4447 - Gamescope video keeps the proven external `gst-launch` pipeline as its4548 configuration default. Linux builds made explicitly with4649 `in-process-gstreamer` can opt into an in-process pipeline for bounded47- bitrate, force-keyframe, and two-tier resolution control; ordinary release48- packages do not enable that feature yet.50+ bitrate, force-keyframe, and two-tier resolution control. Published Sigil51+ packages include that backend while keeping the external pipeline as the52+ runtime default.4953 - Portal reports bounded receiver queue, drop, latency, and recovery telemetry5054 over a session-authenticated feedback stream. The host combines it with5155 trusted path and scheduler pressure, applies hysteresis, and commits an@@ -2693,6 +2693,53 @@ mod tests {
26932693 );26942694 }26952695 2696+ 2697+ fn resolves_pinned_upstream_gamescope_pipewire_contract() {2698+ // Sanitized from the standard interface emitted by Valve Gamescope2699+ // commit 17baf4abd1ab3353fb705e4d0d023f84e870f7e8, src/pipewire.cpp2700+ // blob 76b3ea8cc8ff01c6635498cbafe38130e33215f2. This fixture proves2701+ // interface compatibility; it is not SteamOS hardware evidence.2702+ let dump = include_bytes!("../tests/fixtures/upstream-gamescope-pipewire-contract.json");2703+ let mut config = gamescope_config();2704+ config.width = None;2705+ config.height = None;2706+ config2707+ .gamescope_pipewire2708+ .as_mut()2709+ .unwrap()2710+ .match_properties2711+ .clear();2712+2713+ let resolved = resolve_pipewire_node(dump, &config).unwrap();2714+ assert_eq!(resolved.target_object, "8842");2715+ assert_eq!(2716+ resolved.pointer_surface_dimensions,2717+ PointerSurfaceDimensions::new(1_920, 1_080).unwrap()2718+ );2719+ assert_eq!(2720+ resolved.video_mode,2721+ CaptureVideoMode {2722+ width: 1_920,2723+ height: 1_080,2724+ framerate: 60,2725+ }2726+ );2727+2728+ let args: Vec<String> =2729+ gamescope_pipeline_args(&config, &resolved.target_object, resolved.video_mode)2730+ .unwrap()2731+ .into_iter()2732+ .map(|arg| arg.into_string().unwrap())2733+ .collect();2734+ assert!(args.contains(&"target-object=8842".to_owned()));2735+ assert!(2736+ args.contains(2737+ &"video/x-raw,format=NV12,width=1920,height=1080,framerate=60/1".to_owned()2738+ )2739+ );2740+ assert!(args.contains(&"max-rate=60".to_owned()));2741+ }2742+26962743 26972744 fn rejects_ambiguous_or_unbounded_gamescope_native_size() {26982745 let config = gamescope_config();@@ -0,0 +1,107 @@
1+[2+ {3+ "id": 71,4+ "type": "PipeWire:Interface:Node",5+ "version": 3,6+ "info": {7+ "props": {8+ "media.class": "Video/Source",9+ "node.name": "gamescope",10+ "object.serial": 884211+ },12+ "params": {13+ "EnumFormat": [14+ {15+ "mediaType": "video",16+ "mediaSubtype": "raw",17+ "format": "BGRx",18+ "size": {19+ "width": 1920,20+ "height": 108021+ },22+ "framerate": {23+ "num": 0,24+ "denom": 125+ },26+ "id-00070000": {27+ "default": {28+ "width": 0,29+ "height": 030+ },31+ "min": {32+ "width": 0,33+ "height": 034+ },35+ "max": {36+ "width": 4294967295,37+ "height": 429496729538+ }39+ },40+ "id-00070001": {41+ "default": 0,42+ "min": -9223372036854775808,43+ "max": 922337203685477580744+ }45+ },46+ {47+ "mediaType": "video",48+ "mediaSubtype": "raw",49+ "format": "NV12",50+ "size": {51+ "width": 1920,52+ "height": 108053+ },54+ "framerate": {55+ "num": 0,56+ "denom": 157+ },58+ "id-00070000": {59+ "default": {60+ "width": 0,61+ "height": 062+ },63+ "min": {64+ "width": 0,65+ "height": 066+ },67+ "max": {68+ "width": 4294967295,69+ "height": 429496729570+ }71+ },72+ "id-00070001": {73+ "default": 0,74+ "min": -9223372036854775808,75+ "max": 922337203685477580776+ }77+ }78+ ]79+ }80+ }81+ },82+ {83+ "id": 72,84+ "type": "PipeWire:Interface:Node",85+ "version": 3,86+ "info": {87+ "props": {88+ "media.class": "Video/Source",89+ "node.name": "desktop-capture",90+ "object.serial": "8843"91+ },92+ "params": {93+ "EnumFormat": [94+ {95+ "mediaType": "video",96+ "mediaSubtype": "raw",97+ "format": "BGRx",98+ "size": {99+ "width": 1280,100+ "height": 720101+ }102+ }103+ ]104+ }105+ }106+ }107+]@@ -56,6 +56,8 @@ printf 'revision=%s\n' "$(git rev-parse HEAD)"
5656 rustc --version5757 cargo --version5858 59+require_rust_test 'resolves_pinned_upstream_gamescope_pipewire_contract' \60+ -p sigil-host --bin sigil5961 cargo fmt --all -- --check6062 cargo test --locked --workspace --all-targets6163 cargo clippy --locked --workspace --all-targets -- -D warnings