cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

fix(streaming): keep feedback available for cqp hosts

Dami committed 1ee0f08
commit
1ee0f08932505b4b8cd4cd98c9fc917aae43ea68
parent
596140420f0557ae177c13dafc1d2457fbd695b0
author
Dami <dami.etoile@gmail.com>
1 file changed, +73 -7
Mcrates/sigil-host/src/server.rs80+++++++++++++++++++++++++++---
M crates/sigil-host/src/server.rs +73 -7
@@ -72,7 +72,7 @@ const SOURCE_REAP_GRACE_TIMEOUT: Duration = Duration::from_secs(1);
7272 const MOQ_ATTACHMENT_TIMEOUT: Duration = Duration::from_secs(10);7373 const MOQ_REJECT_CODE: u32 = 0x534d;7474 const ADAPTIVE_BITRATE_FLOOR_KBPS: u32 = 1_000;75-const TEST_PATTERN_BITRATE_CEILING_KBPS: u32 = 12_000;75+const SHADOW_BITRATE_CEILING_KBPS: u32 = 12_000;7676 const ADAPTIVE_BITRATE_QUANTUM_KBPS: u32 = 250;7777 const ADAPTIVE_BITRATE_CLEAN_WINDOWS: u8 = 10;7878 const ADAPTIVE_BITRATE_MODERATE_WINDOWS: u8 = 2;
@@ -3532,12 +3532,19 @@ where
35323532 35333533 fn adaptive_bitrate_ceiling_kbps(config: &HostConfig) -> Result<u32> {35343534 let configured = match config.source {3535- VideoSource::TestPattern => TEST_PATTERN_BITRATE_CEILING_KBPS,3536- VideoSource::GamescopePipewire => config3537- .gamescope_pipewire3538- .as_ref()3539- .and_then(|gamescope| gamescope.bitrate_kbps)3540- .context("adaptive bitrate shadow mode requires a Gamescope CBR bitrate")?,3535+ VideoSource::TestPattern => SHADOW_BITRATE_CEILING_KBPS,3536+ VideoSource::GamescopePipewire => {3537+ let gamescope = config3538+ .gamescope_pipewire3539+ .as_ref()3540+ .context("Gamescope feedback requires gamescope_pipewire configuration")?;3541+ match gamescope.rate_control {3542+ VaapiRateControl::Cbr => gamescope3543+ .bitrate_kbps3544+ .context("adaptive bitrate shadow mode requires a Gamescope CBR bitrate")?,3545+ VaapiRateControl::Cqp => SHADOW_BITRATE_CEILING_KBPS,3546+ }3547+ }35413548 };35423549 let ceiling = quantize_down(configured);35433550 ensure!(
@@ -5927,6 +5934,65 @@ mod tests {
59275934 }59285935 }59295936 5937+ fn gamescope_feedback_test_config(rate_control: VaapiRateControl) -> HostConfig {5938+ let (bitrate_kbps, quantizer) = match rate_control {5939+ VaapiRateControl::Cbr => (Some(12_123), None),5940+ VaapiRateControl::Cqp => (None, Some(24)),5941+ };5942+ let mut config = moq_test_config();5943+ config.source = VideoSource::GamescopePipewire;5944+ config.width = None;5945+ config.height = None;5946+ config.gamescope_pipewire = Some(crate::config::GamescopePipewireConfig {5947+ node_name: "gamescope".into(),5948+ media_class: "Video/Source".into(),5949+ match_properties: std::collections::BTreeMap::new(),5950+ xwayland_display: None,5951+ pw_dump_path: "/usr/bin/pw-dump".into(),5952+ gst_launch_path: "/usr/bin/gst-launch-1.0".into(),5953+ gst_inspect_path: "/usr/bin/gst-inspect-1.0".into(),5954+ encoder_backend: GamescopeEncoderBackend::ExternalGstLaunch,5955+ vaapi_encoder: "vah264enc".into(),5956+ vaapi_render_node: "/dev/dri/renderD128".into(),5957+ rate_control,5958+ bitrate_kbps,5959+ quantizer,5960+ });5961+ config.validate().unwrap();5962+ config5963+ }5964+5965+ #[test]5966+ fn external_cqp_uses_a_fixed_shadow_bitrate_ceiling() {5967+ let config = gamescope_feedback_test_config(VaapiRateControl::Cqp);5968+5969+ assert_eq!(5970+ adaptive_bitrate_ceiling_kbps(&config).unwrap(),5971+ SHADOW_BITRATE_CEILING_KBPS5972+ );5973+ assert!(!adaptive_bitrate_actuation_enabled(&config));5974+ }5975+5976+ #[test]5977+ fn gamescope_cbr_keeps_its_quantized_configured_ceiling() {5978+ let config = gamescope_feedback_test_config(VaapiRateControl::Cbr);5979+5980+ assert_eq!(adaptive_bitrate_ceiling_kbps(&config).unwrap(), 12_000);5981+ }5982+5983+ #[test]5984+ fn malformed_cbr_without_a_bitrate_still_fails_closed() {5985+ let mut config = gamescope_feedback_test_config(VaapiRateControl::Cbr);5986+ config.gamescope_pipewire.as_mut().unwrap().bitrate_kbps = None;5987+5988+ assert_eq!(5989+ adaptive_bitrate_ceiling_kbps(&config)5990+ .unwrap_err()5991+ .to_string(),5992+ "adaptive bitrate shadow mode requires a Gamescope CBR bitrate"5993+ );5994+ }5995+59305996 #[tokio::test]59315997 async fn upstream_moq_groups_are_sequential_and_cancel_the_superseded_gop() {59325998 let track_info = Track {