Commit 1fe6854fd9 for ffmpeg
commit 1fe6854fd98e9a3d732d77cbae48e891b92145ff
Author: Julius Bairaktaris <julius@bairaktaris.de>
Date: Mon Sep 28 11:38:02 2026 +0200
avfilter/vf_frc_amf: use the DX11 engine on a DX11 device
Without engine_type, frc_amf uses the runtime's default DX12 engine even
on a DX11 AMF context. The interpolated frames then come back as DX12
surfaces, and the filter runs about three times slower. Select
FRC_ENGINE_DX11 on a DX11 context whose device has feature level 11_1 or
higher, and keep an explicit engine_type. The DX11 engine fails Init()
on 11_0, which is what hwcontext_d3d11va creates, so those devices keep
the default.
Assisted-by: Claude Opus 5.5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
diff --git a/doc/filters.texi b/doc/filters.texi
index b57a5e8a00..b860e64a1d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -15004,9 +15004,14 @@ Specify the engine used to run shaders.
DirectX 11.
@item dx12
-DirectX 12 (Default value).
+DirectX 12.
@end table
+By default DirectX 11 is used when FFmpeg is built with D3D11VA support and
+the AMF context uses a DirectX 11 device with feature level 11_1 or higher,
+which the DirectX 11 engine requires. Otherwise, the AMF runtime default
+(DirectX 12) is used.
+
@item enable
Boolean value: enable/disable FRC. Dynamic value, can be altered at a runtime
without re-initializing the filter. (Default value: enabled).
diff --git a/libavfilter/vf_frc_amf.c b/libavfilter/vf_frc_amf.c
index c7ef58b429..0cd90e42c7 100644
--- a/libavfilter/vf_frc_amf.c
+++ b/libavfilter/vf_frc_amf.c
@@ -95,7 +95,7 @@ static int amf_frc_filter_config_output(AVFilterLink *outlink)
AMFFilterContext *amf_ctx = &frc_ctx->common;
AVAMFDeviceContext *device_ctx = NULL;
- int err;
+ int err, engine_type;
AMF_RESULT res;
enum AVPixelFormat in_format;
@@ -122,8 +122,16 @@ static int amf_frc_filter_config_output(AVFilterLink *outlink)
// Possible bug: FRC must be initialized enabled to be toggleable on the fly after init.
AMF_FRC_ASSIGN_PROPERTY_INT64_CHECK(avctx, amf_filter, AMF_FRC_MODE, FRC_x2_PRESENT);
- if (frc_ctx->engine_type != -1)
- AMF_FRC_ASSIGN_PROPERTY_INT64_CHECK(avctx, amf_filter, AMF_FRC_ENGINE_TYPE, frc_ctx->engine_type);
+ engine_type = frc_ctx->engine_type;
+#if CONFIG_D3D11VA
+ if (engine_type == -1 && av_amf_get_memory_type(device_ctx) == AMF_MEMORY_DX11) {
+ ID3D11Device *d3d11 = AMF_IFACE_CALL(device_ctx->context, GetDX11Device, AMF_DX11_0);
+ if (d3d11 && d3d11->lpVtbl->GetFeatureLevel(d3d11) >= D3D_FEATURE_LEVEL_11_1)
+ engine_type = FRC_ENGINE_DX11;
+ }
+#endif
+ if (engine_type != -1)
+ AMF_FRC_ASSIGN_PROPERTY_INT64_CHECK(avctx, amf_filter, AMF_FRC_ENGINE_TYPE, engine_type);
AMF_FRC_ASSIGN_PROPERTY_INT64_CHECK(avctx, amf_filter, AMF_FRC_ENABLE_FALLBACK, frc_ctx->fallback);