From 89605d4fb10d008970490c266c3f3256ce7d8db0 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Wed, 4 Dec 2019 18:46:19 +1030 Subject: [PATCH 01/20] Fix VAAPI encoding on 10-bit hevc. Update QSV encoding and scaling to take advantage of scale_qsv and overlay_qsv --- .../Playback/Hls/DynamicHlsService.cs | 7 +- .../MediaEncoding/EncodingHelper.cs | 97 ++++++++++++++----- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 9ecb5fe8c5..78de981989 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -945,7 +945,12 @@ namespace MediaBrowser.Api.Playback.Hls var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; - args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()) + keyFrameArg; + args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); + + // Unable to force key frames to h264_qsv transcode + if (codec != "h264_qsv") { + args += " " + keyFrameArg; + } //args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0"; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 0664bdd984..0859ee9268 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -467,6 +467,25 @@ namespace MediaBrowser.Controller.MediaEncoding .Append(' '); } + if (state.IsVideoRequest + && string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) + { + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); + var outputVideoCodec = GetVideoEncoder(state, encodingOptions); + + if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) + { + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + arg.Append("-hwaccel qsv "); + } else { + arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); + } + } + + arg.Append(videoDecoder + " "); + } + arg.Append("-i ") .Append(GetInputPathArgument(state)); @@ -496,6 +515,7 @@ namespace MediaBrowser.Controller.MediaEncoding } } + arg.Append(" -i \"").Append(subtitlePath).Append('\"'); } @@ -1536,13 +1556,11 @@ namespace MediaBrowser.Controller.MediaEncoding { outputSizeParam = "," + outputSizeParam.Substring(index); } - } - else - { + } else { var index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = "," + outputSizeParam.Substring(index); + outputSizeParam = "," + outputSizeParam.Substring(index); } } } @@ -1550,7 +1568,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase) && outputSizeParam.Length == 0) { - outputSizeParam = ",format=nv12|vaapi,hwupload"; + outputSizeParam = ",format=nv12|vaapi,hwupload"; // Add parameters to use VAAPI with burn-in subttiles (GH issue #642) if (state.SubtitleStream != null @@ -1570,7 +1588,12 @@ namespace MediaBrowser.Controller.MediaEncoding state.VideoStream.Width.Value, state.VideoStream.Height.Value); - videoSizeParam += ":force_original_aspect_ratio=decrease"; + if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { + videoSizeParam += ",hwupload=extra_hw_frames=64"; + } else { + videoSizeParam += ":force_original_aspect_ratio=decrease"; + } } var mapPrefix = state.SubtitleStream.IsExternal ? @@ -1581,11 +1604,25 @@ namespace MediaBrowser.Controller.MediaEncoding ? 0 : state.SubtitleStream.Index; + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); + + var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; + + if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } else { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } + } + return string.Format( - CultureInfo.InvariantCulture, - " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\"", + CultureInfo.InvariantCulture, + retStr, mapPrefix, - subtitleStreamIndex, + subtitleStreamIndex, state.VideoStream.Index, outputSizeParam, videoSizeParam); @@ -1647,18 +1684,16 @@ namespace MediaBrowser.Controller.MediaEncoding requestedMaxWidth, requestedMaxHeight); - if (string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) + if ((string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) || string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase)) && width.HasValue && height.HasValue) { - // Work around vaapi's reduced scaling features - var scaler = "scale_vaapi"; - // Given the input dimensions (inputWidth, inputHeight), determine the output dimensions // (outputWidth, outputHeight). The user may request precise output dimensions or maximum // output dimensions. Output dimensions are guaranteed to be even. var outputWidth = width.Value; var outputHeight = height.Value; + var vaapi_or_qsv = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) ? "qsv" : "vaapi"; if (!videoWidth.HasValue || outputWidth != videoWidth.Value @@ -1668,11 +1703,13 @@ namespace MediaBrowser.Controller.MediaEncoding filters.Add( string.Format( CultureInfo.InvariantCulture, - "{0}=w={1}:h={2}", - scaler, + "scale_{0}=w={1}:h={2}:format=nv12", + vaapi_or_qsv, outputWidth, outputHeight)); - } + } else { + filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); + } } else if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1 && width.HasValue @@ -1911,9 +1948,25 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { filters.Add("format=nv12|vaapi"); - filters.Add("hwupload"); + filters.Add("hwupload"); + } + + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); + + // If we are software decoding, and hardware encoding + if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) + && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) + { + filters.Add("format=nv12|qsv"); + filters.Add("hwupload=extra_hw_frames=64"); } + var inputWidth = videoStream?.Width; + var inputHeight = videoStream?.Height; + var threeDFormat = state.MediaSource.Video3DFormat; + + filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight)); + if (state.DeInterlace("h264", true) && string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { @@ -1936,13 +1989,6 @@ namespace MediaBrowser.Controller.MediaEncoding } } - var inputWidth = videoStream?.Width; - var inputHeight = videoStream?.Height; - var threeDFormat = state.MediaSource.Video3DFormat; - - var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); - - filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight)); var output = string.Empty; @@ -2134,10 +2180,9 @@ namespace MediaBrowser.Controller.MediaEncoding } var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); + if (!string.IsNullOrEmpty(videoDecoder)) { - inputModifier += " " + videoDecoder; - if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1) { var videoStream = state.VideoStream; From 78a161138fbcf087cf0130733647cfc541c1da59 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Thu, 5 Dec 2019 18:07:46 +1030 Subject: [PATCH 02/20] Fix formatting stuffed up by previous commit --- .../MediaEncoding/EncodingHelper.cs | 95 ++++++++++--------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 0859ee9268..b32a3108dd 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -467,24 +467,26 @@ namespace MediaBrowser.Controller.MediaEncoding .Append(' '); } - if (state.IsVideoRequest - && string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) - { - var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); - var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - - if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) - { - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) - { - arg.Append("-hwaccel qsv "); - } else { - arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); - } - } - - arg.Append(videoDecoder + " "); - } + if (state.IsVideoRequest + && string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) + { + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); + var outputVideoCodec = GetVideoEncoder(state, encodingOptions); + + if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) + { + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + arg.Append("-hwaccel qsv "); + } + else + { + arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); + } + } + + arg.Append(videoDecoder + " "); + } arg.Append("-i ") .Append(GetInputPathArgument(state)); @@ -1568,7 +1570,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase) && outputSizeParam.Length == 0) { - outputSizeParam = ",format=nv12|vaapi,hwupload"; + outputSizeParam = ",format=nv12|vaapi,hwupload"; // Add parameters to use VAAPI with burn-in subttiles (GH issue #642) if (state.SubtitleStream != null @@ -1588,12 +1590,14 @@ namespace MediaBrowser.Controller.MediaEncoding state.VideoStream.Width.Value, state.VideoStream.Height.Value); - if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) - { - videoSizeParam += ",hwupload=extra_hw_frames=64"; - } else { - videoSizeParam += ":force_original_aspect_ratio=decrease"; - } + if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { + videoSizeParam += ",hwupload=extra_hw_frames=64"; + } + else + { + videoSizeParam += ":force_original_aspect_ratio=decrease"; + } } var mapPrefix = state.SubtitleStream.IsExternal ? @@ -1604,25 +1608,26 @@ namespace MediaBrowser.Controller.MediaEncoding ? 0 : state.SubtitleStream.Index; - var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); - - var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); + var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) - { - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) - { - retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; - } else { - retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; - } + { + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } + else + { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } } return string.Format( - CultureInfo.InvariantCulture, - retStr, + CultureInfo.InvariantCulture, + retStr, mapPrefix, - subtitleStreamIndex, + subtitleStreamIndex, state.VideoStream.Index, outputSizeParam, videoSizeParam); @@ -1693,7 +1698,7 @@ namespace MediaBrowser.Controller.MediaEncoding // output dimensions. Output dimensions are guaranteed to be even. var outputWidth = width.Value; var outputHeight = height.Value; - var vaapi_or_qsv = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) ? "qsv" : "vaapi"; + var vaapi_or_qsv = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) ? "qsv" : "vaapi"; if (!videoWidth.HasValue || outputWidth != videoWidth.Value @@ -1707,9 +1712,11 @@ namespace MediaBrowser.Controller.MediaEncoding vaapi_or_qsv, outputWidth, outputHeight)); - } else { - filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); - } + } + else + { + filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); + } } else if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1 && width.HasValue @@ -1955,10 +1962,10 @@ namespace MediaBrowser.Controller.MediaEncoding // If we are software decoding, and hardware encoding if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) - && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) + && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) { filters.Add("format=nv12|qsv"); - filters.Add("hwupload=extra_hw_frames=64"); + filters.Add("hwupload=extra_hw_frames=64"); } var inputWidth = videoStream?.Width; From 3d8f3da5d6df7b09c61eed68d31eb6aa3bdb6da4 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Thu, 5 Dec 2019 18:39:09 +1030 Subject: [PATCH 03/20] Add comments --- .../MediaEncoding/EncodingHelper.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index b32a3108dd..aefa5d6c6e 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1582,6 +1582,7 @@ namespace MediaBrowser.Controller.MediaEncoding var videoSizeParam = string.Empty; + // Setup subtitle scaling if (state.VideoStream != null && state.VideoStream.Width.HasValue && state.VideoStream.Height.HasValue) { videoSizeParam = string.Format( @@ -1592,6 +1593,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { + //For QSV, feed it into hardware encoder videoSizeParam += ",hwupload=extra_hw_frames=64"; } else @@ -1609,10 +1611,17 @@ namespace MediaBrowser.Controller.MediaEncoding : state.SubtitleStream.Index; var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); + + // Setup default filtergraph utilizing FFMpeg overlay() and FFMpeg scale() (see the return of this function for index reference) var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { + /* + QSV in FFMpeg can now setup hardware overlay for transcodes. + For software decoding and hardware encoding option, frames must be hwuploaded into hardware + with fixed frame size. + */ if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) { retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; @@ -1705,11 +1714,12 @@ namespace MediaBrowser.Controller.MediaEncoding || !videoHeight.HasValue || outputHeight != videoHeight.Value) { + //Force nv12 pixel format to enable 10-bit to 8-bit colour conversion. filters.Add( string.Format( CultureInfo.InvariantCulture, "scale_{0}=w={1}:h={2}:format=nv12", - vaapi_or_qsv, + vaapi_or_qsv, outputWidth, outputHeight)); } From 70530e1f1415522a601709e11a31f8eb6a3f0a64 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Thu, 5 Dec 2019 19:20:47 +1030 Subject: [PATCH 04/20] Fix formatting (2) --- .../Playback/Hls/DynamicHlsService.cs | 8 +- .../MediaEncoding/EncodingHelper.cs | 90 ++++++++++--------- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 78de981989..0918d57afa 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -947,10 +947,10 @@ namespace MediaBrowser.Api.Playback.Hls args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); - // Unable to force key frames to h264_qsv transcode - if (codec != "h264_qsv") { - args += " " + keyFrameArg; - } + // Unable to force key frames to h264_qsv transcode + if (codec != "h264_qsv") { + args += " " + keyFrameArg; + } //args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0"; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index aefa5d6c6e..cd2c2ff2ec 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -467,26 +467,26 @@ namespace MediaBrowser.Controller.MediaEncoding .Append(' '); } - if (state.IsVideoRequest - && string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) - { - var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); - var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - - if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) - { - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) - { - arg.Append("-hwaccel qsv "); - } - else - { - arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); - } - } - - arg.Append(videoDecoder + " "); - } + if (state.IsVideoRequest + && string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) + { + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); + var outputVideoCodec = GetVideoEncoder(state, encodingOptions); + + if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) + { + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + arg.Append("-hwaccel qsv "); + } + else + { + arg.Append("-init_hw_device qsv=hw -filter_hw_device hw "); + } + } + + arg.Append(videoDecoder + " "); + } arg.Append("-i ") .Append(GetInputPathArgument(state)); @@ -1558,11 +1558,13 @@ namespace MediaBrowser.Controller.MediaEncoding { outputSizeParam = "," + outputSizeParam.Substring(index); } - } else { + } + else + { var index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = "," + outputSizeParam.Substring(index); + outputSizeParam = "," + outputSizeParam.Substring(index); } } } @@ -1595,11 +1597,11 @@ namespace MediaBrowser.Controller.MediaEncoding { //For QSV, feed it into hardware encoder videoSizeParam += ",hwupload=extra_hw_frames=64"; - } - else - { - videoSizeParam += ":force_original_aspect_ratio=decrease"; - } + } + else + { + videoSizeParam += ":force_original_aspect_ratio=decrease"; + } } var mapPrefix = state.SubtitleStream.IsExternal ? @@ -1616,27 +1618,27 @@ namespace MediaBrowser.Controller.MediaEncoding var retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay{3}\""; if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) - { + { /* QSV in FFMpeg can now setup hardware overlay for transcodes. For software decoding and hardware encoding option, frames must be hwuploaded into hardware with fixed frame size. */ - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) - { - retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; - } - else - { - retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; - } + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } + else + { + retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]hwupload=extra_hw_frames=64[v];[v][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; + } } return string.Format( CultureInfo.InvariantCulture, - retStr, + retStr, mapPrefix, - subtitleStreamIndex, + subtitleStreamIndex, state.VideoStream.Index, outputSizeParam, videoSizeParam); @@ -1725,8 +1727,8 @@ namespace MediaBrowser.Controller.MediaEncoding } else { - filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); - } + filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); + } } else if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1 && width.HasValue @@ -1965,17 +1967,17 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { filters.Add("format=nv12|vaapi"); - filters.Add("hwupload"); + filters.Add("hwupload"); } var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, options); - // If we are software decoding, and hardware encoding + // If we are software decoding, and hardware encoding if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) - && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) + && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) { filters.Add("format=nv12|qsv"); - filters.Add("hwupload=extra_hw_frames=64"); + filters.Add("hwupload=extra_hw_frames=64"); } var inputWidth = videoStream?.Width; From 8368815788805c610f3a88be405319ae57cb87d1 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 05:03:46 +1030 Subject: [PATCH 05/20] Remove trailing spaces --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index cd2c2ff2ec..5a83661434 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1558,8 +1558,8 @@ namespace MediaBrowser.Controller.MediaEncoding { outputSizeParam = "," + outputSizeParam.Substring(index); } - } - else + } + else { var index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); if (index != -1) From 7d2bfabb32a5876c977a2a9e4d4e196ee6ca73b2 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 05:12:16 +1030 Subject: [PATCH 06/20] Force original aspect ratio can be used for QSV subtitle scaling --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 5a83661434..ad50504715 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1593,14 +1593,12 @@ namespace MediaBrowser.Controller.MediaEncoding state.VideoStream.Width.Value, state.VideoStream.Height.Value); + videoSizeParam += ":force_original_aspect_ratio=decrease"; + + //For QSV, feed it into hardware encoder if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { - //For QSV, feed it into hardware encoder videoSizeParam += ",hwupload=extra_hw_frames=64"; - } - else - { - videoSizeParam += ":force_original_aspect_ratio=decrease"; } } From 9ee0804407d2a3cbcae913386f8799d938f6b7ed Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 05:52:40 +1030 Subject: [PATCH 07/20] Move scaling filters and definitions before deinterlacing --- .../MediaEncoding/EncodingHelper.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ad50504715..480f33e439 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1978,12 +1978,6 @@ namespace MediaBrowser.Controller.MediaEncoding filters.Add("hwupload=extra_hw_frames=64"); } - var inputWidth = videoStream?.Width; - var inputHeight = videoStream?.Height; - var threeDFormat = state.MediaSource.Video3DFormat; - - filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight)); - if (state.DeInterlace("h264", true) && string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { @@ -2006,6 +2000,11 @@ namespace MediaBrowser.Controller.MediaEncoding } } + var inputWidth = videoStream?.Width; + var inputHeight = videoStream?.Height; + var threeDFormat = state.MediaSource.Video3DFormat; + + filters.AddRange(GetScalingFilters(inputWidth, inputHeight, threeDFormat, videoDecoder, outputVideoCodec, request.Width, request.Height, request.MaxWidth, request.MaxHeight)); var output = string.Empty; From a9766992b7893c134c8227a134947ab2e48db0b8 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 06:08:45 +1030 Subject: [PATCH 08/20] Do not force original aspect ratio to decrease, it causes bitmap subtitles to be off-centre --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 480f33e439..d3cef23bd9 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1593,9 +1593,7 @@ namespace MediaBrowser.Controller.MediaEncoding state.VideoStream.Width.Value, state.VideoStream.Height.Value); - videoSizeParam += ":force_original_aspect_ratio=decrease"; - - //For QSV, feed it into hardware encoder + //For QSV, feed it into hardware encoder now if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { videoSizeParam += ",hwupload=extra_hw_frames=64"; From 535390bb6408bc158ea9de99ef6bf0699ffee072 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 06:30:09 +1030 Subject: [PATCH 09/20] QSV can hardware deinterlace too now --- .../MediaEncoding/EncodingHelper.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index d3cef23bd9..0b6c2a2d1f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1976,10 +1976,16 @@ namespace MediaBrowser.Controller.MediaEncoding filters.Add("hwupload=extra_hw_frames=64"); } - if (state.DeInterlace("h264", true) - && string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + if (state.DeInterlace("h264", true)) { - filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_vaapi")); + if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + { + filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_vaapi")); + } + else if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { + filters.Add(string.Format(CultureInfo.InvariantCulture, "deinterlace_qsv")); + } } if ((state.DeInterlace("h264", true) || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true)) From 3f43aef9974b01f88d795641fb947758cd1cc95e Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 16:04:29 +1030 Subject: [PATCH 10/20] Add back code removed during testing/debugging --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 0b6c2a2d1f..550ad78b87 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2203,6 +2203,8 @@ namespace MediaBrowser.Controller.MediaEncoding if (!string.IsNullOrEmpty(videoDecoder)) { + inputModifier += " " + videoDecoder; + if ((videoDecoder ?? string.Empty).IndexOf("_cuvid", StringComparison.OrdinalIgnoreCase) != -1) { var videoStream = state.VideoStream; From 75426d00042f1140d1a9cd2bb3b53e57cc6db343 Mon Sep 17 00:00:00 2001 From: Petr Janda Date: Fri, 6 Dec 2019 17:21:24 +1030 Subject: [PATCH 11/20] Add logging when force_key_frames is disabled --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 0918d57afa..3207a68825 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -948,9 +948,13 @@ namespace MediaBrowser.Api.Playback.Hls args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); // Unable to force key frames to h264_qsv transcode - if (codec != "h264_qsv") { - args += " " + keyFrameArg; - } + if (codec == "h264_qsv") { + Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv"); + } + else + { + args += " " + keyFrameArg; + } //args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0"; From 68edb9734dfc2feec207f00319588d3cec3b67fb Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 7 Dec 2019 06:46:24 +1030 Subject: [PATCH 12/20] Add space between if statement and boolean expression Co-Authored-By: Vasily --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 550ad78b87..8078efced2 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -473,7 +473,7 @@ namespace MediaBrowser.Controller.MediaEncoding var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - if(encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) + if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) { if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) { From 5b5d527a09a94ef847c60578306c858fe6feff89 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 7 Dec 2019 06:47:57 +1030 Subject: [PATCH 13/20] Use string.Equals instead of of equals operator Co-Authored-By: Vasily --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 3207a68825..e3bd3c8c9c 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -948,7 +948,7 @@ namespace MediaBrowser.Api.Playback.Hls args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); // Unable to force key frames to h264_qsv transcode - if (codec == "h264_qsv") { + if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv"); } else From 408cf017a44748f7085af7e5ffa0ca1c46f0ba19 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 7 Dec 2019 06:48:44 +1030 Subject: [PATCH 14/20] Remove newline Co-Authored-By: Vasily --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 8078efced2..2688955409 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -517,7 +517,6 @@ namespace MediaBrowser.Controller.MediaEncoding } } - arg.Append(" -i \"").Append(subtitlePath).Append('\"'); } From f18d3ed33be09c2b083ffe407b180861dc94ea16 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 14 Dec 2019 11:15:30 +1030 Subject: [PATCH 15/20] Formatting fix (3) Co-Authored-By: Bond-009 --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index e3bd3c8c9c..82fa0e8564 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -948,7 +948,8 @@ namespace MediaBrowser.Api.Playback.Hls args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()); // Unable to force key frames to h264_qsv transcode - if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { + if (string.Equals(codec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) + { Logger.LogInformation("Bug Workaround: Disabling force_key_frames for h264_qsv"); } else From 867b61025d0ed4856e3795cce406961dca0f8e3d Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 14 Dec 2019 11:16:27 +1030 Subject: [PATCH 16/20] Use case insensitive contains (1) Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2688955409..84050d4dcc 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -473,7 +473,7 @@ namespace MediaBrowser.Controller.MediaEncoding var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv")) + if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv", StringComparison.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) { From 802a66a9e6e2f78967c01fcfeb8b043c6a7c6901 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 14 Dec 2019 11:16:55 +1030 Subject: [PATCH 17/20] Use case insensitive contains (2) Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 84050d4dcc..8d2a59c870 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -475,7 +475,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (encodingOptions.EnableHardwareEncoding && outputVideoCodec.Contains("qsv", StringComparison.OrdinalIgnoreCase)) { - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)) { arg.Append("-hwaccel qsv "); } From d0febd6c37454df614216d973f21b400923e8e70 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 14 Dec 2019 11:17:37 +1030 Subject: [PATCH 18/20] Use case insensitive contains (3) Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 8d2a59c870..678e851b70 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1619,7 +1619,7 @@ namespace MediaBrowser.Controller.MediaEncoding For software decoding and hardware encoding option, frames must be hwuploaded into hardware with fixed frame size. */ - if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv")) + if (!string.IsNullOrEmpty(videoDecoder) && videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase)) { retStr = " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv=x=(W-w)/2:y=(H-h)/2{3}\""; } From bafcadbe585f022b6463adad790831a31d60261b Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sat, 14 Dec 2019 11:18:53 +1030 Subject: [PATCH 19/20] Use case insensitive contains (4) Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 678e851b70..46669f4e35 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1969,7 +1969,7 @@ namespace MediaBrowser.Controller.MediaEncoding // If we are software decoding, and hardware encoding if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) - && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv"))) + && (string.IsNullOrEmpty(videoDecoder) || !videoDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase))) { filters.Add("format=nv12|qsv"); filters.Add("hwupload=extra_hw_frames=64"); From d063300af481fe385ce1fb61b440217cdd89ef04 Mon Sep 17 00:00:00 2001 From: cryptobank Date: Sun, 15 Dec 2019 20:35:52 +1030 Subject: [PATCH 20/20] Add space Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 46669f4e35..897e22018c 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1711,7 +1711,7 @@ namespace MediaBrowser.Controller.MediaEncoding || !videoHeight.HasValue || outputHeight != videoHeight.Value) { - //Force nv12 pixel format to enable 10-bit to 8-bit colour conversion. + // Force nv12 pixel format to enable 10-bit to 8-bit colour conversion. filters.Add( string.Format( CultureInfo.InvariantCulture,