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]