From patchwork Thu Oct 15 00:16:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitrii Ovchinnikov X-Patchwork-Id: 22962 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 0EB41449F2C for ; Thu, 15 Oct 2020 03:42:56 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E1A2668B9F1; Thu, 15 Oct 2020 03:42:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f68.google.com (mail-lf1-f68.google.com [209.85.167.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 21FD368A94D for ; Thu, 15 Oct 2020 03:42:49 +0300 (EEST) Received: by mail-lf1-f68.google.com with SMTP id z2so1557549lfr.1 for ; Wed, 14 Oct 2020 17:42:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SGNkpsYxvaQu2E3yih1iXMvqKaK9p1l+d+OJpmiA2lk=; b=QB3aYcutOGJ6N7Uz3LXYcFc2ugdgJr4HuIrvHd+oM2XZdT5j/v3zI5W9i48tXgPtXZ yNe5E1nlBCJN/j8PDS4kNUYxKnp23QUFitOAm6tJWN+SrFG61gjUyq5GwPWMn/W2hgWC tAJURVcIlcGCo+2+b1IYsW+UFgoFuXyL8aRXHlTT0k7mf1O/u5yGLj5cnYGa7TesfapH dGBw9EIInQ0t2JZ9bB292RquSaBABT1m73ceTzLE8qw8EoSZmGgcPubusja+jMrt4g6p QqEgsXLTlsmPJpkTDMn87jOesMUJCTt9g4lhk5pcGm+NeWrGr09dZB7lpzh70xQZl//l RDDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SGNkpsYxvaQu2E3yih1iXMvqKaK9p1l+d+OJpmiA2lk=; b=mCkrWOnqzOL/M8CziQwFlW9D3KuDZaTAMSAl5qF6vkXDNUxl/y9rM1L2LEDfV7E5V9 S8GVZQ6vpfH6XD3NcuZjtKYwZZ+EKVJKkgtGmansKaQw7z+2/tLlr1kMpRI6VezNp3gB wG0NMq2xRK2CrbW/xFYClHjA/lX8oZ9svHvn+vYSk+otXUB0hzAeSJdHrIANRUTJ+v7a +0lRjRdycgk1mKVHR4rfhzRL8RZDP8bhegX/0aWWY97i9blHGz2fehWiOCWpY8s0NdPj OcFrZG07Yjg+z4dEF5EuB7XVDZvQfWILiWVFUpaYfBZ/4IqoX/iFLiu60wDTQe5+uEk+ CCKg== X-Gm-Message-State: AOAM533iZlCk08NBGsMcc24hcR9QfF/XDE7JP9Wjt7afrKIOjKA8GNu3 0VLwtBNP0pVp5aUQYWuiNE559admSuTXvg== X-Google-Smtp-Source: ABdhPJxfRR9cudYWUhGCK9Z0usWL+Sk1jCuiXS/qgIe0eaj2TiKTePGhmSsWWcU10aVYjOxGat3wSg== X-Received: by 2002:a2e:8e32:: with SMTP id r18mr235289ljk.171.1602721000536; Wed, 14 Oct 2020 17:16:40 -0700 (PDT) Received: from localhost.localdomain (95-55-4-47.dynamic.avangarddsl.ru. [95.55.4.47]) by smtp.googlemail.com with ESMTPSA id q20sm333291lfp.43.2020.10.14.17.16.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Oct 2020 17:16:39 -0700 (PDT) From: OvchinnikovDmitrii To: ffmpeg-devel@ffmpeg.org Date: Thu, 15 Oct 2020 03:16:23 +0300 Message-Id: <20201015001625.32832-3-ovchinnikov.dmitrii@gmail.com> X-Mailer: git-send-email 2.19.1.windows.1 In-Reply-To: <20201015001625.32832-1-ovchinnikov.dmitrii@gmail.com> References: <20201015001625.32832-1-ovchinnikov.dmitrii@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/5] lavc/amfenc: redesign to use hwcontext_amf. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Alexander Kravchenko Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Alexander Kravchenko --- libavcodec/amfenc.c | 266 +++++--------------------------------------- libavcodec/amfenc.h | 25 +---- 2 files changed, 32 insertions(+), 259 deletions(-) diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index 33f97dd582..767eab3d56 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -21,13 +21,6 @@ #include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/hwcontext.h" -#if CONFIG_D3D11VA -#include "libavutil/hwcontext_d3d11va.h" -#endif -#if CONFIG_DXVA2 -#define COBJMACROS -#include "libavutil/hwcontext_dxva2.h" -#endif #include "libavutil/mem.h" #include "libavutil/pixdesc.h" #include "libavutil/time.h" @@ -36,18 +29,14 @@ #include "encode.h" #include "internal.h" -#if CONFIG_D3D11VA -#include +#if CONFIG_DXVA2 +#include #endif -#ifdef _WIN32 -#include "compat/w32dlfcn.h" -#else -#include +#if CONFIG_D3D11VA +#include #endif -#define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf" - #define PTS_PROP L"PtsProp" const enum AVPixelFormat ff_amf_pix_fmts[] = { @@ -89,29 +78,11 @@ static enum AMF_SURFACE_FORMAT amf_av_to_amf_format(enum AVPixelFormat fmt) return AMF_SURFACE_UNKNOWN; } -static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter *pThis, - const wchar_t *scope, const wchar_t *message) -{ - AmfTraceWriter *tracer = (AmfTraceWriter*)pThis; - av_log(tracer->avctx, AV_LOG_DEBUG, "%ls: %ls", scope, message); // \n is provided from AMF -} - -static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter *pThis) -{ -} - -static AMFTraceWriterVtbl tracer_vtbl = -{ - .Write = AMFTraceWriter_Write, - .Flush = AMFTraceWriter_Flush, -}; - -static int amf_load_library(AVCodecContext *avctx) +static int amf_init_context(AVCodecContext *avctx) { - AmfContext *ctx = avctx->priv_data; - AMFInit_Fn init_fun; - AMFQueryVersion_Fn version_fun; - AMF_RESULT res; + AmfContext *ctx = avctx->priv_data; + AVAMFDeviceContext *amf_ctx; + int ret; ctx->delayed_frame = av_frame_alloc(); if (!ctx->delayed_frame) { @@ -124,120 +95,9 @@ static int amf_load_library(AVCodecContext *avctx) } ctx->dts_delay = 0; - - ctx->library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL); - AMF_RETURN_IF_FALSE(ctx, ctx->library != NULL, - AVERROR_UNKNOWN, "DLL %s failed to open\n", AMF_DLL_NAMEA); - - init_fun = (AMFInit_Fn)dlsym(ctx->library, AMF_INIT_FUNCTION_NAME); - AMF_RETURN_IF_FALSE(ctx, init_fun != NULL, AVERROR_UNKNOWN, "DLL %s failed to find function %s\n", AMF_DLL_NAMEA, AMF_INIT_FUNCTION_NAME); - - version_fun = (AMFQueryVersion_Fn)dlsym(ctx->library, AMF_QUERY_VERSION_FUNCTION_NAME); - AMF_RETURN_IF_FALSE(ctx, version_fun != NULL, AVERROR_UNKNOWN, "DLL %s failed to find function %s\n", AMF_DLL_NAMEA, AMF_QUERY_VERSION_FUNCTION_NAME); - - res = version_fun(&ctx->version); - AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_QUERY_VERSION_FUNCTION_NAME, res); - res = init_fun(AMF_FULL_VERSION, &ctx->factory); - AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_INIT_FUNCTION_NAME, res); - res = ctx->factory->pVtbl->GetTrace(ctx->factory, &ctx->trace); - AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetTrace() failed with error %d\n", res); - res = ctx->factory->pVtbl->GetDebug(ctx->factory, &ctx->debug); - AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "GetDebug() failed with error %d\n", res); - return 0; -} - -#if CONFIG_D3D11VA -static int amf_init_from_d3d11_device(AVCodecContext *avctx, AVD3D11VADeviceContext *hwctx) -{ - AmfContext *ctx = avctx->priv_data; - AMF_RESULT res; - - res = ctx->context->pVtbl->InitDX11(ctx->context, hwctx->device, AMF_DX11_1); - if (res != AMF_OK) { - if (res == AMF_NOT_SUPPORTED) - av_log(avctx, AV_LOG_ERROR, "AMF via D3D11 is not supported on the given device.\n"); - else - av_log(avctx, AV_LOG_ERROR, "AMF failed to initialise on the given D3D11 device: %d.\n", res); - return AVERROR(ENODEV); - } - - return 0; -} -#endif - -#if CONFIG_DXVA2 -static int amf_init_from_dxva2_device(AVCodecContext *avctx, AVDXVA2DeviceContext *hwctx) -{ - AmfContext *ctx = avctx->priv_data; - HANDLE device_handle; - IDirect3DDevice9 *device; - HRESULT hr; - AMF_RESULT res; - int ret; - - hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &device_handle); - if (FAILED(hr)) { - av_log(avctx, AV_LOG_ERROR, "Failed to open device handle for Direct3D9 device: %lx.\n", (unsigned long)hr); - return AVERROR_EXTERNAL; - } - - hr = IDirect3DDeviceManager9_LockDevice(hwctx->devmgr, device_handle, &device, FALSE); - if (SUCCEEDED(hr)) { - IDirect3DDeviceManager9_UnlockDevice(hwctx->devmgr, device_handle, FALSE); - ret = 0; - } else { - av_log(avctx, AV_LOG_ERROR, "Failed to lock device handle for Direct3D9 device: %lx.\n", (unsigned long)hr); - ret = AVERROR_EXTERNAL; - } - - IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, device_handle); - - if (ret < 0) - return ret; - - res = ctx->context->pVtbl->InitDX9(ctx->context, device); - - IDirect3DDevice9_Release(device); - - if (res != AMF_OK) { - if (res == AMF_NOT_SUPPORTED) - av_log(avctx, AV_LOG_ERROR, "AMF via D3D9 is not supported on the given device.\n"); - else - av_log(avctx, AV_LOG_ERROR, "AMF failed to initialise on given D3D9 device: %d.\n", res); - return AVERROR(ENODEV); - } - - return 0; -} -#endif - -static int amf_init_context(AVCodecContext *avctx) -{ - AmfContext *ctx = avctx->priv_data; - AMFContext1 *context1 = NULL; - AMF_RESULT res; - av_unused int ret; - ctx->hwsurfaces_in_queue = 0; ctx->hwsurfaces_in_queue_max = 16; - // configure AMF logger - // the return of these functions indicates old state and do not affect behaviour - ctx->trace->pVtbl->EnableWriter(ctx->trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, ctx->log_to_dbg != 0 ); - if (ctx->log_to_dbg) - ctx->trace->pVtbl->SetWriterLevel(ctx->trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, AMF_TRACE_TRACE); - ctx->trace->pVtbl->EnableWriter(ctx->trace, AMF_TRACE_WRITER_CONSOLE, 0); - ctx->trace->pVtbl->SetGlobalLevel(ctx->trace, AMF_TRACE_TRACE); - - // connect AMF logger to av_log - ctx->tracer.vtbl = &tracer_vtbl; - ctx->tracer.avctx = avctx; - ctx->trace->pVtbl->RegisterWriter(ctx->trace, FFMPEG_AMF_WRITER_ID,(AMFTraceWriter*)&ctx->tracer, 1); - ctx->trace->pVtbl->SetWriterLevel(ctx->trace, FFMPEG_AMF_WRITER_ID, AMF_TRACE_TRACE); - - res = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx->context); - 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. if (avctx->hw_frames_ctx) { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; @@ -248,27 +108,9 @@ static int amf_init_context(AVCodecContext *avctx) return AVERROR(EINVAL); } - switch (frames_ctx->device_ctx->type) { -#if CONFIG_D3D11VA - case AV_HWDEVICE_TYPE_D3D11VA: - ret = amf_init_from_d3d11_device(avctx, frames_ctx->device_ctx->hwctx); - if (ret < 0) - return ret; - break; -#endif -#if CONFIG_DXVA2 - case AV_HWDEVICE_TYPE_DXVA2: - ret = amf_init_from_dxva2_device(avctx, frames_ctx->device_ctx->hwctx); - if (ret < 0) - return ret; - break; -#endif - default: - av_log(avctx, AV_LOG_ERROR, "AMF initialisation from a %s frames context is not supported.\n", - av_hwdevice_get_type_name(frames_ctx->device_ctx->type)); - return AVERROR(ENOSYS); - } - + ret = av_hwdevice_ctx_create_derived(&ctx->amf_device_ctx, AV_HWDEVICE_TYPE_AMF, frames_ctx->device_ref, 0); + if (ret < 0) + return ret; ctx->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx); if (!ctx->hw_frames_ctx) return AVERROR(ENOMEM); @@ -277,59 +119,17 @@ static int amf_init_context(AVCodecContext *avctx) ctx->hwsurfaces_in_queue_max = frames_ctx->initial_pool_size - 1; } else if (avctx->hw_device_ctx) { - AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data; - - switch (device_ctx->type) { -#if CONFIG_D3D11VA - case AV_HWDEVICE_TYPE_D3D11VA: - ret = amf_init_from_d3d11_device(avctx, device_ctx->hwctx); - if (ret < 0) - return ret; - break; -#endif -#if CONFIG_DXVA2 - case AV_HWDEVICE_TYPE_DXVA2: - ret = amf_init_from_dxva2_device(avctx, device_ctx->hwctx); - if (ret < 0) - return ret; - break; -#endif - default: - av_log(avctx, AV_LOG_ERROR, "AMF initialisation from a %s device is not supported.\n", - av_hwdevice_get_type_name(device_ctx->type)); - return AVERROR(ENOSYS); - } - - ctx->hw_device_ctx = av_buffer_ref(avctx->hw_device_ctx); - if (!ctx->hw_device_ctx) - return AVERROR(ENOMEM); - + ret = av_hwdevice_ctx_create_derived(&ctx->amf_device_ctx, AV_HWDEVICE_TYPE_AMF, avctx->hw_device_ctx, 0); + if (ret < 0) + return ret; } else { - res = ctx->context->pVtbl->InitDX11(ctx->context, NULL, AMF_DX11_1); - if (res == AMF_OK) { - av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D11.\n"); - } else { - res = ctx->context->pVtbl->InitDX9(ctx->context, NULL); - if (res == AMF_OK) { - av_log(avctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D9.\n"); - } else { - AMFGuid guid = IID_AMFContext1(); - res = ctx->context->pVtbl->QueryInterface(ctx->context, &guid, (void**)&context1); - AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res); - - res = context1->pVtbl->InitVulkan(context1, NULL); - context1->pVtbl->Release(context1); - 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"); - } - } + ret = av_hwdevice_ctx_create(&ctx->amf_device_ctx, AV_HWDEVICE_TYPE_AMF, NULL, NULL, 0); + if (ret < 0) + return ret; } + amf_ctx = ((AVHWDeviceContext*)ctx->amf_device_ctx->data)->hwctx; + ctx->context = amf_ctx->context; + ctx->factory = amf_ctx->factory; return 0; } @@ -382,29 +182,17 @@ int av_cold ff_amf_encode_close(AVCodecContext *avctx) ctx->encoder = NULL; } - if (ctx->context) { - ctx->context->pVtbl->Terminate(ctx->context); - ctx->context->pVtbl->Release(ctx->context); - ctx->context = NULL; - } av_buffer_unref(&ctx->hw_device_ctx); av_buffer_unref(&ctx->hw_frames_ctx); - if (ctx->trace) { - ctx->trace->pVtbl->UnregisterWriter(ctx->trace, FFMPEG_AMF_WRITER_ID); - } - if (ctx->library) { - dlclose(ctx->library); - ctx->library = NULL; - } - ctx->trace = NULL; - ctx->debug = NULL; ctx->factory = NULL; - ctx->version = 0; + ctx->context = NULL; ctx->delayed_drain = 0; av_frame_free(&ctx->delayed_frame); av_fifo_freep(&ctx->timestamp_list); + av_buffer_unref(&ctx->amf_device_ctx); + return 0; } @@ -508,11 +296,9 @@ int ff_amf_encode_init(AVCodecContext *avctx) { int ret; - if ((ret = amf_load_library(avctx)) == 0) { - if ((ret = amf_init_context(avctx)) == 0) { - if ((ret = amf_init_encoder(avctx)) == 0) { - return 0; - } + if ((ret = amf_init_context(avctx)) == 0) { + if ((ret = amf_init_encoder(avctx)) == 0) { + return 0; } } ff_amf_encode_close(avctx); diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h index 06994da543..96d1942a37 100644 --- a/libavcodec/amfenc.h +++ b/libavcodec/amfenc.h @@ -25,35 +25,22 @@ #include #include "libavutil/fifo.h" +#include "libavutil/hwcontext_amf.h" #include "avcodec.h" #include "hwconfig.h" -/** -* AMF trace writer callback class -* Used to capture all AMF logging -*/ - -typedef struct AmfTraceWriter { - AMFTraceWriterVtbl *vtbl; - AVCodecContext *avctx; -} AmfTraceWriter; - /** * AMF encoder context */ typedef struct AmfContext { AVClass *avclass; - // access to AMF runtime - amf_handle library; ///< handle to DLL library - AMFFactory *factory; ///< pointer to AMF factory - AMFDebug *debug; ///< pointer to AMF debug interface - AMFTrace *trace; ///< pointer to AMF trace interface - - amf_uint64 version; ///< version of AMF runtime - AmfTraceWriter tracer; ///< AMF writer registered with AMF - AMFContext *context; ///< AMF context + + AMFContext *context; + AMFFactory *factory; + AVBufferRef *amf_device_ctx; + //encoder AMFComponent *encoder; ///< AMF encoder object amf_bool eof; ///< flag indicating EOF happened