mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Use enums for encoding options (#12561)
This commit is contained in:
parent
54f663b0f3
commit
0d85af019c
@ -40,8 +40,8 @@ namespace Jellyfin.Api.Controllers;
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
public class DynamicHlsController : BaseJellyfinApiController
|
public class DynamicHlsController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
private const string DefaultVodEncoderPreset = "veryfast";
|
private const EncoderPreset DefaultVodEncoderPreset = EncoderPreset.veryfast;
|
||||||
private const string DefaultEventEncoderPreset = "superfast";
|
private const EncoderPreset DefaultEventEncoderPreset = EncoderPreset.superfast;
|
||||||
private const TranscodingJobType TranscodingJobType = MediaBrowser.Controller.MediaEncoding.TranscodingJobType.Hls;
|
private const TranscodingJobType TranscodingJobType = MediaBrowser.Controller.MediaEncoding.TranscodingJobType.Hls;
|
||||||
|
|
||||||
private readonly Version _minFFmpegFlacInMp4 = new Version(6, 0);
|
private readonly Version _minFFmpegFlacInMp4 = new Version(6, 0);
|
||||||
|
@ -482,7 +482,7 @@ public class VideosController : BaseJellyfinApiController
|
|||||||
|
|
||||||
// Need to start ffmpeg (because media can't be returned directly)
|
// Need to start ffmpeg (because media can't be returned directly)
|
||||||
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
||||||
var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, "superfast");
|
var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, EncoderPreset.superfast);
|
||||||
return await FileStreamResponseHelpers.GetTranscodedFile(
|
return await FileStreamResponseHelpers.GetTranscodedFile(
|
||||||
state,
|
state,
|
||||||
isHeadRequest,
|
isHeadRequest,
|
||||||
|
@ -23,7 +23,8 @@ namespace Jellyfin.Server.Migrations
|
|||||||
{
|
{
|
||||||
typeof(PreStartupRoutines.CreateNetworkConfiguration),
|
typeof(PreStartupRoutines.CreateNetworkConfiguration),
|
||||||
typeof(PreStartupRoutines.MigrateMusicBrainzTimeout),
|
typeof(PreStartupRoutines.MigrateMusicBrainzTimeout),
|
||||||
typeof(PreStartupRoutines.MigrateNetworkConfiguration)
|
typeof(PreStartupRoutines.MigrateNetworkConfiguration),
|
||||||
|
typeof(PreStartupRoutines.MigrateEncodingOptions)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -132,5 +132,4 @@ public class CreateNetworkConfiguration : IMigrationRoutine
|
|||||||
|
|
||||||
public string[] KnownProxies { get; set; } = Array.Empty<string>();
|
public string[] KnownProxies { get; set; } = Array.Empty<string>();
|
||||||
}
|
}
|
||||||
#pragma warning restore
|
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
@ -48,9 +48,11 @@ public class MigrateMusicBrainzTimeout : IMigrationRoutine
|
|||||||
|
|
||||||
if (oldPluginConfiguration is not null)
|
if (oldPluginConfiguration is not null)
|
||||||
{
|
{
|
||||||
var newPluginConfiguration = new PluginConfiguration();
|
var newPluginConfiguration = new PluginConfiguration
|
||||||
newPluginConfiguration.Server = oldPluginConfiguration.Server;
|
{
|
||||||
newPluginConfiguration.ReplaceArtistName = oldPluginConfiguration.ReplaceArtistName;
|
Server = oldPluginConfiguration.Server,
|
||||||
|
ReplaceArtistName = oldPluginConfiguration.ReplaceArtistName
|
||||||
|
};
|
||||||
var newRateLimit = oldPluginConfiguration.RateLimit / 1000.0;
|
var newRateLimit = oldPluginConfiguration.RateLimit / 1000.0;
|
||||||
newPluginConfiguration.RateLimit = newRateLimit < 1.0 ? 1.0 : newRateLimit;
|
newPluginConfiguration.RateLimit = newRateLimit < 1.0 ? 1.0 : newRateLimit;
|
||||||
WriteNew(path, newPluginConfiguration);
|
WriteNew(path, newPluginConfiguration);
|
||||||
@ -93,6 +95,4 @@ public class MigrateMusicBrainzTimeout : IMigrationRoutine
|
|||||||
|
|
||||||
public bool ReplaceArtistName { get; set; }
|
public bool ReplaceArtistName { get; set; }
|
||||||
}
|
}
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,32 +55,37 @@ public class MigrateNetworkConfiguration : IMigrationRoutine
|
|||||||
_logger.LogError(ex, "Migrate NetworkConfiguration deserialize error");
|
_logger.LogError(ex, "Migrate NetworkConfiguration deserialize error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldNetworkConfiguration is not null)
|
if (oldNetworkConfiguration is null)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Migrate network config values to new config schema
|
// Migrate network config values to new config schema
|
||||||
var networkConfiguration = new NetworkConfiguration();
|
var networkConfiguration = new NetworkConfiguration
|
||||||
networkConfiguration.AutoDiscovery = oldNetworkConfiguration.AutoDiscovery;
|
{
|
||||||
networkConfiguration.BaseUrl = oldNetworkConfiguration.BaseUrl;
|
AutoDiscovery = oldNetworkConfiguration.AutoDiscovery,
|
||||||
networkConfiguration.CertificatePassword = oldNetworkConfiguration.CertificatePassword;
|
BaseUrl = oldNetworkConfiguration.BaseUrl,
|
||||||
networkConfiguration.CertificatePath = oldNetworkConfiguration.CertificatePath;
|
CertificatePassword = oldNetworkConfiguration.CertificatePassword,
|
||||||
networkConfiguration.EnableHttps = oldNetworkConfiguration.EnableHttps;
|
CertificatePath = oldNetworkConfiguration.CertificatePath,
|
||||||
networkConfiguration.EnableIPv4 = oldNetworkConfiguration.EnableIPV4;
|
EnableHttps = oldNetworkConfiguration.EnableHttps,
|
||||||
networkConfiguration.EnableIPv6 = oldNetworkConfiguration.EnableIPV6;
|
EnableIPv4 = oldNetworkConfiguration.EnableIPV4,
|
||||||
networkConfiguration.EnablePublishedServerUriByRequest = oldNetworkConfiguration.EnablePublishedServerUriByRequest;
|
EnableIPv6 = oldNetworkConfiguration.EnableIPV6,
|
||||||
networkConfiguration.EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess;
|
EnablePublishedServerUriByRequest = oldNetworkConfiguration.EnablePublishedServerUriByRequest,
|
||||||
networkConfiguration.EnableUPnP = oldNetworkConfiguration.EnableUPnP;
|
EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess,
|
||||||
networkConfiguration.IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces;
|
EnableUPnP = oldNetworkConfiguration.EnableUPnP,
|
||||||
networkConfiguration.InternalHttpPort = oldNetworkConfiguration.HttpServerPortNumber;
|
IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces,
|
||||||
networkConfiguration.InternalHttpsPort = oldNetworkConfiguration.HttpsPortNumber;
|
InternalHttpPort = oldNetworkConfiguration.HttpServerPortNumber,
|
||||||
networkConfiguration.IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist;
|
InternalHttpsPort = oldNetworkConfiguration.HttpsPortNumber,
|
||||||
networkConfiguration.KnownProxies = oldNetworkConfiguration.KnownProxies;
|
IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist,
|
||||||
networkConfiguration.LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses;
|
KnownProxies = oldNetworkConfiguration.KnownProxies,
|
||||||
networkConfiguration.LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets;
|
LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses,
|
||||||
networkConfiguration.PublicHttpPort = oldNetworkConfiguration.PublicPort;
|
LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets,
|
||||||
networkConfiguration.PublicHttpsPort = oldNetworkConfiguration.PublicHttpsPort;
|
PublicHttpPort = oldNetworkConfiguration.PublicPort,
|
||||||
networkConfiguration.PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet;
|
PublicHttpsPort = oldNetworkConfiguration.PublicHttpsPort,
|
||||||
networkConfiguration.RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter;
|
PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet,
|
||||||
networkConfiguration.RequireHttps = oldNetworkConfiguration.RequireHttps;
|
RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter,
|
||||||
|
RequireHttps = oldNetworkConfiguration.RequireHttps
|
||||||
|
};
|
||||||
|
|
||||||
// Migrate old virtual interface name schema
|
// Migrate old virtual interface name schema
|
||||||
var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames;
|
var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames;
|
||||||
@ -98,7 +103,6 @@ public class MigrateNetworkConfiguration : IMigrationRoutine
|
|||||||
using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings);
|
using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings);
|
||||||
networkConfigSerializer.Serialize(xmlWriter, networkConfiguration);
|
networkConfigSerializer.Serialize(xmlWriter, networkConfiguration);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning disable
|
#pragma warning disable
|
||||||
public sealed class OldNetworkConfiguration
|
public sealed class OldNetworkConfiguration
|
||||||
@ -204,5 +208,4 @@ public class MigrateNetworkConfiguration : IMigrationRoutine
|
|||||||
|
|
||||||
public bool EnablePublishedServerUriByRequest { get; set; } = false;
|
public bool EnablePublishedServerUriByRequest { get; set; } = false;
|
||||||
}
|
}
|
||||||
#pragma warning restore
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string ValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$";
|
public const string ValidationRegex = @"^[a-zA-Z0-9\-\._,|]{0,40}$";
|
||||||
|
|
||||||
|
private const string _defaultMjpegEncoder = "mjpeg";
|
||||||
|
|
||||||
private const string QsvAlias = "qs";
|
private const string QsvAlias = "qs";
|
||||||
private const string VaapiAlias = "va";
|
private const string VaapiAlias = "va";
|
||||||
private const string D3d11vaAlias = "dx11";
|
private const string D3d11vaAlias = "dx11";
|
||||||
@ -72,8 +74,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled);
|
private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly string[] _videoProfilesH264 = new[]
|
private static readonly string[] _videoProfilesH264 =
|
||||||
{
|
[
|
||||||
"ConstrainedBaseline",
|
"ConstrainedBaseline",
|
||||||
"Baseline",
|
"Baseline",
|
||||||
"Extended",
|
"Extended",
|
||||||
@ -82,20 +84,20 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
"ProgressiveHigh",
|
"ProgressiveHigh",
|
||||||
"ConstrainedHigh",
|
"ConstrainedHigh",
|
||||||
"High10"
|
"High10"
|
||||||
};
|
];
|
||||||
|
|
||||||
private static readonly string[] _videoProfilesH265 = new[]
|
private static readonly string[] _videoProfilesH265 =
|
||||||
{
|
[
|
||||||
"Main",
|
"Main",
|
||||||
"Main10"
|
"Main10"
|
||||||
};
|
];
|
||||||
|
|
||||||
private static readonly string[] _videoProfilesAv1 = new[]
|
private static readonly string[] _videoProfilesAv1 =
|
||||||
{
|
[
|
||||||
"Main",
|
"Main",
|
||||||
"High",
|
"High",
|
||||||
"Professional",
|
"Professional",
|
||||||
};
|
];
|
||||||
|
|
||||||
private static readonly HashSet<string> _mp4ContainerNames = new(StringComparer.OrdinalIgnoreCase)
|
private static readonly HashSet<string> _mp4ContainerNames = new(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
@ -107,8 +109,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
"m4v",
|
"m4v",
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly string[] _legacyTonemapModes = new[] { "max", "rgb" };
|
private static readonly TonemappingMode[] _legacyTonemapModes = [TonemappingMode.max, TonemappingMode.rgb];
|
||||||
private static readonly string[] _advancedTonemapModes = new[] { "lum", "itp" };
|
private static readonly TonemappingMode[] _advancedTonemapModes = [TonemappingMode.lum, TonemappingMode.itp];
|
||||||
|
|
||||||
// Set max transcoding channels for encoders that can't handle more than a set amount of channels
|
// Set max transcoding channels for encoders that can't handle more than a set amount of channels
|
||||||
// AAC, FLAC, ALAC, libopus, libvorbis encoders all support at least 8 channels
|
// AAC, FLAC, ALAC, libopus, libvorbis encoders all support at least 8 channels
|
||||||
@ -123,23 +125,22 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
{ "truehd", 6 },
|
{ "truehd", 6 },
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly string _defaultMjpegEncoder = "mjpeg";
|
private static readonly Dictionary<HardwareAccelerationType, string> _mjpegCodecMap = new()
|
||||||
private static readonly Dictionary<string, string> _mjpegCodecMap = new(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
{
|
||||||
{ "vaapi", _defaultMjpegEncoder + "_vaapi" },
|
{ HardwareAccelerationType.vaapi, _defaultMjpegEncoder + "_vaapi" },
|
||||||
{ "qsv", _defaultMjpegEncoder + "_qsv" },
|
{ HardwareAccelerationType.qsv, _defaultMjpegEncoder + "_qsv" },
|
||||||
{ "videotoolbox", _defaultMjpegEncoder + "_videotoolbox" }
|
{ HardwareAccelerationType.videotoolbox, _defaultMjpegEncoder + "_videotoolbox" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly string[] LosslessAudioCodecs = new string[]
|
public static readonly string[] LosslessAudioCodecs =
|
||||||
{
|
[
|
||||||
"alac",
|
"alac",
|
||||||
"ape",
|
"ape",
|
||||||
"flac",
|
"flac",
|
||||||
"mlp",
|
"mlp",
|
||||||
"truehd",
|
"truehd",
|
||||||
"wavpack"
|
"wavpack"
|
||||||
};
|
];
|
||||||
|
|
||||||
public EncodingHelper(
|
public EncodingHelper(
|
||||||
IApplicationPaths appPaths,
|
IApplicationPaths appPaths,
|
||||||
@ -176,18 +177,18 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
{
|
{
|
||||||
var hwType = encodingOptions.HardwareAccelerationType;
|
var hwType = encodingOptions.HardwareAccelerationType;
|
||||||
|
|
||||||
var codecMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
var codecMap = new Dictionary<HardwareAccelerationType, string>()
|
||||||
{
|
{
|
||||||
{ "amf", hwEncoder + "_amf" },
|
{ HardwareAccelerationType.amf, hwEncoder + "_amf" },
|
||||||
{ "nvenc", hwEncoder + "_nvenc" },
|
{ HardwareAccelerationType.nvenc, hwEncoder + "_nvenc" },
|
||||||
{ "qsv", hwEncoder + "_qsv" },
|
{ HardwareAccelerationType.qsv, hwEncoder + "_qsv" },
|
||||||
{ "vaapi", hwEncoder + "_vaapi" },
|
{ HardwareAccelerationType.vaapi, hwEncoder + "_vaapi" },
|
||||||
{ "videotoolbox", hwEncoder + "_videotoolbox" },
|
{ HardwareAccelerationType.videotoolbox, hwEncoder + "_videotoolbox" },
|
||||||
{ "v4l2m2m", hwEncoder + "_v4l2m2m" },
|
{ HardwareAccelerationType.v4l2m2m, hwEncoder + "_v4l2m2m" },
|
||||||
{ "rkmpp", hwEncoder + "_rkmpp" },
|
{ HardwareAccelerationType.rkmpp, hwEncoder + "_rkmpp" },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(hwType)
|
if (hwType != HardwareAccelerationType.none
|
||||||
&& encodingOptions.EnableHardwareEncoding
|
&& encodingOptions.EnableHardwareEncoding
|
||||||
&& codecMap.TryGetValue(hwType, out var preferredEncoder)
|
&& codecMap.TryGetValue(hwType, out var preferredEncoder)
|
||||||
&& _mediaEncoder.SupportsEncoder(preferredEncoder))
|
&& _mediaEncoder.SupportsEncoder(preferredEncoder))
|
||||||
@ -205,7 +206,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
{
|
{
|
||||||
var hwType = encodingOptions.HardwareAccelerationType;
|
var hwType = encodingOptions.HardwareAccelerationType;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(hwType)
|
if (hwType != HardwareAccelerationType.none
|
||||||
&& encodingOptions.EnableHardwareEncoding
|
&& encodingOptions.EnableHardwareEncoding
|
||||||
&& _mjpegCodecMap.TryGetValue(hwType, out var preferredEncoder)
|
&& _mjpegCodecMap.TryGetValue(hwType, out var preferredEncoder)
|
||||||
&& _mediaEncoder.SupportsEncoder(preferredEncoder))
|
&& _mediaEncoder.SupportsEncoder(preferredEncoder))
|
||||||
@ -360,7 +361,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
// prefer 'tonemap_vaapi' over 'vpp_qsv' on Linux for supporting Gen9/KBLx.
|
// prefer 'tonemap_vaapi' over 'vpp_qsv' on Linux for supporting Gen9/KBLx.
|
||||||
// 'vpp_qsv' requires VPL, which is only supported on Gen12/TGLx and newer.
|
// 'vpp_qsv' requires VPL, which is only supported on Gen12/TGLx and newer.
|
||||||
if (OperatingSystem.IsWindows()
|
if (OperatingSystem.IsWindows()
|
||||||
&& string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)
|
&& options.HardwareAccelerationType == HardwareAccelerationType.qsv
|
||||||
&& _mediaEncoder.EncoderVersion < _minFFmpegQsvVppTonemapOption)
|
&& _mediaEncoder.EncoderVersion < _minFFmpegQsvVppTonemapOption)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -970,7 +971,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty;
|
var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty;
|
||||||
var isHwTonemapAvailable = IsHwTonemapAvailable(state, options);
|
var isHwTonemapAvailable = IsHwTonemapAvailable(state, options);
|
||||||
|
|
||||||
if (string.Equals(optHwaccelType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
if (optHwaccelType == HardwareAccelerationType.vaapi)
|
||||||
{
|
{
|
||||||
if (!isLinux || !_mediaEncoder.SupportsHwaccel("vaapi"))
|
if (!isLinux || !_mediaEncoder.SupportsHwaccel("vaapi"))
|
||||||
{
|
{
|
||||||
@ -1044,7 +1045,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
args.Append(filterDevArgs);
|
args.Append(filterDevArgs);
|
||||||
}
|
}
|
||||||
else if (string.Equals(optHwaccelType, "qsv", StringComparison.OrdinalIgnoreCase))
|
else if (optHwaccelType == HardwareAccelerationType.qsv)
|
||||||
{
|
{
|
||||||
if ((!isLinux && !isWindows) || !_mediaEncoder.SupportsHwaccel("qsv"))
|
if ((!isLinux && !isWindows) || !_mediaEncoder.SupportsHwaccel("qsv"))
|
||||||
{
|
{
|
||||||
@ -1079,7 +1080,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
args.Append(filterDevArgs);
|
args.Append(filterDevArgs);
|
||||||
}
|
}
|
||||||
else if (string.Equals(optHwaccelType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
else if (optHwaccelType == HardwareAccelerationType.nvenc)
|
||||||
{
|
{
|
||||||
if ((!isLinux && !isWindows) || !IsCudaFullSupported())
|
if ((!isLinux && !isWindows) || !IsCudaFullSupported())
|
||||||
{
|
{
|
||||||
@ -1098,7 +1099,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
args.Append(GetCudaDeviceArgs(0, CudaAlias))
|
args.Append(GetCudaDeviceArgs(0, CudaAlias))
|
||||||
.Append(GetFilterHwDeviceArgs(CudaAlias));
|
.Append(GetFilterHwDeviceArgs(CudaAlias));
|
||||||
}
|
}
|
||||||
else if (string.Equals(optHwaccelType, "amf", StringComparison.OrdinalIgnoreCase))
|
else if (optHwaccelType == HardwareAccelerationType.amf)
|
||||||
{
|
{
|
||||||
if (!isWindows || !_mediaEncoder.SupportsHwaccel("d3d11va"))
|
if (!isWindows || !_mediaEncoder.SupportsHwaccel("d3d11va"))
|
||||||
{
|
{
|
||||||
@ -1123,7 +1124,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
args.Append(filterDevArgs);
|
args.Append(filterDevArgs);
|
||||||
}
|
}
|
||||||
else if (string.Equals(optHwaccelType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
else if (optHwaccelType == HardwareAccelerationType.videotoolbox)
|
||||||
{
|
{
|
||||||
if (!isMacOS || !_mediaEncoder.SupportsHwaccel("videotoolbox"))
|
if (!isMacOS || !_mediaEncoder.SupportsHwaccel("videotoolbox"))
|
||||||
{
|
{
|
||||||
@ -1140,7 +1141,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
// videotoolbox hw filter does not require device selection
|
// videotoolbox hw filter does not require device selection
|
||||||
args.Append(GetVideoToolboxDeviceArgs(VideotoolboxAlias));
|
args.Append(GetVideoToolboxDeviceArgs(VideotoolboxAlias));
|
||||||
}
|
}
|
||||||
else if (string.Equals(optHwaccelType, "rkmpp", StringComparison.OrdinalIgnoreCase))
|
else if (optHwaccelType == HardwareAccelerationType.rkmpp)
|
||||||
{
|
{
|
||||||
if (!isLinux || !_mediaEncoder.SupportsHwaccel("rkmpp"))
|
if (!isLinux || !_mediaEncoder.SupportsHwaccel("rkmpp"))
|
||||||
{
|
{
|
||||||
@ -1413,6 +1414,149 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return FormattableString.Invariant($" -b:v {bitrate} -maxrate {bitrate} -bufsize {bufsize}");
|
return FormattableString.Invariant($" -b:v {bitrate} -maxrate {bitrate} -bufsize {bufsize}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetEncoderParam(EncoderPreset? preset, EncoderPreset defaultPreset, EncodingOptions encodingOptions, string videoEncoder, bool isLibX265)
|
||||||
|
{
|
||||||
|
var param = string.Empty;
|
||||||
|
var encoderPreset = preset ?? defaultPreset;
|
||||||
|
if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase) || isLibX265)
|
||||||
|
{
|
||||||
|
param += " -preset " + encoderPreset.ToString().ToLowerInvariant();
|
||||||
|
|
||||||
|
int encodeCrf = encodingOptions.H264Crf;
|
||||||
|
if (isLibX265)
|
||||||
|
{
|
||||||
|
encodeCrf = encodingOptions.H265Crf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encodeCrf >= 0 && encodeCrf <= 51)
|
||||||
|
{
|
||||||
|
param += " -crf " + encodeCrf.ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string defaultCrf = "23";
|
||||||
|
if (isLibX265)
|
||||||
|
{
|
||||||
|
defaultCrf = "28";
|
||||||
|
}
|
||||||
|
|
||||||
|
param += " -crf " + defaultCrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "libsvtav1", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Default to use the recommended preset 10.
|
||||||
|
// Omit presets < 5, which are too slow for on the fly encoding.
|
||||||
|
// https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Ffmpeg.md
|
||||||
|
param += encoderPreset switch
|
||||||
|
{
|
||||||
|
EncoderPreset.veryslow => " -preset 5",
|
||||||
|
EncoderPreset.slower => " -preset 6",
|
||||||
|
EncoderPreset.slow => " -preset 7",
|
||||||
|
EncoderPreset.medium => " -preset 8",
|
||||||
|
EncoderPreset.fast => " -preset 9",
|
||||||
|
EncoderPreset.faster => " -preset 10",
|
||||||
|
EncoderPreset.veryfast => " -preset 11",
|
||||||
|
EncoderPreset.superfast => " -preset 12",
|
||||||
|
EncoderPreset.ultrafast => " -preset 13",
|
||||||
|
_ => " -preset 10"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(videoEncoder, "hevc_vaapi", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(videoEncoder, "av1_vaapi", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// -compression_level is not reliable on AMD.
|
||||||
|
if (_mediaEncoder.IsVaapiDeviceInteliHD)
|
||||||
|
{
|
||||||
|
param += encoderPreset switch
|
||||||
|
{
|
||||||
|
EncoderPreset.veryslow => " -compression_level 1",
|
||||||
|
EncoderPreset.slower => " -compression_level 2",
|
||||||
|
EncoderPreset.slow => " -compression_level 3",
|
||||||
|
EncoderPreset.medium => " -compression_level 4",
|
||||||
|
EncoderPreset.fast => " -compression_level 5",
|
||||||
|
EncoderPreset.faster => " -compression_level 6",
|
||||||
|
EncoderPreset.veryfast => " -compression_level 7",
|
||||||
|
EncoderPreset.superfast => " -compression_level 7",
|
||||||
|
EncoderPreset.ultrafast => " -compression_level 7",
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) // h264 (h264_qsv)
|
||||||
|
|| string.Equals(videoEncoder, "hevc_qsv", StringComparison.OrdinalIgnoreCase) // hevc (hevc_qsv)
|
||||||
|
|| string.Equals(videoEncoder, "av1_qsv", StringComparison.OrdinalIgnoreCase)) // av1 (av1_qsv)
|
||||||
|
{
|
||||||
|
EncoderPreset[] valid_presets = [EncoderPreset.veryslow, EncoderPreset.slower, EncoderPreset.slow, EncoderPreset.medium, EncoderPreset.fast, EncoderPreset.faster, EncoderPreset.veryfast];
|
||||||
|
|
||||||
|
if (valid_presets.Contains(encoderPreset))
|
||||||
|
{
|
||||||
|
param += " -preset " + encodingOptions.EncoderPreset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
param += " -preset " + EncoderPreset.veryfast.ToString().ToLowerInvariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase) // h264 (h264_nvenc)
|
||||||
|
|| string.Equals(videoEncoder, "hevc_nvenc", StringComparison.OrdinalIgnoreCase) // hevc (hevc_nvenc)
|
||||||
|
|| string.Equals(videoEncoder, "av1_nvenc", StringComparison.OrdinalIgnoreCase) // av1 (av1_nvenc)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
param += encoderPreset switch
|
||||||
|
{
|
||||||
|
EncoderPreset.veryslow => " -preset p7",
|
||||||
|
EncoderPreset.slower => " -preset p6",
|
||||||
|
EncoderPreset.slow => " -preset p5",
|
||||||
|
EncoderPreset.medium => " -preset p4",
|
||||||
|
EncoderPreset.fast => " -preset p3",
|
||||||
|
EncoderPreset.faster => " -preset p2",
|
||||||
|
_ => " -preset p1"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "h264_amf", StringComparison.OrdinalIgnoreCase) // h264 (h264_amf)
|
||||||
|
|| string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase) // hevc (hevc_amf)
|
||||||
|
|| string.Equals(videoEncoder, "av1_amf", StringComparison.OrdinalIgnoreCase) // av1 (av1_amf)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
param += encoderPreset switch
|
||||||
|
{
|
||||||
|
EncoderPreset.veryslow => " -quality quality",
|
||||||
|
EncoderPreset.slower => " -quality quality",
|
||||||
|
EncoderPreset.slow => " -quality quality",
|
||||||
|
EncoderPreset.medium => " -quality balanced",
|
||||||
|
_ => " -quality speed"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(videoEncoder, "av1_amf", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
param += " -header_insertion_mode gop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
param += " -gops_per_idr 1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.Equals(videoEncoder, "h264_videotoolbox", StringComparison.OrdinalIgnoreCase) // h264 (h264_videotoolbox)
|
||||||
|
|| string.Equals(videoEncoder, "hevc_videotoolbox", StringComparison.OrdinalIgnoreCase) // hevc (hevc_videotoolbox)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
param += encoderPreset switch
|
||||||
|
{
|
||||||
|
EncoderPreset.veryslow => " -prio_speed 0",
|
||||||
|
EncoderPreset.slower => " -prio_speed 0",
|
||||||
|
EncoderPreset.slow => " -prio_speed 0",
|
||||||
|
EncoderPreset.medium => " -prio_speed 0",
|
||||||
|
_ => " -prio_speed 1"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
public static string NormalizeTranscodingLevel(EncodingJobInfo state, string level)
|
public static string NormalizeTranscodingLevel(EncodingJobInfo state, string level)
|
||||||
{
|
{
|
||||||
if (double.TryParse(level, CultureInfo.InvariantCulture, out double requestLevel))
|
if (double.TryParse(level, CultureInfo.InvariantCulture, out double requestLevel))
|
||||||
@ -1625,7 +1769,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
/// <param name="encodingOptions">Encoding options.</param>
|
/// <param name="encodingOptions">Encoding options.</param>
|
||||||
/// <param name="defaultPreset">Default present to use for encoding.</param>
|
/// <param name="defaultPreset">Default present to use for encoding.</param>
|
||||||
/// <returns>Video bitrate.</returns>
|
/// <returns>Video bitrate.</returns>
|
||||||
public string GetVideoQualityParam(EncodingJobInfo state, string videoEncoder, EncodingOptions encodingOptions, string defaultPreset)
|
public string GetVideoQualityParam(EncodingJobInfo state, string videoEncoder, EncodingOptions encodingOptions, EncoderPreset defaultPreset)
|
||||||
{
|
{
|
||||||
var param = string.Empty;
|
var param = string.Empty;
|
||||||
|
|
||||||
@ -1640,7 +1784,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
// https://github.com/intel/media-driver/issues/1456
|
// https://github.com/intel/media-driver/issues/1456
|
||||||
var enableWaFori915Hang = false;
|
var enableWaFori915Hang = false;
|
||||||
|
|
||||||
if (string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
var hardwareAccelerationType = encodingOptions.HardwareAccelerationType;
|
||||||
|
|
||||||
|
if (hardwareAccelerationType == HardwareAccelerationType.vaapi)
|
||||||
{
|
{
|
||||||
var isIntelVaapiDriver = _mediaEncoder.IsVaapiDeviceInteliHD || _mediaEncoder.IsVaapiDeviceInteli965;
|
var isIntelVaapiDriver = _mediaEncoder.IsVaapiDeviceInteliHD || _mediaEncoder.IsVaapiDeviceInteli965;
|
||||||
|
|
||||||
@ -1653,7 +1799,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
intelLowPowerHwEncoding = encodingOptions.EnableIntelLowPowerHevcHwEncoder && isIntelVaapiDriver;
|
intelLowPowerHwEncoding = encodingOptions.EnableIntelLowPowerHevcHwEncoder && isIntelVaapiDriver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
else if (hardwareAccelerationType == HardwareAccelerationType.qsv)
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsLinux())
|
if (OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@ -1700,204 +1846,10 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
param += " -async_depth 1";
|
param += " -async_depth 1";
|
||||||
}
|
}
|
||||||
|
|
||||||
var isVc1 = string.Equals(state.VideoStream?.Codec, "vc1", StringComparison.OrdinalIgnoreCase);
|
|
||||||
var isLibX265 = string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase);
|
var isLibX265 = string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase);
|
||||||
|
var encodingPreset = encodingOptions.EncoderPreset;
|
||||||
|
|
||||||
if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase) || isLibX265)
|
param += GetEncoderParam(encodingPreset, defaultPreset, encodingOptions, videoEncoder, isLibX265);
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(encodingOptions.EncoderPreset))
|
|
||||||
{
|
|
||||||
param += " -preset " + encodingOptions.EncoderPreset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
param += " -preset " + defaultPreset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int encodeCrf = encodingOptions.H264Crf;
|
|
||||||
if (isLibX265)
|
|
||||||
{
|
|
||||||
encodeCrf = encodingOptions.H265Crf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encodeCrf >= 0 && encodeCrf <= 51)
|
|
||||||
{
|
|
||||||
param += " -crf " + encodeCrf.ToString(CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string defaultCrf = "23";
|
|
||||||
if (isLibX265)
|
|
||||||
{
|
|
||||||
defaultCrf = "28";
|
|
||||||
}
|
|
||||||
|
|
||||||
param += " -crf " + defaultCrf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "libsvtav1", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// Default to use the recommended preset 10.
|
|
||||||
// Omit presets < 5, which are too slow for on the fly encoding.
|
|
||||||
// https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Ffmpeg.md
|
|
||||||
param += encodingOptions.EncoderPreset switch
|
|
||||||
{
|
|
||||||
"veryslow" => " -preset 5",
|
|
||||||
"slower" => " -preset 6",
|
|
||||||
"slow" => " -preset 7",
|
|
||||||
"medium" => " -preset 8",
|
|
||||||
"fast" => " -preset 9",
|
|
||||||
"faster" => " -preset 10",
|
|
||||||
"veryfast" => " -preset 11",
|
|
||||||
"superfast" => " -preset 12",
|
|
||||||
"ultrafast" => " -preset 13",
|
|
||||||
_ => " -preset 10"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(videoEncoder, "hevc_vaapi", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(videoEncoder, "av1_vaapi", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// -compression_level is not reliable on AMD.
|
|
||||||
if (_mediaEncoder.IsVaapiDeviceInteliHD)
|
|
||||||
{
|
|
||||||
param += encodingOptions.EncoderPreset switch
|
|
||||||
{
|
|
||||||
"veryslow" => " -compression_level 1",
|
|
||||||
"slower" => " -compression_level 2",
|
|
||||||
"slow" => " -compression_level 3",
|
|
||||||
"medium" => " -compression_level 4",
|
|
||||||
"fast" => " -compression_level 5",
|
|
||||||
"faster" => " -compression_level 6",
|
|
||||||
"veryfast" => " -compression_level 7",
|
|
||||||
"superfast" => " -compression_level 7",
|
|
||||||
"ultrafast" => " -compression_level 7",
|
|
||||||
_ => string.Empty
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) // h264 (h264_qsv)
|
|
||||||
|| string.Equals(videoEncoder, "hevc_qsv", StringComparison.OrdinalIgnoreCase) // hevc (hevc_qsv)
|
|
||||||
|| string.Equals(videoEncoder, "av1_qsv", StringComparison.OrdinalIgnoreCase)) // av1 (av1_qsv)
|
|
||||||
{
|
|
||||||
string[] valid_presets = { "veryslow", "slower", "slow", "medium", "fast", "faster", "veryfast" };
|
|
||||||
|
|
||||||
if (valid_presets.Contains(encodingOptions.EncoderPreset, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
param += " -preset " + encodingOptions.EncoderPreset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
param += " -preset veryfast";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase) // h264 (h264_nvenc)
|
|
||||||
|| string.Equals(videoEncoder, "hevc_nvenc", StringComparison.OrdinalIgnoreCase) // hevc (hevc_nvenc)
|
|
||||||
|| string.Equals(videoEncoder, "av1_nvenc", StringComparison.OrdinalIgnoreCase)) // av1 (av1_nvenc)
|
|
||||||
{
|
|
||||||
switch (encodingOptions.EncoderPreset)
|
|
||||||
{
|
|
||||||
case "veryslow":
|
|
||||||
param += " -preset p7";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "slower":
|
|
||||||
param += " -preset p6";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "slow":
|
|
||||||
param += " -preset p5";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "medium":
|
|
||||||
param += " -preset p4";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "fast":
|
|
||||||
param += " -preset p3";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "faster":
|
|
||||||
param += " -preset p2";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "veryfast":
|
|
||||||
case "superfast":
|
|
||||||
case "ultrafast":
|
|
||||||
param += " -preset p1";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
param += " -preset p1";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "h264_amf", StringComparison.OrdinalIgnoreCase) // h264 (h264_amf)
|
|
||||||
|| string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase) // hevc (hevc_amf)
|
|
||||||
|| string.Equals(videoEncoder, "av1_amf", StringComparison.OrdinalIgnoreCase)) // av1 (av1_amf)
|
|
||||||
{
|
|
||||||
switch (encodingOptions.EncoderPreset)
|
|
||||||
{
|
|
||||||
case "veryslow":
|
|
||||||
case "slower":
|
|
||||||
case "slow":
|
|
||||||
param += " -quality quality";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "medium":
|
|
||||||
param += " -quality balanced";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "fast":
|
|
||||||
case "faster":
|
|
||||||
case "veryfast":
|
|
||||||
case "superfast":
|
|
||||||
case "ultrafast":
|
|
||||||
param += " -quality speed";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
param += " -quality speed";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(videoEncoder, "av1_amf", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
param += " -header_insertion_mode gop";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(videoEncoder, "hevc_amf", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
param += " -gops_per_idr 1";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(videoEncoder, "h264_videotoolbox", StringComparison.OrdinalIgnoreCase) // h264 (h264_videotoolbox)
|
|
||||||
|| string.Equals(videoEncoder, "hevc_videotoolbox", StringComparison.OrdinalIgnoreCase)) // hevc (hevc_videotoolbox)
|
|
||||||
{
|
|
||||||
switch (encodingOptions.EncoderPreset)
|
|
||||||
{
|
|
||||||
case "veryslow":
|
|
||||||
case "slower":
|
|
||||||
case "slow":
|
|
||||||
case "medium":
|
|
||||||
param += " -prio_speed 0";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "fast":
|
|
||||||
case "faster":
|
|
||||||
case "veryfast":
|
|
||||||
case "superfast":
|
|
||||||
case "ultrafast":
|
|
||||||
param += " -prio_speed 1";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
param += " -prio_speed 1";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
param += GetVideoBitrateParam(state, videoEncoder);
|
param += GetVideoBitrateParam(state, videoEncoder);
|
||||||
|
|
||||||
var framerate = GetFramerateParam(state);
|
var framerate = GetFramerateParam(state);
|
||||||
@ -3256,7 +3208,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return string.Format(
|
return string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
"{0}={1}:-1:0",
|
"{0}={1}:-1:0",
|
||||||
string.Equals(options.DeinterlaceMethod, "bwdif", StringComparison.OrdinalIgnoreCase) ? "bwdif" : "yadif",
|
options.DeinterlaceMethod.ToString().ToLowerInvariant(),
|
||||||
doubleRateDeint ? "1" : "0");
|
doubleRateDeint ? "1" : "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3265,8 +3217,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.ReferenceFrameRate ?? 60) <= 30;
|
var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.ReferenceFrameRate ?? 60) <= 30;
|
||||||
if (hwDeintSuffix.Contains("cuda", StringComparison.OrdinalIgnoreCase))
|
if (hwDeintSuffix.Contains("cuda", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var useBwdif = string.Equals(options.DeinterlaceMethod, "bwdif", StringComparison.OrdinalIgnoreCase)
|
var useBwdif = options.DeinterlaceMethod == DeinterlaceMethod.bwdif && _mediaEncoder.SupportsFilter("bwdif_cuda");
|
||||||
&& _mediaEncoder.SupportsFilter("bwdif_cuda");
|
|
||||||
|
|
||||||
return string.Format(
|
return string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
@ -3307,7 +3258,10 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
var args = string.Empty;
|
var args = string.Empty;
|
||||||
var algorithm = options.TonemappingAlgorithm;
|
var algorithm = options.TonemappingAlgorithm.ToString().ToLowerInvariant();
|
||||||
|
var mode = options.TonemappingMode.ToString().ToLowerInvariant();
|
||||||
|
var range = options.TonemappingRange;
|
||||||
|
var rangeString = range.ToString().ToLowerInvariant();
|
||||||
|
|
||||||
if (string.Equals(hwTonemapSuffix, "vaapi", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(hwTonemapSuffix, "vaapi", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
@ -3342,10 +3296,10 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
args = "tonemap_{0}=format={1}:p=bt709:t=bt709:m=bt709:tonemap={2}:peak={3}:desat={4}";
|
args = "tonemap_{0}=format={1}:p=bt709:t=bt709:m=bt709:tonemap={2}:peak={3}:desat={4}";
|
||||||
|
|
||||||
var useLegacyTonemapModes = _mediaEncoder.EncoderVersion >= _minFFmpegOclCuTonemapMode
|
var useLegacyTonemapModes = _mediaEncoder.EncoderVersion >= _minFFmpegOclCuTonemapMode
|
||||||
&& _legacyTonemapModes.Contains(options.TonemappingMode, StringComparison.OrdinalIgnoreCase);
|
&& _legacyTonemapModes.Contains(options.TonemappingMode);
|
||||||
|
|
||||||
var useAdvancedTonemapModes = _mediaEncoder.EncoderVersion >= _minFFmpegAdvancedTonemapMode
|
var useAdvancedTonemapModes = _mediaEncoder.EncoderVersion >= _minFFmpegAdvancedTonemapMode
|
||||||
&& _advancedTonemapModes.Contains(options.TonemappingMode, StringComparison.OrdinalIgnoreCase);
|
&& _advancedTonemapModes.Contains(options.TonemappingMode);
|
||||||
|
|
||||||
if (useLegacyTonemapModes || useAdvancedTonemapModes)
|
if (useLegacyTonemapModes || useAdvancedTonemapModes)
|
||||||
{
|
{
|
||||||
@ -3357,8 +3311,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
args += ":param={6}";
|
args += ":param={6}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(options.TonemappingRange, "tv", StringComparison.OrdinalIgnoreCase)
|
if (range == TonemappingRange.tv || range == TonemappingRange.pc)
|
||||||
|| string.Equals(options.TonemappingRange, "pc", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
args += ":range={7}";
|
args += ":range={7}";
|
||||||
}
|
}
|
||||||
@ -3372,9 +3325,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
algorithm,
|
algorithm,
|
||||||
options.TonemappingPeak,
|
options.TonemappingPeak,
|
||||||
options.TonemappingDesat,
|
options.TonemappingDesat,
|
||||||
options.TonemappingMode,
|
mode,
|
||||||
options.TonemappingParam,
|
options.TonemappingParam,
|
||||||
options.TonemappingRange);
|
rangeString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLibplaceboFilter(
|
public string GetLibplaceboFilter(
|
||||||
@ -3409,24 +3362,24 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
if (doTonemap)
|
if (doTonemap)
|
||||||
{
|
{
|
||||||
var algorithm = options.TonemappingAlgorithm;
|
var algorithm = options.TonemappingAlgorithm;
|
||||||
|
var algorithmString = "clip";
|
||||||
var mode = options.TonemappingMode;
|
var mode = options.TonemappingMode;
|
||||||
var range = options.TonemappingRange;
|
var range = options.TonemappingRange;
|
||||||
|
|
||||||
if (string.Equals(algorithm, "bt2390", StringComparison.OrdinalIgnoreCase))
|
if (algorithm == TonemappingAlgorithm.bt2390)
|
||||||
{
|
{
|
||||||
algorithm = "bt.2390";
|
algorithmString = "bt.2390";
|
||||||
}
|
}
|
||||||
else if (string.Equals(algorithm, "none", StringComparison.OrdinalIgnoreCase))
|
else if (algorithm != TonemappingAlgorithm.none)
|
||||||
{
|
{
|
||||||
algorithm = "clip";
|
algorithmString = algorithm.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
tonemapArg = ":tonemapping=" + algorithm + ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709";
|
tonemapArg = ":tonemapping=" + algorithm + ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709";
|
||||||
|
|
||||||
if (string.Equals(range, "tv", StringComparison.OrdinalIgnoreCase)
|
if (range == TonemappingRange.tv || range == TonemappingRange.pc)
|
||||||
|| string.Equals(range, "pc", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
tonemapArg += ":range=" + range;
|
tonemapArg += ":range=" + range.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3530,8 +3483,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
tonemapArgs += $":param={options.TonemappingParam}";
|
tonemapArgs += $":param={options.TonemappingParam}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(options.TonemappingRange, "tv", StringComparison.OrdinalIgnoreCase)
|
var range = options.TonemappingRange;
|
||||||
|| string.Equals(options.TonemappingRange, "pc", StringComparison.OrdinalIgnoreCase))
|
if (range == TonemappingRange.tv || range == TonemappingRange.pc)
|
||||||
{
|
{
|
||||||
tonemapArgs += $":range={options.TonemappingRange}";
|
tonemapArgs += $":range={options.TonemappingRange}";
|
||||||
}
|
}
|
||||||
@ -3575,7 +3528,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.nvenc)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -3777,7 +3730,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.amf)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -3993,7 +3946,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.qsv)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -4543,7 +4496,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.vaapi)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -5247,7 +5200,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.videotoolbox)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -5436,7 +5389,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
EncodingOptions options,
|
EncodingOptions options,
|
||||||
string vidEncoder)
|
string vidEncoder)
|
||||||
{
|
{
|
||||||
if (!string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase))
|
if (options.HardwareAccelerationType != HardwareAccelerationType.rkmpp)
|
||||||
{
|
{
|
||||||
return (null, null, null);
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
@ -5696,38 +5649,20 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
List<string> subFilters;
|
List<string> subFilters;
|
||||||
List<string> overlayFilters;
|
List<string> overlayFilters;
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
(mainFilters, subFilters, overlayFilters) = options.HardwareAccelerationType switch
|
||||||
{
|
{
|
||||||
(mainFilters, subFilters, overlayFilters) = GetVaapiVidFilterChain(state, options, outputVideoCodec);
|
HardwareAccelerationType.vaapi => GetVaapiVidFilterChain(state, options, outputVideoCodec),
|
||||||
}
|
HardwareAccelerationType.amf => GetAmdVidFilterChain(state, options, outputVideoCodec),
|
||||||
else if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
HardwareAccelerationType.qsv => GetIntelVidFilterChain(state, options, outputVideoCodec),
|
||||||
{
|
HardwareAccelerationType.nvenc => GetNvidiaVidFilterChain(state, options, outputVideoCodec),
|
||||||
(mainFilters, subFilters, overlayFilters) = GetIntelVidFilterChain(state, options, outputVideoCodec);
|
HardwareAccelerationType.videotoolbox => GetAppleVidFilterChain(state, options, outputVideoCodec),
|
||||||
}
|
HardwareAccelerationType.rkmpp => GetRkmppVidFilterChain(state, options, outputVideoCodec),
|
||||||
else if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
_ => GetSwVidFilterChain(state, options, outputVideoCodec),
|
||||||
{
|
};
|
||||||
(mainFilters, subFilters, overlayFilters) = GetNvidiaVidFilterChain(state, options, outputVideoCodec);
|
|
||||||
}
|
|
||||||
else if (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
(mainFilters, subFilters, overlayFilters) = GetAmdVidFilterChain(state, options, outputVideoCodec);
|
|
||||||
}
|
|
||||||
else if (string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
(mainFilters, subFilters, overlayFilters) = GetAppleVidFilterChain(state, options, outputVideoCodec);
|
|
||||||
}
|
|
||||||
else if (string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
(mainFilters, subFilters, overlayFilters) = GetRkmppVidFilterChain(state, options, outputVideoCodec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(mainFilters, subFilters, overlayFilters) = GetSwVidFilterChain(state, options, outputVideoCodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
mainFilters?.RemoveAll(filter => string.IsNullOrEmpty(filter));
|
mainFilters?.RemoveAll(string.IsNullOrEmpty);
|
||||||
subFilters?.RemoveAll(filter => string.IsNullOrEmpty(filter));
|
subFilters?.RemoveAll(string.IsNullOrEmpty);
|
||||||
overlayFilters?.RemoveAll(filter => string.IsNullOrEmpty(filter));
|
overlayFilters?.RemoveAll(string.IsNullOrEmpty);
|
||||||
|
|
||||||
var framerate = GetFramerateParam(state);
|
var framerate = GetFramerateParam(state);
|
||||||
if (framerate.HasValue)
|
if (framerate.HasValue)
|
||||||
@ -5907,7 +5842,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(videoStream.Codec) && !string.IsNullOrEmpty(options.HardwareAccelerationType))
|
var hardwareAccelerationType = options.HardwareAccelerationType;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(videoStream.Codec) && hardwareAccelerationType != HardwareAccelerationType.none)
|
||||||
{
|
{
|
||||||
var bitDepth = GetVideoColorBitDepth(state);
|
var bitDepth = GetVideoColorBitDepth(state);
|
||||||
|
|
||||||
@ -5919,10 +5856,10 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|| string.Equals(videoStream.Codec, "av1", StringComparison.OrdinalIgnoreCase)))
|
|| string.Equals(videoStream.Codec, "av1", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
// RKMPP has H.264 Hi10P decoder
|
// RKMPP has H.264 Hi10P decoder
|
||||||
bool hasHardwareHi10P = string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase);
|
bool hasHardwareHi10P = hardwareAccelerationType == HardwareAccelerationType.rkmpp;
|
||||||
|
|
||||||
// VideoToolbox on Apple Silicon has H.264 Hi10P mode enabled after macOS 14.6
|
// VideoToolbox on Apple Silicon has H.264 Hi10P mode enabled after macOS 14.6
|
||||||
if (string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
if (hardwareAccelerationType == HardwareAccelerationType.videotoolbox)
|
||||||
{
|
{
|
||||||
var ver = Environment.OSVersion.Version;
|
var ver = Environment.OSVersion.Version;
|
||||||
var arch = RuntimeInformation.OSArchitecture;
|
var arch = RuntimeInformation.OSArchitecture;
|
||||||
@ -5939,34 +5876,20 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
var decoder = hardwareAccelerationType switch
|
||||||
{
|
{
|
||||||
return GetQsvHwVidDecoder(state, options, videoStream, bitDepth);
|
HardwareAccelerationType.vaapi => GetVaapiVidDecoder(state, options, videoStream, bitDepth),
|
||||||
}
|
HardwareAccelerationType.amf => GetAmfVidDecoder(state, options, videoStream, bitDepth),
|
||||||
|
HardwareAccelerationType.qsv => GetQsvHwVidDecoder(state, options, videoStream, bitDepth),
|
||||||
|
HardwareAccelerationType.nvenc => GetNvdecVidDecoder(state, options, videoStream, bitDepth),
|
||||||
|
HardwareAccelerationType.videotoolbox => GetVideotoolboxVidDecoder(state, options, videoStream, bitDepth),
|
||||||
|
HardwareAccelerationType.rkmpp => GetRkmppVidDecoder(state, options, videoStream, bitDepth),
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
if (!string.IsNullOrEmpty(decoder))
|
||||||
{
|
{
|
||||||
return GetNvdecVidDecoder(state, options, videoStream, bitDepth);
|
return decoder;
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return GetAmfVidDecoder(state, options, videoStream, bitDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return GetVaapiVidDecoder(state, options, videoStream, bitDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return GetVideotoolboxVidDecoder(state, options, videoStream, bitDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return GetRkmppVidDecoder(state, options, videoStream, bitDepth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5981,7 +5904,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid a second attempt if no hardware acceleration is being used
|
// Avoid a second attempt if no hardware acceleration is being used
|
||||||
options.HardwareDecodingCodecs = Array.FindAll(options.HardwareDecodingCodecs, val => !string.Equals(val, whichCodec, StringComparison.OrdinalIgnoreCase));
|
options.HardwareDecodingCodecs = options.HardwareDecodingCodecs.Where(c => !string.Equals(c, whichCodec, StringComparison.OrdinalIgnoreCase)).ToArray();
|
||||||
|
|
||||||
// leave blank so ffmpeg will decide
|
// leave blank so ffmpeg will decide
|
||||||
return null;
|
return null;
|
||||||
@ -6062,6 +5985,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var isVideotoolboxSupported = isMacOS && _mediaEncoder.SupportsHwaccel("videotoolbox");
|
var isVideotoolboxSupported = isMacOS && _mediaEncoder.SupportsHwaccel("videotoolbox");
|
||||||
var isRkmppSupported = isLinux && IsRkmppFullSupported();
|
var isRkmppSupported = isLinux && IsRkmppFullSupported();
|
||||||
var isCodecAvailable = options.HardwareDecodingCodecs.Contains(videoCodec, StringComparison.OrdinalIgnoreCase);
|
var isCodecAvailable = options.HardwareDecodingCodecs.Contains(videoCodec, StringComparison.OrdinalIgnoreCase);
|
||||||
|
var hardwareAccelerationType = options.HardwareAccelerationType;
|
||||||
|
|
||||||
var ffmpegVersion = _mediaEncoder.EncoderVersion;
|
var ffmpegVersion = _mediaEncoder.EncoderVersion;
|
||||||
|
|
||||||
@ -6099,7 +6023,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Intel qsv/d3d11va/vaapi
|
// Intel qsv/d3d11va/vaapi
|
||||||
if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (hardwareAccelerationType == HardwareAccelerationType.qsv)
|
||||||
{
|
{
|
||||||
if (options.PreferSystemNativeHwDecoder)
|
if (options.PreferSystemNativeHwDecoder)
|
||||||
{
|
{
|
||||||
@ -6125,7 +6049,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nvidia cuda
|
// Nvidia cuda
|
||||||
if (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
if (hardwareAccelerationType == HardwareAccelerationType.nvenc)
|
||||||
{
|
{
|
||||||
if (isCudaSupported && isCodecAvailable)
|
if (isCudaSupported && isCodecAvailable)
|
||||||
{
|
{
|
||||||
@ -6142,7 +6066,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Amd d3d11va
|
// Amd d3d11va
|
||||||
if (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
|
if (hardwareAccelerationType == HardwareAccelerationType.amf)
|
||||||
{
|
{
|
||||||
if (isD3d11Supported && isCodecAvailable)
|
if (isD3d11Supported && isCodecAvailable)
|
||||||
{
|
{
|
||||||
@ -6152,7 +6076,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vaapi
|
// Vaapi
|
||||||
if (string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
|
if (hardwareAccelerationType == HardwareAccelerationType.vaapi
|
||||||
&& isVaapiSupported
|
&& isVaapiSupported
|
||||||
&& isCodecAvailable)
|
&& isCodecAvailable)
|
||||||
{
|
{
|
||||||
@ -6161,7 +6085,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apple videotoolbox
|
// Apple videotoolbox
|
||||||
if (string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase)
|
if (hardwareAccelerationType == HardwareAccelerationType.videotoolbox
|
||||||
&& isVideotoolboxSupported
|
&& isVideotoolboxSupported
|
||||||
&& isCodecAvailable)
|
&& isCodecAvailable)
|
||||||
{
|
{
|
||||||
@ -6169,7 +6093,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rockchip rkmpp
|
// Rockchip rkmpp
|
||||||
if (string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase)
|
if (hardwareAccelerationType == HardwareAccelerationType.rkmpp
|
||||||
&& isRkmppSupported
|
&& isRkmppSupported
|
||||||
&& isCodecAvailable)
|
&& isCodecAvailable)
|
||||||
{
|
{
|
||||||
@ -6185,7 +6109,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var isLinux = OperatingSystem.IsLinux();
|
var isLinux = OperatingSystem.IsLinux();
|
||||||
|
|
||||||
if ((!isWindows && !isLinux)
|
if ((!isWindows && !isLinux)
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.qsv)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6254,7 +6178,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
public string GetNvdecVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
public string GetNvdecVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
||||||
{
|
{
|
||||||
if ((!OperatingSystem.IsWindows() && !OperatingSystem.IsLinux())
|
if ((!OperatingSystem.IsWindows() && !OperatingSystem.IsLinux())
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.nvenc)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6319,7 +6243,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
public string GetAmfVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
public string GetAmfVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
||||||
{
|
{
|
||||||
if (!OperatingSystem.IsWindows()
|
if (!OperatingSystem.IsWindows()
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.amf)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6375,7 +6299,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
public string GetVaapiVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
public string GetVaapiVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
||||||
{
|
{
|
||||||
if (!OperatingSystem.IsLinux()
|
if (!OperatingSystem.IsLinux()
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.vaapi)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6437,7 +6361,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
public string GetVideotoolboxVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
public string GetVideotoolboxVidDecoder(EncodingJobInfo state, EncodingOptions options, MediaStream videoStream, int bitDepth)
|
||||||
{
|
{
|
||||||
if (!OperatingSystem.IsMacOS()
|
if (!OperatingSystem.IsMacOS()
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.videotoolbox)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6485,7 +6409,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
var isLinux = OperatingSystem.IsLinux();
|
var isLinux = OperatingSystem.IsLinux();
|
||||||
|
|
||||||
if (!isLinux
|
if (!isLinux
|
||||||
|| !string.Equals(options.HardwareAccelerationType, "rkmpp", StringComparison.OrdinalIgnoreCase))
|
|| options.HardwareAccelerationType != HardwareAccelerationType.rkmpp)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -6749,7 +6673,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
if (state.IsVideoRequest)
|
if (state.IsVideoRequest)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(state.InputContainer) && state.VideoType == VideoType.VideoFile && string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType))
|
if (!string.IsNullOrEmpty(state.InputContainer) && state.VideoType == VideoType.VideoFile && encodingOptions.HardwareAccelerationType != HardwareAccelerationType.none)
|
||||||
{
|
{
|
||||||
var inputFormat = GetInputFormat(state.InputContainer);
|
var inputFormat = GetInputFormat(state.InputContainer);
|
||||||
if (!string.IsNullOrEmpty(inputFormat))
|
if (!string.IsNullOrEmpty(inputFormat))
|
||||||
@ -6865,7 +6789,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
state.SupportedAudioCodecs = supportedAudioCodecsList.ToArray();
|
state.SupportedAudioCodecs = supportedAudioCodecsList.ToArray();
|
||||||
|
|
||||||
request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => _mediaEncoder.CanEncodeToAudioCodec(i))
|
request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(_mediaEncoder.CanEncodeToAudioCodec)
|
||||||
?? state.SupportedAudioCodecs.FirstOrDefault();
|
?? state.SupportedAudioCodecs.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6991,7 +6915,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return " -codec:s:0 " + codec + " -disposition:s:0 default";
|
return " -codec:s:0 " + codec + " -disposition:s:0 default";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetProgressiveVideoFullCommandLine(EncodingJobInfo state, EncodingOptions encodingOptions, string defaultPreset)
|
public string GetProgressiveVideoFullCommandLine(EncodingJobInfo state, EncodingOptions encodingOptions, EncoderPreset defaultPreset)
|
||||||
{
|
{
|
||||||
// Get the output codec name
|
// Get the output codec name
|
||||||
var videoCodec = GetVideoEncoder(state, encodingOptions);
|
var videoCodec = GetVideoEncoder(state, encodingOptions);
|
||||||
@ -7042,7 +6966,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetProgressiveVideoArguments(EncodingJobInfo state, EncodingOptions encodingOptions, string videoCodec, string defaultPreset)
|
public string GetProgressiveVideoArguments(EncodingJobInfo state, EncodingOptions encodingOptions, string videoCodec, EncoderPreset defaultPreset)
|
||||||
{
|
{
|
||||||
var args = "-codec:v:0 " + videoCodec;
|
var args = "-codec:v:0 " + videoCodec;
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
if (OperatingSystem.IsLinux()
|
if (OperatingSystem.IsLinux()
|
||||||
&& SupportsHwaccel("vaapi")
|
&& SupportsHwaccel("vaapi")
|
||||||
&& !string.IsNullOrEmpty(options.VaapiDevice)
|
&& !string.IsNullOrEmpty(options.VaapiDevice)
|
||||||
&& string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase))
|
&& options.HardwareAccelerationType == HardwareAccelerationType.vaapi)
|
||||||
{
|
{
|
||||||
_isVaapiDeviceAmd = validator.CheckVaapiDeviceByDriverName("Mesa Gallium driver", options.VaapiDevice);
|
_isVaapiDeviceAmd = validator.CheckVaapiDeviceByDriverName("Mesa Gallium driver", options.VaapiDevice);
|
||||||
_isVaapiDeviceInteliHD = validator.CheckVaapiDeviceByDriverName("Intel iHD driver", options.VaapiDevice);
|
_isVaapiDeviceInteliHD = validator.CheckVaapiDeviceByDriverName("Intel iHD driver", options.VaapiDevice);
|
||||||
@ -799,11 +799,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
|
|
||||||
if (allowHwAccel && enableKeyFrameOnlyExtraction)
|
if (allowHwAccel && enableKeyFrameOnlyExtraction)
|
||||||
{
|
{
|
||||||
var supportsKeyFrameOnly = (string.Equals(options.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase) && options.EnableEnhancedNvdecDecoder)
|
var hardwareAccelerationType = options.HardwareAccelerationType;
|
||||||
|| (string.Equals(options.HardwareAccelerationType, "amf", StringComparison.OrdinalIgnoreCase) && OperatingSystem.IsWindows())
|
var supportsKeyFrameOnly = (hardwareAccelerationType == HardwareAccelerationType.nvenc && options.EnableEnhancedNvdecDecoder)
|
||||||
|| (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) && options.PreferSystemNativeHwDecoder)
|
|| (hardwareAccelerationType == HardwareAccelerationType.amf && OperatingSystem.IsWindows())
|
||||||
|| string.Equals(options.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)
|
|| (hardwareAccelerationType == HardwareAccelerationType.qsv && options.PreferSystemNativeHwDecoder)
|
||||||
|| string.Equals(options.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase);
|
|| hardwareAccelerationType == HardwareAccelerationType.vaapi
|
||||||
|
|| hardwareAccelerationType == HardwareAccelerationType.videotoolbox;
|
||||||
if (!supportsKeyFrameOnly)
|
if (!supportsKeyFrameOnly)
|
||||||
{
|
{
|
||||||
// Disable hardware acceleration when the hardware decoder does not support keyframe only mode.
|
// Disable hardware acceleration when the hardware decoder does not support keyframe only mode.
|
||||||
@ -817,7 +818,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
if (!allowHwAccel)
|
if (!allowHwAccel)
|
||||||
{
|
{
|
||||||
options.EnableHardwareEncoding = false;
|
options.EnableHardwareEncoding = false;
|
||||||
options.HardwareAccelerationType = string.Empty;
|
options.HardwareAccelerationType = HardwareAccelerationType.none;
|
||||||
options.EnableTonemapping = false;
|
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
|
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
|
// VideoToolbox supports low priority decoding, which is useful for trickplay
|
||||||
inputArg = "-hwaccel_flags +low_priority " + inputArg;
|
inputArg = "-hwaccel_flags +low_priority " + inputArg;
|
||||||
|
@ -352,12 +352,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
{
|
{
|
||||||
var audioCodec = state.ActualOutputAudioCodec;
|
var audioCodec = state.ActualOutputAudioCodec;
|
||||||
var videoCodec = state.ActualOutputVideoCodec;
|
var videoCodec = state.ActualOutputVideoCodec;
|
||||||
var hardwareAccelerationTypeString = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
|
var hardwareAccelerationType = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
|
||||||
HardwareEncodingType? hardwareAccelerationType = null;
|
|
||||||
if (Enum.TryParse<HardwareEncodingType>(hardwareAccelerationTypeString, out var parsedHardwareAccelerationType))
|
|
||||||
{
|
|
||||||
hardwareAccelerationType = parsedHardwareAccelerationType;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
|
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma warning disable CA1819 // XML serialization handles collections improperly, so we need to use arrays
|
||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
@ -30,9 +32,9 @@ public class EncodingOptions
|
|||||||
EnableTonemapping = false;
|
EnableTonemapping = false;
|
||||||
EnableVppTonemapping = false;
|
EnableVppTonemapping = false;
|
||||||
EnableVideoToolboxTonemapping = false;
|
EnableVideoToolboxTonemapping = false;
|
||||||
TonemappingAlgorithm = "bt2390";
|
TonemappingAlgorithm = TonemappingAlgorithm.bt2390;
|
||||||
TonemappingMode = "auto";
|
TonemappingMode = TonemappingMode.auto;
|
||||||
TonemappingRange = "auto";
|
TonemappingRange = TonemappingRange.auto;
|
||||||
TonemappingDesat = 0;
|
TonemappingDesat = 0;
|
||||||
TonemappingPeak = 100;
|
TonemappingPeak = 100;
|
||||||
TonemappingParam = 0;
|
TonemappingParam = 0;
|
||||||
@ -41,7 +43,7 @@ public class EncodingOptions
|
|||||||
H264Crf = 23;
|
H264Crf = 23;
|
||||||
H265Crf = 28;
|
H265Crf = 28;
|
||||||
DeinterlaceDoubleRate = false;
|
DeinterlaceDoubleRate = false;
|
||||||
DeinterlaceMethod = "yadif";
|
DeinterlaceMethod = DeinterlaceMethod.yadif;
|
||||||
EnableDecodingColorDepth10Hevc = true;
|
EnableDecodingColorDepth10Hevc = true;
|
||||||
EnableDecodingColorDepth10Vp9 = true;
|
EnableDecodingColorDepth10Vp9 = true;
|
||||||
// Enhanced Nvdec or system native decoder is required for DoVi to SDR tone-mapping.
|
// Enhanced Nvdec or system native decoder is required for DoVi to SDR tone-mapping.
|
||||||
@ -53,8 +55,8 @@ public class EncodingOptions
|
|||||||
AllowHevcEncoding = false;
|
AllowHevcEncoding = false;
|
||||||
AllowAv1Encoding = false;
|
AllowAv1Encoding = false;
|
||||||
EnableSubtitleExtraction = true;
|
EnableSubtitleExtraction = true;
|
||||||
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" };
|
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = ["mkv"];
|
||||||
HardwareDecodingCodecs = new string[] { "h264", "vc1" };
|
HardwareDecodingCodecs = ["h264", "vc1"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -120,7 +122,7 @@ public class EncodingOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the hardware acceleration type.
|
/// Gets or sets the hardware acceleration type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string HardwareAccelerationType { get; set; }
|
public HardwareAccelerationType HardwareAccelerationType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the FFmpeg path as set by the user via the UI.
|
/// Gets or sets the FFmpeg path as set by the user via the UI.
|
||||||
@ -160,17 +162,17 @@ public class EncodingOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the tone-mapping algorithm.
|
/// Gets or sets the tone-mapping algorithm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TonemappingAlgorithm { get; set; }
|
public TonemappingAlgorithm TonemappingAlgorithm { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the tone-mapping mode.
|
/// Gets or sets the tone-mapping mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TonemappingMode { get; set; }
|
public TonemappingMode TonemappingMode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the tone-mapping range.
|
/// Gets or sets the tone-mapping range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TonemappingRange { get; set; }
|
public TonemappingRange TonemappingRange { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the tone-mapping desaturation.
|
/// Gets or sets the tone-mapping desaturation.
|
||||||
@ -210,7 +212,7 @@ public class EncodingOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the encoder preset.
|
/// Gets or sets the encoder preset.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string EncoderPreset { get; set; }
|
public EncoderPreset? EncoderPreset { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the framerate is doubled when deinterlacing.
|
/// Gets or sets a value indicating whether the framerate is doubled when deinterlacing.
|
||||||
@ -220,7 +222,7 @@ public class EncodingOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the deinterlace method.
|
/// Gets or sets the deinterlace method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DeinterlaceMethod { get; set; }
|
public DeinterlaceMethod DeinterlaceMethod { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether 10bit HEVC decoding is enabled.
|
/// Gets or sets a value indicating whether 10bit HEVC decoding is enabled.
|
||||||
|
19
MediaBrowser.Model/Entities/DeinterlaceMethod.cs
Normal file
19
MediaBrowser.Model/Entities/DeinterlaceMethod.cs
Normal file
@ -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
MediaBrowser.Model/Entities/EncoderPreset.cs
Normal file
64
MediaBrowser.Model/Entities/EncoderPreset.cs
Normal file
@ -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
MediaBrowser.Model/Entities/HardwareAccelerationType.cs
Normal file
49
MediaBrowser.Model/Entities/HardwareAccelerationType.cs
Normal file
@ -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
MediaBrowser.Model/Entities/TonemappingAlgorithm.cs
Normal file
49
MediaBrowser.Model/Entities/TonemappingAlgorithm.cs
Normal file
@ -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
MediaBrowser.Model/Entities/TonemappingMode.cs
Normal file
34
MediaBrowser.Model/Entities/TonemappingMode.cs
Normal file
@ -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
MediaBrowser.Model/Entities/TonemappingRange.cs
Normal file
24
MediaBrowser.Model/Entities/TonemappingRange.cs
Normal file
@ -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
|
||||||
|
}
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +1,76 @@
|
|||||||
#nullable disable
|
#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
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the thread count used for encoding.
|
||||||
|
/// </summary>
|
||||||
public string AudioCodec { get; set; }
|
public string AudioCodec { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the thread count used for encoding.
|
||||||
|
/// </summary>
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the thread count used for encoding.
|
||||||
|
/// </summary>
|
||||||
public string Container { get; set; }
|
public string Container { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the video is passed through.
|
||||||
|
/// </summary>
|
||||||
public bool IsVideoDirect { get; set; }
|
public bool IsVideoDirect { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the audio is passed through.
|
||||||
|
/// </summary>
|
||||||
public bool IsAudioDirect { get; set; }
|
public bool IsAudioDirect { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the bitrate.
|
||||||
|
/// </summary>
|
||||||
public int? Bitrate { get; set; }
|
public int? Bitrate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the framerate.
|
||||||
|
/// </summary>
|
||||||
public float? Framerate { get; set; }
|
public float? Framerate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the completion percentage.
|
||||||
|
/// </summary>
|
||||||
public double? CompletionPercentage { get; set; }
|
public double? CompletionPercentage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the video width.
|
||||||
|
/// </summary>
|
||||||
public int? Width { get; set; }
|
public int? Width { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the video height.
|
||||||
|
/// </summary>
|
||||||
public int? Height { get; set; }
|
public int? Height { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the audio channels.
|
||||||
|
/// </summary>
|
||||||
public int? AudioChannels { get; set; }
|
public int? AudioChannels { get; set; }
|
||||||
|
|
||||||
public HardwareEncodingType? HardwareAccelerationType { get; set; }
|
/// <summary>
|
||||||
|
/// Gets or sets the hardware acceleration type.
|
||||||
|
/// </summary>
|
||||||
|
public HardwareAccelerationType? HardwareAccelerationType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the transcode reasons.
|
||||||
|
/// </summary>
|
||||||
public TranscodeReason TranscodeReasons { get; set; }
|
public TranscodeReason TranscodeReasons { get; set; }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -128,7 +128,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
|
|||||||
return false;
|
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);
|
var extension = Path.GetExtension(filePath);
|
||||||
if (extension.IsEmpty)
|
if (extension.IsEmpty)
|
||||||
@ -138,7 +138,7 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
|
|||||||
|
|
||||||
// Remove the leading dot
|
// Remove the leading dot
|
||||||
var extensionWithoutDot = extension[1..];
|
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('.');
|
var allowedExtension = allowedExtensions[i].AsSpan().TrimStart('.');
|
||||||
if (extensionWithoutDot.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))
|
if (extensionWithoutDot.Equals(allowedExtension, StringComparison.OrdinalIgnoreCase))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user