From patchwork Mon Jul 25 04:11:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xiang, Haihao" X-Patchwork-Id: 36947 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:1649:b0:8b:613a:194d with SMTP id no9csp1814754pzb; Sun, 24 Jul 2022 21:13:50 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t8FFVA9o0nu1gCY/x3KG/FGslw+jgP7ufTunFcXpKuz0lDjTErwRrZThsIM8rD3I2a4ag5 X-Received: by 2002:a17:907:608d:b0:72f:191b:7625 with SMTP id ht13-20020a170907608d00b0072f191b7625mr8659933ejc.754.1658722430621; Sun, 24 Jul 2022 21:13:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658722430; cv=none; d=google.com; s=arc-20160816; b=TEUL/MbeikELm5A/BSJQNEUCv56+C03jnOzZz/0zNP930vn0G6+7RoLIYAVfDIGbM9 MmvvB5N18UVtDkCexbSHOHchq7c0GshdIciKI931xo0XtRRYdh+zxUkRA52B6Z9hG2sA CGpb6Ve+FN4VCyNIHex5gAyIixlYjsjDkiUYyzyp1HFbQgqNDXP3XLeTB7Y3Q2+47YlB 3MMd0kUlJMlxilhNHDZeD+wE9Em+5jDBn3B+XC1U8LfU1dK4TesQ4xyOZcDTgjIF65YV +4GLJrrUzgtjKrvqY6cm/iWFfNnyG6HXXGfJt+Cvcg/4B9lenWsVCL0Omim5FS/Gornk ZZzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to; bh=oltiS7B0ZxF0ZUm8pKJzI4WmdCjdyJN0AHxGVf5Fd9A=; b=e6SVXGE6/MXR1JCduDOOilhTeDNZNTb4c5kzBwxvpwET16npFpOh+bLjHw6n8dt0wR zd8PE082oUPj46+KmDeqC2tvGZR2yFGK8anoS2VnRAHTHvBXPnt6R8Z3YSowyCc2/fH9 vWPb1sxSU69QJd7gaOQ5H0aCNUf8qTUuLPcXMCCJ9n4CLjgtFI2Bn34TrdCWKcQt/jvT wNg4kB0Z/zK71TpepPbk0+5bqMZNlDRfcTDjgsR7wazNnoaQ1/bzfLAnYUxBO5EtV7Cf E3sloKCvbe8ADgRowHJX7Avd5w7U7sn0/n3Fc/SQj03X2xE8sj9qCrvWp9uGcv4IE+gx Vk7w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=XoVGSwN4; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l15-20020a056402230f00b0043a71d95839si10358887eda.546.2022.07.24.21.13.50; Sun, 24 Jul 2022 21:13:50 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=XoVGSwN4; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8137168B87D; Mon, 25 Jul 2022 07:12:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E319568B7E1 for ; Mon, 25 Jul 2022 07:12:19 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1658722340; x=1690258340; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=i0fgplRIzUKWDHHLj8VwsI4HhAtqY+JcEOB1+wISYfg=; b=XoVGSwN4jWsrUwq8uEee2bonQnQlkRuhBI+lzVh6BJ67+VUZA3rO0HCk +C4iVhsel/nvv+hGUBA5qOuNwa1ELrdt81t20hoBbHtBXoOO3G+q+hnx8 QYZ8TmZR2kXLzHR/d48diizPpGLNA5ojku/23InbF4lBeHGLpDnqc2yiQ g+nRa3/QLrojs2JtqEbuhhieoSlVSefrR9OJwrXmCpfYzZGXXrKHaLvYJ usQGvx9b53v1ckxgR/ybsU0WoxGliFWcwUvQFZhQR8tT/arUsURYW+aKq McNr/U036o6AJJKzajsvls5iV4fe0knFgiK/GRLVrunTafBLLLZMMkHb+ w==; X-IronPort-AV: E=McAfee;i="6400,9594,10418"; a="274468235" X-IronPort-AV: E=Sophos;i="5.93,191,1654585200"; d="scan'208";a="274468235" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jul 2022 21:12:14 -0700 X-IronPort-AV: E=Sophos;i="5.93,191,1654585200"; d="scan'208";a="596544038" Received: from xhh-dg164.sh.intel.com ([10.238.5.169]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jul 2022 21:12:13 -0700 From: "Xiang, Haihao" To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 Jul 2022 12:11:48 +0800 Message-Id: <20220725041151.7710-11-haihao.xiang@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220725041151.7710-1-haihao.xiang@intel.com> References: <20220725041151.7710-1-haihao.xiang@intel.com> Subject: [FFmpeg-devel] [PATCH v12 10/13] lavu/hwcontext_qsv: make qsv hwdevice works with oneVPL X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Haihao Xiang , galinart MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 9ECtkKy+2Iq2 From: Haihao Xiang In oneVPL, MFXLoad() and MFXCreateSession() are required to create a workable mfx session[1] Add config filters for D3D9/D3D11 session (galinart) The default device is changed to d3d11va for oneVPL when both d3d11va and dxva2 are enabled on Microsoft Windows This is in preparation for oneVPL support [1] https://spec.oneapi.io/versions/latest/elements/oneVPL/source/programming_guide/VPL_prg_session.html#onevpl-dispatcher Co-authored-by: galinart Signed-off-by: galinart Signed-off-by: Haihao Xiang --- libavutil/hwcontext_qsv.c | 532 +++++++++++++++++++++++++++++++++++--- 1 file changed, 494 insertions(+), 38 deletions(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 21a2a805f8..510f422562 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -49,6 +49,7 @@ #include "pixdesc.h" #include "time.h" #include "imgutils.h" +#include "avassert.h" #define QSV_VERSION_ATLEAST(MAJOR, MINOR) \ (MFX_VERSION_MAJOR > (MAJOR) || \ @@ -58,6 +59,12 @@ #define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) #define QSV_HAVE_OPAQUE !QSV_ONEVPL +#if QSV_ONEVPL +#include +#else +#define MFXUnload(a) do { } while(0) +#endif + typedef struct QSVDevicePriv { AVBufferRef *child_device_ctx; } QSVDevicePriv; @@ -619,6 +626,437 @@ static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) return MFX_ERR_NONE; } +#if QSV_ONEVPL + +static int qsv_d3d11_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ +#if CONFIG_D3D11VA + mfxStatus sts; + IDXGIAdapter *pDXGIAdapter; + DXGI_ADAPTER_DESC adapterDesc; + IDXGIDevice *pDXGIDevice = NULL; + HRESULT hr; + ID3D11Device *device = handle; + mfxVariant impl_value; + + hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void**)&pDXGIDevice); + if (SUCCEEDED(hr)) { + hr = IDXGIDevice_GetAdapter(pDXGIDevice, &pDXGIAdapter); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDXGIDevice_GetAdapter %d\n", hr); + goto fail; + } + + hr = IDXGIAdapter_GetDesc(pDXGIAdapter, &adapterDesc); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDXGIAdapter_GetDesc %d\n", hr); + goto fail; + } + } else { + av_log(ctx, AV_LOG_ERROR, "Error ID3D11Device_QueryInterface %d\n", hr); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = adapterDesc.DeviceId; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceID property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_PTR; + impl_value.Data.Ptr = &adapterDesc.AdapterLuid; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceLUID property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = 0x0001; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.LUIDDeviceNodeMask", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "LUIDDeviceNodeMask property: %d.\n", sts); + goto fail; + } + + return 0; + +fail: +#endif + return AVERROR_UNKNOWN; +} + +static int qsv_d3d9_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ + int ret = AVERROR_UNKNOWN; +#if CONFIG_DXVA2 + mfxStatus sts; + IDirect3DDeviceManager9* devmgr = handle; + IDirect3DDevice9Ex *device = NULL; + HANDLE device_handle = 0; + IDirect3D9Ex *d3d9ex = NULL; + LUID luid; + D3DDEVICE_CREATION_PARAMETERS params; + HRESULT hr; + mfxVariant impl_value; + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(devmgr, &device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error OpenDeviceHandle %d\n", hr); + goto fail; + } + + hr = IDirect3DDeviceManager9_LockDevice(devmgr, device_handle, &device, TRUE); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error LockDevice %d\n", hr); + goto fail; + } + + hr = IDirect3DDevice9Ex_GetCreationParameters(device, ¶ms); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9_GetCreationParameters %d\n", hr); + goto unlock; + } + + hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d9ex); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr); + goto unlock; + } + + hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, params.AdapterOrdinal, &luid); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr); + goto unlock; + } + + impl_value.Type = MFX_VARIANT_TYPE_PTR; + impl_value.Data.Ptr = &luid; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceLUID property: %d.\n", sts); + goto unlock; + } + + ret = 0; + +unlock: + IDirect3DDeviceManager9_UnlockDevice(devmgr, device_handle, FALSE); +fail: +#endif + return ret; +} + +static int qsv_va_update_config(void *ctx, mfxHDL handle, mfxConfig cfg) +{ +#if CONFIG_VAAPI +#if VA_CHECK_VERSION(1, 15, 0) + mfxStatus sts; + VADisplay dpy = handle; + VAStatus vas; + VADisplayAttribute attr = { + .type = VADisplayPCIID, + }; + mfxVariant impl_value; + + vas = vaGetDisplayAttributes(dpy, &attr, 1); + if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED) { + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = (attr.value & 0xFFFF); + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "DeviceID property: %d.\n", sts); + goto fail; + } + } else { + av_log(ctx, AV_LOG_ERROR, "libva: Failed to get device id from the driver. Please " + "consider to upgrade the driver to support VA-API 1.15.0\n"); + goto fail; + } + + return 0; + +fail: +#else + av_log(ctx, AV_LOG_ERROR, "libva: This version of libva doesn't support retrieving " + "the device information from the driver. Please consider to upgrade libva to " + "support VA-API 1.15.0\n"); +#endif +#endif + return AVERROR_UNKNOWN; +} + +static int qsv_new_mfx_loader(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + void **ploader) +{ + mfxStatus sts; + mfxLoader loader = NULL; + mfxConfig cfg; + mfxVariant impl_value; + + *ploader = NULL; + loader = MFXLoad(); + if (!loader) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX loader\n"); + goto fail; + } + + /* Create configurations for implementation */ + cfg = MFXCreateConfig(loader); + if (!cfg) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX configuration\n"); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ? + MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.Impl", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + impl_value.Data.U32 = pver->Version; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.ApiVersion.Version", + impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration " + "property: %d.\n", sts); + goto fail; + } + + impl_value.Type = MFX_VARIANT_TYPE_U16; + impl_value.Data.U16 = 0x8086; // Intel device only + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxExtendedDeviceId.VendorID", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "VendorID property: %d.\n", sts); + goto fail; + } + + if (MFX_HANDLE_VA_DISPLAY == handle_type) { + if (handle && qsv_va_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI; + } else if (MFX_HANDLE_D3D9_DEVICE_MANAGER == handle_type) { + if (handle && qsv_d3d9_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9; + } else { + if (handle && qsv_d3d11_update_config(ctx, handle, cfg)) + goto fail; + + impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11; + } + + impl_value.Type = MFX_VARIANT_TYPE_U32; + sts = MFXSetConfigFilterProperty(cfg, + (const mfxU8 *)"mfxImplDescription.AccelerationMode", impl_value); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration" + "AccelerationMode property: %d.\n", sts); + goto fail; + } + + *ploader = loader; + + return 0; + +fail: + if (loader) + MFXUnload(loader); + + return AVERROR_UNKNOWN; +} + +static int qsv_create_mfx_session_from_loader(void *ctx, mfxLoader loader, mfxSession *psession) +{ + mfxStatus sts; + mfxSession session = NULL; + uint32_t impl_idx = 0; + mfxVersion ver; + + while (1) { + /* Enumerate all implementations */ + mfxImplDescription *impl_desc; + + sts = MFXEnumImplementations(loader, impl_idx, + MFX_IMPLCAPS_IMPLDESCSTRUCTURE, + (mfxHDL *)&impl_desc); + /* Failed to find an available implementation */ + if (sts == MFX_ERR_NOT_FOUND) + break; + else if (sts != MFX_ERR_NONE) { + impl_idx++; + continue; + } + + sts = MFXCreateSession(loader, impl_idx, &session); + MFXDispReleaseImplDescription(loader, impl_desc); + if (sts == MFX_ERR_NONE) + break; + + impl_idx++; + } + + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error creating a MFX session: %d.\n", sts); + goto fail; + } + + sts = MFXQueryVersion(session, &ver); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying a MFX session: %d.\n", sts); + goto fail; + } + + av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation " + "version is %d.%d\n", ver.Major, ver.Minor); + + *psession = session; + + return 0; + +fail: + if (session) + MFXClose(session); + + return AVERROR_UNKNOWN; +} + +static int qsv_create_mfx_session(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + mfxSession *psession, + void **ploader) +{ + mfxLoader loader = NULL; + + av_log(ctx, AV_LOG_VERBOSE, + "Use Intel(R) oneVPL to create MFX session, API version is " + "%d.%d, the required implementation version is %d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor); + + if (handle_type != MFX_HANDLE_VA_DISPLAY && + handle_type != MFX_HANDLE_D3D9_DEVICE_MANAGER && + handle_type != MFX_HANDLE_D3D11_DEVICE) { + av_log(ctx, AV_LOG_ERROR, + "Invalid MFX device handle type\n"); + return AVERROR(EXDEV); + } + + *psession = NULL; + + if (!*ploader) { + if (qsv_new_mfx_loader(ctx, handle, handle_type, implementation, pver, (void **)&loader)) + goto fail; + + av_assert0(loader); + } else + loader = *ploader; // Use the input mfxLoader to create mfx session + + if (qsv_create_mfx_session_from_loader(ctx, loader, psession)) + goto fail; + + if (!*ploader) + *ploader = loader; + + return 0; + +fail: + if (!*ploader && loader) + MFXUnload(loader); + + return AVERROR_UNKNOWN; +} + +#else + +static int qsv_create_mfx_session(void *ctx, + mfxHDL handle, + mfxHandleType handle_type, + mfxIMPL implementation, + mfxVersion *pver, + mfxSession *psession, + void **ploader) +{ + mfxVersion ver; + mfxStatus sts; + mfxSession session = NULL; + + av_log(ctx, AV_LOG_VERBOSE, + "Use Intel(R) Media SDK to create MFX session, API version is " + "%d.%d, the required implementation version is %d.%d\n", + MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor); + + *ploader = NULL; + *psession = NULL; + ver = *pver; + sts = MFXInit(implementation, &ver, &session); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " + "%d.\n", sts); + goto fail; + } + + sts = MFXQueryVersion(session, &ver); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: " + "%d.\n", sts); + goto fail; + } + + av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation " + "version is %d.%d\n", ver.Major, ver.Minor); + + MFXClose(session); + + sts = MFXInit(implementation, &ver, &session); + if (sts != MFX_ERR_NONE) { + av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " + "%d.\n", sts); + goto fail; + } + + *psession = session; + + return 0; + +fail: + if (session) + MFXClose(session); + + return AVERROR_UNKNOWN; +} + +#endif + static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxSession *session, int upload) { @@ -637,29 +1075,36 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxVideoParam par; mfxStatus err; + int ret = AVERROR_UNKNOWN; + AVQSVDeviceContext *hwctx = ctx->device_ctx->hwctx; + /* hwctx->loader is non-NULL for oneVPL user and NULL for non-oneVPL user */ + void **loader = &hwctx->loader; #if QSV_HAVE_OPAQUE QSVFramesContext *s = ctx->internal->priv; opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); #endif - err = MFXInit(device_priv->impl, &device_priv->ver, session); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); - return AVERROR_UNKNOWN; - } + ret = qsv_create_mfx_session(ctx, device_priv->handle, device_priv->handle_type, + device_priv->impl, &device_priv->ver, session, loader); + if (ret) + goto fail; if (device_priv->handle) { err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type, device_priv->handle); - if (err != MFX_ERR_NONE) - return AVERROR_UNKNOWN; + if (err != MFX_ERR_NONE) { + ret = AVERROR_UNKNOWN; + goto fail; + } } if (!opaque) { err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator); - if (err != MFX_ERR_NONE) - return AVERROR_UNKNOWN; + if (err != MFX_ERR_NONE) { + ret = AVERROR_UNKNOWN; + goto fail; + } } memset(&par, 0, sizeof(par)); @@ -695,11 +1140,20 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, if (err != MFX_ERR_NONE) { av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session." "Surface upload/download will not be possible\n"); - MFXClose(*session); - *session = NULL; + + ret = AVERROR_UNKNOWN; + goto fail; } return 0; + +fail: + if (*session) + MFXClose(*session); + + *session = NULL; + + return ret; } static int qsv_frames_init(AVHWFramesContext *ctx) @@ -1456,6 +1910,8 @@ static void qsv_device_free(AVHWDeviceContext *ctx) if (hwctx->session) MFXClose(hwctx->session); + if (hwctx->loader) + MFXUnload(hwctx->loader); av_buffer_unref(&priv->child_device_ctx); av_freep(&priv); } @@ -1545,34 +2001,10 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, goto fail; } - err = MFXInit(implementation, &ver, &hwctx->session); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " - "%d.\n", err); - ret = AVERROR_UNKNOWN; - goto fail; - } - - err = MFXQueryVersion(hwctx->session, &ver); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: %d.\n", err); - ret = AVERROR_UNKNOWN; - goto fail; - } - - av_log(ctx, AV_LOG_VERBOSE, - "Initialize MFX session: API version is %d.%d, implementation version is %d.%d\n", - MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor); - - MFXClose(hwctx->session); - - err = MFXInit(implementation, &ver, &hwctx->session); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, - "Error initializing an MFX session: %d.\n", err); - ret = AVERROR_UNKNOWN; + ret = qsv_create_mfx_session(ctx, handle, handle_type, implementation, &ver, + &hwctx->session, &hwctx->loader); + if (ret) goto fail; - } err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); if (err != MFX_ERR_NONE) { @@ -1587,6 +2019,12 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, fail: if (hwctx->session) MFXClose(hwctx->session); + + if (hwctx->loader) + MFXUnload(hwctx->loader); + + hwctx->session = NULL; + hwctx->loader = NULL; return ret; } @@ -1629,6 +2067,16 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, } } else if (CONFIG_VAAPI) { child_device_type = AV_HWDEVICE_TYPE_VAAPI; +#if QSV_ONEVPL + } else if (CONFIG_D3D11VA) { // Use D3D11 by default if d3d11va is enabled + av_log(ctx, AV_LOG_VERBOSE, + "Defaulting child_device_type to AV_HWDEVICE_TYPE_D3D11VA for oneVPL." + "Please explicitly set child device type via \"-init_hw_device\" " + "option if needed.\n"); + child_device_type = AV_HWDEVICE_TYPE_D3D11VA; + } else if (CONFIG_DXVA2) { + child_device_type = AV_HWDEVICE_TYPE_DXVA2; +#else } else if (CONFIG_DXVA2) { av_log(NULL, AV_LOG_WARNING, "WARNING: defaulting child_device_type to AV_HWDEVICE_TYPE_DXVA2 for compatibility " @@ -1637,6 +2085,7 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, child_device_type = AV_HWDEVICE_TYPE_DXVA2; } else if (CONFIG_D3D11VA) { child_device_type = AV_HWDEVICE_TYPE_D3D11VA; +#endif } else { av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n"); return AVERROR(ENOSYS); @@ -1663,6 +2112,13 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, #endif #if CONFIG_DXVA2 case AV_HWDEVICE_TYPE_DXVA2: +#if QSV_ONEVPL + { + av_log(ctx, AV_LOG_VERBOSE, + "d3d11va is not available or child device type is set to dxva2 " + "explicitly for oneVPL.\n"); + } +#endif break; #endif default: