Adapting AMD VAAPI-Vulkan pipeline to FFmpeg 7.0 (#12577)

This commit is contained in:
Nyanmisaka 2024-09-04 21:36:49 +08:00 committed by GitHub
parent e68755a6c1
commit 95f91e0263
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 11 deletions

View File

@ -67,6 +67,7 @@ namespace MediaBrowser.Controller.MediaEncoding
private readonly Version _minFFmpegWorkingVtHwSurface = new Version(7, 0, 1); private readonly Version _minFFmpegWorkingVtHwSurface = new Version(7, 0, 1);
private readonly Version _minFFmpegDisplayRotationOption = new Version(6, 0); private readonly Version _minFFmpegDisplayRotationOption = new Version(6, 0);
private readonly Version _minFFmpegAdvancedTonemapMode = new Version(7, 0, 1); private readonly Version _minFFmpegAdvancedTonemapMode = new Version(7, 0, 1);
private readonly Version _minFFmpegAlteredVaVkInterop = new Version(7, 0, 1);
private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled); private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled);
@ -3367,15 +3368,7 @@ namespace MediaBrowser.Controller.MediaEncoding
algorithm = "clip"; algorithm = "clip";
} }
tonemapArg = ":tonemapping=" + algorithm; tonemapArg = ":tonemapping=" + algorithm + ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709";
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) if (string.Equals(range, "tv", StringComparison.OrdinalIgnoreCase)
|| string.Equals(range, "pc", StringComparison.OrdinalIgnoreCase)) || string.Equals(range, "pc", StringComparison.OrdinalIgnoreCase))
@ -4804,8 +4797,34 @@ namespace MediaBrowser.Controller.MediaEncoding
if (doVkTranspose || doVkTonemap || hasSubs) if (doVkTranspose || doVkTonemap || hasSubs)
{ {
// map from vaapi to vulkan/drm via interop (Polaris/gfx8+). // map from vaapi to vulkan/drm via interop (Polaris/gfx8+).
mainFilters.Add("hwmap=derive_device=vulkan"); if (_mediaEncoder.EncoderVersion >= _minFFmpegAlteredVaVkInterop)
mainFilters.Add("format=vulkan"); {
if (doVkTranspose || !_mediaEncoder.IsVaapiDeviceSupportVulkanDrmModifier)
{
// disable the indirect va-drm-vk mapping since it's no longer reliable.
mainFilters.Add("hwmap=derive_device=drm");
mainFilters.Add("format=drm_prime");
mainFilters.Add("hwmap=derive_device=vulkan");
mainFilters.Add("format=vulkan");
// workaround for libplacebo using the imported vulkan frame on gfx8.
if (!_mediaEncoder.IsVaapiDeviceSupportVulkanDrmModifier)
{
mainFilters.Add("scale_vulkan");
}
}
else if (doVkTonemap || hasSubs)
{
// non ad-hoc libplacebo also accepts drm_prime direct input.
mainFilters.Add("hwmap=derive_device=drm");
mainFilters.Add("format=drm_prime");
}
}
else // legacy va-vk mapping that works only in jellyfin-ffmpeg6
{
mainFilters.Add("hwmap=derive_device=vulkan");
mainFilters.Add("format=vulkan");
}
} }
else else
{ {
@ -4840,6 +4859,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
var libplaceboFilter = GetLibplaceboFilter(options, "bgra", doVkTonemap, swpInW, swpInH, reqW, reqH, reqMaxW, reqMaxH); var libplaceboFilter = GetLibplaceboFilter(options, "bgra", doVkTonemap, swpInW, swpInH, reqW, reqH, reqMaxW, reqMaxH);
mainFilters.Add(libplaceboFilter); mainFilters.Add(libplaceboFilter);
mainFilters.Add("format=vulkan");
} }
if (doVkTonemap && !hasSubs) if (doVkTonemap && !hasSubs)

View File

@ -66,6 +66,12 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary> /// <summary>
/// Gets a value indicating whether the configured Vaapi device supports vulkan drm format modifier. /// Gets a value indicating whether the configured Vaapi device supports vulkan drm format modifier.
/// </summary> /// </summary>
/// <value><c>true</c> if the Vaapi device supports vulkan drm format modifier, <c>false</c> otherwise.</value>
bool IsVaapiDeviceSupportVulkanDrmModifier { get; }
/// <summary>
/// Gets a value indicating whether the configured Vaapi device supports vulkan drm interop via dma-buf.
/// </summary>
/// <value><c>true</c> if the Vaapi device supports vulkan drm interop, <c>false</c> otherwise.</value> /// <value><c>true</c> if the Vaapi device supports vulkan drm interop, <c>false</c> otherwise.</value>
bool IsVaapiDeviceSupportVulkanDrmInterop { get; } bool IsVaapiDeviceSupportVulkanDrmInterop { get; }

