From 6bbeaae02e5a08e7b34adb977dd9555f0b3aca9c Mon Sep 17 00:00:00 2001 From: Tom Peeters Date: Thu, 13 Sep 2018 19:35:37 +0200 Subject: [PATCH] win-capture: Add option to adjust hook rate for game capture This option slows down or speeds up the rate at which the game capture plugin checks for a valid window. --- plugins/win-capture/data/locale/en-US.ini | 5 ++ plugins/win-capture/game-capture.c | 61 ++++++++++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/plugins/win-capture/data/locale/en-US.ini b/plugins/win-capture/data/locale/en-US.ini index a88fb18ac..cdcbdf918 100644 --- a/plugins/win-capture/data/locale/en-US.ini +++ b/plugins/win-capture/data/locale/en-US.ini @@ -22,4 +22,9 @@ GameCapture.CaptureOverlays="Capture third-party overlays (such as steam)" GameCapture.AntiCheatHook="Use anti-cheat compatibility hook" GameCapture.HotkeyStart="Capture foreground window" GameCapture.HotkeyStop="Deactivate capture" +GameCapture.HookRate="Hook Rate" +GameCapture.HookRate.Slow="Slow" +GameCapture.HookRate.Normal="Normal (recommended)" +GameCapture.HookRate.Fast="Fast" +GameCapture.HookRate.Fastest="Fastest" Mode="Mode" diff --git a/plugins/win-capture/game-capture.c b/plugins/win-capture/game-capture.c index dc3e64ecc..744ae5a7a 100644 --- a/plugins/win-capture/game-capture.c +++ b/plugins/win-capture/game-capture.c @@ -35,6 +35,7 @@ #define SETTING_LIMIT_FRAMERATE "limit_framerate" #define SETTING_CAPTURE_OVERLAYS "capture_overlays" #define SETTING_ANTI_CHEAT_HOOK "anti_cheat_hook" +#define SETTING_HOOK_RATE "hook_rate" /* deprecated */ #define SETTING_ANY_FULLSCREEN "capture_any_fullscreen" @@ -62,6 +63,11 @@ #define TEXT_LIMIT_FRAMERATE obs_module_text("GameCapture.LimitFramerate") #define TEXT_CAPTURE_OVERLAYS obs_module_text("GameCapture.CaptureOverlays") #define TEXT_ANTI_CHEAT_HOOK obs_module_text("GameCapture.AntiCheatHook") +#define TEXT_HOOK_RATE obs_module_text("GameCapture.HookRate") +#define TEXT_HOOK_RATE_SLOW obs_module_text("GameCapture.HookRate.Slow") +#define TEXT_HOOK_RATE_NORMAL obs_module_text("GameCapture.HookRate.Normal") +#define TEXT_HOOK_RATE_FAST obs_module_text("GameCapture.HookRate.Fast") +#define TEXT_HOOK_RATE_FASTEST obs_module_text("GameCapture.HookRate.Fastest") #define TEXT_MODE_ANY TEXT_ANY_FULLSCREEN #define TEXT_MODE_WINDOW obs_module_text("GameCapture.CaptureWindow") @@ -79,6 +85,13 @@ enum capture_mode { CAPTURE_MODE_HOTKEY }; +enum hook_rate { + HOOK_RATE_SLOW, + HOOK_RATE_NORMAL, + HOOK_RATE_FAST, + HOOK_RATE_FASTEST +}; + struct game_capture_config { char *title; char *class; @@ -94,6 +107,7 @@ struct game_capture_config { bool limit_framerate; bool capture_overlays; bool anticheat_hook; + enum hook_rate hook_rate; }; struct game_capture { @@ -266,6 +280,22 @@ static inline HANDLE open_process(DWORD desired_access, bool inherit_handle, return open_process_proc(desired_access, inherit_handle, process_id); } +static inline float hook_rate_to_float(enum hook_rate rate) +{ + switch (rate) { + case HOOK_RATE_SLOW: + return 2.0f; + case HOOK_RATE_FAST: + return 0.5f; + case HOOK_RATE_FASTEST: + return 0.1f; + case HOOK_RATE_NORMAL: + /* FALLTHROUGH */ + default: + return 1.0f; + } +} + static void stop_capture(struct game_capture *gc) { ipc_pipe_server_free(&gc->pipe); @@ -390,6 +420,8 @@ static inline void get_config(struct game_capture_config *cfg, SETTING_CAPTURE_OVERLAYS); cfg->anticheat_hook = obs_data_get_bool(settings, SETTING_ANTI_CHEAT_HOOK); + cfg->hook_rate = (enum hook_rate)obs_data_get_int(settings, + SETTING_HOOK_RATE); scale_str = obs_data_get_string(settings, SETTING_SCALE_RES); ret = sscanf(scale_str, "%"PRIu32"x%"PRIu32, @@ -504,7 +536,8 @@ static void game_capture_update(void *data, obs_data_t *settings) free_config(&gc->config); gc->config = cfg; - gc->retry_interval = DEFAULT_RETRY_INTERVAL; + gc->retry_interval = DEFAULT_RETRY_INTERVAL * + hook_rate_to_float(gc->config.hook_rate); gc->wait_for_target_startup = false; dstr_free(&gc->title); @@ -537,7 +570,8 @@ static void *game_capture_create(obs_data_t *settings, obs_source_t *source) gc->source = source; gc->initial_config = true; - gc->retry_interval = DEFAULT_RETRY_INTERVAL; + gc->retry_interval = DEFAULT_RETRY_INTERVAL * + hook_rate_to_float(gc->config.hook_rate); gc->hotkey_pair = obs_hotkey_pair_register_source( gc->source, HOTKEY_START, TEXT_HOTKEY_START, @@ -1044,7 +1078,8 @@ static void setup_window(struct game_capture *gc, HWND window) * (such as steam) need a little bit of time to load. ultimately this * helps prevent crashes */ if (gc->wait_for_target_startup) { - gc->retry_interval = 3.0f; + gc->retry_interval = 3.0f * + hook_rate_to_float(gc->config.hook_rate); gc->wait_for_target_startup = false; } else { gc->next_window = window; @@ -1595,7 +1630,7 @@ static void game_capture_tick(void *data, float seconds) get_window_class(&gc->class, hwnd); gc->priority = WINDOW_PRIORITY_CLASS; - gc->retry_time = 10.0f; + gc->retry_time = 10.0f * hook_rate_to_float(gc->config.hook_rate); gc->activate_hook = true; } else { deactivate = false; @@ -1614,7 +1649,7 @@ static void game_capture_tick(void *data, float seconds) return; } else if (!gc->showing) { - gc->retry_time = 10.0f; + gc->retry_time = 10.0f * hook_rate_to_float(gc->config.hook_rate); } if (gc->hook_stop && object_signalled(gc->hook_stop)) { @@ -1640,7 +1675,8 @@ static void game_capture_tick(void *data, float seconds) gc->error_acquiring = true; } else if (!gc->capturing) { - gc->retry_interval = ERROR_RETRY_INTERVAL; + gc->retry_interval = ERROR_RETRY_INTERVAL * + hook_rate_to_float(gc->config.hook_rate); stop_capture(gc); } } @@ -1655,7 +1691,8 @@ static void game_capture_tick(void *data, float seconds) debug("init_capture_data failed"); if (result != CAPTURE_RETRY && !gc->capturing) { - gc->retry_interval = ERROR_RETRY_INTERVAL; + gc->retry_interval = ERROR_RETRY_INTERVAL * + hook_rate_to_float(gc->config.hook_rate); stop_capture(gc); } } @@ -1787,6 +1824,8 @@ static void game_capture_defaults(obs_data_t *settings) obs_data_set_default_bool(settings, SETTING_LIMIT_FRAMERATE, false); obs_data_set_default_bool(settings, SETTING_CAPTURE_OVERLAYS, false); obs_data_set_default_bool(settings, SETTING_ANTI_CHEAT_HOOK, true); + obs_data_set_default_int(settings, SETTING_HOOK_RATE, + (int)HOOK_RATE_NORMAL); } static bool mode_callback(obs_properties_t *ppts, @@ -2002,6 +2041,14 @@ static obs_properties_t *game_capture_properties(void *data) obs_properties_add_bool(ppts, SETTING_CAPTURE_OVERLAYS, TEXT_CAPTURE_OVERLAYS); + p = obs_properties_add_list(ppts, SETTING_HOOK_RATE, + TEXT_HOOK_RATE, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, TEXT_HOOK_RATE_SLOW, HOOK_RATE_SLOW); + obs_property_list_add_int(p, TEXT_HOOK_RATE_NORMAL, HOOK_RATE_NORMAL); + obs_property_list_add_int(p, TEXT_HOOK_RATE_FAST, HOOK_RATE_FAST); + obs_property_list_add_int(p, TEXT_HOOK_RATE_FASTEST, HOOK_RATE_FASTEST); + UNUSED_PARAMETER(data); return ppts; }