|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
}
|