mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-20 02:41:06 -05:00
Added proper physical GPU detection on Linux/Windows/macOS
Separated physical GPU detection from FFmpeg encoder support Only enable GPU encoding when both physical GPU and FFmpeg support exist Added multiple detection methods for better reliability
This commit is contained in:
@@ -5,7 +5,7 @@ import subprocess
|
||||
import logging
|
||||
import platform
|
||||
import re
|
||||
from typing import Dict, List
|
||||
from typing import Dict, List, Tuple
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger("VideoArchiver")
|
||||
@@ -34,24 +34,23 @@ class GPUDetector:
|
||||
}
|
||||
|
||||
try:
|
||||
# Check system-specific GPU detection first
|
||||
system = platform.system().lower()
|
||||
if system == "windows":
|
||||
gpu_info.update(self._detect_windows_gpu())
|
||||
elif system == "linux":
|
||||
gpu_info.update(self._detect_linux_gpu())
|
||||
elif system == "darwin":
|
||||
gpu_info.update(self._detect_macos_gpu())
|
||||
|
||||
# Verify GPU support in FFmpeg
|
||||
gpu_info.update(self._verify_ffmpeg_gpu_support())
|
||||
# First detect physical GPUs
|
||||
physical_gpus = self._detect_physical_gpus()
|
||||
|
||||
# Then check FFmpeg support
|
||||
ffmpeg_support = self._verify_ffmpeg_gpu_support()
|
||||
|
||||
# Only enable GPU if both physical GPU exists and FFmpeg supports it
|
||||
gpu_info["nvidia"] = physical_gpus["nvidia"] and ffmpeg_support["nvidia"]
|
||||
gpu_info["amd"] = physical_gpus["amd"] and ffmpeg_support["amd"]
|
||||
gpu_info["intel"] = physical_gpus["intel"] and ffmpeg_support["intel"]
|
||||
|
||||
# Log detection results
|
||||
detected_gpus = [name for name, detected in gpu_info.items() if detected]
|
||||
if detected_gpus:
|
||||
logger.info(f"Detected GPUs: {', '.join(detected_gpus)}")
|
||||
logger.info(f"Detected GPUs with FFmpeg support: {', '.join(detected_gpus)}")
|
||||
else:
|
||||
logger.info("No GPU acceleration support detected")
|
||||
logger.info("No GPU acceleration available")
|
||||
|
||||
return gpu_info
|
||||
|
||||
@@ -59,6 +58,17 @@ class GPUDetector:
|
||||
logger.error(f"Error during GPU detection: {str(e)}")
|
||||
return {"nvidia": False, "amd": False, "intel": False}
|
||||
|
||||
def _detect_physical_gpus(self) -> Dict[str, bool]:
|
||||
"""Detect physical GPUs in the system"""
|
||||
system = platform.system().lower()
|
||||
if system == "windows":
|
||||
return self._detect_windows_gpu()
|
||||
elif system == "linux":
|
||||
return self._detect_linux_gpu()
|
||||
elif system == "darwin":
|
||||
return self._detect_macos_gpu()
|
||||
return {"nvidia": False, "amd": False, "intel": False}
|
||||
|
||||
def _detect_windows_gpu(self) -> Dict[str, bool]:
|
||||
"""Detect GPUs on Windows using PowerShell"""
|
||||
gpu_info = {"nvidia": False, "amd": False, "intel": False}
|
||||
@@ -80,60 +90,56 @@ class GPUDetector:
|
||||
return gpu_info
|
||||
|
||||
def _detect_linux_gpu(self) -> Dict[str, bool]:
|
||||
"""Detect GPUs on Linux using lspci and other tools"""
|
||||
"""Detect GPUs on Linux using multiple methods"""
|
||||
gpu_info = {"nvidia": False, "amd": False, "intel": False}
|
||||
|
||||
try:
|
||||
# Try lspci first
|
||||
# Check for NVIDIA GPU
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["lspci", "-v"],
|
||||
["nvidia-smi"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
if result.returncode == 0:
|
||||
output = result.stdout.lower()
|
||||
gpu_info["nvidia"] = "nvidia" in output
|
||||
gpu_info["amd"] = any(x in output for x in ["amd", "radeon"])
|
||||
gpu_info["intel"] = "intel" in output
|
||||
gpu_info["nvidia"] = result.returncode == 0
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Check for NVIDIA using nvidia-smi
|
||||
if not gpu_info["nvidia"]:
|
||||
# Check for AMD GPU using DRI
|
||||
if os.path.exists("/dev/dri"):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nvidia-smi"],
|
||||
["ls", "/dev/dri/render*"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
gpu_info["nvidia"] = result.returncode == 0
|
||||
except FileNotFoundError:
|
||||
if result.returncode == 0:
|
||||
# Check device info using lspci
|
||||
lspci_result = subprocess.run(
|
||||
["lspci", "-v"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
if lspci_result.returncode == 0:
|
||||
output = lspci_result.stdout.lower()
|
||||
gpu_info["amd"] = any(x in output for x in ["amd", "radeon", "advanced micro devices"])
|
||||
gpu_info["intel"] = "intel" in output and "graphics" in output
|
||||
except (FileNotFoundError, subprocess.SubprocessError):
|
||||
pass
|
||||
|
||||
# Check for AMD using rocm-smi
|
||||
if not gpu_info["amd"]:
|
||||
# Additional check for Intel GPU
|
||||
if not gpu_info["intel"] and os.path.exists("/sys/class/drm"):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["rocm-smi"],
|
||||
["find", "/sys/class/drm", "-name", "*i915*"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
gpu_info["amd"] = result.returncode == 0
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Check for Intel using intel_gpu_top
|
||||
if not gpu_info["intel"]:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["intel_gpu_top", "-L"],
|
||||
capture_output=True,
|
||||
timeout=10
|
||||
)
|
||||
gpu_info["intel"] = result.returncode == 0
|
||||
except FileNotFoundError:
|
||||
gpu_info["intel"] = bool(result.stdout.strip())
|
||||
except subprocess.SubprocessError:
|
||||
pass
|
||||
|
||||
except Exception as e:
|
||||
@@ -187,7 +193,7 @@ class GPUDetector:
|
||||
encoders.append("QSV")
|
||||
|
||||
if encoders:
|
||||
logger.info(f"FFmpeg supports GPU encoders: {', '.join(encoders)}")
|
||||
logger.info(f"FFmpeg compiled with GPU encoders: {', '.join(encoders)}")
|
||||
else:
|
||||
logger.info("No GPU encoders available in FFmpeg")
|
||||
|
||||
@@ -197,11 +203,7 @@ class GPUDetector:
|
||||
return gpu_support
|
||||
|
||||
def get_gpu_info(self) -> Dict[str, List[str]]:
|
||||
"""Get detailed GPU information
|
||||
|
||||
Returns:
|
||||
Dict containing lists of GPU names by type
|
||||
"""
|
||||
"""Get detailed GPU information"""
|
||||
gpu_info = {
|
||||
"nvidia": [],
|
||||
"amd": [],
|
||||
@@ -211,23 +213,9 @@ class GPUDetector:
|
||||
try:
|
||||
system = platform.system().lower()
|
||||
|
||||
if system == "windows":
|
||||
cmd = ["powershell", "-Command", "Get-WmiObject Win32_VideoController | Select-Object Name"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
||||
|
||||
if result.returncode == 0:
|
||||
for line in result.stdout.splitlines():
|
||||
line = line.strip().lower()
|
||||
if line:
|
||||
if "nvidia" in line:
|
||||
gpu_info["nvidia"].append(line)
|
||||
elif any(x in line for x in ["amd", "radeon"]):
|
||||
gpu_info["amd"].append(line)
|
||||
elif "intel" in line:
|
||||
gpu_info["intel"].append(line)
|
||||
|
||||
elif system == "linux":
|
||||
if system == "linux":
|
||||
try:
|
||||
# Try lspci first
|
||||
result = subprocess.run(
|
||||
["lspci", "-v"],
|
||||
capture_output=True,
|
||||
@@ -246,6 +234,35 @@ class GPUDetector:
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Try nvidia-smi for NVIDIA GPUs
|
||||
if not gpu_info["nvidia"]:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nvidia-smi", "-L"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
if result.returncode == 0:
|
||||
gpu_info["nvidia"].extend(line.strip() for line in result.stdout.splitlines() if line.strip())
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
elif system == "windows":
|
||||
cmd = ["powershell", "-Command", "Get-WmiObject Win32_VideoController | Select-Object Name"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
||||
|
||||
if result.returncode == 0:
|
||||
for line in result.stdout.splitlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith("Name"):
|
||||
if "nvidia" in line.lower():
|
||||
gpu_info["nvidia"].append(line)
|
||||
elif any(x in line.lower() for x in ["amd", "radeon"]):
|
||||
gpu_info["amd"].append(line)
|
||||
elif "intel" in line.lower():
|
||||
gpu_info["intel"].append(line)
|
||||
|
||||
elif system == "darwin":
|
||||
cmd = ["system_profiler", "SPDisplaysDataType"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
||||
@@ -253,17 +270,15 @@ class GPUDetector:
|
||||
if result.returncode == 0:
|
||||
current_gpu = None
|
||||
for line in result.stdout.splitlines():
|
||||
line = line.strip().lower()
|
||||
if "chipset model" in line:
|
||||
if "nvidia" in line:
|
||||
current_gpu = "nvidia"
|
||||
gpu_info["nvidia"].append(line.split(":")[1].strip())
|
||||
elif any(x in line for x in ["amd", "radeon"]):
|
||||
current_gpu = "amd"
|
||||
gpu_info["amd"].append(line.split(":")[1].strip())
|
||||
elif "intel" in line:
|
||||
current_gpu = "intel"
|
||||
gpu_info["intel"].append(line.split(":")[1].strip())
|
||||
line = line.strip()
|
||||
if "Chipset Model:" in line:
|
||||
model = line.split(":", 1)[1].strip()
|
||||
if "nvidia" in model.lower():
|
||||
gpu_info["nvidia"].append(model)
|
||||
elif any(x in model.lower() for x in ["amd", "radeon"]):
|
||||
gpu_info["amd"].append(model)
|
||||
elif "intel" in model.lower():
|
||||
gpu_info["intel"].append(model)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting detailed GPU info: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user