From patchwork Thu Feb 16 13:12:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sil Vilerino X-Patchwork-Id: 40419 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:5494:b0:bf:7b3a:fd32 with SMTP id i20csp490016pzk; Thu, 16 Feb 2023 05:12:40 -0800 (PST) X-Google-Smtp-Source: AK7set/Hkyt5fE/8700ADJjFfi97NrtE4JZJBLkwMD1TROK9wPzxj8X4FEJL/4YEzomDD/nA+HSs X-Received: by 2002:a05:6402:328:b0:4aa:a4e9:fa28 with SMTP id q8-20020a056402032800b004aaa4e9fa28mr5526634edw.34.1676553160080; Thu, 16 Feb 2023 05:12:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676553160; cv=none; d=google.com; s=arc-20160816; b=QZCYrUOA6xVWMKB+r0SiTMFrl/w5LT6nmLQfRNUnCgfEM4gSUYfICQ/v32WaoIlG1C yyZ0gSKgifyWz27YkK2H1SGGTttCH1YOddGcp3Zp8Rmryo2cr2ndpvjPLzCEX/bKNALw lKXJ6+rERYvstHl0gUrkjsrH23LHzsHBAZaco2qFKrLlr42Wils0JrerukRlQsM1RUW3 O/X7xx9umXKcdMdtrY9aqHwhbstZnvGjV2D4YIiox1mfG67q3Kni9p5+hXi69n7t91ND tM6uXpxS55sSikwec1zIEyWyHm3JtK1u6kbhSSXf6tPUDdEA+Y2kG+yhGxJoIdoccHkY 78ZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from:dkim-filter :delivered-to; bh=5WssC6Pa6PI4f/utNuPnEbnFJKcQ4IZKwWhwHVA5Hhs=; b=fgcpTidm25xdL7eHlXBTHzrXE7PgcNRA0gpGNSljJ6GT4lXP/7x67driAE98EhTaHg Uj6Kh4bvnBghWVbFHhatJ3/WBgTotdt3q37thYp7wKqm6xmT80e3C0nK/pcHTe2PkrEv BJkprS02BSTKfrV6y9NoogUxy8RW2YBqi5giPc+vgiGyD9zEVqgh04NTWbYW3uWv0aND oQOxU/c3L9MCURaQJH3dfsSw7ZZ7iJMbCudJfoyfGzsNhL/dKsKC/3kOoJfFA66sqNBK TRf7ZsRNv6O826ojIcyw8/rKde+9vsiTM0qsmVx3fEyHVi0Gc56vS4crUS0er9AnTkaI QnxA== ARC-Authentication-Results: i=1; mx.google.com; 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 w24-20020aa7d298000000b004ab44dde183si2037021edq.281.2023.02.16.05.12.39; Thu, 16 Feb 2023 05:12:40 -0800 (PST) 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; 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 BDE8368BF12; Thu, 16 Feb 2023 15:12:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 996ED68BE3B for ; Thu, 16 Feb 2023 15:12:29 +0200 (EET) Received: from localhost.localdomain (pool-108-28-73-40.washdc.fios.verizon.net [108.28.73.40]) by linux.microsoft.com (Postfix) with ESMTPSA id 274AA20B9C3D for ; Thu, 16 Feb 2023 05:12:28 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 274AA20B9C3D From: Sil Vilerino To: ffmpeg-devel@ffmpeg.org Date: Thu, 16 Feb 2023 08:12:13 -0500 Message-Id: <20230216131213.2326-1-sivileri@microsoft.com> X-Mailer: git-send-email 2.37.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] hwcontext_vaapi: Add support for vaGetDisplayWin32 initialization 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: p29WpX/VKWzw These changes add support for VAAPI on Windows in hwcontext_vaapi using vaGetDisplayWin32, also allowing for DirectX adapter index selection via the "-device" command line argument. Libva 2.17+ adds a new libva-win32 node and Mesa 22.3 adds a VAAPI driver based on Direct3D 12 for Windows, both available at: https://www.nuget.org/packages/Microsoft.Direct3D.VideoAccelerationCompatibilityPack Initial review at https://github.com/intel-media-ci/ffmpeg/pull/619/ Additional changes were made to the changelog and minor version bump as well as to QSV to not break with this new change: - qsv_internal.h: Remove unnecessary include va_drm.h - qsv_internal.h: Enable AVCODEC_QSV_LINUX_SESSION_HANDLE on Linux/VA only - hwcontext_qsv.c: Do not allow child_device_type VAAPI for Windows until support is added, keep D3D11/DXVA2 as more prioritary defaults. Signed-off-by: Sil Vilerino Reviewed-by: Dmitry Rogozhkin Reviewed-by: Wu, Tong1 --- Changelog | 2 +- configure | 27 ++++++++++++- fftools/ffmpeg_opt.c | 2 +- libavcodec/qsv_internal.h | 5 +-- libavutil/hwcontext_qsv.c | 14 ++++++- libavutil/hwcontext_vaapi.c | 75 ++++++++++++++++++++++++++++++++++++- libavutil/tests/hwdevice.c | 2 +- libavutil/version.h | 2 +- 8 files changed, 117 insertions(+), 12 deletions(-) diff --git a/Changelog b/Changelog index 0644f39d59..9248a07043 100644 --- a/Changelog +++ b/Changelog @@ -44,7 +44,7 @@ version : - RKA decoder and demuxer - filtergraph syntax in ffmpeg CLI now supports passing file contents as option values, by prefixing option name with '/' -- hstack_qsv, vstack_qsv and xstack_qsv filters +- Extend VAAPI support for libva-win32 on Windows version 5.1: diff --git a/configure b/configure index bf8ae1c789..01fe0378f3 100755 --- a/configure +++ b/configure @@ -2314,6 +2314,7 @@ SYSTEM_LIBRARIES=" bcrypt vaapi_drm vaapi_x11 + vaapi_win32 vdpau_x11 " @@ -3828,7 +3829,7 @@ swscale_suggest="libm stdatomic" avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs lcms2_extralibs" avfilter_extralibs="pthreads_extralibs" -avutil_extralibs="d3d11va_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vdpau_x11_extralibs" +avutil_extralibs="d3d11va_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vaapi_win32_extralibs vdpau_x11_extralibs" # programs ffmpeg_deps="avcodec avfilter avformat threads" @@ -6945,6 +6946,21 @@ test_cpp < +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#error desktop, not uwp +#else +// WINAPI_FAMILY_APP, WINAPI_FAMILY_PHONE_APP => UWP +#endif +#else +#error no family set +#endif +EOF + # mediafoundation requires linking directly to mfplat if building for uwp target enabled uwp && mediafoundation_extralibs="-lmfplat -lmfuuid -lole32 -lstrmiids" || mediafoundation_extralibs="-lmfuuid -lole32 -lstrmiids" @@ -6955,7 +6971,14 @@ enabled vaapi && check_pkg_config vaapi "libva >= 0.35.0" "va/va.h" vaInitialize if enabled vaapi; then - check_pkg_config vaapi_drm "libva-drm" "va/va_drm.h" vaGetDisplayDRM + case $target_os in + mingw32*|mingw64*|win32|win64) + check_pkg_config vaapi_win32 "libva-win32" "va/va_win32.h" vaGetDisplayWin32 + ;; + *) + check_pkg_config vaapi_drm "libva-drm" "va/va_drm.h" vaGetDisplayDRM + ;; + esac if enabled xlib_x11; then check_pkg_config vaapi_x11 "libva-x11" "va/va_x11.h" vaGetDisplay diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 055275d813..043cf539a5 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -1758,7 +1758,7 @@ const OptionDef options[] = { #if CONFIG_VAAPI { "vaapi_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vaapi_device }, - "set VAAPI hardware device (DRM path or X11 display name)", "device" }, + "set VAAPI hardware device (DirectX adapter index, DRM path or X11 display name)", "device" }, #endif #if CONFIG_QSV diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 5119ef4dff..df5e1e05ca 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -23,9 +23,9 @@ #include "config.h" -#if CONFIG_VAAPI +#if CONFIG_VAAPI && !_WIN32 // Do not enable for libva-win32 on Windows #define AVCODEC_QSV_LINUX_SESSION_HANDLE -#endif //CONFIG_VAAPI +#endif //CONFIG_VAAPI && !_WIN32 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE #include @@ -35,7 +35,6 @@ #endif #include #include -#include #include "libavutil/hwcontext_vaapi.h" #endif diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 42851d4fd5..14fa8eec87 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -2126,8 +2126,6 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, "\"%s\".\n", e->value); return AVERROR(EINVAL); } - } 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, @@ -2147,11 +2145,23 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, } else if (CONFIG_D3D11VA) { child_device_type = AV_HWDEVICE_TYPE_D3D11VA; #endif + } else if (CONFIG_VAAPI) { + child_device_type = AV_HWDEVICE_TYPE_VAAPI; } else { av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n"); return AVERROR(ENOSYS); } +#if CONFIG_VAAPI && _WIN32 + /* AV_HWDEVICE_TYPE_VAAPI on Windows/Libva-win32 not supported */ + /* Reject user specified child_device_type or CONFIG_VAAPI on Windows */ + if (child_device_type == AV_HWDEVICE_TYPE_VAAPI) { + av_log(ctx, AV_LOG_ERROR, "VAAPI child device type not supported for oneVPL on Windows" + "\"%s\".\n", e->value); + return AVERROR(EINVAL); + } +#endif + child_device_opts = NULL; switch (child_device_type) { #if CONFIG_VAAPI diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 938bd5447d..8da2f3196c 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -18,6 +18,15 @@ #include "config.h" +#if HAVE_VAAPI_WIN32 +# include +#define COBJMACROS +# include +# include +# include "compat/w32dlfcn.h" +# include +typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); +#endif #if HAVE_VAAPI_X11 # include #endif @@ -1654,7 +1663,7 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, VAAPIDevicePriv *priv; VADisplay display = NULL; const AVDictionaryEntry *ent; - int try_drm, try_x11, try_all; + int try_drm, try_x11, try_win32, try_all; priv = av_mallocz(sizeof(*priv)); if (!priv) @@ -1672,6 +1681,8 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, try_drm = 1; } else if (!strcmp(ent->value, "x11")) { try_x11 = 1; + } else if (!strcmp(ent->value, "win32")) { + try_win32 = 1; } else { av_log(ctx, AV_LOG_ERROR, "Invalid connection type %s.\n", ent->value); @@ -1681,6 +1692,7 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, try_all = 1; try_drm = HAVE_VAAPI_DRM; try_x11 = HAVE_VAAPI_X11; + try_win32 = HAVE_VAAPI_WIN32; } #if HAVE_VAAPI_DRM @@ -1788,6 +1800,67 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, } #endif +#if HAVE_VAAPI_WIN32 + if (!display && try_win32) { + // Try to create a display from the specified device, if any. + if (!device) { + display = vaGetDisplayWin32(NULL); + } else { + IDXGIFactory2 *pDXGIFactory = NULL; + IDXGIAdapter *pAdapter = NULL; +#if !HAVE_UWP + HANDLE dxgi = dlopen("dxgi.dll", 0); + if (!dxgi) { + av_log(ctx, AV_LOG_ERROR, "Failed to load dxgi.dll\n"); + return AVERROR_UNKNOWN; + } + PFN_CREATE_DXGI_FACTORY pfnCreateDXGIFactory = + (PFN_CREATE_DXGI_FACTORY)dlsym(dxgi, "CreateDXGIFactory"); + if (!pfnCreateDXGIFactory) { + av_log(ctx, AV_LOG_ERROR, "CreateDXGIFactory load failed\n"); + return AVERROR_UNKNOWN; + } +#else + // In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't + // available, only CreateDXGIFactory1 + PFN_CREATE_DXGI_FACTORY pfnCreateDXGIFactory = + (PFN_CREATE_DXGI_FACTORY)CreateDXGIFactory1; +#endif + if (SUCCEEDED(pfnCreateDXGIFactory(&IID_IDXGIFactory2, + (void **)&pDXGIFactory))) { + int adapter = atoi(device); + if (SUCCEEDED(IDXGIFactory2_EnumAdapters(pDXGIFactory, + adapter, + &pAdapter))) { + DXGI_ADAPTER_DESC desc; + if (SUCCEEDED(IDXGIAdapter2_GetDesc(pAdapter, &desc))) { + av_log(ctx, AV_LOG_INFO, + "Using device %04x:%04x (%ls) - LUID %lu %ld.\n", + desc.VendorId, desc.DeviceId, desc.Description, + desc.AdapterLuid.LowPart, + desc.AdapterLuid.HighPart); + display = vaGetDisplayWin32(&desc.AdapterLuid); + } + IDXGIAdapter_Release(pAdapter); + } + IDXGIFactory2_Release(pDXGIFactory); + } +#if !HAVE_UWP + dlclose(dxgi); +#endif + } + + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " + "from Win32 display.\n"); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " + "Win32 display.\n"); + } +#endif + if (!display) { if (device) av_log(ctx, AV_LOG_ERROR, "No VA display found for " diff --git a/libavutil/tests/hwdevice.c b/libavutil/tests/hwdevice.c index 7eb355c988..c57586613a 100644 --- a/libavutil/tests/hwdevice.c +++ b/libavutil/tests/hwdevice.c @@ -140,7 +140,7 @@ static const struct { { AV_HWDEVICE_TYPE_OPENCL, { "0.0", "0.1", "1.0", "1.1" } }, { AV_HWDEVICE_TYPE_VAAPI, - { "/dev/dri/renderD128", "/dev/dri/renderD129", ":0" } }, + { "/dev/dri/renderD128", "/dev/dri/renderD129", ":0", "0", "1" } }, }; static int test_device_type(enum AVHWDeviceType type) diff --git a/libavutil/version.h b/libavutil/version.h index 11b4387f64..e8ec604349 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 58 -#define LIBAVUTIL_VERSION_MINOR 1 +#define LIBAVUTIL_VERSION_MINOR 2 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \