Browse Source

fix nvidia capabilities for second-gen maxwell (#899)

pull/900/head
Jason Dove 4 years ago committed by GitHub
parent
commit
4176df9940
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs
  3. 25
      ErsatzTV.FFmpeg/Capabilities/HardwareCapabilitiesFactory.cs
  4. 16
      ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs

1
CHANGELOG.md

@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- Fix subtitle stream selection when subtitle language is different than audio language - Fix subtitle stream selection when subtitle language is different than audio language
- Fix bug with unsupported AAC channel layouts - Fix bug with unsupported AAC channel layouts
- Fix NVIDIA second-gen maxwell capabilities detection
### Added ### Added
- Add `640x480` resolution - Add `640x480` resolution

2
ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs

@ -585,7 +585,7 @@ public class TranscodingTests
public Task<IHardwareCapabilities> GetHardwareCapabilities( public Task<IHardwareCapabilities> GetHardwareCapabilities(
string ffmpegPath, string ffmpegPath,
HardwareAccelerationMode hardwareAccelerationMode) => HardwareAccelerationMode hardwareAccelerationMode) =>
Task.FromResult<IHardwareCapabilities>(new NvidiaHardwareCapabilities(61)); Task.FromResult<IHardwareCapabilities>(new NvidiaHardwareCapabilities(61, string.Empty));
} }
private static string ExecutableName(string baseName) => private static string ExecutableName(string baseName) =>

25
ErsatzTV.FFmpeg/Capabilities/HardwareCapabilitiesFactory.cs

@ -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);
} }
} }

16
ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs

@ -5,8 +5,14 @@ namespace ErsatzTV.FFmpeg.Capabilities;
public class NvidiaHardwareCapabilities : IHardwareCapabilities public class NvidiaHardwareCapabilities : IHardwareCapabilities
{ {
private readonly int _architecture; private readonly int _architecture;
private readonly List<string> _maxwellGm206 = new() { "GTX 750", "GTX 950", "GTX 960", "GTX 965M" };
private readonly string _model;
public NvidiaHardwareCapabilities(int architecture) => _architecture = architecture; public NvidiaHardwareCapabilities(int architecture, string model)
{
_architecture = architecture;
_model = model;
}
public bool CanDecode(string videoFormat, Option<IPixelFormat> maybePixelFormat) public bool CanDecode(string videoFormat, Option<IPixelFormat> maybePixelFormat)
{ {
@ -14,14 +20,14 @@ public class NvidiaHardwareCapabilities : IHardwareCapabilities
return videoFormat switch return videoFormat switch
{ {
// second gen maxwell is required to decode hevc // some second gen maxwell can decode hevc, otherwise pascal is required
VideoFormat.Hevc => _architecture >= 52, VideoFormat.Hevc => _architecture == 52 && _maxwellGm206.Contains(_model) || _architecture >= 60,
// pascal is required to decode vp9 10-bit // pascal is required to decode vp9 10-bit
VideoFormat.Vp9 when bitDepth == 10 => _architecture >= 60, VideoFormat.Vp9 when bitDepth == 10 => _architecture >= 60,
// second gen maxwell is required to decode vp9 // some second gen maxwell can decode vp9, otherwise pascal is required
VideoFormat.Vp9 => _architecture >= 52, VideoFormat.Vp9 => _architecture == 52 && _maxwellGm206.Contains(_model) || _architecture >= 60,
_ => true _ => true
}; };

Loading…
Cancel
Save