Skip to content

Commit

Permalink
Merge branch 'streamlabs' into obs_2913_merge_3
Browse files Browse the repository at this point in the history
  • Loading branch information
summeroff authored Dec 19, 2023
2 parents 72c75b8 + 2a64222 commit 642a1fa
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 22 deletions.
9 changes: 9 additions & 0 deletions libobs/obs-encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,22 @@ static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder)
obs_encoder_shutdown(encoder);

if (encoder->orig_info.create) {
pthread_mutex_lock(&obs->video.mixes_mutex);
if (!obs->video.main_mix) {
// App is at shutdown state if no main mix
pthread_mutex_unlock(&obs->video.mixes_mutex);
return false;
}

can_reroute = true;
encoder->info = encoder->orig_info;
if (!encoder->video)
encoder->video = obs->video.main_mix;
encoder->context.data = encoder->orig_info.create(
encoder->context.settings, encoder);
can_reroute = false;

pthread_mutex_unlock(&obs->video.mixes_mutex);
}
if (!encoder->context.data)
return false;
Expand Down
3 changes: 2 additions & 1 deletion libobs/obs.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,8 @@ static void obs_free_video(bool full_clean)
}
if (num_views > 0)
blog(LOG_WARNING, "Number of remaining views: %ld", num_views);

obs->video.main_mix = NULL;
pthread_mutex_unlock(&obs->video.mixes_mutex);

pthread_mutex_destroy(&obs->video.mixes_mutex);
Expand All @@ -944,7 +946,6 @@ static void obs_free_video(bool full_clean)
pthread_mutex_destroy(&obs->video.task_mutex);
pthread_mutex_init_value(&obs->video.task_mutex);
circlebuf_free(&obs->video.tasks);
obs->video.main_mix = NULL;
}

static void obs_free_graphics(void)
Expand Down
165 changes: 145 additions & 20 deletions plugins/win-capture/game-capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,17 @@ extern struct obs_core *obs = NULL;
#define SETTING_RGBA10A2_SPACE "rgb10a2_space"
#define SETTINGS_COMPAT_INFO "compat_info"

#define SETTING_AUTO_LIST_FILE "auto_capture_rules_path"
#define SETTING_PLACEHOLDER_IMG "auto_placeholder_image"
#define SETTING_PLACEHOLDER_MSG "auto_placeholder_message"
#define SETTING_PLACEHOLDER_USE "user_placeholder_use"
#define SETTING_PLACEHOLDER_USR "user_placeholder_image"
#define SETTING_AUTO_LIST_FILE "auto_capture_rules_path"
#define SETTING_PLACEHOLDER_IMG "auto_placeholder_image"
#define SETTING_PLACEHOLDER_MSG "auto_placeholder_message"
#define SETTING_PLACEHOLDER_USE "user_placeholder_use"
#define SETTING_PLACEHOLDER_USR "user_placeholder_image"
#define SETTING_PLACEHOLDER_WND_IMG "window_placeholder_image"
#define SETTING_PLACEHOLDER_WND_MSG_WAIT "window_placeholder_waiting_message"
#define SETTING_PLACEHOLDER_WND_MSG_ERR "window_placeholder_missing_message"

/* custom props */
# define COMPAT_INFO_VISIBLE "compat_info_visible"

/* deprecated */
#define SETTING_ANY_FULLSCREEN "capture_any_fullscreen"
Expand Down Expand Up @@ -192,7 +198,11 @@ struct game_capture {
gs_image_file2_t placeholder_image;
gs_texture_t *placeholder_text_texture;
struct dstr placeholder_image_path;
struct dstr placeholder_text;
struct dstr
placeholder_text; // currently active placeholder message (if any)

struct dstr placeholder_wait_text; // default message
struct dstr placeholder_error_text; // error message

ipc_pipe_server_t pipe;
gs_texture_t *texture;
Expand Down Expand Up @@ -516,6 +526,8 @@ static void game_capture_destroy(void *data)
close_handle(&gc->auto_capture.mutex);
dstr_free(&gc->placeholder_image_path);
dstr_free(&gc->placeholder_text);
dstr_free(&gc->placeholder_wait_text);
dstr_free(&gc->placeholder_error_text);
unload_placeholder_image(gc);

bfree(gc);
Expand Down Expand Up @@ -810,26 +822,46 @@ static void game_capture_update(void *data, obs_data_t *settings)

const char *img_path = NULL;
const char *placeholder_text = NULL;
const char *placeholder_wait_text = NULL;
const char *placeholder_error_text = NULL;
bool use_custom_placeholder =
obs_data_get_bool(settings, SETTING_PLACEHOLDER_USE);
if (use_custom_placeholder)
img_path =
obs_data_get_string(settings, SETTING_PLACEHOLDER_USR);
else
img_path =
obs_data_get_string(settings, SETTING_PLACEHOLDER_IMG);
else {
if (cfg.mode == CAPTURE_MODE_WINDOW) {
img_path = obs_data_get_string(
settings, SETTING_PLACEHOLDER_WND_IMG);
} else {
img_path = obs_data_get_string(settings,
SETTING_PLACEHOLDER_IMG);
}
}

if (gc->placeholder_image_path.len == 0 ||
dstr_cmp(&gc->placeholder_image_path, img_path) != 0) {
unload_placeholder_image(gc);
}
dstr_copy(&gc->placeholder_image_path, img_path);

if (!use_custom_placeholder)
placeholder_text =
obs_data_get_string(settings, SETTING_PLACEHOLDER_MSG);
if (!use_custom_placeholder) {
if (cfg.mode == CAPTURE_MODE_WINDOW) {
placeholder_wait_text = obs_data_get_string(
settings, SETTING_PLACEHOLDER_WND_MSG_WAIT);
placeholder_error_text = obs_data_get_string(
settings, SETTING_PLACEHOLDER_WND_MSG_ERR);

placeholder_text = placeholder_wait_text;
} else {
placeholder_text = obs_data_get_string(
settings, SETTING_PLACEHOLDER_MSG);
}
}

dstr_copy(&gc->placeholder_text, placeholder_text);
dstr_copy(&gc->placeholder_wait_text, placeholder_wait_text);
dstr_copy(&gc->placeholder_error_text, placeholder_error_text);

reset_capture = capture_needs_reset(&cfg, &gc->config);

Expand Down Expand Up @@ -860,7 +892,7 @@ static void game_capture_update(void *data, obs_data_t *settings)
gc->priority = gc->config.priority;
}

