Browse Source

Use enums for encoding options (#12561)

Tim Eisele 8 months ago
parent
commit
0d85af019c

+ 2 - 2
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -40,8 +40,8 @@ namespace Jellyfin.Api.Controllers;
 [Authorize]
 public class DynamicHlsController : BaseJellyfinApiController
 {
-    private const string DefaultVodEncoderPreset = "veryfast";
-    private const string DefaultEventEncoderPreset = "superfast";
+    private const EncoderPreset DefaultVodEncoderPreset = EncoderPreset.veryfast;
+    private const EncoderPreset DefaultEventEncoderPreset = EncoderPreset.superfast;
     private const TranscodingJobType TranscodingJobType = MediaBrowser.Controller.MediaEncoding.TranscodingJobType.Hls;
 
     private readonly Version _minFFmpegFlacInMp4 = new Version(6, 0);

+ 1 - 1
Jellyfin.Api/Controllers/VideosController.cs

@@ -482,7 +482,7 @@ public class VideosController : BaseJellyfinApiController
 
         // Need to start ffmpeg (because media can't be returned directly)
         var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
-        var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, "superfast");
+        var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, EncoderPreset.superfast);
         return await FileStreamResponseHelpers.GetTranscodedFile(
             state,
             isHeadRequest,

+ 2 - 1
Jellyfin.Server/Migrations/MigrationRunner.cs

@@ -23,7 +23,8 @@ namespace Jellyfin.Server.Migrations
         {
             typeof(PreStartupRoutines.CreateNetworkConfiguration),
             typeof(PreStartupRoutines.MigrateMusicBrainzTimeout),
-            typeof(PreStartupRoutines.MigrateNetworkConfiguration)
+            typeof(PreStartupRoutines.MigrateNetworkConfiguration),
+            typeof(PreStartupRoutines.MigrateEncodingOptions)
         };
 
         /// <summary>

+ 0 - 1
Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs

@@ -132,5 +132,4 @@ public class CreateNetworkConfiguration : IMigrationRoutine
 
         public string[] KnownProxies { get; set; } = Array.Empty<string>();
     }
-#pragma warning restore
 }

+ 245 - 0
Jellyfin.Server/Migrations/PreStartupRoutines/MigrateEncodingOptions.cs

