Add stereo downmix algorithm selection.

pull/9001/head
Shadowghost 1 year ago
parent 223aaec93f
commit 407c716f82

@ -22,6 +22,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Authorization;
@ -1731,7 +1732,12 @@ namespace Jellyfin.Api.Controllers
var channels = state.OutputAudioChannels;
if (channels.HasValue)
if (channels.HasValue
&& (channels.Value != 2
|| (state.AudioStream is not null
&& state.AudioStream.Channels.HasValue
&& state.AudioStream.Channels.Value > 5
&& _encodingOptions.DownMixStereoAlgorithm == DownMixStereoAlgorithms.None)))
{
args += " -ac " + channels.Value;
}

@ -2129,15 +2129,30 @@ namespace MediaBrowser.Controller.MediaEncoding
var filters = new List<string>();
// Boost volume to 200% when downsampling from 6ch to 2ch
if (channels.HasValue
&& channels.Value <= 2
&& channels.Value == 2
&& state.AudioStream is not null
&& state.AudioStream.Channels.HasValue
&& state.AudioStream.Channels.Value > 5
&& !encodingOptions.DownMixAudioBoost.Equals(1))
&& state.AudioStream.Channels.Value > 5)
{
filters.Add("volume=" + encodingOptions.DownMixAudioBoost.ToString(CultureInfo.InvariantCulture));
switch (encodingOptions.DownMixStereoAlgorithm)
{
case DownMixStereoAlgorithms.Dave750:
filters.Add("volume=4.25");
filters.Add("pan=stereo|c0=0.5*c2+0.707*c0+0.707*c4+0.5*c3|c1=0.5*c2+0.707*c1+0.707*c5+0.5*c3");
break;
case DownMixStereoAlgorithms.NightmodeDialogue:
filters.Add("pan=stereo|c0=c2+0.30*c0+0.30*c4|c1=c2+0.30*c1+0.30*c5");
break;
case DownMixStereoAlgorithms.None:
default:
if (!encodingOptions.DownMixAudioBoost.Equals(1))
{
filters.Add("volume=" + encodingOptions.DownMixAudioBoost.ToString(CultureInfo.InvariantCulture));
}
break;
}
}
var isCopyingTimestamps = state.CopyTimestamps || state.TranscodingType != TranscodingJobType.Progressive;
@ -5711,10 +5726,9 @@ namespace MediaBrowser.Controller.MediaEncoding
return args;
}
// Add the number of audio channels
var channels = state.OutputAudioChannels;
if (channels.HasValue)
if (channels.HasValue && ((channels.Value != 2 && state.AudioStream.Channels <= 5) || encodingOptions.DownMixStereoAlgorithm == DownMixStereoAlgorithms.None))
{
args += " -ac " + channels.Value;
}

