record-daemon: refactor encoder detection logic
Some checks failed
record-daemon / Build, check and test (push) Failing after 11m31s
Some checks failed
record-daemon / Build, check and test (push) Failing after 11m31s
This commit is contained in:
@@ -300,48 +300,25 @@ pub fn detect_hardware_encoders() -> Vec<EncoderCapability> {
|
||||
|
||||
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<EncoderCapability> {
|
||||
}
|
||||
}
|
||||
|
||||
// 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<GpuVendor> {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user