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]
