diff --git a/libs/scrap/src/common/vram.rs b/libs/scrap/src/common/vram.rs index 28c786a68..d99a6bc59 100644 --- a/libs/scrap/src/common/vram.rs +++ b/libs/scrap/src/common/vram.rs @@ -1,5 +1,5 @@ use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, ffi::c_void, sync::{Arc, Mutex}, }; @@ -30,6 +30,7 @@ use hwcodec::{ // https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getadapterluid#remarks lazy_static::lazy_static! { static ref ENOCDE_NOT_USE: Arc>> = Default::default(); + static ref FALLBACK_GDI_DISPLAYS: Arc>> = Default::default(); } #[derive(Debug, Clone)] @@ -212,6 +213,11 @@ impl VRamEncoder { } pub fn available(format: CodecFormat) -> Vec { + let fallbacks = FALLBACK_GDI_DISPLAYS.lock().unwrap().clone(); + if !fallbacks.is_empty() { + log::info!("fallback gdi displays not empty: {fallbacks:?}"); + return vec![]; + } let not_use = ENOCDE_NOT_USE.lock().unwrap().clone(); if not_use.values().any(|not_use| *not_use) { log::info!("currently not use vram encoders: {not_use:?}"); @@ -298,6 +304,14 @@ impl VRamEncoder { log::info!("set display#{display} not use vram encode to {not_use}"); ENOCDE_NOT_USE.lock().unwrap().insert(display, not_use); } + + pub fn set_fallback_gdi(display: usize, fallback: bool) { + if fallback { + FALLBACK_GDI_DISPLAYS.lock().unwrap().insert(display); + } else { + FALLBACK_GDI_DISPLAYS.lock().unwrap().remove(&display); + } + } } pub struct VRamDecoder { diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 0d8e1e261..d196d4e9f 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -528,6 +528,7 @@ fn run(vs: VideoService) -> ResultType<()> { #[cfg(all(windows, feature = "vram"))] if c.is_gdi() && encoder.input_texture() { log::info!("changed to gdi when using vram"); + VRamEncoder::set_fallback_gdi(display_idx, true); bail!("SWITCH"); } check_privacy_mode_changed(&sp, c.privacy_mode_id)?; @@ -568,6 +569,10 @@ fn run(vs: VideoService) -> ResultType<()> { } #[cfg(windows)] { + #[cfg(feature = "vram")] + if try_gdi == 1 && !c.is_gdi() { + VRamEncoder::set_fallback_gdi(display_idx, false); + } try_gdi = 0; } Ok(())