@@ -0,0 +1,245 @@
+using System;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using Emby.Server.Implementations;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Server.Migrations.PreStartupRoutines;
+
+/// <inheritdoc />
+public class MigrateEncodingOptions : IMigrationRoutine
+{
+    private readonly ServerApplicationPaths _applicationPaths;
+    private readonly ILogger<MigrateEncodingOptions> _logger;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="MigrateEncodingOptions"/> class.
+    /// </summary>
+    /// <param name="applicationPaths">An instance of <see cref="ServerApplicationPaths"/>.</param>
+    /// <param name="loggerFactory">An instance of the <see cref="ILoggerFactory"/> interface.</param>
+    public MigrateEncodingOptions(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory)
+    {
+        _applicationPaths = applicationPaths;
+        _logger = loggerFactory.CreateLogger<MigrateEncodingOptions>();
+    }
+
+    /// <inheritdoc />
+    public Guid Id => Guid.Parse("A8E61960-7726-4450-8F3D-82C12DAABBCB");
+
+    /// <inheritdoc />
+    public string Name => nameof(MigrateEncodingOptions);
+
+    /// <inheritdoc />
+    public bool PerformOnNewInstall => false;
+
+    /// <inheritdoc />
+    public void Perform()
+    {
+        string path = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "encoding.xml");
+        var oldSerializer = new XmlSerializer(typeof(OldEncodingOptions), new XmlRootAttribute("EncodingOptions"));
+        OldEncodingOptions? oldConfig = null;
+
+        try
+        {
+            using var xmlReader = XmlReader.Create(path);
+            oldConfig = (OldEncodingOptions?)oldSerializer.Deserialize(xmlReader);
+        }
+        catch (InvalidOperationException ex)
+        {
+            _logger.LogError(ex, "Migrate EncodingOptions deserialize Invalid Operation error");
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex, "Migrate EncodingOptions deserialize error");
+        }
+
+        if (oldConfig is null)
+        {
+            return;
+        }
+
+        var hardwareAccelerationType = HardwareAccelerationType.none;
+        if (Enum.TryParse<HardwareAccelerationType>(oldConfig.HardwareAccelerationType, true, out var parsedHardwareAccelerationType))
+        {
+            hardwareAccelerationType = parsedHardwareAccelerationType;
+        }
+
+        var tonemappingAlgorithm = TonemappingAlgorithm.none;
+        if (Enum.TryParse<TonemappingAlgorithm>(oldConfig.TonemappingAlgorithm, true, out var parsedTonemappingAlgorithm))
+        {
+            tonemappingAlgorithm = parsedTonemappingAlgorithm;
+        }
+
+        var tonemappingMode = TonemappingMode.auto;
+        if (Enum.TryParse<TonemappingMode>(oldConfig.TonemappingMode, true, out var parsedTonemappingMode))
+        {
+            tonemappingMode = parsedTonemappingMode;
+        }
+
+        var tonemappingRange = TonemappingRange.auto;
+        if (Enum.TryParse<TonemappingRange>(oldConfig.TonemappingRange, true, out var parsedTonemappingRange))
+        {
+            tonemappingRange = parsedTonemappingRange;
+        }
+
+        var encoderPreset = EncoderPreset.superfast;
+        if (Enum.TryParse<EncoderPreset>(oldConfig.TonemappingRange, true, out var parsedEncoderPreset))
+        {
+            encoderPreset = parsedEncoderPreset;
+        }
+
+        var deinterlaceMethod = DeinterlaceMethod.yadif;
+        if (Enum.TryParse<DeinterlaceMethod>(oldConfig.TonemappingRange, true, out var parsedDeinterlaceMethod))
+        {
+            deinterlaceMethod = parsedDeinterlaceMethod;
+        }
+
+        var encodingOptions = new EncodingOptions()
+        {
+            EncodingThreadCount = oldConfig.EncodingThreadCount,
+            TranscodingTempPath = oldConfig.TranscodingTempPath,
+            FallbackFontPath = oldConfig.FallbackFontPath,
+            EnableFallbackFont = oldConfig.EnableFallbackFont,
+            EnableAudioVbr = oldConfig.EnableAudioVbr,
+            DownMixAudioBoost = oldConfig.DownMixAudioBoost,
+            DownMixStereoAlgorithm = oldConfig.DownMixStereoAlgorithm,
+            MaxMuxingQueueSize = oldConfig.MaxMuxingQueueSize,
+            EnableThrottling = oldConfig.EnableThrottling,
+            ThrottleDelaySeconds = oldConfig.ThrottleDelaySeconds,
+            EnableSegmentDeletion = oldConfig.EnableSegmentDeletion,
+            SegmentKeepSeconds = oldConfig.SegmentKeepSeconds,
+            HardwareAccelerationType = hardwareAccelerationType,
+            EncoderAppPath = oldConfig.EncoderAppPath,
+            EncoderAppPathDisplay = oldConfig.EncoderAppPathDisplay,
+            VaapiDevice = oldConfig.VaapiDevice,
+            EnableTonemapping = oldConfig.EnableTonemapping,
+            EnableVppTonemapping = oldConfig.EnableVppTonemapping,
+            EnableVideoToolboxTonemapping = oldConfig.EnableVideoToolboxTonemapping,
+            TonemappingAlgorithm = tonemappingAlgorithm,
+            TonemappingMode = tonemappingMode,
+            TonemappingRange = tonemappingRange,
+            TonemappingDesat = oldConfig.TonemappingDesat,
+            TonemappingPeak = oldConfig.TonemappingPeak,
+            TonemappingParam = oldConfig.TonemappingParam,
+            VppTonemappingBrightness = oldConfig.VppTonemappingBrightness,
+            VppTonemappingContrast = oldConfig.VppTonemappingContrast,
+            H264Crf = oldConfig.H264Crf,
+            H265Crf = oldConfig.H265Crf,
+            EncoderPreset = encoderPreset,
+            DeinterlaceDoubleRate = oldConfig.DeinterlaceDoubleRate,
+            DeinterlaceMethod = deinterlaceMethod,
+            EnableDecodingColorDepth10Hevc = oldConfig.EnableDecodingColorDepth10Hevc,
+            EnableDecodingColorDepth10Vp9 = oldConfig.EnableDecodingColorDepth10Vp9,
+            EnableEnhancedNvdecDecoder = oldConfig.EnableEnhancedNvdecDecoder,
+            PreferSystemNativeHwDecoder = oldConfig.PreferSystemNativeHwDecoder,
+            EnableIntelLowPowerH264HwEncoder = oldConfig.EnableIntelLowPowerH264HwEncoder,
+            EnableIntelLowPowerHevcHwEncoder = oldConfig.EnableIntelLowPowerHevcHwEncoder,
+            EnableHardwareEncoding = oldConfig.EnableHardwareEncoding,
+            AllowHevcEncoding = oldConfig.AllowHevcEncoding,
+            AllowAv1Encoding = oldConfig.AllowAv1Encoding,
+            EnableSubtitleExtraction = oldConfig.EnableSubtitleExtraction,
+            HardwareDecodingCodecs = oldConfig.HardwareDecodingCodecs,
+            AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = oldConfig.AllowOnDemandMetadataBasedKeyframeExtractionForExtensions
+        };
+
+        var newSerializer = new XmlSerializer(typeof(EncodingOptions));
+        var xmlWriterSettings = new XmlWriterSettings { Indent = true };
+        using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings);
+        newSerializer.Serialize(xmlWriter, encodingOptions);
+    }
+
+#pragma warning disable
+    public sealed class OldEncodingOptions
+    {
+        public int EncodingThreadCount { get; set; }
+
+        public string TranscodingTempPath { get; set; }
+
+        public string FallbackFontPath { get; set; }
+
+        public bool EnableFallbackFont { get; set; }
+
+        public bool EnableAudioVbr { get; set; }
+
+        public double DownMixAudioBoost { get; set; }
+
+        public DownMixStereoAlgorithms DownMixStereoAlgorithm { get; set; }
+
+        public int MaxMuxingQueueSize { get; set; }
+
+        public bool EnableThrottling { get; set; }
+
+        public int ThrottleDelaySeconds { get; set; }
+
+        public bool EnableSegmentDeletion { get; set; }
+
+        public int SegmentKeepSeconds { get; set; }
+
+        public string HardwareAccelerationType { get; set; }
+
+        public string EncoderAppPath { get; set; }
+
+        public string EncoderAppPathDisplay { get; set; }
+
+        public string VaapiDevice { get; set; }
+
+        public bool EnableTonemapping { get; set; }
+
+        public bool EnableVppTonemapping { get; set; }
+
+        public bool EnableVideoToolboxTonemapping { get; set; }
+
+        public string TonemappingAlgorithm { get; set; }
+
+        public string TonemappingMode { get; set; }
+
+        public string TonemappingRange { get; set; }
+
+        public double TonemappingDesat { get; set; }
+
+        public double TonemappingPeak { get; set; }
+
+        public double TonemappingParam { get; set; }
+
+        public double VppTonemappingBrightness { get; set; }
+
+        public double VppTonemappingContrast { get; set; }
+
+        public int H264Crf { get; set; }
+
+        public int H265Crf { get; set; }
+
+        public string EncoderPreset { get; set; }
+
+        public bool DeinterlaceDoubleRate { get; set; }
+
+        public string DeinterlaceMethod { get; set; }
+
+        public bool EnableDecodingColorDepth10Hevc { get; set; }
+
+        public bool EnableDecodingColorDepth10Vp9 { get; set; }
+
+        public bool EnableEnhancedNvdecDecoder { get; set; }
+
+        public bool PreferSystemNativeHwDecoder { get; set; }
+
+        public bool EnableIntelLowPowerH264HwEncoder { get; set; }
+
+        public bool EnableIntelLowPowerHevcHwEncoder { get; set; }
+
+        public bool EnableHardwareEncoding { get; set; }
+
+        public bool AllowHevcEncoding { get; set; }
+
+        public bool AllowAv1Encoding { get; set; }
+
+        public bool EnableSubtitleExtraction { get; set; }
+
+        public string[] HardwareDecodingCodecs { get; set; }
+
+        public string[] AllowOnDemandMetadataBasedKeyframeExtractionForExtensions { get; set; }
+    }
+}

