From patchwork Mon Sep 17 00:00:00 2001
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [FFmpeg-devel] amfenc: Add support Vulkan encoder
From: OvchinnikovDmitrii <ovchinnikov.dmitrii@gmail.com>
Date: Wed, 5 Jun 2019 02:43:10 +0300
Subject: [PATCH] patch.


---
 libavcodec/amfenc.c | 22 ++++++++++++++++++++--
 libavcodec/amfenc.h |  3 ++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 3be9ff9..04d21f2 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -234,6 +234,7 @@ static int amf_init_context(AVCodecContext *avctx)
     ctx->trace->pVtbl->SetWriterLevel(ctx->trace, FFMPEG_AMF_WRITER_ID, AMF_TRACE_TRACE);
 
     res = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx->context);
+    ctx->context1 = NULL;
     AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext() failed with error %d\n", res);
 
     // If a device was passed to the encoder, try to initialise from that.
@@ -311,8 +312,19 @@ static int amf_init_context(AVCodecContext *avctx)
             if (res == AMF_OK) {
                 av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D9.\n");
             } else {
-                av_log(avctx, AV_LOG_ERROR, "AMF initialisation failed via D3D9: error %d.\n", res);
-                return AVERROR(ENOSYS);
+                AMFGuid guid = IID_AMFContext1();
+                res = ctx->context->pVtbl->QueryInterface(ctx->context, &guid, (void**)&ctx->context1);
+                AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res);
+
+                res = ctx->context1->pVtbl->InitVulkan(ctx->context1, NULL);
+                if (res != AMF_OK) {
+                    if (res == AMF_NOT_SUPPORTED)
+                        av_log(avctx, AV_LOG_ERROR, "AMF via Vulkan is not supported on the given device.\n");
+                    else
+                        av_log(avctx, AV_LOG_ERROR, "AMF failed to initialise on the given Vulkan device: %d.\n", res);
+                    return AVERROR(ENOSYS);
+                }
+                av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via Vulkan.\n");
             }
         }
     }
@@ -373,6 +385,12 @@ int av_cold ff_amf_encode_close(AVCodecContext *avctx)
         ctx->context->pVtbl->Release(ctx->context);
         ctx->context = NULL;
     }
+
+    if (ctx->context1) {
+        ctx->context1->pVtbl->Terminate(ctx->context1);
+        ctx->context1->pVtbl->Release(ctx->context1);
+        ctx->context1 = NULL;
+    }
     av_buffer_unref(&ctx->hw_device_ctx);
     av_buffer_unref(&ctx->hw_frames_ctx);
 
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index b136184..ac2ed43 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -53,7 +53,8 @@ typedef struct AmfContext {
 
     amf_uint64          version; ///< version of AMF runtime
     AmfTraceWriter      tracer;  ///< AMF writer registered with AMF
-    AMFContext         *context; ///< AMF context
+    AMFContext        *context; ///< AMF context
+    AMFContext1       *context1;
     //encoder
     AMFComponent       *encoder; ///< AMF encoder object
     amf_bool            eof;     ///< flag indicating EOF happened
-- 
2.18.0.windows.1
