| 
					
				 | 
			
			
				@@ -163,7 +163,8 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool IsVaapiFullSupported() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return _mediaEncoder.SupportsHwaccel("vaapi") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return _mediaEncoder.SupportsHwaccel("drm") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   && _mediaEncoder.SupportsHwaccel("vaapi") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    && _mediaEncoder.SupportsFilter("scale_vaapi") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    && _mediaEncoder.SupportsFilter("deinterlace_vaapi") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    && _mediaEncoder.SupportsFilter("tonemap_vaapi") 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -713,28 +714,43 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 options); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private string GetVaapiDeviceArgs(string renderNodePath, string driver, string kernelDriver, string alias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private string GetVaapiDeviceArgs(string renderNodePath, string driver, string kernelDriver, string srcDeviceAlias, string alias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             alias ??= VaapiAlias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             renderNodePath = renderNodePath ?? "/dev/dri/renderD128"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var options = string.IsNullOrEmpty(driver) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? renderNodePath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : ",driver=" + driver + (string.IsNullOrEmpty(kernelDriver) ? string.Empty : ",kernel_driver=" + kernelDriver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var driverOpts = string.IsNullOrEmpty(driver) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ? ":" + renderNodePath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                : ":,driver=" + driver + (string.IsNullOrEmpty(kernelDriver) ? string.Empty : ",kernel_driver=" + kernelDriver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var options = string.IsNullOrEmpty(srcDeviceAlias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ? driverOpts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                : "@" + srcDeviceAlias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return string.Format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 CultureInfo.InvariantCulture, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                " -init_hw_device vaapi={0}:{1}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " -init_hw_device vaapi={0}{1}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 alias, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 options); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private string GetDrmDeviceArgs(string renderNodePath, string alias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            alias ??= DrmAlias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            renderNodePath = renderNodePath ?? "/dev/dri/renderD128"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return string.Format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                CultureInfo.InvariantCulture, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " -init_hw_device drm={0}:{1}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                alias, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                renderNodePath); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private string GetQsvDeviceArgs(string alias) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var arg = " -init_hw_device qsv=" + (alias ?? QsvAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (OperatingSystem.IsLinux()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // derive qsv from vaapi device 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return GetVaapiDeviceArgs(null, "iHD", "i915", VaapiAlias) + arg + "@" + VaapiAlias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return GetVaapiDeviceArgs(null, "iHD", "i915", null, VaapiAlias) + arg + "@" + VaapiAlias; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (OperatingSystem.IsWindows()) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -828,21 +844,17 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (_mediaEncoder.IsVaapiDeviceInteliHD) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    args.Append(GetVaapiDeviceArgs(null, "iHD", null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    args.Append(GetVaapiDeviceArgs(null, "iHD", null, null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else if (_mediaEncoder.IsVaapiDeviceInteli965) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     // Only override i965 since it has lower priority than iHD in libva lookup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     Environment.SetEnvironmentVariable("LIBVA_DRIVER_NAME", "i965"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     Environment.SetEnvironmentVariable("LIBVA_DRIVER_NAME_JELLYFIN", "i965"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    args.Append(GetVaapiDeviceArgs(null, "i965", null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    args.Append(GetVaapiDeviceArgs(options.VaapiDevice, null, null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    args.Append(GetVaapiDeviceArgs(null, "i965", null, null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var filterDevArgs = GetFilterHwDeviceArgs(VaapiAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var filterDevArgs = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 var doOclTonemap = isHwTonemapAvailable && IsOpenclFullSupported(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (_mediaEncoder.IsVaapiDeviceInteliHD || _mediaEncoder.IsVaapiDeviceInteli965) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -859,15 +871,24 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         && _mediaEncoder.IsVaapiDeviceSupportVulkanFmtModifier 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         && Environment.OSVersion.Version >= _minKernelVersionAmdVkFmtModifier) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        args.Append(GetDrmDeviceArgs(options.VaapiDevice, DrmAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        args.Append(GetVaapiDeviceArgs(null, null, null, DrmAlias, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        args.Append(GetVulkanDeviceArgs(0, null, DrmAlias, VulkanAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         // libplacebo wants an explicitly set vulkan filter device. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        args.Append(GetVulkanDeviceArgs(0, null, VaapiAlias, VulkanAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         filterDevArgs = GetFilterHwDeviceArgs(VulkanAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    else if (doOclTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // ROCm/ROCr OpenCL runtime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        args.Append(GetOpenclDeviceArgs(0, "Advanced Micro Devices", null, OpenclAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        filterDevArgs = GetFilterHwDeviceArgs(OpenclAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        args.Append(GetVaapiDeviceArgs(options.VaapiDevice, null, null, null, VaapiAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        filterDevArgs = GetFilterHwDeviceArgs(VaapiAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (doOclTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            // ROCm/ROCr OpenCL runtime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            args.Append(GetOpenclDeviceArgs(0, "Advanced Micro Devices", null, OpenclAlias)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            filterDevArgs = GetFilterHwDeviceArgs(OpenclAlias); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else if (doOclTonemap) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -3011,6 +3032,75 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     options.TonemappingRange); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public string GetLibplaceboFilter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            EncodingOptions options, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string videoFormat, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bool doTonemap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? videoWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? videoHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? requestedWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? requestedHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? requestedMaxWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int? requestedMaxHeight) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var (outWidth, outHeight) = GetFixedOutputSize( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                requestedWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                requestedHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                requestedMaxWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                requestedMaxHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var isFormatFixed = !string.IsNullOrEmpty(videoFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var isSizeFixed = !videoWidth.HasValue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || outWidth.Value != videoWidth.Value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || !videoHeight.HasValue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || outHeight.Value != videoHeight.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var sizeArg = isSizeFixed ? (":w=" + outWidth.Value + ":h=" + outHeight.Value) : string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var formatArg = isFormatFixed ? (":format=" + videoFormat) : string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var tonemapArg = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (doTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var algorithm = options.TonemappingAlgorithm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var mode = options.TonemappingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var range = options.TonemappingRange; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (string.Equals(algorithm, "bt2390", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    algorithm = "bt.2390"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else if (string.Equals(algorithm, "none", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    algorithm = "clip"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                tonemapArg = ":tonemapping=" + algorithm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (string.Equals(mode, "max", StringComparison.OrdinalIgnoreCase) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    || string.Equals(mode, "rgb", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    tonemapArg += ":tonemapping_mode=" + mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                tonemapArg += ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (string.Equals(range, "tv", StringComparison.OrdinalIgnoreCase) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    || string.Equals(range, "pc", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    tonemapArg += ":range=" + range; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return string.Format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                CultureInfo.InvariantCulture, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "libplacebo=upscaler=none:downscaler=none{0}{1}{2}", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sizeArg, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                formatArg, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                tonemapArg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Gets the parameter of software filter chain. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4240,7 +4330,6 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var isVaapiEncoder = vidEncoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var isSwDecoder = string.IsNullOrEmpty(vidDecoder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var isSwEncoder = !isVaapiEncoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var isVaInVaOut = isVaapiDecoder && isVaapiEncoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4269,99 +4358,81 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     mainFilters.Add(swDeintFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var outFormat = doVkTonemap ? "yuv420p10le" : "nv12"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var swScaleFilter = GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // sw scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add(swScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("format=" + outFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // keep video at memory except vk tonemap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // since the overhead caused by hwupload >>> using sw filter. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // sw => hw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (doVkTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (doVkTonemap || hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mainFilters.Add("hwupload=derive_device=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mainFilters.Add("format=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mainFilters.Add("hwmap=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // sw => hw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("hwupload=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     mainFilters.Add("format=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // sw scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var swScaleFilter = GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add(swScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else if (isVaapiDecoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 // INPUT vaapi surface(vram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // hw deint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (doDeintH2645) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (doVkTonemap || hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var deintFilter = GetHwDeinterlaceFilter(state, options, "vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mainFilters.Add(deintFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // map from vaapi to vulkan/drm via interop (Vega/gfx9+). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("hwmap=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("format=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var outFormat = doVkTonemap ? string.Empty : (hasSubs && isVaInVaOut ? "bgra" : "nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var hwScaleFilter = GetHwScaleFilter("vaapi", outFormat, inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // allocate extra pool sizes for overlay_vulkan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!string.IsNullOrEmpty(hwScaleFilter) && isVaInVaOut && hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    hwScaleFilter += ":extra_hw_frames=32"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // hw scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add(hwScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // hw deint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (doDeintH2645) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var deintFilter = GetHwDeinterlaceFilter(state, options, "vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        mainFilters.Add(deintFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if ((isVaapiDecoder && doVkTonemap) || (isVaInVaOut && (doVkTonemap || hasSubs))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // map from vaapi to vulkan via vaapi-vulkan interop (Vega/gfx9+). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("hwmap=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("format=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // hw scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var hwScaleFilter = GetHwScaleFilter("vaapi", "nv12", inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add(hwScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // vk tonemap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (doVkTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // vk libplacebo 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (doVkTonemap || hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var outFormat = isVaInVaOut && hasSubs ? "bgra" : "nv12"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var tonemapFilter = GetHwTonemapFilter(options, "vulkan", outFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add(tonemapFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var libplaceboFilter = GetLibplaceboFilter(options, "bgra", doVkTonemap, inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mainFilters.Add(libplaceboFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (doVkTonemap && isVaInVaOut && !hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (doVkTonemap && !hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // OUTPUT vaapi(nv12/bgra) surface(vram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // reverse-mapping via vaapi-vulkan interop. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("hwmap=derive_device=vaapi:reverse=1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // OUTPUT vaapi(nv12) surface(vram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // map from vulkan/drm to vaapi via interop (Vega/gfx9+). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mainFilters.Add("hwmap=derive_device=drm"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mainFilters.Add("format=drm_prime"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mainFilters.Add("hwmap=derive_device=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 mainFilters.Add("format=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var memoryOutput = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var isUploadForVkTonemap = isSwDecoder && doVkTonemap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if ((isVaapiDecoder && isSwEncoder) || isUploadForVkTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                memoryOutput = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // clear the surf->meta_offset and output nv12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mainFilters.Add("scale_vaapi=format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // OUTPUT nv12 surface(memory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("hwdownload"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mainFilters.Add("format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // OUTPUT nv12 surface(memory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (isSwDecoder && isVaapiEncoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                memoryOutput = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // hw deint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (doDeintH2645) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var deintFilter = GetHwDeinterlaceFilter(state, options, "vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add(deintFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (memoryOutput) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // text subtitles 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hasTextSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // OUTPUT nv12 surface(memory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (isSwEncoder && (doVkTonemap || isVaapiDecoder)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var textSubtitlesFilter = GetTextSubtitlesFilter(state, false, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mainFilters.Add(textSubtitlesFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("hwdownload"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    mainFilters.Add("format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (memoryOutput && isVaapiEncoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!hasGraphicalSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (isSwDecoder && isVaapiEncoder && !doVkTonemap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     mainFilters.Add("hwupload_vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4370,55 +4441,53 @@ namespace MediaBrowser.Controller.MediaEncoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             /* Make sub and overlay filters for subtitle stream */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var subFilters = new List<string>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var overlayFilters = new List<string>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (isVaInVaOut) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hasSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (hasGraphicalSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (hasGraphicalSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // scale=s=1280x720,format=bgra,hwupload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        subFilters.Add(subSwScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        subFilters.Add("format=bgra"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    else if (hasTextSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        var alphaSrcFilter = GetAlphaSrcFilter(state, inW, inH, reqW, reqH, reqMaxW, reqMaxH, hasAssSubs ? 10 : 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        var subTextSubtitlesFilter = GetTextSubtitlesFilter(state, true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        subFilters.Add(alphaSrcFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        subFilters.Add("format=bgra"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        subFilters.Add(subTextSubtitlesFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // prefer vaapi hwupload to vulkan hwupload, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // Mesa RADV does not support a dedicated transfer queue. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    subFilters.Add("hwupload=derive_device=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    subFilters.Add("format=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    subFilters.Add("hwmap=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    subFilters.Add("format=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // scale=s=1280x720,format=bgra,hwupload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subFilters.Add(subSwScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subFilters.Add("format=bgra"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else if (hasTextSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var alphaSrcFilter = GetAlphaSrcFilter(state, inW, inH, reqW, reqH, reqMaxW, reqMaxH, hasAssSubs ? 10 : 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var subTextSubtitlesFilter = GetTextSubtitlesFilter(state, true, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subFilters.Add(alphaSrcFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subFilters.Add("format=bgra"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subFilters.Add(subTextSubtitlesFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    overlayFilters.Add("overlay_vulkan=eof_action=endall:shortest=1:repeatlast=0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                subFilters.Add("hwupload=derive_device=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                subFilters.Add("format=vulkan"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // TODO: figure out why libplacebo can sync without vaSyncSurface VPP support in radeonsi. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    overlayFilters.Add("libplacebo=format=nv12:apply_filmgrain=0:apply_dolbyvision=0:upscaler=none:downscaler=none:dithering=none"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                overlayFilters.Add("overlay_vulkan=eof_action=endall:shortest=1:repeatlast=0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // OUTPUT vaapi(nv12/bgra) surface(vram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // reverse-mapping via vaapi-vulkan interop. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    overlayFilters.Add("hwmap=derive_device=vaapi:reverse=1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    overlayFilters.Add("format=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (isSwEncoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // OUTPUT nv12 surface(memory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("scale_vulkan=format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("hwdownload"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            else if (memoryOutput) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hasGraphicalSubs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else if (isVaapiEncoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    subFilters.Add(subSwScaleFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // OUTPUT vaapi(nv12) surface(vram) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // map from vulkan/drm to vaapi via interop (Vega/gfx9+). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("hwmap=derive_device=drm"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("format=drm_prime"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("hwmap=derive_device=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("format=vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (isVaapiEncoder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // clear the surf->meta_offset and output nv12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    overlayFilters.Add("scale_vaapi=format=nv12"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // hw deint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (doDeintH2645) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        overlayFilters.Add("hwupload_vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var deintFilter = GetHwDeinterlaceFilter(state, options, "vaapi"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        overlayFilters.Add(deintFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 |