From e92818ee0b595f991497273a2fd2fdfdeb783fe4 Mon Sep 17 00:00:00 2001 From: Norihiro Kamae Date: Wed, 16 Mar 2022 05:47:04 +0900 Subject: [PATCH] Check and update target of the source periodically Fix #1 --- src/async-source-duplication-source.c | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/async-source-duplication-source.c b/src/async-source-duplication-source.c index 717f736..43823a7 100644 --- a/src/async-source-duplication-source.c +++ b/src/async-source-duplication-source.c @@ -1,4 +1,5 @@ #include +#include #include "plugin-macros.generated.h" struct source_s @@ -8,7 +9,9 @@ struct source_s // properties char *target_source_name; + pthread_mutex_t target_update_mutex; obs_weak_source_t *target_weak; + float target_check; }; static const char *get_name(void *type_data) @@ -66,6 +69,7 @@ static void set_weak_target(struct source_s *s, obs_source_t *target) if (s->target_weak) release_weak_target(s); s->target_weak = obs_source_get_weak_source(target); + s->target_check = 3.0f; signal_handler_t *sh = obs_source_get_signal_handler(target); signal_handler_connect(sh, "output_video", output_video, s); @@ -96,17 +100,23 @@ static inline obs_source_t *source_to_filter(obs_source_t *src) return target; } -static inline void set_weak_target_by_name(struct source_s *s, const char *target_source_name) +static obs_source_t *get_filter_by_target_source_name(const char *target_source_name) { obs_source_t *src = obs_get_source_by_name(target_source_name); if (!src) - return; + return NULL; obs_source_t *target = source_to_filter(src); + obs_source_release(src); + return target; +} + +static inline void set_weak_target_by_name(struct source_s *s, const char *target_source_name) +{ + obs_source_t *target = get_filter_by_target_source_name(target_source_name); if (target) { set_weak_target(s, target); obs_source_release(target); } - obs_source_release(src); } static void update(void *data, obs_data_t *settings) @@ -114,18 +124,40 @@ static void update(void *data, obs_data_t *settings) struct source_s *s = data; const char *target_source_name = obs_data_get_string(settings, "target_source_name"); + pthread_mutex_lock(&s->target_update_mutex); if (target_source_name && (!s->target_source_name || strcmp(target_source_name, s->target_source_name))) { bfree(s->target_source_name); s->target_source_name = bstrdup(target_source_name); release_weak_target(s); set_weak_target_by_name(s, target_source_name); } + pthread_mutex_unlock(&s->target_update_mutex); +} + +static void tick(void *data, float seconds) +{ + struct source_s *s = data; + + pthread_mutex_lock(&s->target_update_mutex); + if ((s->target_check -= seconds) < 0.0f) { + obs_source_t *target_by_name = get_filter_by_target_source_name(s->target_source_name); + obs_source_t *target_by_weak = obs_weak_source_get_source(s->target_weak); + if (target_by_name != target_by_weak) { + blog(LOG_INFO, "updating target from %p to %p", target_by_weak, target_by_name); + set_weak_target(s, target_by_name); + } + obs_source_release(target_by_weak); + obs_source_release(target_by_name); + s->target_check = 3.0f; + } + pthread_mutex_unlock(&s->target_update_mutex); } static void *create(obs_data_t *settings, obs_source_t *source) { struct source_s *s = bzalloc(sizeof(struct source_s)); s->context = source; + pthread_mutex_init(&s->target_update_mutex, NULL); update(s, settings); @@ -137,6 +169,7 @@ static void destroy(void *data) struct source_s *s = data; release_weak_target(s); + pthread_mutex_destroy(&s->target_update_mutex); bfree(s->target_source_name); bfree(s); @@ -150,5 +183,6 @@ const struct obs_source_info async_srcdup_source = { .create = create, .destroy = destroy, .update = update, + .video_tick = tick, .get_properties = get_properties, };