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

Mark Thompson sw at jkqxz.net
Sun Jul 7 16:10:19 EEST 2019


On 19/06/2019 16:03, OvchinnikovDmitrii wrote:
> 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.

Does Vulkan initialisation work on Windows?

Please add a note in the docs to make it clear that on Linux this only works on the weird proprietary graphics stack that is rarely used and won't be installed by default anywhere.  The regular Mesa driver supports encode through OpenMAX and VAAPI.

> ---
>  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

AMFContext1 seems to be a superset of AMFContext - do you actually need both variables, or can you just have an AMFContext1?

Relatedly, is there any version requirement on this being present?  Currently the only check is for AMF version 1.4.4.1 or greater.

>      //encoder
>      AMFComponent       *encoder; ///< AMF encoder object
>      amf_bool            eof;     ///< flag indicating EOF happened
> 

- Mark


More information about the ffmpeg-devel mailing list