From 6ac2fe9cd38a064cb9952f31707a4ffa8446e9b8 Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Sat, 21 Mar 2026 19:10:32 +0100 Subject: [PATCH] record-daemon: refactor encoder detection logic --- record-daemon/src/recording/encoder.rs | 160 +------------------------ 1 file changed, 5 insertions(+), 155 deletions(-) diff --git a/record-daemon/src/recording/encoder.rs b/record-daemon/src/recording/encoder.rs index 24052c6..46f7ed2 100644 --- a/record-daemon/src/recording/encoder.rs +++ b/record-daemon/src/recording/encoder.rs @@ -300,48 +300,25 @@ pub fn detect_hardware_encoders() -> Vec { let mut capabilities = Vec::new(); - #[cfg(target_os = "linux")] - { - // Check for NVIDIA - if std::path::Path::new("/dev/nvidia0").exists() { - info!("[ENCODER_DETECT] Found NVIDIA device"); - capabilities.push(EncoderCapability::Nvenc); - } - - // Check for AMD - if std::path::Path::new("/sys/class/drm").exists() { - // Would check for AMD GPU - // capabilities.push(EncoderCapability::Amf); - } - } - #[cfg(target_os = "windows")] { - // On Windows, check for NVIDIA first - // Try to load nvenc DLL - info!("[ENCODER_DETECT] Checking for NVENC..."); + let gpu_vendors = detect_gpu_vendors(); - if is_nvenc_available() { + if gpu_vendors.contains(&GpuVendor::Nvidia) { info!("[ENCODER_DETECT] NVENC available"); capabilities.push(EncoderCapability::Nvenc); } else { info!("[ENCODER_DETECT] NVENC not available"); } - // Check for AMD AMF - info!("[ENCODER_DETECT] Checking for AMF..."); - - if is_amf_available() { + if gpu_vendors.contains(&GpuVendor::Amd) { info!("[ENCODER_DETECT] AMF available"); capabilities.push(EncoderCapability::Amf); } else { info!("[ENCODER_DETECT] AMF not available"); } - // Check for Intel QuickSync - info!("[ENCODER_DETECT] Checking for QuickSync..."); - - if is_quicksync_available() { + if gpu_vendors.contains(&GpuVendor::Intel) { info!("[ENCODER_DETECT] QuickSync available"); capabilities.push(EncoderCapability::QuickSync); } else { @@ -349,8 +326,7 @@ pub fn detect_hardware_encoders() -> Vec { } } - // Always available - info!("[ENCODER_DETECT] Software encoder always available"); + // Software encoding is always available capabilities.push(EncoderCapability::Software); info!("[ENCODER_DETECT] Detected encoders: {:?}", capabilities); @@ -424,132 +400,6 @@ fn detect_gpu_vendors() -> Vec { vendors } -/// Check if NVIDIA NVENC is available. -#[cfg(target_os = "windows")] -fn is_nvenc_available() -> bool { - use tracing::info; - use winreg::enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; - use winreg::RegKey; - - // First check if NVIDIA GPU is present via registry - let vendors = detect_gpu_vendors(); - if !vendors.contains(&GpuVendor::Nvidia) { - info!("[ENCODER_DETECT] No NVIDIA GPU detected via registry"); - return false; - } - - // NVIDIA GPU found, now check for NVENC support - // NVENC is available on most modern NVIDIA GPUs (GTX 600+ and all RTX cards) - // We can verify by checking if nvEncAPI is loadable or by checking registry - - // Check for NVENC capability in registry (NVIDIA stores encoder info here) - const NVENC_REGISTRY_PATH: &str = r"SOFTWARE\NVIDIA Corporation\Global\NvEnc"; - - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - - // Try HKCU first - if hkcu.open_subkey(NVENC_REGISTRY_PATH).is_ok() { - info!("[ENCODER_DETECT] NVENC registry key found (HKCU)"); - return true; - } - - // Try HKLM - if hklm.open_subkey(NVENC_REGISTRY_PATH).is_ok() { - info!("[ENCODER_DETECT] NVENC registry key found (HKLM)"); - return true; - } - - // If NVIDIA GPU is present, assume NVENC is available - // Modern NVIDIA GPUs (GTX 600 series and newer) all have NVENC - // This is a reasonable fallback since the registry check might not work on all systems - info!("[ENCODER_DETECT] NVIDIA GPU detected, assuming NVENC available"); - true -} - -/// Check if AMD AMF is available. -#[cfg(target_os = "windows")] -fn is_amf_available() -> bool { - use tracing::info; - use winreg::enums::HKEY_LOCAL_MACHINE; - use winreg::RegKey; - - // Check if AMD GPU is present via registry - let vendors = detect_gpu_vendors(); - if !vendors.contains(&GpuVendor::Amd) { - info!("[ENCODER_DETECT] No AMD GPU detected via registry"); - return false; - } - - // AMD GPU found, check for AMF runtime - // AMF is available on modern AMD GPUs (RX 400+ and some older cards) - - // Check for AMF runtime in registry - const AMF_REGISTRY_PATH: &str = r"SOFTWARE\AMD\AMF"; - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - - if hklm.open_subkey(AMF_REGISTRY_PATH).is_ok() { - info!("[ENCODER_DETECT] AMF registry key found"); - return true; - } - - // Fallback: check for amdocl64.dll or amfrt64.dll in system - let system32 = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string()); - let amdocl_path = format!("{}\\System32\\amdocl64.dll", system32); - let amfrt_path = format!("{}\\System32\\amfrt64.dll", system32); - - if std::path::Path::new(&amdocl_path).exists() || std::path::Path::new(&amfrt_path).exists() { - info!("[ENCODER_DETECT] AMF DLL found"); - return true; - } - - // If AMD GPU is present, assume AMF is available on modern cards - info!("[ENCODER_DETECT] AMD GPU detected, assuming AMF available"); - true -} - -/// Check if Intel QuickSync is available. -#[cfg(target_os = "windows")] -fn is_quicksync_available() -> bool { - use tracing::info; - - // Check if Intel GPU is present via registry - let vendors = detect_gpu_vendors(); - if !vendors.contains(&GpuVendor::Intel) { - info!("[ENCODER_DETECT] No Intel GPU detected via registry"); - return false; - } - - // Intel GPU found, check for QuickSync (Intel Media SDK / oneVPL) - // QuickSync is available on Intel CPUs with integrated graphics (Sandy Bridge and newer) - - // Check for Intel Media SDK or oneVPL - let system32 = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string()); - let mfx_path = format!("{}\\System32\\mfx64.dll", system32); - let vpl_path = format!("{}\\System32\\libmfx64.dll", system32); - - if std::path::Path::new(&mfx_path).exists() || std::path::Path::new(&vpl_path).exists() { - info!("[ENCODER_DETECT] Intel Media SDK DLL found"); - return true; - } - - // Check for oneVPL runtime - const VPL_REGISTRY_PATH: &str = r"SOFTWARE\Intel\oneVPL"; - use winreg::enums::HKEY_LOCAL_MACHINE; - use winreg::RegKey; - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - - if hklm.open_subkey(VPL_REGISTRY_PATH).is_ok() { - info!("[ENCODER_DETECT] oneVPL registry key found"); - return true; - } - - // If Intel GPU is present, assume QuickSync might be available - // Note: Not all Intel GPUs have QuickSync (some low-end chips don't) - info!("[ENCODER_DETECT] Intel GPU detected, assuming QuickSync available"); - true -} - /// Get the best available encoder capability. pub fn best_available_encoder() -> EncoderCapability { let capabilities = detect_hardware_encoders();