This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 96f93ece11 avutil/hwcontext_amf: Fix double init for derived devices.
96f93ece11 is described below

commit 96f93ece11f47eb5b7677618caeb858e275ae3c4
Author:     Dmitrii Gershenkop <[email protected]>
AuthorDate: Thu Aug 13 11:42:31 2026 +0200
Commit:     ArazIusubov <[email protected]>
CommitDate: Mon Aug 17 14:09:14 2026 +0000

    avutil/hwcontext_amf: Fix double init for derived devices.
    
    Right after device_derive, FFmpeg also calls device_init. And in 
device_init (amf_device_init), the fact that AMF might be already initialized 
with, for example, Vulkan, is ignored and gets initialized again with DX11.
---
 libavutil/hwcontext_amf.c | 86 +++++++++++++++++++++++++++++++++--------------
 libavutil/hwcontext_amf.h |  2 ++
 2 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/libavutil/hwcontext_amf.c b/libavutil/hwcontext_amf.c
index 7d877683b4..5ab9678c3c 100644
--- a/libavutil/hwcontext_amf.c
+++ b/libavutil/hwcontext_amf.c
@@ -558,10 +558,37 @@ static void amf_device_uninit(AVHWDeviceContext 
*device_ctx)
     amf_ctx->version = 0;
 }
 
+enum AMF_MEMORY_TYPE av_amf_get_memory_type(AVAMFDeviceContext *amf_ctx)
+{
+    AMFContext  *context = amf_ctx->context;
+    AMFContext1 *context1 = NULL;
+    AMFGuid guid1 = IID_AMFContext1();
+
+#ifdef _WIN32
+    if (AMF_IFACE_CALL(context, GetDX11Device, AMF_DX11_1))
+        return AMF_MEMORY_DX11;
+
+    if (AMF_IFACE_CALL(context, GetDX9Device, AMF_DX9))
+        return AMF_MEMORY_DX9;
+#endif
+
+    if (AMF_IFACE_CALL(context, QueryInterface, &guid1, (void**)&context1) != 
AMF_OK)
+        return AMF_MEMORY_UNKNOWN;
+
+    if (AMF_IFACE_CALL(context1, GetVulkanDevice)) {
+        context1->pVtbl->Release(context1);
+        return AMF_MEMORY_VULKAN;
+    }
+
+    return AMF_MEMORY_UNKNOWN;
+}
+
 static int amf_device_init(AVHWDeviceContext *ctx)
 {
     AVAMFDeviceContext *amf_ctx = ctx->hwctx;
+    AMFContext *context = amf_ctx->context;
     AMFContext1 *context1 = NULL;
+    AMFGuid guid1 = IID_AMFContext1();
     AMF_RESULT res;
 
     if (!amf_ctx->lock) {
@@ -574,35 +601,44 @@ static int amf_device_init(AVHWDeviceContext *ctx)
         amf_ctx->unlock = amf_unlock_default;
     }
 
-#ifdef _WIN32
-    res = amf_ctx->context->pVtbl->InitDX11(amf_ctx->context, NULL, 
AMF_DX11_1);
-    if (res == AMF_OK || res == AMF_ALREADY_INITIALIZED) {
-        av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via 
D3D11.\n");
-    } else {
-        res = amf_ctx->context->pVtbl->InitDX9(amf_ctx->context, NULL);
-        if (res == AMF_OK) {
-            av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via 
D3D9.\n");
-        } else {
-#endif
-            AMFGuid guid = IID_AMFContext1();
-            res = amf_ctx->context->pVtbl->QueryInterface(amf_ctx->context, 
&guid, (void**)&context1);
-            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, 
"CreateContext1() failed with error %d\n", res);
+    if (av_amf_get_memory_type(amf_ctx) != AMF_MEMORY_UNKNOWN) {
+        av_log(ctx, AV_LOG_VERBOSE, "AMF is already initialized, skipping 
init.\n");
+        return 0;
+    }
 
-            res = context1->pVtbl->InitVulkan(context1, NULL);
-            context1->pVtbl->Release(context1);
-            if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
-                if (res == AMF_NOT_SUPPORTED)
-                    av_log(ctx, AV_LOG_ERROR, "AMF via Vulkan is not supported 
on the given device.\n");
-                else
-                    av_log(ctx, AV_LOG_ERROR, "AMF failed to initialise on the 
given Vulkan device: %d.\n", res);
-                 return AVERROR(ENOSYS);
-            }
-            av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via 
Vulkan.\n");
 #ifdef _WIN32
-        }
-     }
+    res = AMF_IFACE_CALL(context, InitDX11, NULL, AMF_DX11_1);
+    if (res == AMF_OK) {
+        av_log(ctx, AV_LOG_VERBOSE, "Successfully initialized AMF via 
D3D11.\n");
+        return 0;
+    }
+
+    res = AMF_IFACE_CALL(context, InitDX9, NULL);
+    if (res == AMF_OK) {
+        av_log(ctx, AV_LOG_VERBOSE, "Successfully initialized AMF via 
D3D9.\n");
+        return 0;
+    }
+
+    av_log(ctx, AV_LOG_WARNING, "AMF failed to initialize with any of 
supported versions of DirectX, trying Vulkan instead...\n");
 #endif
 
+    res = AMF_IFACE_CALL(context, QueryInterface, &guid1, (void**)&context1);
+    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() 
failed with error %d\n", res);
+
+    res = AMF_IFACE_CALL(context1, InitVulkan, NULL);
+    AMF_IFACE_CALL(context1, Release);
+
+    if (res == AMF_OK)
+        av_log(ctx, AV_LOG_VERBOSE, "Successfully initialized AMF via 
Vulkan.\n");
+    else {
+        if (res == AMF_NOT_SUPPORTED)
+            av_log(ctx, AV_LOG_ERROR, "AMF via Vulkan is not supported on the 
given device.\n");
+        else
+            av_log(ctx, AV_LOG_ERROR, "Failed to initialize AMF via Vulkan, 
error %d\n", res);
+
+        return AVERROR(ENOSYS);
+    }
+
     return 0;
 }
 
diff --git a/libavutil/hwcontext_amf.h b/libavutil/hwcontext_amf.h
index 918eec97b8..d2bbb41891 100644
--- a/libavutil/hwcontext_amf.h
+++ b/libavutil/hwcontext_amf.h
@@ -46,6 +46,8 @@ typedef struct AVAMFDeviceContext {
     void *lock_ctx;
 } AVAMFDeviceContext;
 
+enum AMF_MEMORY_TYPE av_amf_get_memory_type(AVAMFDeviceContext *amf_ctx);
+
 enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt);
 enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt);
 

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to