diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 7c3138002f..0bc922cbbb 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -3947,6 +3947,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasSubs)
{
+ var alphaFormatOpt = string.Empty;
if (hasGraphicalSubs)
{
var subPreProcFilters = GetGraphicalSubPreProcessFilters(swpInW, swpInH, subW, subH, reqW, reqH, reqMaxW, reqMaxH);
@@ -3964,10 +3965,13 @@ namespace MediaBrowser.Controller.MediaEncoding
subFilters.Add(alphaSrcFilter);
subFilters.Add("format=yuva420p");
subFilters.Add(subTextSubtitlesFilter);
+
+ alphaFormatOpt = _mediaEncoder.SupportsFilterWithOption(FilterOptionType.OverlayCudaAlphaFormat)
+ ? ":alpha_format=premultiplied" : string.Empty;
}
subFilters.Add("hwupload=derive_device=cuda");
- overlayFilters.Add("overlay_cuda=eof_action=pass:repeatlast=0");
+ overlayFilters.Add($"overlay_cuda=eof_action=pass:repeatlast=0{alphaFormatOpt}");
}
}
else
@@ -4164,6 +4168,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (hasSubs)
{
+ var alphaFormatOpt = string.Empty;
if (hasGraphicalSubs)
{
var subPreProcFilters = GetGraphicalSubPreProcessFilters(swpInW, swpInH, subW, subH, reqW, reqH, reqMaxW, reqMaxH);
@@ -4181,10 +4186,13 @@ namespace MediaBrowser.Controller.MediaEncoding
subFilters.Add(alphaSrcFilter);
subFilters.Add("format=yuva420p");
subFilters.Add(subTextSubtitlesFilter);
+
+ alphaFormatOpt = _mediaEncoder.SupportsFilterWithOption(FilterOptionType.OverlayOpenclAlphaFormat)
+ ? ":alpha_format=premultiplied" : string.Empty;
}
subFilters.Add("hwupload=derive_device=opencl");
- overlayFilters.Add("overlay_opencl=eof_action=pass:repeatlast=0");
+ overlayFilters.Add($"overlay_opencl=eof_action=pass:repeatlast=0{alphaFormatOpt}");
overlayFilters.Add("hwmap=derive_device=d3d11va:mode=write:reverse=1");
overlayFilters.Add("format=d3d11");
}
@@ -6947,7 +6955,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(videoStream.Codec, "av1", StringComparison.OrdinalIgnoreCase))
{
- return GetHwaccelType(state, options, "av1", bitDepth, hwSurface);
+ var accelType = GetHwaccelType(state, options, "av1", bitDepth, hwSurface);
+ return accelType + ((!string.IsNullOrEmpty(accelType) && isAfbcSupported) ? " -afbc rga" : string.Empty);
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/FilterOptionType.cs b/MediaBrowser.Controller/MediaEncoding/FilterOptionType.cs
index a2b6e1d739..6ad953023d 100644
--- a/MediaBrowser.Controller/MediaEncoding/FilterOptionType.cs
+++ b/MediaBrowser.Controller/MediaEncoding/FilterOptionType.cs
@@ -38,6 +38,16 @@ namespace MediaBrowser.Controller.MediaEncoding
///
/// The transpose_opencl_reversal.
///
- TransposeOpenclReversal = 6
+ TransposeOpenclReversal = 6,
+
+ ///
+ /// The overlay_opencl_alpha_format.
+ ///
+ OverlayOpenclAlphaFormat = 7,
+
+ ///
+ /// The overlay_cuda_alpha_format.
+ ///
+ OverlayCudaAlphaFormat = 8
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 5683de169f..77fd1bcd26 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -150,15 +150,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
"overlay_rkrga"
];
- private static readonly Dictionary _filterOptionsDict = new Dictionary
+ private static readonly Dictionary _filterOptionsDict = new Dictionary
{
- { 0, new string[] { "scale_cuda", "format" } },
- { 1, new string[] { "tonemap_cuda", "GPU accelerated HDR to SDR tonemapping" } },
- { 2, new string[] { "tonemap_opencl", "bt2390" } },
- { 3, new string[] { "overlay_opencl", "Action to take when encountering EOF from secondary input" } },
- { 4, new string[] { "overlay_vaapi", "Action to take when encountering EOF from secondary input" } },
- { 5, new string[] { "overlay_vulkan", "Action to take when encountering EOF from secondary input" } },
- { 6, new string[] { "transpose_opencl", "rotate by half-turn" } }
+ { FilterOptionType.ScaleCudaFormat, ("scale_cuda", "format") },
+ { FilterOptionType.TonemapCudaName, ("tonemap_cuda", "GPU accelerated HDR to SDR tonemapping") },
+ { FilterOptionType.TonemapOpenclBt2390, ("tonemap_opencl", "bt2390") },
+ { FilterOptionType.OverlayOpenclFrameSync, ("overlay_opencl", "Action to take when encountering EOF from secondary input") },
+ { FilterOptionType.OverlayVaapiFrameSync, ("overlay_vaapi", "Action to take when encountering EOF from secondary input") },
+ { FilterOptionType.OverlayVulkanFrameSync, ("overlay_vulkan", "Action to take when encountering EOF from secondary input") },
+ { FilterOptionType.TransposeOpenclReversal, ("transpose_opencl", "rotate by half-turn") },
+ { FilterOptionType.OverlayOpenclAlphaFormat, ("overlay_opencl", "alpha_format") },
+ { FilterOptionType.OverlayCudaAlphaFormat, ("overlay_cuda", "alpha_format") }
};
private static readonly Dictionary _bsfOptionsDict = new Dictionary
@@ -294,7 +296,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
public IEnumerable GetFilters() => GetFFmpegFilters();
- public IDictionary GetFiltersWithOption() => GetFFmpegFiltersWithOption();
+ public IDictionary GetFiltersWithOption() => _filterOptionsDict
+ .ToDictionary(item => item.Key, item => CheckFilterWithOption(item.Value.Item1, item.Value.Item2));
public IDictionary GetBitStreamFiltersWithOption() => _bsfOptionsDict
.ToDictionary(item => item.Key, item => CheckBitStreamFilterWithOption(item.Value.Item1, item.Value.Item2));
@@ -628,20 +631,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
return found;
}
- private Dictionary GetFFmpegFiltersWithOption()
- {
- Dictionary dict = new Dictionary();
- for (int i = 0; i < _filterOptionsDict.Count; i++)
- {
- if (_filterOptionsDict.TryGetValue(i, out var val) && val.Length == 2)
- {
- dict.Add(i, CheckFilterWithOption(val[0], val[1]));
- }
- }
-
- return dict;
- }
-
private string GetProcessOutput(string path, string arguments, bool readStdErr, string? testKey)
{
var redirectStandardIn = !string.IsNullOrEmpty(testKey);
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index bf574a06ff..897652fcd6 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private List _decoders = new List();
private List _hwaccels = new List();
private List _filters = new List();
- private IDictionary _filtersWithOption = new Dictionary();
+ private IDictionary _filtersWithOption = new Dictionary();
private IDictionary _bitStreamFiltersWithOption = new Dictionary();
private bool _isPkeyPauseSupported = false;
@@ -341,7 +341,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_filters = list.ToList();
}
- public void SetAvailableFiltersWithOption(IDictionary dict)
+ public void SetAvailableFiltersWithOption(IDictionary dict)
{
_filtersWithOption = dict;
}
@@ -383,12 +383,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
///
public bool SupportsFilterWithOption(FilterOptionType option)
{
- if (_filtersWithOption.TryGetValue((int)option, out var val))
- {
- return val;
- }
-
- return false;
+ return _filtersWithOption.TryGetValue(option, out var val) && val;
}
public bool SupportsBitStreamFilterWithOption(BitStreamFilterOptionType option)