aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs')
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs120
1 files changed, 77 insertions, 43 deletions
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 7264c5eed..9b5edabc0 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -38,7 +38,10 @@ namespace MediaBrowser.Controller.MediaEncoding
private readonly ISubtitleEncoder _subtitleEncoder;
private readonly IConfiguration _config;
private readonly Version _minKernelVersionAmdVkFmtModifier = new Version(5, 15);
- private readonly Version _minKernelVersioni915Hang = new Version(5, 18);
+ // i915 hang was fixed by linux 6.2 (3f882f2)
+ private readonly Version _minKerneli915Hang = new Version(5, 18);
+ private readonly Version _maxKerneli915Hang = new Version(6, 1, 3);
+ private readonly Version _minFixedKernel60i915Hang = new Version(6, 0, 18);
private static readonly string[] _videoProfilesH264 = new[]
{
@@ -58,6 +61,16 @@ namespace MediaBrowser.Controller.MediaEncoding
"Main10"
};
+ private static readonly HashSet<string> _mp4ContainerNames = new(StringComparer.OrdinalIgnoreCase)
+ {
+ "mp4",
+ "m4a",
+ "m4p",
+ "m4b",
+ "m4r",
+ "m4v",
+ };
+
public EncodingHelper(
IApplicationPaths appPaths,
IMediaEncoder mediaEncoder,
@@ -938,8 +951,10 @@ namespace MediaBrowser.Controller.MediaEncoding
&& state.SubtitleStream.IsExternal)
{
var subtitlePath = state.SubtitleStream.Path;
+ var subtitleExtension = Path.GetExtension(subtitlePath);
- if (string.Equals(Path.GetExtension(subtitlePath), ".sub", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(subtitleExtension, ".sub", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(subtitleExtension, ".sup", StringComparison.OrdinalIgnoreCase))
{
var idxFile = Path.ChangeExtension(subtitlePath, ".idx");
if (File.Exists(idxFile))
@@ -1334,7 +1349,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// which will reduce overhead in performance intensive tasks such as 4k transcoding and tonemapping.
var intelLowPowerHwEncoding = false;
- // Workaround for linux 5.18+ i915 hang at cost of performance.
+ // Workaround for linux 5.18 to 6.1.3 i915 hang at cost of performance.
// https://github.com/intel/media-driver/issues/1456
var enableWaFori915Hang = false;
@@ -1353,18 +1368,25 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
{
- if (OperatingSystem.IsLinux() && Environment.OSVersion.Version >= _minKernelVersioni915Hang)
+ if (OperatingSystem.IsLinux())
{
- var vidDecoder = GetHardwareVideoDecoder(state, encodingOptions) ?? string.Empty;
- var isIntelDecoder = vidDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)
- || vidDecoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase);
- var doOclTonemap = _mediaEncoder.SupportsHwaccel("qsv")
- && IsVaapiSupported(state)
- && IsOpenclFullSupported()
- && !IsVaapiVppTonemapAvailable(state, encodingOptions)
- && IsHwTonemapAvailable(state, encodingOptions);
+ var ver = Environment.OSVersion.Version;
+ var isFixedKernel60 = ver.Major == 6 && ver.Minor == 0 && ver >= _minFixedKernel60i915Hang;
+ var isUnaffectedKernel = ver < _minKerneli915Hang || ver > _maxKerneli915Hang;
- enableWaFori915Hang = isIntelDecoder && doOclTonemap;
+ if (!(isUnaffectedKernel || isFixedKernel60))
+ {
+ var vidDecoder = GetHardwareVideoDecoder(state, encodingOptions) ?? string.Empty;
+ var isIntelDecoder = vidDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)
+ || vidDecoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase);
+ var doOclTonemap = _mediaEncoder.SupportsHwaccel("qsv")
+ && IsVaapiSupported(state)
+ && IsOpenclFullSupported()
+ && !IsVaapiVppTonemapAvailable(state, encodingOptions)
+ && IsHwTonemapAvailable(state, encodingOptions);
+
+ enableWaFori915Hang = isIntelDecoder && doOclTonemap;
+ }
}
if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase))
@@ -2127,15 +2149,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;
@@ -2922,8 +2959,8 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (hasGraphicalSubs)
{
- // [0:s]scale=expr
- var subSwScaleFilter = GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH);
+ // [0:s]scale=s=1280x720
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
}
@@ -3109,9 +3146,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
}
@@ -3311,9 +3346,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
}
@@ -3565,9 +3598,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
}
@@ -3776,9 +3807,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
}
@@ -4037,9 +4066,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
@@ -4234,9 +4261,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
@@ -4411,9 +4436,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasGraphicalSubs)
{
- var subSwScaleFilter = isSwDecoder
- ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH)
- : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
+ var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
@@ -5709,10 +5732,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;
}
@@ -5750,6 +5772,11 @@ namespace MediaBrowser.Controller.MediaEncoding
audioTranscodeParams.Add("-ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture));
}
+ if (!string.IsNullOrEmpty(state.OutputAudioCodec))
+ {
+ audioTranscodeParams.Add("-acodec " + GetAudioEncoder(state));
+ }
+
if (!string.Equals(state.OutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase))
{
// opus only supports specific sampling rates
@@ -5769,6 +5796,13 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
+ // Copy the movflags from GetProgressiveVideoFullCommandLine
+ // See #9248 and the associated PR for why this is needed
+ if (_mp4ContainerNames.Contains(state.OutputContainer))
+ {
+ audioTranscodeParams.Add("-movflags empty_moov+delay_moov");
+ }
+
var threads = GetNumberOfThreads(state, encodingOptions, null);
var inputModifier = GetInputModifier(state, encodingOptions, null);