Message ID | 20230412122741.474-1-sivileri@microsoft.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v3,1/3] Add support for VAAPI on Windows in hwcontext_vaapi using vaGetDisplayWin32. | expand |
Context | Check | Description |
---|---|---|
yinshiyou/commit_msg_loongarch64 | warning | The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ". |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
yinshiyou/make_loongarch64 | warning | New warnings during build |
andriy/commit_msg_x86 | warning | The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ". |
andriy/make_fate_x86 | success | Make fate finished |
andriy/make_x86 | warning | New warnings during build |
Please don't send emails again. On Wed, Apr 12, 2023, 5:28 PM Sil Vilerino < sivileri-at-microsoft.com@ffmpeg.org> wrote: > Libva 2.17+ adds a new libva-win32 node and Mesa 22.3 adds a VAAPI driver > based on Direct3D 12 for Windows. > Both of them are available at: > https://www.nuget.org/packages/Microsoft.Direct3D.VideoAccelerationCompatibilityPack > > Initial review at https://github.com/intel-media-ci/ffmpeg/pull/619/ > Reviewed-by > <https://github.com/intel-media-ci/ffmpeg/pull/619/Reviewed-by>: Dmitry > Rogozhkin <dmitry.v.rogozhkin@intel.com> > Reviewed-by: Wu, Tong1 <tong1.wu@intel.com> > --- > Changelog | 1 + > configure | 27 ++++++++++++- > libavutil/hwcontext_vaapi.c | 76 ++++++++++++++++++++++++++++++++++++- > libavutil/tests/hwdevice.c | 2 +- > 4 files changed, 102 insertions(+), 4 deletions(-) > > diff --git a/Changelog b/Changelog > index a40f32c23f..4ae8a4fe20 100644 > --- a/Changelog > +++ b/Changelog > @@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. > > version <next>: > - libaribcaption decoder > +- Extend VAAPI support for libva-win32 on Windows > > version 6.0: > - Radiance HDR image support > diff --git a/configure b/configure > index 033db7442d..2a45b11aa4 100755 > --- a/configure > +++ b/configure > @@ -2316,6 +2316,7 @@ SYSTEM_LIBRARIES=" > bcrypt > vaapi_drm > vaapi_x11 > + vaapi_win32 > vdpau_x11 > " > > @@ -3826,7 +3827,7 @@ swscale_suggest="libm stdatomic" > > avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs > lcms2_extralibs" > avfilter_extralibs="pthreads_extralibs" > -avutil_extralibs="d3d11va_extralibs mediacodec_extralibs > nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs > vaapi_x11_extralibs vdpau_x11_extralibs" > +avutil_extralibs="d3d11va_extralibs mediacodec_extralibs > nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs > vaapi_x11_extralibs vaapi_win32_extralibs vdpau_x11_extralibs" > > # programs > ffmpeg_deps="avcodec avfilter avformat threads" > @@ -6947,6 +6948,21 @@ test_cpp <<EOF && enable uwp && > d3d11va_extralibs="-ldxgi -ld3d11" > #endif > EOF > > +# vaapi_win32 requires linking directly to dxgi if not building for > +# the desktop api partition > +test_cpp <<EOF && enable uwp && vaapi_win32_extralibs="-ldxgi" > +#ifdef WINAPI_FAMILY > +#include <winapifamily.h> > +#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" > > @@ -6957,7 +6973,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/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c > index 90c2c191d9..13633bdff1 100644 > --- a/libavutil/hwcontext_vaapi.c > +++ b/libavutil/hwcontext_vaapi.c > @@ -18,6 +18,15 @@ > > #include "config.h" > > +#if HAVE_VAAPI_WIN32 > +# include <windows.h> > +#define COBJMACROS > +# include <initguid.h> > +# include <dxgi1_2.h> > +# include "compat/w32dlfcn.h" > +# include <va/va_win32.h> > +typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void > **ppFactory); > +#endif > #if HAVE_VAAPI_X11 > # include <va/va_x11.h> > #endif > @@ -1663,7 +1672,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) > @@ -1681,6 +1690,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); > @@ -1690,6 +1701,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 > @@ -1797,6 +1809,68 @@ 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"); > + dlclose(dxgi); > + 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) > -- > 2.39.2.vfs.0.0 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". >
diff --git a/Changelog b/Changelog index a40f32c23f..4ae8a4fe20 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. version <next>: - libaribcaption decoder +- Extend VAAPI support for libva-win32 on Windows version 6.0: - Radiance HDR image support diff --git a/configure b/configure index 033db7442d..2a45b11aa4 100755 --- a/configure +++ b/configure @@ -2316,6 +2316,7 @@ SYSTEM_LIBRARIES=" bcrypt vaapi_drm vaapi_x11 + vaapi_win32 vdpau_x11 " @@ -3826,7 +3827,7 @@ swscale_suggest="libm stdatomic" avcodec_extralibs="pthreads_extralibs iconv_extralibs dxva2_extralibs lcms2_extralibs" avfilter_extralibs="pthreads_extralibs" -avutil_extralibs="d3d11va_extralibs mediacodec_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vdpau_x11_extralibs" +avutil_extralibs="d3d11va_extralibs mediacodec_extralibs nanosleep_extralibs pthreads_extralibs vaapi_drm_extralibs vaapi_x11_extralibs vaapi_win32_extralibs vdpau_x11_extralibs" # programs ffmpeg_deps="avcodec avfilter avformat threads" @@ -6947,6 +6948,21 @@ test_cpp <<EOF && enable uwp && d3d11va_extralibs="-ldxgi -ld3d11" #endif EOF +# vaapi_win32 requires linking directly to dxgi if not building for +# the desktop api partition +test_cpp <<EOF && enable uwp && vaapi_win32_extralibs="-ldxgi" +#ifdef WINAPI_FAMILY +#include <winapifamily.h> +#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" @@ -6957,7 +6973,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/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 90c2c191d9..13633bdff1 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -18,6 +18,15 @@ #include "config.h" +#if HAVE_VAAPI_WIN32 +# include <windows.h> +#define COBJMACROS +# include <initguid.h> +# include <dxgi1_2.h> +# include "compat/w32dlfcn.h" +# include <va/va_win32.h> +typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); +#endif #if HAVE_VAAPI_X11 # include <va/va_x11.h> #endif @@ -1663,7 +1672,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) @@ -1681,6 +1690,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); @@ -1690,6 +1701,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 @@ -1797,6 +1809,68 @@ 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"); + dlclose(dxgi); + 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)