if (cfg.mode == CAPTURE_MODE_AUTO) {
if (cfg.mode == CAPTURE_MODE_AUTO || cfg.mode == CAPTURE_MODE_WINDOW) {
load_placeholder_image(gc);
} else {
unload_placeholder_image(gc);
Expand Down Expand Up @@ -898,6 +930,8 @@ static void *game_capture_create(obs_data_t *settings, obs_source_t *source)

dstr_init(&gc->placeholder_image_path);
dstr_init(&gc->placeholder_text);
dstr_init(&gc->placeholder_wait_text);
dstr_init(&gc->placeholder_error_text);
gc->placeholder_text_texture = NULL;
const HMODULE hModuleUser32 = GetModuleHandle(L"User32.dll");
if (hModuleUser32) {
Expand Down Expand Up @@ -928,6 +962,8 @@ static void *game_capture_create(obs_data_t *settings, obs_source_t *source)
}
}

obs_data_set_bool(settings, COMPAT_INFO_VISIBLE, false);

game_capture_update(gc, settings);
return gc;
}
Expand Down Expand Up @@ -1335,6 +1371,7 @@ static bool target_suspended(struct game_capture *gc)
}

static bool init_events(struct game_capture *gc);
//static void set_compat_info_visible(struct game_capture* gc, bool visible); // TODO: remove????

static bool init_hook(struct game_capture *gc)
{
Expand Down Expand Up @@ -1522,6 +1559,7 @@ static void get_selected_window(struct game_capture *gc)
if (window) {
setup_window(gc, window);
} else {
gc->window = NULL;
gc->wait_for_target_startup = true;
}
}
Expand Down Expand Up @@ -2133,6 +2171,25 @@ static void check_foreground_window(struct game_capture *gc, float seconds)
}
}

static void set_compat_info_visible(struct game_capture *gc, bool visible)
{
// 30 is just big enought number to not overlap with the existing and possible future flags
const uint32_t CUSTOM_REFRESH_UI_FLAG = (1 << 30);

obs_data_t *setings = obs_source_get_settings(gc->source);
obs_data_set_bool(setings, COMPAT_INFO_VISIBLE, visible);

obs_properties_t *props = obs_source_properties(gc->source);
obs_properties_destroy(props);

// Toggling custom flag to force UI refresh
// For details see 'globalCallback::worker()' in obs-studio-node and
// 'updateSourceFlags' in desktop repo
gc->source->info.output_flags ^= CUSTOM_REFRESH_UI_FLAG;

obs_data_release(setings);
}

static void game_capture_tick(void *data, float seconds)
{
struct game_capture *gc = data;
Expand Down Expand Up @@ -2234,7 +2291,43 @@ static void game_capture_tick(void *data, float seconds)
gc->retry_time = 0.0f;
}
}

