mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
win-capture: Support EnumDisplayDevices failure
Seeing EnumDisplayDevices fail in the wild, so use GetMonitorInfo name
when the persistent name is unavailable.
(cherry picked from commit 0b30ff1deb
)
This commit is contained in:
parent
ab69f5db05
commit
d66b9bd8e9
@ -92,7 +92,7 @@ struct duplicator_capture {
|
||||
struct winrt_capture *capture_winrt;
|
||||
};
|
||||
|
||||
struct wgc_monitor_info {
|
||||
struct duplicator_monitor_info {
|
||||
char device_id[128];
|
||||
char name[64];
|
||||
RECT rect;
|
||||
@ -187,7 +187,8 @@ static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
|
||||
{
|
||||
UNUSED_PARAMETER(hdc);
|
||||
|
||||
struct wgc_monitor_info *monitor = (struct wgc_monitor_info *)param;
|
||||
struct duplicator_monitor_info *monitor =
|
||||
(struct duplicator_monitor_info *)param;
|
||||
|
||||
bool match = false;
|
||||
|
||||
@ -198,8 +199,8 @@ static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
|
||||
device.cb = sizeof(device);
|
||||
if (EnumDisplayDevicesA(mi.szDevice, 0, &device,
|
||||
EDD_GET_DEVICE_INTERFACE_NAME)) {
|
||||
const bool match = strcmp(monitor->device_id,
|
||||
device.DeviceID) == 0;
|
||||
match = strcmp(monitor->device_id, device.DeviceID) ==
|
||||
0;
|
||||
if (match) {
|
||||
monitor->rect = *rect;
|
||||
monitor->handle = handle;
|
||||
@ -212,6 +213,31 @@ static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
|
||||
return !match;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enum_monitor_fallback(HMONITOR handle, HDC hdc,
|
||||
LPRECT rect, LPARAM param)
|
||||
{
|
||||
UNUSED_PARAMETER(hdc);
|
||||
|
||||
struct duplicator_monitor_info *monitor =
|
||||
(struct duplicator_monitor_info *)param;
|
||||
|
||||
bool match = false;
|
||||
|
||||
MONITORINFOEXA mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfoA(handle, (LPMONITORINFO)&mi)) {
|
||||
match = strcmp(monitor->device_id, mi.szDevice) == 0;
|
||||
if (match) {
|
||||
monitor->rect = *rect;
|
||||
monitor->handle = handle;
|
||||
GetMonitorName(handle, monitor->name,
|
||||
_countof(monitor->name));
|
||||
}
|
||||
}
|
||||
|
||||
return !match;
|
||||
}
|
||||
|
||||
static void log_settings(struct duplicator_capture *capture,
|
||||
const char *monitor, LONG width, LONG height)
|
||||
{
|
||||
@ -257,15 +283,26 @@ choose_method(enum display_capture_method method, bool wgc_supported,
|
||||
|
||||
extern bool wgc_supported;
|
||||
|
||||
static struct duplicator_monitor_info find_monitor(const char *monitor_id)
|
||||
{
|
||||
struct duplicator_monitor_info monitor = {0};
|
||||
strcpy_s(monitor.device_id, _countof(monitor.device_id), monitor_id);
|
||||
EnumDisplayMonitors(NULL, NULL, &enum_monitor, (LPARAM)&monitor);
|
||||
if (monitor.handle == NULL) {
|
||||
EnumDisplayMonitors(NULL, NULL, &enum_monitor_fallback,
|
||||
(LPARAM)&monitor);
|
||||
}
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
static inline void update_settings(struct duplicator_capture *capture,
|
||||
obs_data_t *settings)
|
||||
{
|
||||
pthread_mutex_lock(&capture->update_mutex);
|
||||
|
||||
struct wgc_monitor_info monitor = {0};
|
||||
strcpy_s(monitor.device_id, _countof(monitor.device_id),
|
||||
obs_data_get_string(settings, "monitor_id"));
|
||||
EnumDisplayMonitors(NULL, NULL, enum_monitor, (LPARAM)&monitor);
|
||||
struct duplicator_monitor_info monitor =
|
||||
find_monitor(obs_data_get_string(settings, "monitor_id"));
|
||||
|
||||
capture->method =
|
||||
choose_method((int)obs_data_get_int(settings, "method"),
|
||||
@ -463,11 +500,7 @@ static void free_capture_data(struct duplicator_capture *capture)
|
||||
|
||||
static void update_monitor_handle(struct duplicator_capture *capture)
|
||||
{
|
||||
struct wgc_monitor_info monitor = {0};
|
||||
strcpy_s(monitor.device_id, _countof(monitor.device_id),
|
||||
capture->monitor_id);
|
||||
EnumDisplayMonitors(NULL, NULL, enum_monitor, (LPARAM)&monitor);
|
||||
capture->handle = monitor.handle;
|
||||
capture->handle = find_monitor(capture->monitor_id).handle;
|
||||
}
|
||||
|
||||
static void duplicator_capture_tick(void *data, float seconds)
|
||||
@ -727,40 +760,41 @@ static BOOL CALLBACK enum_monitor_props(HMONITOR handle, HDC hdc, LPRECT rect,
|
||||
UNUSED_PARAMETER(hdc);
|
||||
UNUSED_PARAMETER(rect);
|
||||
|
||||
char monitor_name[64];
|
||||
GetMonitorName(handle, monitor_name, sizeof(monitor_name));
|
||||
|
||||
MONITORINFOEXA mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfoA(handle, (LPMONITORINFO)&mi)) {
|
||||
obs_property_t *monitor_list = (obs_property_t *)param;
|
||||
struct dstr monitor_desc = {0};
|
||||
dstr_printf(&monitor_desc, "%s: %dx%d @ %d,%d", monitor_name,
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
mi.rcMonitor.bottom - mi.rcMonitor.top,
|
||||
mi.rcMonitor.left, mi.rcMonitor.top);
|
||||
if (mi.dwFlags == MONITORINFOF_PRIMARY)
|
||||
dstr_catf(&monitor_desc, " (%s)", TEXT_PRIMARY_MONITOR);
|
||||
|
||||
DISPLAY_DEVICEA device;
|
||||
device.cb = sizeof(device);
|
||||
if (EnumDisplayDevicesA(mi.szDevice, 0, &device,
|
||||
EDD_GET_DEVICE_INTERFACE_NAME)) {
|
||||
obs_property_t *monitor_list = (obs_property_t *)param;
|
||||
struct dstr monitor_desc = {0};
|
||||
struct dstr resolution = {0};
|
||||
|
||||
dstr_catf(&resolution, "%dx%d @ %d,%d",
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
mi.rcMonitor.bottom - mi.rcMonitor.top,
|
||||
mi.rcMonitor.left, mi.rcMonitor.top);
|
||||
|
||||
char monitor_name[64];
|
||||
GetMonitorName(handle, monitor_name,
|
||||
sizeof(monitor_name));
|
||||
dstr_catf(&monitor_desc, "%s: %s", monitor_name,
|
||||
resolution.array);
|
||||
|
||||
if (mi.dwFlags == MONITORINFOF_PRIMARY) {
|
||||
dstr_catf(&monitor_desc, " (%s)",
|
||||
TEXT_PRIMARY_MONITOR);
|
||||
}
|
||||
|
||||
obs_property_list_add_string(monitor_list,
|
||||
monitor_desc.array,
|
||||
device.DeviceID);
|
||||
|
||||
dstr_free(&monitor_desc);
|
||||
dstr_free(&resolution);
|
||||
} else {
|
||||
blog(LOG_WARNING,
|
||||
"[duplicator-monitor-capture] EnumDisplayDevices failed for monitor (%s), falling back to szDevice",
|
||||
monitor_name);
|
||||
obs_property_list_add_string(
|
||||
monitor_list, monitor_desc.array, mi.szDevice);
|
||||
}
|
||||
|
||||
dstr_free(&monitor_desc);
|
||||
} else {
|
||||
blog(LOG_WARNING,
|
||||
"[duplicator-monitor-capture] GetMonitorInfo failed for monitor: %s",
|
||||
monitor_name);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user