|
|
|
@ -9,7 +9,8 @@ namespace ErsatzTV.FFmpeg.Capabilities; |
|
|
|
|
|
|
|
|
|
|
|
public class HardwareCapabilitiesFactory : IHardwareCapabilitiesFactory |
|
|
|
public class HardwareCapabilitiesFactory : IHardwareCapabilitiesFactory |
|
|
|
{ |
|
|
|
{ |
|
|
|
private const string CacheKey = "ffmpeg.hardware.nvidia.architecture"; |
|
|
|
private const string ArchitectureCacheKey = "ffmpeg.hardware.nvidia.architecture"; |
|
|
|
|
|
|
|
private const string ModelCacheKey = "ffmpeg.hardware.nvidia.model"; |
|
|
|
private readonly ILogger<HardwareCapabilitiesFactory> _logger; |
|
|
|
private readonly ILogger<HardwareCapabilitiesFactory> _logger; |
|
|
|
|
|
|
|
|
|
|
|
private readonly IMemoryCache _memoryCache; |
|
|
|
private readonly IMemoryCache _memoryCache; |
|
|
|
@ -31,9 +32,10 @@ public class HardwareCapabilitiesFactory : IHardwareCapabilitiesFactory |
|
|
|
|
|
|
|
|
|
|
|
private async Task<IHardwareCapabilities> GetNvidiaCapabilities(string ffmpegPath) |
|
|
|
private async Task<IHardwareCapabilities> GetNvidiaCapabilities(string ffmpegPath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (_memoryCache.TryGetValue(CacheKey, out int cachedArchitecture)) |
|
|
|
if (_memoryCache.TryGetValue(ArchitectureCacheKey, out int cachedArchitecture) |
|
|
|
|
|
|
|
&& _memoryCache.TryGetValue(ModelCacheKey, out string cachedModel)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return new NvidiaHardwareCapabilities(cachedArchitecture); |
|
|
|
return new NvidiaHardwareCapabilities(cachedArchitecture, cachedModel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string[] arguments = |
|
|
|
string[] arguments = |
|
|
|
@ -57,13 +59,20 @@ public class HardwareCapabilitiesFactory : IHardwareCapabilitiesFactory |
|
|
|
Option<string> maybeLine = Optional(output.Split("\n").FirstOrDefault(x => x.Contains("GPU"))); |
|
|
|
Option<string> maybeLine = Optional(output.Split("\n").FirstOrDefault(x => x.Contains("GPU"))); |
|
|
|
foreach (string line in maybeLine) |
|
|
|
foreach (string line in maybeLine) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const string PATTERN = @"SM\s+(\d\.\d)"; |
|
|
|
const string ARCHITECTURE_PATTERN = @"SM\s+(\d\.\d)"; |
|
|
|
Match match = Regex.Match(line, PATTERN); |
|
|
|
Match match = Regex.Match(line, ARCHITECTURE_PATTERN); |
|
|
|
if (match.Success && int.TryParse(match.Groups[1].Value.Replace(".", string.Empty), out int architecture)) |
|
|
|
if (match.Success && int.TryParse(match.Groups[1].Value.Replace(".", string.Empty), out int architecture)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_logger.LogInformation("Detected NVIDIA GPU architecture SM {Architecture}", architecture); |
|
|
|
const string MODEL_PATTERN = @"(GTX\s+[0-9a-zA-Z]+[\sTtIi]+)"; |
|
|
|
_memoryCache.Set(CacheKey, architecture); |
|
|
|
Match modelMatch = Regex.Match(line, MODEL_PATTERN); |
|
|
|
return new NvidiaHardwareCapabilities(architecture); |
|
|
|
string model = modelMatch.Success ? modelMatch.Groups[1].Value.Trim() : "unknown"; |
|
|
|
|
|
|
|
_logger.LogInformation( |
|
|
|
|
|
|
|
"Detected NVIDIA GPU model {Model} architecture SM {Architecture}", |
|
|
|
|
|
|
|
model, |
|
|
|
|
|
|
|
architecture); |
|
|
|
|
|
|
|
_memoryCache.Set(ArchitectureCacheKey, architecture); |
|
|
|
|
|
|
|
_memoryCache.Set(ModelCacheKey, model); |
|
|
|
|
|
|
|
return new NvidiaHardwareCapabilities(architecture, model); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|