1
0

avfilter/vsrc_ddagrab: dynamically load SetThreadDpiAwarenessContext

It's a Windows 10 only function, and its presence alone prevents the
binary from loading on older Windows versions.
This commit is contained in:
Timo Rothenpieler 2022-07-19 00:51:18 +02:00
parent d72a671c60
commit 61c151a098
2 changed files with 33 additions and 10 deletions

2
configure vendored
View File

@ -2309,7 +2309,6 @@ SYSTEM_FUNCS="
SetDllDirectory
setmode
setrlimit
SetThreadDpiAwarenessContext
Sleep
strerror_r
sysconf
@ -6401,7 +6400,6 @@ check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
check_type "windows.h d3d11.h" "ID3D11VideoContext"
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
check_func_headers windows.h SetThreadDpiAwarenessContext -D_WIN32_WINNT=0x0A00
check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
check_type "vdpau/vdpau.h" "VdpPictureInfoVP9"

View File

@ -18,9 +18,9 @@
#include "config.h"
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0A00
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#define _WIN32_WINNT 0x0602
#endif
#define WIN32_LEAN_AND_MEAN
@ -41,6 +41,7 @@
#include "libavutil/avassert.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_d3d11va.h"
#include "compat/w32dlfcn.h"
#include "avfilter.h"
#include "internal.h"
#include "formats.h"
@ -150,8 +151,12 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
IDXGIAdapter *dxgi_adapter = NULL;
IDXGIOutput *dxgi_output = NULL;
IDXGIOutput1 *dxgi_output1 = NULL;
#if HAVE_IDXGIOUTPUT5 && HAVE_SETTHREADDPIAWARENESSCONTEXT
#if HAVE_IDXGIOUTPUT5
IDXGIOutput5 *dxgi_output5 = NULL;
typedef DPI_AWARENESS_CONTEXT (*set_thread_dpi_t)(DPI_AWARENESS_CONTEXT);
set_thread_dpi_t set_thread_dpi;
HMODULE user32_module;
#endif
int w, h;
HRESULT hr;
@ -185,9 +190,19 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
return AVERROR_EXTERNAL;
}
#if HAVE_IDXGIOUTPUT5 && HAVE_SETTHREADDPIAWARENESSCONTEXT
hr = IDXGIOutput_QueryInterface(dxgi_output, &IID_IDXGIOutput5, (void**)&dxgi_output5);
if (SUCCEEDED(hr)) {
#if HAVE_IDXGIOUTPUT5
user32_module = dlopen("user32.dll", 0);
if (!user32_module) {
av_log(avctx, AV_LOG_ERROR, "Failed loading user32.dll\n");
return AVERROR_EXTERNAL;
}
set_thread_dpi = (set_thread_dpi_t)dlsym(user32_module, "SetThreadDpiAwarenessContext");
if (set_thread_dpi)
hr = IDXGIOutput_QueryInterface(dxgi_output, &IID_IDXGIOutput5, (void**)&dxgi_output5);
if (set_thread_dpi && SUCCEEDED(hr)) {
DPI_AWARENESS_CONTEXT prev_dpi_ctx;
DXGI_FORMAT formats[] = {
DXGI_FORMAT_R10G10B10A2_UNORM,
@ -197,7 +212,7 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
IDXGIOutput_Release(dxgi_output);
dxgi_output = NULL;
prev_dpi_ctx = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
prev_dpi_ctx = set_thread_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!prev_dpi_ctx)
av_log(avctx, AV_LOG_WARNING, "Failed enabling DPI awareness for DDA\n");
@ -211,8 +226,18 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
dxgi_output5 = NULL;
if (prev_dpi_ctx)
SetThreadDpiAwarenessContext(prev_dpi_ctx);
set_thread_dpi(prev_dpi_ctx);
dlclose(user32_module);
user32_module = NULL;
set_thread_dpi = NULL;
av_log(avctx, AV_LOG_DEBUG, "Using IDXGIOutput5 interface\n");
} else {
dlclose(user32_module);
user32_module = NULL;
set_thread_dpi = NULL;
av_log(avctx, AV_LOG_DEBUG, "Falling back to IDXGIOutput1\n");
#else
{