@ -1,128 +1,247 @@
#nullable disable
#pragma warning disable CS1591
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Model.Configuration
namespace MediaBrowser.Model.Configuration;
/// <summary>
/// Class EncodingOptions.
/// </summary>
public class EncodingOptions
{
public class EncodingOptions
/// <summary>
/// Initializes a new instance of the <see cref="EncodingOptions" /> class.
/// </summary>
public EncodingOptions()
{
public EncodingOptions()
{
EnableFallbackFont = false;
DownMixAudioBoost = 2;
MaxMuxingQueueSize = 2048;
EnableThrottling = false;
ThrottleDelaySeconds = 180;
EncodingThreadCount = -1;
// This is a DRM device that is almost guaranteed to be there on every intel platform,
// plus it's the default one in ffmpeg if you don't specify anything
VaapiDevice = "/dev/dri/renderD128";
EnableTonemapping = false;
EnableVppTonemapping = false;
TonemappingAlgorithm = "bt2390";
TonemappingRange = "auto";
TonemappingDesat = 0;
TonemappingThreshold = 0.8;
TonemappingPeak = 100;
TonemappingParam = 0;
VppTonemappingBrightness = 0;
VppTonemappingContrast = 1.2;
H264Crf = 23;
H265Crf = 28;
DeinterlaceDoubleRate = false;
DeinterlaceMethod = "yadif";
EnableDecodingColorDepth10Hevc = true;
EnableDecodingColorDepth10Vp9 = true;
EnableEnhancedNvdecDecoder = false;
PreferSystemNativeHwDecoder = true;
EnableIntelLowPowerH264HwEncoder = false;
EnableIntelLowPowerHevcHwEncoder = false;
EnableHardwareEncoding = true;
AllowHevcEncoding = false;
EnableSubtitleExtraction = true;
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" };
HardwareDecodingCodecs = new string[] { "h264", "vc1" };
}
public int EncodingThreadCount { get; set; }
public string TranscodingTempPath { get; set; }
public string FallbackFontPath { get; set; }
public bool EnableFallbackFont { get; set; }
public double DownMixAudioBoost { get; set; }
public int MaxMuxingQueueSize { get; set; }
public bool EnableThrottling { get; set; }
public int ThrottleDelaySeconds { get; set; }
public string HardwareAccelerationType { get; set; }
/// <summary>
/// Gets or sets the FFmpeg path as set by the user via the UI.
/// </summary>
public string EncoderAppPath { get; set; }
/// <summary>
/// Gets or sets the current FFmpeg path being used by the system and displayed on the transcode page.
/// </summary>
public string EncoderAppPathDisplay { get; set; }
public string VaapiDevice { get; set; }
public bool EnableTonemapping { get; set; }
public bool EnableVppTonemapping { get; set; }
public string TonemappingAlgorithm { get; set; }
public string TonemappingRange { get; set; }
public double TonemappingDesat { get; set; }
public double TonemappingThreshold { 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 EnableSubtitleExtraction { get; set; }
public string[] HardwareDecodingCodecs { get; set; }
public string[] AllowOnDemandMetadataBasedKeyframeExtractionForExtensions { get; set; }
EnableFallbackFont = false;
DownMixAudioBoost = 2;
DownMixStereoAlgorithm = DownMixStereoAlgorithms.None;
MaxMuxingQueueSize = 2048;
EnableThrottling = false;
ThrottleDelaySeconds = 180;
EncodingThreadCount = -1;
// This is a DRM device that is almost guaranteed to be there on every intel platform,
// plus it's the default one in ffmpeg if you don't specify anything
VaapiDevice = "/dev/dri/renderD128";
EnableTonemapping = false;
EnableVppTonemapping = false;
TonemappingAlgorithm = "bt2390";
TonemappingRange = "auto";
TonemappingDesat = 0;
TonemappingThreshold = 0.8;
TonemappingPeak = 100;
TonemappingParam = 0;
VppTonemappingBrightness = 0;
VppTonemappingContrast = 1.2;
H264Crf = 23;
H265Crf = 28;
DeinterlaceDoubleRate = false;
DeinterlaceMethod = "yadif";
EnableDecodingColorDepth10Hevc = true;
EnableDecodingColorDepth10Vp9 = true;
EnableEnhancedNvdecDecoder = false;
PreferSystemNativeHwDecoder = true;
EnableIntelLowPowerH264HwEncoder = false;
EnableIntelLowPowerHevcHwEncoder = false;
EnableHardwareEncoding = true;
AllowHevcEncoding = false;
EnableSubtitleExtraction = true;
AllowOnDemandMetadataBasedKeyframeExtractionForExtensions = new[] { "mkv" };
HardwareDecodingCodecs = new string[] { "h264", "vc1" };
}
/// <summary>
/// Gets or sets the thread count used for encoding.
/// </summary>
public int EncodingThreadCount { get; set; }
/// <summary>
/// Gets or sets the temporary transcoding path.
/// </summary>
public string TranscodingTempPath { get; set; }
/// <summary>
/// Gets or sets the path to the fallback font.
/// </summary>
public string FallbackFontPath { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to use the fallback font.
/// </summary>
public bool EnableFallbackFont { get; set; }
/// <summary>
/// Gets or sets the audio boost applied when downmixing audio.
/// </summary>
public double DownMixAudioBoost { get; set; }
/// <summary>
/// Gets or sets the algorithm used for downmixing audio to stereo.
/// </summary>
public DownMixStereoAlgorithms DownMixStereoAlgorithm { get; set; }
/// <summary>
/// Gets or sets the maximum size of the muxing queue.
/// </summary>
public int MaxMuxingQueueSize { get; set; }
/// <summary>
/// Gets or sets a value indicating whether throttling is enabled.
/// </summary>
public bool EnableThrottling { get; set; }
/// <summary>
/// Gets or sets the delay after which throttling happens.
/// </summary>
public int ThrottleDelaySeconds { get; set; }
/// <summary>
/// Gets or sets the hardware acceleration type.
/// </summary>
public string HardwareAccelerationType { get; set; }
/// <summary>
/// Gets or sets the FFmpeg path as set by the user via the UI.
/// </summary>
public string EncoderAppPath { get; set; }
/// <summary>
/// Gets or sets the current FFmpeg path being used by the system and displayed on the transcode page.
/// </summary>
public string EncoderAppPathDisplay { get; set; }
/// <summary>
/// Gets or sets the VA-API device.
/// </summary>
public string VaapiDevice { get; set; }
/// <summary>
/// Gets or sets a value indicating whether tonemapping is enabled.
/// </summary>
public bool EnableTonemapping { get; set; }
/// <summary>
/// Gets or sets a value indicating whether VPP tonemapping is enabled.
/// </summary>
public bool EnableVppTonemapping { get; set; }
/// <summary>
/// Gets or sets the tone-mapping algorithm.
/// </summary>
public string TonemappingAlgorithm { get; set; }
/// <summary>
/// Gets or sets the tone-mapping range.
/// </summary>
public string TonemappingRange { get; set; }
/// <summary>
/// Gets or sets the tone-mapping desaturation.
/// </summary>
public double TonemappingDesat { get; set; }
/// <summary>
/// Gets or sets the tone-mapping threshold.
/// </summary>
public double TonemappingThreshold { get; set; }
/// <summary>
/// Gets or sets the tone-mapping peak.
/// </summary>
public double TonemappingPeak { get; set; }
/// <summary>
/// Gets or sets the tone-mapping parameters.
/// </summary>
public double TonemappingParam { get; set; }
/// <summary>
/// Gets or sets the VPP tone-mapping brightness.
/// </summary>
public double VppTonemappingBrightness { get; set; }
/// <summary>
/// Gets or sets the VPP tone-mapping contrast.
/// </summary>
public double VppTonemappingContrast { get; set; }
/// <summary>
/// Gets or sets the H264 CRF.
/// </summary>
public int H264Crf { get; set; }
/// <summary>
/// Gets or sets the H265 CRF.
/// </summary>
public int H265Crf { get; set; }
/// <summary>
/// Gets or sets the encoder preset.
/// </summary>
public string EncoderPreset { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the framerate is doubled when deinterlacing.
/// </summary>
public bool DeinterlaceDoubleRate { get; set; }
/// <summary>
/// Gets or sets the deinterlace method.
/// </summary>
public string DeinterlaceMethod { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 10bit HEVC decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth10Hevc { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 10bit VP9 decoding is enabled.
/// </summary>
public bool EnableDecodingColorDepth10Vp9 { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the enhanced NVDEC is enabled.
/// </summary>
public bool EnableEnhancedNvdecDecoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the system native hardware decoder should be used.
/// </summary>
public bool PreferSystemNativeHwDecoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the Intel H264 low-power hardware encoder should be used.
/// </summary>
public bool EnableIntelLowPowerH264HwEncoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the Intel HEVC low-power hardware encoder should be used.
/// </summary>
public bool EnableIntelLowPowerHevcHwEncoder { get; set; }
/// <summary>
/// Gets or sets a value indicating whether hardware encoding is enabled.
/// </summary>
public bool EnableHardwareEncoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether HEVC encoding is enabled.
/// </summary>
public bool AllowHevcEncoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether subtitle extraction is enabled.
/// </summary>
public bool EnableSubtitleExtraction { get; set; }
/// <summary>
/// Gets or sets the codecs hardware encoding is used for.
/// </summary>
public string[] HardwareDecodingCodecs { get; set; }
/// <summary>
/// Gets or sets the file extensions on-demand metadata based keyframe extraction is enabled for.
/// </summary>
public string[] AllowOnDemandMetadataBasedKeyframeExtractionForExtensions { get; set; }
}

@ -0,0 +1,23 @@
namespace MediaBrowser.Model.Entities;
/// <summary>
/// An enum representing an algorithm to downmix 6ch+ to stereo.
/// Algorithms sourced from https://superuser.com/questions/852400/properly-downmix-5-1-to-stereo-using-ffmpeg/1410620#1410620.
/// </summary>
public enum DownMixStereoAlgorithms
{
/// <summary>
/// No special algorithm.
/// </summary>
None = 0,
/// <summary>
/// Algorithm by Dave_750.
/// </summary>
Dave750 = 1,
/// <summary>
/// Nightmode Dialogue algorithm.
/// </summary>
NightmodeDialogue = 2
}
Loading…
Cancel
Save