win-capture: Put window capture update data in a mutex

Because the window capture source updates its data whenever certain
properties are modified, this would cause a race condition because
source updates normally happen in the graphics thread.  To solve this
for the time being, put access to that data within a mutex when updating
or updating visibility.
master
jp9000 2020-09-03 05:35:48 -07:00
parent b99613b677
commit bdd6562a94
2 changed files with 21 additions and 0 deletions

View File

@ -1,5 +1,10 @@
project(win-capture)
if(MSVC)
set(win-capture_PLATFORM_DEPS
w32-pthreads)
endif()
set(win-capture_HEADERS
nt-stuff.h
obfuscate.h
@ -31,6 +36,7 @@ add_library(win-capture MODULE
${win-capture_SOURCES}
${win-capture_HEADERS})
target_link_libraries(win-capture
${win-capture_PLATFORM_DEPS}
libobs
Dwmapi
ipc-util

View File

@ -1,5 +1,6 @@
#include <stdlib.h>
#include <util/dstr.h>
#include <util/threading.h>
#include "dc-capture.h"
#include "window-helpers.h"
#include "../../libobs/util/platform.h"
@ -49,6 +50,8 @@ enum window_capture_method {
struct window_capture {
obs_source_t *source;
pthread_mutex_t update_mutex;
char *title;
char *class;
char *executable;
@ -158,6 +161,8 @@ static void log_settings(struct window_capture *wc, obs_data_t *s)
static void update_settings(struct window_capture *wc, obs_data_t *s)
{
pthread_mutex_lock(&wc->update_mutex);
int method = (int)obs_data_get_int(s, "method");
const char *window = obs_data_get_string(s, "window");
int priority = (int)obs_data_get_int(s, "priority");
@ -174,6 +179,8 @@ static void update_settings(struct window_capture *wc, obs_data_t *s)
wc->use_wildcards = obs_data_get_bool(s, "use_wildcards");
wc->compatibility = obs_data_get_bool(s, "compatibility");
wc->client_area = obs_data_get_bool(s, "client_area");
pthread_mutex_unlock(&wc->update_mutex);
}
/* ------------------------------------------------------------------------- */
@ -219,6 +226,8 @@ static void *wc_create(obs_data_t *settings, obs_source_t *source)
struct window_capture *wc = bzalloc(sizeof(struct window_capture));
wc->source = source;
pthread_mutex_init(&wc->update_mutex, NULL);
obs_enter_graphics();
const bool uses_d3d11 = gs_get_device_type() == GS_DEVICE_DIRECT3D_11;
obs_leave_graphics();
@ -259,6 +268,8 @@ static void wc_actual_destroy(void *data)
if (wc->winrt_module)
os_dlclose(wc->winrt_module);
pthread_mutex_destroy(&wc->update_mutex);
bfree(wc);
}
@ -307,6 +318,8 @@ static void wc_defaults(obs_data_t *defaults)
static void update_settings_visibility(obs_properties_t *props,
struct window_capture *wc)
{
pthread_mutex_lock(&wc->update_mutex);
const enum window_capture_method method = wc->method;
const bool bitblt_options = method == METHOD_BITBLT;
const bool wgc_options = method == METHOD_WGC;
@ -323,6 +336,8 @@ static void update_settings_visibility(obs_properties_t *props,
p = obs_properties_get(props, "client_area");
obs_property_set_visible(p, wgc_options);
pthread_mutex_unlock(&wc->update_mutex);
}
static bool wc_capture_method_changed(obs_properties_t *props,