win-capture: Use window for keepalive check
To check to make sure game capture is still active in the capture program, it currently uses a named event, and then it checks to see if that named event exists. However with UWP programs, you can't open a named event outside of the UWP process. FindWindow on the other hand does work, so instead of checking to see if a named kernel object exists, create a window and check to see if that window exists.
This commit is contained in:
parent
1e48b522fa
commit
d19342442f
@ -133,7 +133,8 @@ struct game_capture {
|
||||
ipc_pipe_server_t pipe;
|
||||
gs_texture_t *texture;
|
||||
struct hook_info *global_hook_info;
|
||||
HANDLE keep_alive;
|
||||
HANDLE keepalive_thread;
|
||||
DWORD keepalive_thread_id;
|
||||
HANDLE hook_restart;
|
||||
HANDLE hook_stop;
|
||||
HANDLE hook_ready;
|
||||
@ -219,7 +220,12 @@ static void stop_capture(struct game_capture *gc)
|
||||
gc->data = NULL;
|
||||
}
|
||||
|
||||
close_handle(&gc->keep_alive);
|
||||
if (gc->keepalive_thread) {
|
||||
PostThreadMessage(gc->keepalive_thread_id, WM_QUIT, 0, 0);
|
||||
WaitForSingleObject(gc->keepalive_thread, 300);
|
||||
close_handle(&gc->keepalive_thread);
|
||||
}
|
||||
|
||||
close_handle(&gc->hook_restart);
|
||||
close_handle(&gc->hook_stop);
|
||||
close_handle(&gc->hook_ready);
|
||||
@ -473,14 +479,6 @@ static void *game_capture_create(obs_data_t *settings, obs_source_t *source)
|
||||
return gc;
|
||||
}
|
||||
|
||||
static inline HANDLE create_event_id(bool manual_reset, bool initial_state,
|
||||
const char *name, DWORD process_id)
|
||||
{
|
||||
char new_name[128];
|
||||
sprintf(new_name, "%s%lu", name, process_id);
|
||||
return CreateEventA(NULL, manual_reset, initial_state, new_name);
|
||||
}
|
||||
|
||||
static inline HANDLE open_event_id(const char *name, DWORD process_id)
|
||||
{
|
||||
char new_name[128];
|
||||
@ -573,15 +571,78 @@ static inline bool open_target_process(struct game_capture *gc)
|
||||
return true;
|
||||
}
|
||||
|
||||
struct keepalive_data {
|
||||
struct game_capture *gc;
|
||||
HANDLE initialized;
|
||||
};
|
||||
|
||||
#define DEF_FLAGS (WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
|
||||
|
||||
static DWORD WINAPI keepalive_window_thread(struct keepalive_data *data)
|
||||
{
|
||||
HANDLE initialized = data->initialized;
|
||||
struct game_capture *gc = data->gc;
|
||||
wchar_t new_name[64];
|
||||
WNDCLASSW wc;
|
||||
HWND window;
|
||||
MSG msg;
|
||||
|
||||
_snwprintf(new_name, sizeof(new_name), L"%s%lu",
|
||||
WINDOW_HOOK_KEEPALIVE, gc->process_id);
|
||||
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.style = CS_OWNDC;
|
||||
wc.hInstance = GetModuleHandleW(NULL);
|
||||
wc.lpfnWndProc = (WNDPROC)DefWindowProc;
|
||||
wc.lpszClassName = new_name;
|
||||
|
||||
if (!RegisterClass(&wc)) {
|
||||
warn("Failed to create keepalive window class: %lu",
|
||||
GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
window = CreateWindowExW(0, new_name, NULL, DEF_FLAGS, 0, 0, 1, 1,
|
||||
NULL, NULL, wc.hInstance, NULL);
|
||||
if (!window) {
|
||||
warn("Failed to create keepalive window: %lu",
|
||||
GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetEvent(initialized);
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
DestroyWindow(window);
|
||||
UnregisterClassW(new_name, wc.hInstance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool init_keepalive(struct game_capture *gc)
|
||||
{
|
||||
gc->keep_alive = create_event_id(false, false, EVENT_HOOK_KEEPALIVE,
|
||||
gc->process_id);
|
||||
if (!gc->keep_alive) {
|
||||
warn("failed to create keepalive event");
|
||||
struct keepalive_data data;
|
||||
HANDLE initialized = CreateEvent(NULL, false, false, NULL);
|
||||
|
||||
data.gc = gc;
|
||||
data.initialized = initialized;
|
||||
|
||||
gc->keepalive_thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)keepalive_window_thread,
|
||||
&data, 0, &gc->keepalive_thread_id);
|
||||
if (!gc->keepalive_thread) {
|
||||
warn("Failed to create keepalive window thread: %lu",
|
||||
GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
WaitForSingleObject(initialized, INFINITE);
|
||||
CloseHandle(initialized);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define EVENT_HOOK_READY "CaptureHook_HookReady"
|
||||
#define EVENT_HOOK_EXIT "CaptureHook_Exit"
|
||||
|
||||
#define EVENT_HOOK_KEEPALIVE "CaptureHook_KeepAlive"
|
||||
#define WINDOW_HOOK_KEEPALIVE L"CaptureHook_KeepAlive"
|
||||
|
||||
#define MUTEX_TEXTURE1 "CaptureHook_TextureMutex1"
|
||||
#define MUTEX_TEXTURE2 "CaptureHook_TextureMutex2"
|
||||
|
@ -39,7 +39,7 @@ static volatile bool stop_loop = false;
|
||||
static HANDLE capture_thread = NULL;
|
||||
char system_path[MAX_PATH] = {0};
|
||||
char process_name[MAX_PATH] = {0};
|
||||
char keepalive_name[64] = {0};
|
||||
wchar_t keepalive_name[64] = {0};
|
||||
HWND dummy_window = NULL;
|
||||
|
||||
static unsigned int shmem_id_counter = 0;
|
||||
@ -234,8 +234,8 @@ static inline bool init_hook(HANDLE thread_handle)
|
||||
{
|
||||
wait_for_dll_main_finish(thread_handle);
|
||||
|
||||
sprintf(keepalive_name, "%s%lu", EVENT_HOOK_KEEPALIVE,
|
||||
GetCurrentProcessId());
|
||||
_snwprintf(keepalive_name, sizeof(keepalive_name), L"%s%lu",
|
||||
WINDOW_HOOK_KEEPALIVE, GetCurrentProcessId());
|
||||
|
||||
init_pipe();
|
||||
if (!init_signals()) {
|
||||
|
@ -98,7 +98,7 @@ extern HANDLE signal_exit;
|
||||
extern HANDLE tex_mutexes[2];
|
||||
extern char system_path[MAX_PATH];
|
||||
extern char process_name[MAX_PATH];
|
||||
extern char keepalive_name[64];
|
||||
extern wchar_t keepalive_name[64];
|
||||
extern HWND dummy_window;
|
||||
extern volatile bool active;
|
||||
|
||||
@ -143,13 +143,7 @@ static inline HMODULE load_system_library(const char *name)
|
||||
|
||||
static inline bool capture_alive(void)
|
||||
{
|
||||
HANDLE event = OpenEventA(GC_EVENT_FLAGS, false, keepalive_name);
|
||||
if (event) {
|
||||
CloseHandle(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return !!FindWindowW(keepalive_name, NULL);
|
||||
}
|
||||
|
||||
static inline bool capture_active(void)
|
||||
@ -198,8 +192,18 @@ static inline bool capture_should_stop(void)
|
||||
{
|
||||
bool stop_requested = false;
|
||||
|
||||
if (capture_active())
|
||||
stop_requested = capture_stopped() || !capture_alive();
|
||||
if (capture_active()) {
|
||||
static uint64_t last_keepalive_check = 0;
|
||||
uint64_t cur_time = os_gettime_ns();
|
||||
bool alive = true;
|
||||
|
||||
if (cur_time - last_keepalive_check > 5000000000) {
|
||||
alive = capture_alive();
|
||||
last_keepalive_check = cur_time;
|
||||
}
|
||||
|
||||
stop_requested = capture_stopped() || !alive;
|
||||
}
|
||||
|
||||
return stop_requested;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user