diff options
author | OvchinnikovDmitrii <[email protected]> | 2019-06-14 20:39:32 +0300 |
---|---|---|
committer | Bradley Sepos <[email protected]> | 2019-08-28 13:10:24 -0400 |
commit | 67bf399b8360c255ffc3130cc9857a7c803664c1 (patch) | |
tree | 1e5e3e7b32f0c13a572899309d2e99daaa834ec0 | |
parent | d18951c264350f59edda84305fed9d0ecd4e1496 (diff) |
VCE: Vulkan support on linux.
-rwxr-xr-x | contrib/ffmpeg/A12-FFmpeg-devel-Vulkan-support.patch | 78 | ||||
-rw-r--r-- | libhb/vce_common.c | 44 | ||||
-rw-r--r-- | make/configure.py | 4 |
3 files changed, 113 insertions, 13 deletions
diff --git a/contrib/ffmpeg/A12-FFmpeg-devel-Vulkan-support.patch b/contrib/ffmpeg/A12-FFmpeg-devel-Vulkan-support.patch new file mode 100755 index 000000000..64c4b1132 --- /dev/null +++ b/contrib/ffmpeg/A12-FFmpeg-devel-Vulkan-support.patch @@ -0,0 +1,78 @@ +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 <[email protected]> +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 diff --git a/libhb/vce_common.c b/libhb/vce_common.c index 632bf9757..8223e5671 100644 --- a/libhb/vce_common.c +++ b/libhb/vce_common.c @@ -17,30 +17,32 @@ AMF_RESULT check_component_available(const wchar_t *componentID) { - amf_handle library = NULL; - AMFInit_Fn init_fun; + amf_handle libHandle = NULL; + AMFInit_Fn initFun; AMFFactory *factory = NULL; AMFContext *context = NULL; + AMFContext1 *context1 = NULL; AMFComponent *encoder = NULL; AMFCaps *encoderCaps = NULL; AMF_RESULT result = AMF_FAIL; - library = hb_dlopen(AMF_DLL_NAMEA); - if(!library) + libHandle = hb_dlopen(AMF_DLL_NAMEA); + + if(!libHandle) { result = AMF_FAIL; goto clean; } - init_fun = (AMFInit_Fn)(hb_dlsym(library, AMF_INIT_FUNCTION_NAME)); - if(!init_fun) + initFun = (AMFInit_Fn)(hb_dlsym(libHandle, AMF_INIT_FUNCTION_NAME)); + if(!initFun) { result = AMF_FAIL; hb_error("VCE: Load Library Failed"); goto clean; } - result = init_fun(AMF_FULL_VERSION, &factory); + result = initFun(AMF_FULL_VERSION, &factory); if(result != AMF_OK) { hb_error("VCE: Init Failed"); @@ -58,12 +60,26 @@ AMF_RESULT check_component_available(const wchar_t *componentID) if (result != AMF_OK) { result = context->pVtbl->InitDX9(context, NULL); if (result != AMF_OK) { - hb_error("VCE: DX11 and DX9 Failed"); - goto clean; + AMFGuid guid = IID_AMFContext1(); + result = context->pVtbl->QueryInterface(context, &guid, (void**)&context1); + if (result != AMF_OK) { + hb_error("VCE: CreateContext1() failed"); + goto clean; + } + + result = context1->pVtbl->InitVulkan(context1, NULL); + if (result != AMF_OK) { + if (result == AMF_NOT_SUPPORTED) + hb_error("VCE: AMF via Vulkan is not supported on the given device.\n"); + else + hb_error("VCE: AMF failed to initialise on the given Vulkan device.\n"); + goto clean; + } } } result = factory->pVtbl->CreateComponent(factory, context, componentID, &encoder); + if(result != AMF_OK) { goto clean; @@ -90,9 +106,15 @@ clean: context->pVtbl->Release(context); context = NULL; } - if(library) + if (context1) + { + context1->pVtbl->Terminate(context1); + context1->pVtbl->Release(context1); + context1 = NULL; + } + if(libHandle) { - hb_dlclose(library); + hb_dlclose(libHandle); } return result; diff --git a/make/configure.py b/make/configure.py index cdcd425bc..7e4457fc2 100644 --- a/make/configure.py +++ b/make/configure.py @@ -1401,7 +1401,7 @@ def createCLI( cross = None ): grp.add_argument( '--enable-qsv', dest="enable_qsv", default=IfHost(True, "*-*-mingw*", none=False).value, action='store_true', help=(( 'enable %s' %h ) if h != argparse.SUPPRESS else h) ) grp.add_argument( '--disable-qsv', dest="enable_qsv", action='store_false', help=(( 'disable %s' %h ) if h != argparse.SUPPRESS else h) ) - h = IfHost( 'AMD VCE video encoder', '*-*-mingw*', none=argparse.SUPPRESS).value + h = IfHost( 'AMD VCE video encoder', '*-*-linux*', '*-*-mingw*', none=argparse.SUPPRESS).value grp.add_argument( '--enable-vce', dest="enable_vce", default=IfHost(True, '*-*-mingw*', none=False).value, action='store_true', help=(( 'enable %s' %h ) if h != argparse.SUPPRESS else h) ) grp.add_argument( '--disable-vce', dest="enable_vce", action='store_false', help=(( 'disable %s' %h ) if h != argparse.SUPPRESS else h) ) @@ -1668,7 +1668,7 @@ try: options.enable_qsv = IfHost(options.enable_qsv, '*-*-linux*', '*-*-mingw*', none=False).value # Disable VCE on unsupported platforms - options.enable_vce = IfHost(options.enable_vce, '*-*-mingw*', + options.enable_vce = IfHost(options.enable_vce, '*-*-linux*', '*-*-mingw*', none=False).value |