+ 5 - 5
Jellyfin.Server/Migrations/PreStartupRoutines/MigrateMusicBrainzTimeout.cs

@@ -48,9 +48,11 @@ public class MigrateMusicBrainzTimeout : IMigrationRoutine
 
         if (oldPluginConfiguration is not null)
         {
-            var newPluginConfiguration = new PluginConfiguration();
-            newPluginConfiguration.Server = oldPluginConfiguration.Server;
-            newPluginConfiguration.ReplaceArtistName = oldPluginConfiguration.ReplaceArtistName;
+            var newPluginConfiguration = new PluginConfiguration
+            {
+                Server = oldPluginConfiguration.Server,
+                ReplaceArtistName = oldPluginConfiguration.ReplaceArtistName
+            };
             var newRateLimit = oldPluginConfiguration.RateLimit / 1000.0;
             newPluginConfiguration.RateLimit = newRateLimit < 1.0 ? 1.0 : newRateLimit;
             WriteNew(path, newPluginConfiguration);
@@ -93,6 +95,4 @@ public class MigrateMusicBrainzTimeout : IMigrationRoutine
 
         public bool ReplaceArtistName { get; set; }
     }
-#pragma warning restore
-
 }

+ 44 - 41
Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs

@@ -55,49 +55,53 @@ public class MigrateNetworkConfiguration : IMigrationRoutine
             _logger.LogError(ex, "Migrate NetworkConfiguration deserialize error");
         }
 
