[FFmpeg-devel] [PATCH] AMF: Vulkan initialization support for encoder.

OvchinnikovDmitrii ovchinnikov.dmitrii at gmail.com
Wed Jun 19 18:03:07 EEST 2019


Added linux support for amf encoder through vulkan.

To use h.264(AMD VCE) encoder on linux amdgru-pro version 19.20+ and amf-amdgpu-pro package(amdgru-pro contains, but does not install automatically) are required.

Initialization of amf encoder occurs in this order:
1) trying to initialize through dx11
2) trying to initialize through dx9
3) trying to initialize through vulkan

Only Vulkan initialization available on linux.


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

diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 384d8efc92..5f42c2328a 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 b1361842bd..9c4ea7c071 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -54,6 +54,7 @@ typedef struct AmfContext {
     amf_uint64          version; ///< version of AMF runtime
     AmfTraceWriter      tracer;  ///< AMF writer registered with AMF
     AMFContext         *context; ///< AMF context
+    AMFContext1        *context1;///< AMF context1 with vulkan support
     //encoder
     AMFComponent       *encoder; ///< AMF encoder object
     amf_bool            eof;     ///< flag indicating EOF happened
-- 
2.19.1.windows.1



More information about the ffmpeg-devel mailing list