aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs94
1 files changed, 81 insertions, 13 deletions
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index a459ce8b6..61e925f44 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -68,6 +68,7 @@ namespace MediaBrowser.Controller.MediaEncoding
private readonly Version _minFFmpegDisplayRotationOption = new Version(6, 0);
private readonly Version _minFFmpegAdvancedTonemapMode = new Version(7, 0, 1);
private readonly Version _minFFmpegAlteredVaVkInterop = new Version(7, 0, 1);
+ private readonly Version _minFFmpegQsvVppTonemapOption = new Version(7, 0, 1);
private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled);
@@ -348,7 +349,7 @@ namespace MediaBrowser.Controller.MediaEncoding
&& GetVideoColorBitDepth(state) == 10;
}
- private bool IsVaapiVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options)
+ private bool IsIntelVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options)
{
if (state.VideoStream is null
|| !options.EnableVppTonemapping
@@ -357,7 +358,14 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
- // Native VPP tonemapping may come to QSV in the future.
+ // 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.
+ if (OperatingSystem.IsWindows()
+ && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)
+ && _mediaEncoder.EncoderVersion < _minFFmpegQsvVppTonemapOption)
+ {
+ return false;
+ }
return state.VideoStream.VideoRange == VideoRange.HDR
&& (state.VideoStream.VideoRangeType == VideoRangeType.HDR10
@@ -1662,7 +1670,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var doOclTonemap = _mediaEncoder.SupportsHwaccel("qsv")
&& IsVaapiSupported(state)
&& IsOpenclFullSupported()
- && !IsVaapiVppTonemapAvailable(state, encodingOptions)
+ && !IsIntelVppTonemapAvailable(state, encodingOptions)
&& IsHwTonemapAvailable(state, encodingOptions);
enableWaFori915Hang = isIntelDecoder && doOclTonemap;
@@ -3281,14 +3289,31 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(hwTonemapSuffix, "vaapi", StringComparison.OrdinalIgnoreCase))
{
- args = "procamp_vaapi=b={1}:c={2},tonemap_vaapi=format={0}:p=bt709:t=bt709:m=bt709:extra_hw_frames=32";
+ var doVaVppProcamp = false;
+ var procampParams = string.Empty;
+ if (options.VppTonemappingBrightness != 0
+ && options.VppTonemappingBrightness >= -100
+ && options.VppTonemappingBrightness <= 100)
+ {
+ procampParams += $"=b={options.VppTonemappingBrightness}";
+ doVaVppProcamp = true;
+ }
+
+ if (options.VppTonemappingContrast > 1
+ && options.VppTonemappingContrast <= 10)
+ {
+ procampParams += doVaVppProcamp ? ":" : "=";
+ procampParams += $"c={options.VppTonemappingContrast}";
+ doVaVppProcamp = true;
+ }
+
+ args = "{0}tonemap_vaapi=format={1}:p=bt709:t=bt709:m=bt709:extra_hw_frames=32";
return string.Format(
CultureInfo.InvariantCulture,
args,
- videoFormat ?? "nv12",
- options.VppTonemappingBrightness,
- options.VppTonemappingContrast);
+ doVaVppProcamp ? $"procamp_vaapi{procampParams}," : string.Empty,
+ videoFormat ?? "nv12");
}
else
{
@@ -4012,7 +4037,9 @@ namespace MediaBrowser.Controller.MediaEncoding
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
var doDeintH2645 = doDeintH264 || doDeintHevc;
- var doOclTonemap = IsHwTonemapAvailable(state, options);
+ var doVppTonemap = IsIntelVppTonemapAvailable(state, options);
+ var doOclTonemap = !doVppTonemap && IsHwTonemapAvailable(state, options);
+ var doTonemap = doVppTonemap || doOclTonemap;
var hasSubs = state.SubtitleStream is not null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
var hasTextSubs = hasSubs && state.SubtitleStream.IsTextSubtitleStream;
@@ -4031,7 +4058,7 @@ namespace MediaBrowser.Controller.MediaEncoding
/* Make main filters for video stream */
var mainFilters = new List<string>();
- mainFilters.Add(GetOverwriteColorPropertiesParam(state, doOclTonemap));
+ mainFilters.Add(GetOverwriteColorPropertiesParam(state, doTonemap));
if (isSwDecoder)
{
@@ -4059,9 +4086,33 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (isD3d11vaDecoder || isQsvDecoder)
{
+ var doVppProcamp = false;
+ var procampParams = string.Empty;
+ if (doVppTonemap)
+ {
+ if (options.VppTonemappingBrightness != 0
+ && options.VppTonemappingBrightness >= -100
+ && options.VppTonemappingBrightness <= 100)
+ {
+ procampParams += $":brightness={options.VppTonemappingBrightness}";
+ doVppProcamp = true;
+ }
+
+ if (options.VppTonemappingContrast > 1
+ && options.VppTonemappingContrast <= 10)
+ {
+ procampParams += $":contrast={options.VppTonemappingContrast}";
+ doVppProcamp = true;
+ }
+
+ procampParams += doVppProcamp ? ":procamp=1:async_depth=2" : string.Empty;
+ }
+
var outFormat = doOclTonemap ? (doVppTranspose ? "p010" : string.Empty) : "nv12";
+ outFormat = (doVppTonemap && doVppProcamp) ? "p010" : outFormat;
+
var swapOutputWandH = doVppTranspose && swapWAndH;
- var hwScalePrefix = doVppTranspose ? "vpp" : "scale";
+ var hwScalePrefix = (doVppTranspose || doVppTonemap) ? "vpp" : "scale";
var hwScaleFilter = GetHwScaleFilter(hwScalePrefix, "qsv", outFormat, swapOutputWandH, swpInW, swpInH, reqW, reqH, reqMaxW, reqMaxH);
if (!string.IsNullOrEmpty(hwScaleFilter) && doVppTranspose)
@@ -4069,6 +4120,11 @@ namespace MediaBrowser.Controller.MediaEncoding
hwScaleFilter += $":transpose={tranposeDir}";
}
+ if (!string.IsNullOrEmpty(hwScaleFilter) && doVppTonemap)
+ {
+ hwScaleFilter += doVppProcamp ? procampParams : ":tonemap=1";
+ }
+
if (isD3d11vaDecoder)
{
if (!string.IsNullOrEmpty(hwScaleFilter) || doDeintH2645)
@@ -4086,8 +4142,20 @@ namespace MediaBrowser.Controller.MediaEncoding
mainFilters.Add(deintFilter);
}
- // hw transpose & scale
+ // hw transpose & scale & tonemap(w/o procamp)
mainFilters.Add(hwScaleFilter);
+
+ // hw tonemap(w/ procamp)
+ if (doVppTonemap && doVppProcamp)
+ {
+ mainFilters.Add("vpp_qsv=tonemap=1:format=nv12:async_depth=2");
+ }
+
+ // force bt709 just in case vpp tonemap is not triggered or using MSDK instead of VPL.
+ if (doVppTonemap)
+ {
+ mainFilters.Add(GetOverwriteColorPropertiesParam(state, false));
+ }
}
if (doOclTonemap && isHwDecoder)
@@ -4220,7 +4288,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
- var doVaVppTonemap = IsVaapiVppTonemapAvailable(state, options);
+ var doVaVppTonemap = IsIntelVppTonemapAvailable(state, options);
var doOclTonemap = !doVaVppTonemap && IsHwTonemapAvailable(state, options);
var doTonemap = doVaVppTonemap || doOclTonemap;
var doDeintH2645 = doDeintH264 || doDeintHevc;
@@ -4531,7 +4599,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true);
var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true);
- var doVaVppTonemap = isVaapiDecoder && IsVaapiVppTonemapAvailable(state, options);
+ var doVaVppTonemap = isVaapiDecoder && IsIntelVppTonemapAvailable(state, options);
var doOclTonemap = !doVaVppTonemap && IsHwTonemapAvailable(state, options);
var doTonemap = doVaVppTonemap || doOclTonemap;
var doDeintH2645 = doDeintH264 || doDeintHevc;