-        if (oldNetworkConfiguration is not null)
+        if (oldNetworkConfiguration is null)
         {
-            // Migrate network config values to new config schema
-            var networkConfiguration = new NetworkConfiguration();
-            networkConfiguration.AutoDiscovery = oldNetworkConfiguration.AutoDiscovery;
-            networkConfiguration.BaseUrl = oldNetworkConfiguration.BaseUrl;
-            networkConfiguration.CertificatePassword = oldNetworkConfiguration.CertificatePassword;
-            networkConfiguration.CertificatePath = oldNetworkConfiguration.CertificatePath;
-            networkConfiguration.EnableHttps = oldNetworkConfiguration.EnableHttps;
-            networkConfiguration.EnableIPv4 = oldNetworkConfiguration.EnableIPV4;
-            networkConfiguration.EnableIPv6 = oldNetworkConfiguration.EnableIPV6;
-            networkConfiguration.EnablePublishedServerUriByRequest = oldNetworkConfiguration.EnablePublishedServerUriByRequest;
-            networkConfiguration.EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess;
-            networkConfiguration.EnableUPnP = oldNetworkConfiguration.EnableUPnP;
-            networkConfiguration.IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces;
-            networkConfiguration.InternalHttpPort = oldNetworkConfiguration.HttpServerPortNumber;
-            networkConfiguration.InternalHttpsPort = oldNetworkConfiguration.HttpsPortNumber;
-            networkConfiguration.IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist;
-            networkConfiguration.KnownProxies = oldNetworkConfiguration.KnownProxies;
-            networkConfiguration.LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses;
-            networkConfiguration.LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets;
-            networkConfiguration.PublicHttpPort = oldNetworkConfiguration.PublicPort;
-            networkConfiguration.PublicHttpsPort = oldNetworkConfiguration.PublicHttpsPort;
-            networkConfiguration.PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet;
-            networkConfiguration.RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter;
-            networkConfiguration.RequireHttps = oldNetworkConfiguration.RequireHttps;
-
-            // Migrate old virtual interface name schema
-            var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames;
-            if (oldVirtualInterfaceNames.Equals("vEthernet*", StringComparison.OrdinalIgnoreCase))
-            {
-                networkConfiguration.VirtualInterfaceNames = new string[] { "veth" };
-            }
-            else
-            {
-                networkConfiguration.VirtualInterfaceNames = oldVirtualInterfaceNames.Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase).Split(',');
-            }
+            return;
+        }
 
-            var networkConfigSerializer = new XmlSerializer(typeof(NetworkConfiguration));
-            var xmlWriterSettings = new XmlWriterSettings { Indent = true };
-            using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings);
-            networkConfigSerializer.Serialize(xmlWriter, networkConfiguration);
+        // Migrate network config values to new config schema
+        var networkConfiguration = new NetworkConfiguration
+        {
+            AutoDiscovery = oldNetworkConfiguration.AutoDiscovery,
+            BaseUrl = oldNetworkConfiguration.BaseUrl,
+            CertificatePassword = oldNetworkConfiguration.CertificatePassword,
+            CertificatePath = oldNetworkConfiguration.CertificatePath,
+            EnableHttps = oldNetworkConfiguration.EnableHttps,
+            EnableIPv4 = oldNetworkConfiguration.EnableIPV4,
+            EnableIPv6 = oldNetworkConfiguration.EnableIPV6,
+            EnablePublishedServerUriByRequest = oldNetworkConfiguration.EnablePublishedServerUriByRequest,
+            EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess,
+            EnableUPnP = oldNetworkConfiguration.EnableUPnP,
+            IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces,
+            InternalHttpPort = oldNetworkConfiguration.HttpServerPortNumber,
+            InternalHttpsPort = oldNetworkConfiguration.HttpsPortNumber,
+            IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist,
+            KnownProxies = oldNetworkConfiguration.KnownProxies,
+            LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses,
+            LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets,
+            PublicHttpPort = oldNetworkConfiguration.PublicPort,
+            PublicHttpsPort = oldNetworkConfiguration.PublicHttpsPort,
+            PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet,
+            RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter,
+            RequireHttps = oldNetworkConfiguration.RequireHttps
+        };
+
+        // Migrate old virtual interface name schema
+        var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames;
+        if (oldVirtualInterfaceNames.Equals("vEthernet*", StringComparison.OrdinalIgnoreCase))
+        {
+            networkConfiguration.VirtualInterfaceNames = new string[] { "veth" };
         }