View File

@ -80,8 +80,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
private bool _isVaapiDeviceAmd = false; private bool _isVaapiDeviceAmd = false;
private bool _isVaapiDeviceInteliHD = false; private bool _isVaapiDeviceInteliHD = false;
private bool _isVaapiDeviceInteli965 = false; private bool _isVaapiDeviceInteli965 = false;
private bool _isVaapiDeviceSupportVulkanDrmModifier = false;
private bool _isVaapiDeviceSupportVulkanDrmInterop = false; private bool _isVaapiDeviceSupportVulkanDrmInterop = false;
private static string[] _vulkanImageDrmFmtModifierExts =
{
"VK_EXT_image_drm_format_modifier",
};
private static string[] _vulkanExternalMemoryDmaBufExts = private static string[] _vulkanExternalMemoryDmaBufExts =
{ {
"VK_KHR_external_memory_fd", "VK_KHR_external_memory_fd",
@ -141,6 +147,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <inheritdoc /> /// <inheritdoc />
public bool IsVaapiDeviceInteli965 => _isVaapiDeviceInteli965; public bool IsVaapiDeviceInteli965 => _isVaapiDeviceInteli965;
/// <inheritdoc />
public bool IsVaapiDeviceSupportVulkanDrmModifier => _isVaapiDeviceSupportVulkanDrmModifier;
/// <inheritdoc /> /// <inheritdoc />
public bool IsVaapiDeviceSupportVulkanDrmInterop => _isVaapiDeviceSupportVulkanDrmInterop; public bool IsVaapiDeviceSupportVulkanDrmInterop => _isVaapiDeviceSupportVulkanDrmInterop;
@ -220,6 +229,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_isVaapiDeviceAmd = validator.CheckVaapiDeviceByDriverName("Mesa Gallium driver", options.VaapiDevice); _isVaapiDeviceAmd = validator.CheckVaapiDeviceByDriverName("Mesa Gallium driver", options.VaapiDevice);
_isVaapiDeviceInteliHD = validator.CheckVaapiDeviceByDriverName("Intel iHD driver", options.VaapiDevice); _isVaapiDeviceInteliHD = validator.CheckVaapiDeviceByDriverName("Intel iHD driver", options.VaapiDevice);
_isVaapiDeviceInteli965 = validator.CheckVaapiDeviceByDriverName("Intel i965 driver", options.VaapiDevice); _isVaapiDeviceInteli965 = validator.CheckVaapiDeviceByDriverName("Intel i965 driver", options.VaapiDevice);
_isVaapiDeviceSupportVulkanDrmModifier = validator.CheckVulkanDrmDeviceByExtensionName(options.VaapiDevice, _vulkanImageDrmFmtModifierExts);
_isVaapiDeviceSupportVulkanDrmInterop = validator.CheckVulkanDrmDeviceByExtensionName(options.VaapiDevice, _vulkanExternalMemoryDmaBufExts); _isVaapiDeviceSupportVulkanDrmInterop = validator.CheckVulkanDrmDeviceByExtensionName(options.VaapiDevice, _vulkanExternalMemoryDmaBufExts);
if (_isVaapiDeviceAmd) if (_isVaapiDeviceAmd)
@ -235,6 +245,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.LogInformation("VAAPI device {RenderNodePath} is Intel GPU (i965)", options.VaapiDevice); _logger.LogInformation("VAAPI device {RenderNodePath} is Intel GPU (i965)", options.VaapiDevice);
} }
if (_isVaapiDeviceSupportVulkanDrmModifier)
{
_logger.LogInformation("VAAPI device {RenderNodePath} supports Vulkan DRM modifier", options.VaapiDevice);
}
if (_isVaapiDeviceSupportVulkanDrmInterop) if (_isVaapiDeviceSupportVulkanDrmInterop)
{ {
_logger.LogInformation("VAAPI device {RenderNodePath} supports Vulkan DRM interop", options.VaapiDevice); _logger.LogInformation("VAAPI device {RenderNodePath} supports Vulkan DRM interop", options.VaapiDevice);