if (gc->config.mode == CAPTURE_MODE_WINDOW) {
if (gc->window) {
if (dstr_cmpi(
&gc->placeholder_text,
gc->placeholder_error_text.array) !=
0) {
set_compat_info_visible(gc, true);

dstr_copy(&gc->placeholder_text,
gc->placeholder_error_text
.array);
load_placeholder_image(gc);
}
} else {
if (dstr_cmpi(&gc->placeholder_text,
gc->placeholder_wait_text.array) !=
0) {
set_compat_info_visible(gc, false);

dstr_copy(
&gc->placeholder_text,
gc->placeholder_wait_text.array);
load_placeholder_image(gc);
}
}
}
} else {
if (gc->capturing) {
obs_data_t *settings =
obs_source_get_settings(gc->source);
if (obs_data_get_bool(settings, COMPAT_INFO_VISIBLE)) {
set_compat_info_visible(gc, false);
}
obs_data_release(settings);
}

if (!capture_valid(gc)) {
info("capture window no longer exists, "
"terminating capture");
Expand Down Expand Up @@ -2315,7 +2408,8 @@ static void game_capture_render(void *data, gs_effect_t *unused)

struct game_capture *gc = data;
if (!gc->texture || !gc->active) {
if (gc->config.mode == CAPTURE_MODE_AUTO) {
if (gc->config.mode == CAPTURE_MODE_AUTO ||
gc->config.mode == CAPTURE_MODE_WINDOW) {
if (gc->placeholder_image.image.texture) {
//draw placeholder image
gs_effect_t *effect;
Expand Down Expand Up @@ -2391,7 +2485,8 @@ static void game_capture_render(void *data, gs_effect_t *unused)
gs_effect_t *const effect = obs_get_base_effect(
allow_transparency ? OBS_EFFECT_DEFAULT : OBS_EFFECT_OPAQUE);

if (gc->config.mode == CAPTURE_MODE_AUTO) {
if (gc->config.mode == CAPTURE_MODE_AUTO ||
gc->config.mode == CAPTURE_MODE_WINDOW) {
float cx_scale = gc->config.base_width / (float)gc->cx;
float cy_scale = gc->config.base_height / (float)gc->cy;
gs_matrix_push();
Expand Down Expand Up @@ -2630,15 +2725,17 @@ static void game_capture_render(void *data, gs_effect_t *unused)
gs_set_linear_srgb(previous);
}

if (gc->config.mode == CAPTURE_MODE_AUTO) {
if (gc->config.mode == CAPTURE_MODE_AUTO ||
gc->config.mode == CAPTURE_MODE_WINDOW) {
gs_matrix_pop();
}
}

static uint32_t game_capture_width(void *data)
{
struct game_capture *gc = data;
if (gc->config.mode == CAPTURE_MODE_AUTO) {
if (gc->config.mode == CAPTURE_MODE_AUTO ||
gc->config.mode == CAPTURE_MODE_WINDOW) {
return gc->config.base_width;
}
return (gc->active && gc->capturing) ? gc->cx : 0;
Expand All @@ -2647,7 +2744,8 @@ static uint32_t game_capture_width(void *data)
static uint32_t game_capture_height(void *data)
{
struct game_capture *gc = data;
if (gc->config.mode == CAPTURE_MODE_AUTO) {
if (gc->config.mode == CAPTURE_MODE_AUTO ||
gc->config.mode == CAPTURE_MODE_WINDOW) {
return gc->config.base_height;
}
return (gc->active && gc->capturing) ? gc->cy : 0;
Expand Down Expand Up @@ -2677,6 +2775,11 @@ static void game_capture_defaults(obs_data_t *settings)
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_IMG, "");
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_USR, "");
obs_data_set_default_bool(settings, SETTING_PLACEHOLDER_USE, false);
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_WND_IMG, "");
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_WND_MSG_WAIT,
"Looking for a game to capture");
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_WND_MSG_ERR,
"");
obs_data_set_default_string(settings, SETTING_PLACEHOLDER_MSG,
"Looking for a game to capture");
obs_data_set_default_string(settings, SETTING_RGBA10A2_SPACE,
Expand Down Expand Up @@ -2746,6 +2849,18 @@ static bool mode_callback(obs_properties_t *ppts, obs_property_t *p,
return true;
}

static bool status_message_changed_callback(obs_properties_t *ppts,
obs_property_t *p,
obs_data_t *settings)
{
UNUSED_PARAMETER(ppts);

obs_property_set_visible(p, obs_data_get_bool(settings,
COMPAT_INFO_VISIBLE));

return true;
}

static bool window_changed_callback(obs_properties_t *ppts, obs_property_t *p,
obs_data_t *settings)
{
Expand Down Expand Up @@ -2878,9 +2993,19 @@ static obs_properties_t *game_capture_properties(void *data)
obs_property_list_add_int(p, TEXT_MATCH_CLASS, WINDOW_PRIORITY_CLASS);
obs_property_list_add_int(p, TEXT_MATCH_EXE, WINDOW_PRIORITY_EXE);

p = obs_properties_add_text(ppts, SETTINGS_COMPAT_INFO, NULL,
p = obs_properties_add_text(ppts, SETTINGS_COMPAT_INFO,
"Specified window is not a game",
OBS_TEXT_INFO);
obs_property_set_enabled(p, false);
obs_property_text_set_info_type(p, OBS_TEXT_INFO_ERROR);
obs_property_set_visible(p, false);
if (data) {
struct game_capture *gc = data;
obs_data_t *settings = obs_source_get_settings(gc->source);
obs_property_set_visible(
p, obs_data_get_bool(settings, COMPAT_INFO_VISIBLE));
obs_data_release(settings);
}
obs_property_set_modified_callback(p, status_message_changed_callback);

obs_properties_add_bool(ppts, SETTING_COMPATIBILITY,
TEXT_SLI_COMPATIBILITY);
Expand Down
2 changes: 1 addition & 1 deletion plugins/win-spout

0 comments on commit 642a1fa

Please sign in to comment.