+        else
+        {
+            networkConfiguration.VirtualInterfaceNames = oldVirtualInterfaceNames.Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase).Split(',');
+        }
+
+        var networkConfigSerializer = new XmlSerializer(typeof(NetworkConfiguration));
+        var xmlWriterSettings = new XmlWriterSettings { Indent = true };
+        using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings);
+        networkConfigSerializer.Serialize(xmlWriter, networkConfiguration);
     }
 
 #pragma warning disable
@@ -204,5 +208,4 @@ public class MigrateNetworkConfiguration : IMigrationRoutine
 
         public bool EnablePublishedServerUriByRequest { get; set; } = false;
     }
-#pragma warning restore
 }

File diff suppressed because it is too large
+ 257 - 333
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs


+ 9 - 8
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -224,7 +224,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 if (OperatingSystem.IsLinux()
                     && SupportsHwaccel("vaapi")
                     && !string.IsNullOrEmpty(options.VaapiDevice)
-                    && string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
+                    && options.HardwareAccelerationType == HardwareAccelerationType.vaapi)
                 {
                     _isVaapiDeviceAmd = validator.CheckVaapiDeviceByDriverName("Mesa Gallium driver", options.VaapiDevice);
                     _isVaapiDeviceInteliHD = validator.CheckVaapiDeviceByDriverName("Intel iHD driver", options.VaapiDevice);
@@ -799,11 +799,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
             if (allowHwAccel && enableKeyFrameOnlyExtraction)
             {
-                var supportsKeyFrameOnly = (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase) && options.EnableEnhancedNvdecDecoder)
-                                           || (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase) && OperatingSystem.IsWindows())
-                                           || (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) && options.PreferSystemNativeHwDecoder)
-                                           || string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
-                                           || string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase);
+                var hardwareAccelerationType = options.HardwareAccelerationType;
+                var supportsKeyFrameOnly = (hardwareAccelerationType == HardwareAccelerationType.nvenc && options.EnableEnhancedNvdecDecoder)
+                                           || (hardwareAccelerationType == HardwareAccelerationType.amf && OperatingSystem.IsWindows())
+                                           || (hardwareAccelerationType == HardwareAccelerationType.qsv && options.PreferSystemNativeHwDecoder)
+                                           || hardwareAccelerationType == HardwareAccelerationType.vaapi
+                                           || hardwareAccelerationType == HardwareAccelerationType.videotoolbox;
                 if (!supportsKeyFrameOnly)
                 {
                     // Disable hardware acceleration when the hardware decoder does not support keyframe only mode.
@@ -817,7 +818,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             if (!allowHwAccel)
             {
                 options.EnableHardwareEncoding = false;
-                options.HardwareAccelerationType = string.Empty;
+                options.HardwareAccelerationType = HardwareAccelerationType.none;
                 options.EnableTonemapping = false;
             }
 
@@ -861,7 +862,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 inputArg = "-threads " + threads + " " + inputArg; // HW accel args set a different input thread count, only set if disabled
             }
 
