PR #24393 opened by Forgejo_Fairy
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24393
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24393.patch

Media Foundation encoder builds with `--disable-d3d11va` fail because D3D11 
context members and frame-processing helpers remain compiled while their header 
is excluded. Guard the members, helpers, caller, library and entry-point 
loading, and cleanup with `CONFIG_D3D11VA`, and advertise D3D11 input only when 
enabled.

Fixes #23068. The regression was verified by compiling d56522c6eb75 and its 
immediate parent 96821211c22e with the same disabled-D3D11VA configuration: the 
former fails and the latter succeeds.

Validation used x86_64-w64-mingw32 GCC 13 with mingw-w64 11.0.1 headers. 
Patched master builds and links `ffmpeg.exe` with D3D11VA both enabled and 
disabled. The patch also applies cleanly to release/8.0, release/8.1, and 
release/9.0; on each, the previously failing disabled-D3D11VA build 
successfully compiles `mfenc.o` and `mf_utils.o`. MSVC and Windows encoding 
runtime behavior were not tested.


>From 225f3f35001f2b92f9d7baca00aa2b2f376aa7c4 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Sun, 6 Sep 2026 22:30:22 +0000
Subject: [PATCH] avcodec/mfenc: guard D3D11 input support when disabled

The D3D11 header is conditional, but the context members and frame
processing helpers using its types are not. This breaks Media Foundation
encoder builds with --disable-d3d11va.

Guard the D3D11 context members, helpers and call site, as well as DLL
loading, DXGI entry point loading and cleanup. Only advertise D3D11 input
when the corresponding support is enabled.

Fixes: d56522c6eb754cd5c648bc0c0b39bd4fbd77c47c
Fixes: #23068

Verified with x86_64-w64-mingw32 GCC 13 and mingw-w64 11.0.1:
- The introducing commit fails and its parent builds mfenc.o with
  --disable-d3d11va.
- Patched master builds and links ffmpeg.exe with D3D11VA on and off.
- The patch applies to release/8.0, release/8.1 and release/9.0, where
  mfenc.o and mf_utils.o build with D3D11VA disabled after failing before.

Assisted-by: Fairy
---
 libavcodec/mfenc.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c
index b51735268b..db3c1e10a3 100644
--- a/libavcodec/mfenc.c
+++ b/libavcodec/mfenc.c
@@ -38,10 +38,13 @@
 typedef struct MFContext {
     AVClass *av_class;
     HMODULE library;
+#if CONFIG_D3D11VA
     HMODULE d3d_dll;
     ID3D11DeviceContext* d3d_context;
     IMFDXGIDeviceManager *dxgiManager;
     int resetToken;
+    AVD3D11VADeviceContext* device_hwctx;
+#endif
 
     MFFunctions functions;
     AVFrame *frame;
@@ -64,7 +67,6 @@ typedef struct MFContext {
     int opt_enc_quality;
     int opt_enc_scenario;
     int opt_enc_hw;
-    AVD3D11VADeviceContext* device_hwctx;
 } MFContext;
 
 static int mf_choose_output_type(AVCodecContext *avctx);
@@ -327,6 +329,7 @@ static int mf_a_avframe_to_sample(AVCodecContext *avctx, 
const AVFrame *frame, I
     return 0;
 }
 
+#if CONFIG_D3D11VA
 static int initialize_dxgi_manager(AVCodecContext *avctx)
 {
     MFContext *c = avctx->priv_data;
@@ -410,6 +413,8 @@ static int process_d3d11_frame(AVCodecContext *avctx, const 
AVFrame *frame, IMFS
     return 0;
 }
 
+#endif
+
 static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, 
IMFSample **out_sample)
 {
     MFContext *c = avctx->priv_data;
@@ -463,13 +468,16 @@ static int mf_v_avframe_to_sample(AVCodecContext *avctx, 
const AVFrame *frame, I
     HRESULT hr;
     int ret;
 
+#if CONFIG_D3D11VA
     if (frame->format == AV_PIX_FMT_D3D11) {
         // Handle D3D11 hardware frames
         ret = process_d3d11_frame(avctx, frame, &sample);
         if (ret < 0) {
             return ret;
         }
-    } else {
+    } else
+#endif
+    {
         // Handle software frames
         ret = process_software_frame(avctx, frame, &sample);
         if (ret < 0) {
@@ -1349,7 +1357,9 @@ static int mf_load_library(AVCodecContext *avctx)
 
 #if !HAVE_UWP
     c->library = dlopen("mfplat.dll", 0);
+#if CONFIG_D3D11VA
     c->d3d_dll = dlopen("D3D11.dll", 0);
+#endif
 
     if (!c->library) {
         av_log(c, AV_LOG_ERROR, "DLL mfplat.dll failed to open\n");
@@ -1362,8 +1372,10 @@ static int mf_load_library(AVCodecContext *avctx)
     LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer);
     LOAD_MF_FUNCTION(c, MFCreateSample);
     LOAD_MF_FUNCTION(c, MFCreateMediaType);
+#if CONFIG_D3D11VA
     LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer);
     LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager);
+#endif
     // MFTEnumEx is missing in Windows Vista's mfplat.dll.
     LOAD_MF_FUNCTION(c, MFTEnumEx);
 
@@ -1380,15 +1392,19 @@ static int mf_close(AVCodecContext *avctx)
     if (c->async_events)
         IMFMediaEventGenerator_Release(c->async_events);
 
+#if CONFIG_D3D11VA
     if (c->dxgiManager)
         IMFDXGIDeviceManager_Release(c->dxgiManager);
+#endif
 
 #if !HAVE_UWP
     if (c->library)
         ff_free_mf(&c->functions, &c->mft);
 
     dlclose(c->library);
+#if CONFIG_D3D11VA
     dlclose(c->d3d_dll);
+#endif
     c->library = NULL;
 #else
     ff_free_mf(&c->functions, &c->mft);
@@ -1480,8 +1496,13 @@ static const FFCodecDefault defaults[] = {
     { NULL },
 };
 
+#if CONFIG_D3D11VA
 #define VFMTS \
         CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_D3D11),
+#else
+#define VFMTS \
+        CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P),
+#endif
 #define VCAPS \
         .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID |           
\
                           AV_CODEC_CAP_DR1,
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to