-            if (options.HardwareAccelerationType.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase) && _isLowPriorityHwDecodeSupported)
+            if (options.HardwareAccelerationType == HardwareAccelerationType.videotoolbox && _isLowPriorityHwDecodeSupported)
             {
                 // VideoToolbox supports low priority decoding, which is useful for trickplay
                 inputArg = "-hwaccel_flags +low_priority " + inputArg;

+ 1 - 6
MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs

@@ -352,12 +352,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
         {
             var audioCodec = state.ActualOutputAudioCodec;
             var videoCodec = state.ActualOutputVideoCodec;
-            var hardwareAccelerationTypeString = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
-            HardwareEncodingType? hardwareAccelerationType = null;
-            if (Enum.TryParse<HardwareEncodingType>(hardwareAccelerationTypeString, out var parsedHardwareAccelerationType))
-            {
-                hardwareAccelerationType = parsedHardwareAccelerationType;
-            }
+            var hardwareAccelerationType = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
 
             _sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
             {

+ 14 - 12
MediaBrowser.Model/Configuration/EncodingOptions.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CA1819 // XML serialization handles collections improperly, so we need to use arrays
+
 #nullable disable
 using MediaBrowser.Model.Entities;
 
@@ -30,9 +32,9 @@ public class EncodingOptions
         EnableTonemapping = false;
         EnableVppTonemapping = false;
         EnableVideoToolboxTonemapping = false;
-        TonemappingAlgorithm = "bt2390";
-        TonemappingMode = "auto";
-        TonemappingRange = "auto";
+        TonemappingAlgorithm = TonemappingAlgorithm.bt2390;
+        TonemappingMode = TonemappingMode.auto;
+        TonemappingRange = TonemappingRange.auto;
         TonemappingDesat = 0;
         TonemappingPeak = 100;
         TonemappingParam = 0;
@@ -41,7 +43,7 @@ public class EncodingOptions
         H264Crf = 23;
         H265Crf = 28;
         DeinterlaceDoubleRate = false;
-        DeinterlaceMethod = "yadif";
+        DeinterlaceMethod = DeinterlaceMethod.yadif;
         EnableDecodingColorDepth10Hevc = true;
         EnableDecodingColorDepth10Vp9 = true;
         // Enhanced Nvdec or system native decoder is required for DoVi to SDR tone-mapping.
@@ -53,8 +55,8 @@ public class EncodingOptions
         AllowHevcEncoding = false;
         AllowAv1Encoding = false;
         EnableSubtitleExtraction = true;
-        AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" };
-        HardwareDecodingCodecs = new string[] { "h264", "vc1" };
+        AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = ["mkv"];
+        HardwareDecodingCodecs = ["h264", "vc1"];
     }
 
     /// <summary>
@@ -120,7 +122,7 @@ public class EncodingOptions
     /// <summary>
     /// Gets or sets the hardware acceleration type.
     /// </summary>
-    public string HardwareAccelerationType { get; set; }
+    public HardwareAccelerationType HardwareAccelerationType { get; set; }
 
     /// <summary>
     /// Gets or sets the FFmpeg path as set by the user via the UI.
@@ -160,17 +162,17 @@ public class EncodingOptions
     /// <summary>
     /// Gets or sets the tone-mapping algorithm.
     /// </summary>
-    public string TonemappingAlgorithm { get; set; }
+    public TonemappingAlgorithm TonemappingAlgorithm { get; set; }
 
     /// <summary>
     /// Gets or sets the tone-mapping mode.
     /// </summary>
-    public string TonemappingMode { get; set; }
+    public TonemappingMode TonemappingMode { get; set; }
 
     /// <summary>
     /// Gets or sets the tone-mapping range.
     /// </summary>
-    public string TonemappingRange { get; set; }
+    public TonemappingRange TonemappingRange { get; set; }
 
     /// <summary>
     /// Gets or sets the tone-mapping desaturation.
@@ -210,7 +212,7 @@ public class EncodingOptions
     /// <summary>
     /// Gets or sets the encoder preset.
     /// </summary>
-    public string EncoderPreset { get; set; }
+    public EncoderPreset? EncoderPreset { get; set; }
 
     /// <summary>
     /// Gets or sets a value indicating whether the framerate is doubled when deinterlacing.
@@ -220,7 +222,7 @@ public class EncodingOptions
     /// <summary>
     /// Gets or sets the deinterlace method.
     /// </summary>
-    public string DeinterlaceMethod { get; set; }
+    public DeinterlaceMethod DeinterlaceMethod { get; set; }
 
     /// <summary>
     /// Gets or sets a value indicating whether 10bit HEVC decoding is enabled.

+ 19 - 0
MediaBrowser.Model/Entities/DeinterlaceMethod.cs

@@ -0,0 +1,19 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing deinterlace methods.
+/// </summary>
+public enum DeinterlaceMethod
+{
+    /// <summary>
+    /// YADIF.
+    /// </summary>
+    yadif = 0,
+
+    /// <summary>
+    /// BWDIF.
+    /// </summary>
+    bwdif = 1
+}

+ 64 - 0
MediaBrowser.Model/Entities/EncoderPreset.cs

@@ -0,0 +1,64 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing encoder presets.
+/// </summary>
+public enum EncoderPreset
+{
+    /// <summary>
+    /// Auto preset.
+    /// </summary>
+    auto = 0,
+
+    /// <summary>
+    /// Placebo preset.
+    /// </summary>
+    placebo = 1,
+
+    /// <summary>
+    /// Veryslow preset.
+    /// </summary>
+    veryslow = 2,
+
+    /// <summary>
+    /// Slower preset.
+    /// </summary>
+    slower = 3,
+
+    /// <summary>
+    /// Slow preset.
+    /// </summary>
+    slow = 4,
+
+    /// <summary>
+    /// Medium preset.
+    /// </summary>
+    medium = 5,
+
+    /// <summary>
+    /// Fast preset.
+    /// </summary>
+    fast = 6,
+
+    /// <summary>
+    /// Faster preset.
+    /// </summary>
+    faster = 7,
+
+    /// <summary>
+    /// Veryfast preset.
+    /// </summary>
+    veryfast = 8,
+
+    /// <summary>
+    /// Superfast preset.
+    /// </summary>
+    superfast = 9,
+
+    /// <summary>
+    /// Ultrafast preset.
+    /// </summary>
+    ultrafast = 10
+}

+ 49 - 0
MediaBrowser.Model/Entities/HardwareAccelerationType.cs

@@ -0,0 +1,49 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing hardware acceleration types.
+/// </summary>
+public enum HardwareAccelerationType
+{
+    /// <summary>
+    /// Software accelleration.
+    /// </summary>
+    none = 0,
+
+    /// <summary>
+    /// AMD AMF.
+    /// </summary>
+    amf = 1,
+
+    /// <summary>
+    /// Intel Quick Sync Video.
+    /// </summary>
+    qsv = 2,
+
+    /// <summary>
+    /// NVIDIA NVENC.
+    /// </summary>
+    nvenc = 3,
+
+    /// <summary>
+    /// Video4Linux2 V4L2M2M.
+    /// </summary>
+    v4l2m2m = 4,
+
+    /// <summary>
+    /// Video Acceleration API (VAAPI).
+    /// </summary>
+    vaapi = 5,
+
+    /// <summary>
+    /// Video ToolBox.
+    /// </summary>
+    videotoolbox = 6,
+
+    /// <summary>
+    /// Rockchip Media Process Platform (RKMPP).
+    /// </summary>
+    rkmpp = 7
+}

+ 49 - 0
MediaBrowser.Model/Entities/TonemappingAlgorithm.cs

@@ -0,0 +1,49 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing tonemapping algorithms.
+/// </summary>
+public enum TonemappingAlgorithm
+{
+    /// <summary>
+    /// None.
+    /// </summary>
+    none = 0,
+
+    /// <summary>
+    /// Clip.
+    /// </summary>
+    clip = 1,
+
+    /// <summary>
+    /// Linear.
+    /// </summary>
+    linear = 2,
+
+    /// <summary>
+    /// Gamma.
+    /// </summary>
+    gamma = 3,
+
+    /// <summary>
+    /// Reinhard.
+    /// </summary>
+    reinhard = 4,
+
+    /// <summary>
+    /// Hable.
+    /// </summary>
+    hable = 5,
+
+    /// <summary>
+    /// Mobius.
+    /// </summary>
+    mobius = 6,
+
+    /// <summary>
+    /// BT2390.
+    /// </summary>
+    bt2390 = 7
+}

+ 34 - 0
MediaBrowser.Model/Entities/TonemappingMode.cs

@@ -0,0 +1,34 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing tonemapping modes.
+/// </summary>
+public enum TonemappingMode
+{
+    /// <summary>
+    /// Auto.
+    /// </summary>
+    auto = 0,
+
+    /// <summary>
+    /// Max.
+    /// </summary>
+    max = 1,
+
+    /// <summary>
+    /// RGB.
+    /// </summary>
+    rgb = 2,
+
+    /// <summary>
+    /// Lum.
+    /// </summary>
+    lum = 3,
+
+    /// <summary>
+    /// ITP.
+    /// </summary>
+    itp = 4
+}

+ 24 - 0
MediaBrowser.Model/Entities/TonemappingRange.cs

@@ -0,0 +1,24 @@
+#pragma warning disable SA1300 // Lowercase required for backwards compat.
+
+namespace MediaBrowser.Model.Entities;
+
+/// <summary>
+/// Enum containing tonemapping ranges.
+/// </summary>
+public enum TonemappingRange
+{
+    /// <summary>
+    /// Auto.
+    /// </summary>
+    auto = 0,
+
+    /// <summary>
+    /// TV.
+    /// </summary>
+    tv = 1,
+
+    /// <summary>
+    /// PC.
+    /// </summary>
+    pc = 2
+}

+ 0 - 43
MediaBrowser.Model/Session/HardwareEncodingType.cs

@@ -1,43 +0,0 @@
-namespace MediaBrowser.Model.Session
-{
-    /// <summary>
-    /// Enum HardwareEncodingType.
-    /// </summary>
-    public enum HardwareEncodingType
-    {
-        /// <summary>
-        /// AMD AMF.
-        /// </summary>
-        AMF = 0,
-
-        /// <summary>
-        /// Intel Quick Sync Video.
-        /// </summary>
-        QSV = 1,
-
-        /// <summary>
-        /// NVIDIA NVENC.
-        /// </summary>
-        NVENC = 2,
-
-        /// <summary>
-        /// Video4Linux2 V4L2.
-        /// </summary>
-        V4L2M2M = 3,
-
-        /// <summary>
-        /// Video Acceleration API (VAAPI).
-        /// </summary>
-        VAAPI = 4,
-
-        /// <summary>
-        /// Video ToolBox.
-        /// </summary>
-        VideoToolBox = 5,
-
-        /// <summary>
-        /// Rockchip Media Process Platform (RKMPP).
-        /// </summary>
-        RKMPP = 6
-    }
-}

+ 60 - 18
MediaBrowser.Model/Session/TranscodingInfo.cs

@@ -1,34 +1,76 @@
 #nullable disable
-#pragma warning disable CS1591
 
-namespace MediaBrowser.Model.Session
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.Session;
+
+/// <summary>
+/// Class holding information on a runnning transcode.
+/// </summary>
+public class TranscodingInfo
 {
-    public class TranscodingInfo
-    {
-        public string AudioCodec { get; set; }
+    /// <summary>
+    /// Gets or sets the thread count used for encoding.
+    /// </summary>
+    public string AudioCodec { get; set; }
 
-        public string VideoCodec { get; set; }
+    /// <summary>
+    /// Gets or sets the thread count used for encoding.
+    /// </summary>
+    public string VideoCodec { get; set; }
 
-        public string Container { get; set; }
+    /// <summary>
+    /// Gets or sets the thread count used for encoding.
+    /// </summary>
+    public string Container { get; set; }
 
-        public bool IsVideoDirect { get; set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether the video is passed through.
+    /// </summary>
+    public bool IsVideoDirect { get; set; }
 
-        public bool IsAudioDirect { get; set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether the audio is passed through.
+    /// </summary>
+    public bool IsAudioDirect { get; set; }
 
-        public int? Bitrate { get; set; }
+    /// <summary>
+    /// Gets or sets the bitrate.
+    /// </summary>
+    public int? Bitrate { get; set; }
 
-        public float? Framerate { get; set; }
+    /// <summary>
+    /// Gets or sets the framerate.
+    /// </summary>
+    public float? Framerate { get; set; }
 
-        public double? CompletionPercentage { get; set; }
+    /// <summary>
+    /// Gets or sets the completion percentage.
+    /// </summary>
+    public double? CompletionPercentage { get; set; }
 
-        public int? Width { get; set; }
+    /// <summary>
+    /// Gets or sets the video width.
+    /// </summary>
+    public int? Width { get; set; }
 
-        public int? Height { get; set; }
+    /// <summary>
+    /// Gets or sets the video height.
+    /// </summary>
+    public int? Height { get; set; }
 
-        public int? AudioChannels { get; set; }
+    /// <summary>
+    /// Gets or sets the audio channels.
+    /// </summary>
+    public int? AudioChannels { get; set; }
 
-        public HardwareEncodingType? HardwareAccelerationType { get; set; }
+    /// <summary>
+    /// Gets or sets the hardware acceleration type.
+    /// </summary>
+    public HardwareAccelerationType? HardwareAccelerationType { get; set; }
 
-        public TranscodeReason TranscodeReasons { get; set; }
-    }
+    /// <summary>
+    /// Gets or sets the transcode reasons.
+    /// </summary>
+    public TranscodeReason TranscodeReasons { get; set; }
 }

+ 2 - 2
src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs

@@ -128,7 +128,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
         return false;
     }
 
-    internal static bool IsExtractionAllowedForFile(ReadOnlySpan<char> filePath, string[] allowedExtensions)
+    internal static bool IsExtractionAllowedForFile(ReadOnlySpan<char> filePath, IReadOnlyList<string> allowedExtensions)
     {
         var extension = Path.GetExtension(filePath);
         if (extension.IsEmpty)
@@ -138,7 +138,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
 
         // Remove the leading dot
         var extensionWithoutDot = extension[1..];
-        for (var i = 0; i < allowedExtensions.Length; i++)
+        for (var i = 0; i < allowedExtensions.Count; i++)
         {
             var allowedExtension = allowedExtensions[i].AsSpan().TrimStart('.');
             if (extensionWithoutDot.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))

Some files were not shown because too many files changed in this diff