From f29e5ffbc73146b71f72cf6b3f6fc73367b0cb8c Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 13:02:39 -0800 Subject: [PATCH 1/7] libobs: Add obs_scene_get_ref() --- libobs/obs-scene.c | 9 +++++++++ libobs/obs.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index c5ce68636..163ef334b 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -1649,6 +1649,15 @@ void obs_scene_addref(obs_scene_t *scene) obs_source_addref(scene->source); } +obs_scene_t *obs_scene_get_ref(obs_scene_t *scene) +{ + if (!scene) + return NULL; + if (obs_source_get_ref(scene->source) != NULL) + return scene; + return NULL; +} + void obs_scene_release(obs_scene_t *scene) { if (scene) diff --git a/libobs/obs.h b/libobs/obs.h index ade027525..17189b5a1 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1593,6 +1593,8 @@ EXPORT obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, EXPORT void obs_scene_addref(obs_scene_t *scene); EXPORT void obs_scene_release(obs_scene_t *scene); +EXPORT obs_scene_t *obs_scene_get_ref(obs_scene_t *scene); + /** Gets the scene's source context */ EXPORT obs_source_t *obs_scene_get_source(const obs_scene_t *scene); From ad6cb5a8be4bcffa7fd5c3d9ffa4901625bab303 Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 11:36:20 -0800 Subject: [PATCH 2/7] image-source: Replace source addref calls with get_ref --- plugins/image-source/obs-slideshow.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/image-source/obs-slideshow.c b/plugins/image-source/obs-slideshow.c index 98adae075..78e4eedc2 100644 --- a/plugins/image-source/obs-slideshow.c +++ b/plugins/image-source/obs-slideshow.c @@ -133,8 +133,7 @@ static obs_source_t *get_transition(struct slideshow *ss) obs_source_t *tr; pthread_mutex_lock(&ss->mutex); - tr = ss->transition; - obs_source_addref(tr); + tr = obs_source_get_ref(ss->transition); pthread_mutex_unlock(&ss->mutex); return tr; @@ -151,8 +150,7 @@ static obs_source_t *get_source(struct darray *array, const char *path) const char *cur_path = files.array[i].path; if (strcmp(path, cur_path) == 0) { - source = files.array[i].source; - obs_source_addref(source); + source = obs_source_get_ref(files.array[i].source); break; } } From 404ebdbd51a62e4560193e0a27c5a0f7c5c6be1e Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 11:36:41 -0800 Subject: [PATCH 3/7] mac-syphon: Replace source addref calls with get_ref --- plugins/mac-syphon/syphon.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/mac-syphon/syphon.m b/plugins/mac-syphon/syphon.m index 6d4a5c230..a34f5eb29 100644 --- a/plugins/mac-syphon/syphon.m +++ b/plugins/mac-syphon/syphon.m @@ -892,8 +892,9 @@ static void syphon_release(void *param) static inline obs_properties_t *syphon_properties_internal(syphon_t s) { - if (s) - obs_source_addref(s->source); + if (s && obs_source_get_ref(s->source) == NULL) { + s = NULL; + } obs_properties_t *props = obs_properties_create_param(s, syphon_release); From b9e01380f340105de7a18e1768db0cec4035a2a4 Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 11:26:04 -0800 Subject: [PATCH 4/7] UI: Replace addref calls with get_ref --- UI/api-interface.cpp | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/UI/api-interface.cpp b/UI/api-interface.cpp index 3d6980b73..4b19207b8 100644 --- a/UI/api-interface.cpp +++ b/UI/api-interface.cpp @@ -81,22 +81,19 @@ struct OBSStudioAPI : obs_frontend_callbacks { OBSScene scene = GetOBSRef(item); obs_source_t *source = obs_scene_get_source(scene); - obs_source_addref(source); - da_push_back(sources->sources, &source); + if (obs_source_get_ref(source) != nullptr) + da_push_back(sources->sources, &source); } } obs_source_t *obs_frontend_get_current_scene(void) override { - OBSSource source; - if (main->IsPreviewProgramMode()) { - source = obs_weak_source_get_source(main->programScene); + return obs_weak_source_get_source(main->programScene); } else { - source = main->GetCurrentSceneSource(); - obs_source_addref(source); + OBSSource source = main->GetCurrentSceneSource(); + return obs_source_get_ref(source); } - return source; } void obs_frontend_set_current_scene(obs_source_t *scene) override @@ -123,17 +120,15 @@ struct OBSStudioAPI : obs_frontend_callbacks { if (!tr) continue; - obs_source_addref(tr); - da_push_back(sources->sources, &tr); + if (obs_source_get_ref(tr) != nullptr) + da_push_back(sources->sources, &tr); } } obs_source_t *obs_frontend_get_current_transition(void) override { OBSSource tr = main->GetCurrentTransition(); - - obs_source_addref(tr); - return tr; + return obs_source_get_ref(tr); } void @@ -391,22 +386,19 @@ struct OBSStudioAPI : obs_frontend_callbacks { obs_output_t *obs_frontend_get_streaming_output(void) override { OBSOutput output = main->outputHandler->streamOutput.Get(); - obs_output_addref(output); - return output; + return obs_output_get_ref(output); } obs_output_t *obs_frontend_get_recording_output(void) override { OBSOutput out = main->outputHandler->fileOutput.Get(); - obs_output_addref(out); - return out; + return obs_output_get_ref(out); } obs_output_t *obs_frontend_get_replay_buffer_output(void) override { OBSOutput out = main->outputHandler->replayBuffer.Get(); - obs_output_addref(out); - return out; + return obs_output_get_ref(out); } config_t *obs_frontend_get_profile_config(void) override @@ -550,14 +542,12 @@ struct OBSStudioAPI : obs_frontend_callbacks { obs_source_t *obs_frontend_get_current_preview_scene(void) override { - OBSSource source = nullptr; - if (main->IsPreviewProgramMode()) { - source = main->GetCurrentSceneSource(); - obs_source_addref(source); + OBSSource source = main->GetCurrentSceneSource(); + return obs_source_get_ref(source); } - return source; + return nullptr; } void @@ -585,8 +575,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { obs_output_t *obs_frontend_get_virtualcam_output(void) override { OBSOutput output = main->outputHandler->virtualCam.Get(); - obs_output_addref(output); - return output; + return obs_output_get_ref(output); } void obs_frontend_start_virtualcam(void) override From 77a35e93ea53b92d1fffadb234d8bad0b668a246 Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 11:59:17 -0800 Subject: [PATCH 5/7] libobs: Use get_ref calls for obs.hpp helper classes --- libobs/obs.hpp | 67 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/libobs/obs.hpp b/libobs/obs.hpp index 2fac266f4..2cbb1650c 100644 --- a/libobs/obs.hpp +++ b/libobs/obs.hpp @@ -25,19 +25,23 @@ template class OBSRefAutoRelease; template class OBSRef; +template class OBSSafeRef; -using OBSSource = OBSRef; -using OBSScene = OBSRef; +using OBSSource = + OBSSafeRef; +using OBSScene = + OBSSafeRef; using OBSSceneItem = OBSRef; using OBSData = OBSRef; using OBSDataArray = OBSRef; -using OBSOutput = OBSRef; +using OBSOutput = + OBSSafeRef; using OBSEncoder = - OBSRef; + OBSSafeRef; using OBSService = - OBSRef; + OBSSafeRef; using OBSWeakSource = OBSRef; @@ -150,19 +154,58 @@ public: inline OBSRef &operator=(const OBSRef &ref) { return Replace(ref.val); } inline OBSRef &operator=(T valIn) { return Replace(valIn); } - friend OBSSource OBSGetStrongRef(obs_weak_source_t *weak); friend OBSWeakSource OBSGetWeakRef(obs_source_t *source); - - friend OBSOutput OBSGetStrongRef(obs_weak_output_t *weak); friend OBSWeakOutput OBSGetWeakRef(obs_output_t *output); - - friend OBSEncoder OBSGetStrongRef(obs_weak_encoder_t *weak); friend OBSWeakEncoder OBSGetWeakRef(obs_encoder_t *encoder); - - friend OBSService OBSGetStrongRef(obs_weak_service_t *weak); friend OBSWeakService OBSGetWeakRef(obs_service_t *service); }; +template +class OBSSafeRef : public OBSRefAutoRelease { + + inline OBSSafeRef &Replace(T valIn) + { + T newVal = getref(valIn); + release(this->val); + this->val = newVal; + return *this; + } + + struct TakeOwnership { + }; + inline OBSSafeRef(T val_, TakeOwnership) + : OBSRefAutoRelease::OBSRefAutoRelease(val_) + { + } + +public: + inline OBSSafeRef() + : OBSRefAutoRelease::OBSRefAutoRelease(nullptr) + { + } + inline OBSSafeRef(const OBSSafeRef &ref) + : OBSRefAutoRelease::OBSRefAutoRelease(ref.val) + { + this->val = getref(ref.val); + } + inline OBSSafeRef(T val_) + : OBSRefAutoRelease::OBSRefAutoRelease(val_) + { + this->val = getref(this->val); + } + + inline OBSSafeRef &operator=(const OBSSafeRef &ref) + { + return Replace(ref.val); + } + inline OBSSafeRef &operator=(T valIn) { return Replace(valIn); } + + friend OBSSource OBSGetStrongRef(obs_weak_source_t *weak); + friend OBSOutput OBSGetStrongRef(obs_weak_output_t *weak); + friend OBSEncoder OBSGetStrongRef(obs_weak_encoder_t *weak); + friend OBSService OBSGetStrongRef(obs_weak_service_t *weak); +}; + inline OBSSource OBSGetStrongRef(obs_weak_source_t *weak) { return {obs_weak_source_get_source(weak), OBSSource::TakeOwnership()}; From 0523c2e5e92c9acdf4733531d174d576ff76c3ae Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 13:47:56 -0800 Subject: [PATCH 6/7] libobs: Replace addref calls with get_ref --- libobs/obs-scene.c | 54 ++++++++++++++++++++-------------- libobs/obs-source-transition.c | 18 +++++------- libobs/obs-source.c | 48 +++++++++++++++++------------- libobs/obs-view.c | 10 ++----- libobs/obs.c | 2 +- 5 files changed, 71 insertions(+), 61 deletions(-) diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 163ef334b..2ce9f6444 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -1478,8 +1478,7 @@ static inline obs_source_t *dup_child(struct darray *array, size_t idx, struct obs_scene_item *item = old_items.array[i]; if (item->source == source) { source = get_child_at_idx(new_scene, i); - obs_source_addref(source); - return source; + return obs_source_get_ref(source); } } @@ -1489,8 +1488,7 @@ static inline obs_source_t *dup_child(struct darray *array, size_t idx, static inline obs_source_t *new_ref(obs_source_t *source) { - obs_source_addref(source); - return source; + return obs_source_get_ref(source); } static inline void duplicate_item_data(struct obs_scene_item *dst, @@ -1954,6 +1952,7 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, if (!scene) return NULL; + source = obs_source_get_ref(source); if (!source) { blog(LOG_ERROR, "Tried to add a NULL source to a scene"); return NULL; @@ -1961,19 +1960,19 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, if (source->removed) { blog(LOG_WARNING, "Tried to add a removed source to a scene"); - return NULL; + goto release_source_and_fail; } if (pthread_mutex_init(&mutex, NULL) != 0) { blog(LOG_WARNING, "Failed to create scene item mutex"); - return NULL; + goto release_source_and_fail; } if (!obs_source_add_active_child(scene->source, source)) { blog(LOG_WARNING, "Failed to add source to scene due to " "infinite source recursion"); pthread_mutex_destroy(&mutex); - return NULL; + goto release_source_and_fail; } item = bzalloc(sizeof(struct obs_scene_item)); @@ -1993,8 +1992,6 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, matrix4_identity(&item->draw_transform); matrix4_identity(&item->box_transform); - obs_source_addref(source); - if (source_has_audio(source)) { item->visible = false; da_push_back(item->audio_actions, &action); @@ -2039,6 +2036,10 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene, sceneitem_renamed, item); return item; + +release_source_and_fail: + obs_source_release(source); + return NULL; } obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) @@ -2433,9 +2434,11 @@ void obs_sceneitem_set_order(obs_sceneitem_t *item, return; struct obs_scene_item *next, *prev; - struct obs_scene *scene = item->parent; + struct obs_scene *scene = obs_scene_get_ref(item->parent); + + if (!scene) + return; - obs_scene_addref(scene); full_lock(scene); next = item->next; @@ -2493,10 +2496,12 @@ void obs_sceneitem_set_order_position(obs_sceneitem_t *item, int position) if (!item) return; - struct obs_scene *scene = item->parent; + struct obs_scene *scene = obs_scene_get_ref(item->parent); struct obs_scene_item *next; - obs_scene_addref(scene); + if (!scene) + return; + full_lock(scene); detach_sceneitem(item); @@ -2766,7 +2771,10 @@ bool obs_scene_reorder_items(obs_scene_t *scene, if (!scene || !item_order_size) return false; - obs_scene_addref(scene); + scene = obs_scene_get_ref(scene); + if (!scene) + return false; + full_lock(scene); bool order_matches = true; @@ -2804,7 +2812,10 @@ void obs_scene_atomic_update(obs_scene_t *scene, if (!scene) return; - obs_scene_addref(scene); + scene = obs_scene_get_ref(scene); + if (!scene) + return; + full_lock(scene); func(data, scene); full_unlock(scene); @@ -3441,7 +3452,10 @@ bool obs_scene_reorder_items2(obs_scene_t *scene, if (!scene || !item_order_size || !item_order) return false; - obs_scene_addref(scene); + scene = obs_scene_get_ref(scene); + if (!scene) + return false; + full_lock(scene); if (sceneitems_match2(scene, item_order, item_order_size)) { @@ -3583,9 +3597,7 @@ void obs_sceneitem_set_show_transition(obs_sceneitem_t *item, if (item->show_transition) obs_source_release(item->show_transition); - item->show_transition = transition; - if (item->show_transition) - obs_source_addref(item->show_transition); + item->show_transition = obs_source_get_ref(transition); } void obs_sceneitem_set_show_transition_duration(obs_sceneitem_t *item, @@ -3618,9 +3630,7 @@ void obs_sceneitem_set_hide_transition(obs_sceneitem_t *item, if (item->hide_transition) obs_source_release(item->hide_transition); - item->hide_transition = transition; - if (item->hide_transition) - obs_source_addref(item->hide_transition); + item->hide_transition = obs_source_get_ref(transition); } void obs_sceneitem_set_hide_transition_duration(obs_sceneitem_t *item, diff --git a/libobs/obs-source-transition.c b/libobs/obs-source-transition.c index d3b718d61..68d4abf68 100644 --- a/libobs/obs-source-transition.c +++ b/libobs/obs-source-transition.c @@ -241,7 +241,7 @@ set_source(obs_source_t *transition, enum obs_transition_target target, bool already_active; if (new_child) - obs_source_addref(new_child); + new_child = obs_source_get_ref(new_child); lock_transition(transition); @@ -294,7 +294,7 @@ obs_source_t *obs_transition_get_source(obs_source_t *transition, lock_transition(transition); ret = transition->transition_sources[idx]; - obs_source_addref(ret); + ret = obs_source_get_ref(ret); unlock_transition(transition); return ret; @@ -312,7 +312,7 @@ obs_source_t *obs_transition_get_active_source(obs_source_t *transition) ret = transition->transition_sources[1]; else ret = transition->transition_sources[0]; - obs_source_addref(ret); + ret = obs_source_get_ref(ret); unlock_transition(transition); return ret; @@ -442,7 +442,7 @@ void obs_transition_set(obs_source_t *transition, obs_source_t *source) if (!transition_valid(transition, "obs_transition_clear")) return; - obs_source_addref(source); + source = obs_source_get_ref(source); lock_transition(transition); for (size_t i = 0; i < 2; i++) { @@ -632,10 +632,8 @@ struct transition_state { static inline void copy_transition_state(obs_source_t *transition, struct transition_state *state) { - state->s[0] = transition->transition_sources[0]; - state->s[1] = transition->transition_sources[1]; - obs_source_addref(state->s[0]); - obs_source_addref(state->s[1]); + state->s[0] = obs_source_get_ref(transition->transition_sources[0]); + state->s[1] = obs_source_get_ref(transition->transition_sources[1]); state->transitioning_video = transition->transitioning_video; state->transitioning_audio = transition->transitioning_audio; @@ -1038,7 +1036,8 @@ static inline obs_source_t * copy_source_state(obs_source_t *tr_dest, obs_source_t *tr_source, size_t idx) { obs_source_t *old_child = tr_dest->transition_sources[idx]; - obs_source_t *new_child = tr_source->transition_sources[idx]; + obs_source_t *new_child = + obs_source_get_ref(tr_source->transition_sources[idx]); bool active = tr_source->transition_source_active[idx]; if (old_child && tr_dest->transition_source_active[idx]) @@ -1049,7 +1048,6 @@ copy_source_state(obs_source_t *tr_dest, obs_source_t *tr_source, size_t idx) if (active && new_child) obs_source_add_active_child(tr_dest, new_child); - obs_source_addref(new_child); return old_child; } diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 2a6a1d2dd..e8289c124 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -465,9 +465,12 @@ static void duplicate_filters(obs_source_t *dst, obs_source_t *src, da_init(filters); pthread_mutex_lock(&src->filter_mutex); - for (size_t i = 0; i < src->filters.num; i++) - obs_source_addref(src->filters.array[i]); - da_copy(filters, src->filters); + da_reserve(filters, src->filters.num); + for (size_t i = 0; i < src->filters.num; i++) { + obs_source_t *s = obs_source_get_ref(src->filters.array[i]); + if (s) + da_push_back(filters, &s); + } pthread_mutex_unlock(&src->filter_mutex); for (size_t i = filters.num; i > 0; i--) { @@ -537,8 +540,7 @@ obs_source_t *obs_source_duplicate(obs_source_t *source, const char *new_name, if (source->info.type == OBS_SOURCE_TYPE_SCENE) { obs_scene_t *scene = obs_scene_from_source(source); if (scene && !create_private) { - obs_source_addref(source); - return source; + return obs_source_get_ref(source); } if (!scene) scene = obs_group_from_source(source); @@ -554,8 +556,7 @@ obs_source_t *obs_source_duplicate(obs_source_t *source, const char *new_name, } if ((source->info.output_flags & OBS_SOURCE_DO_NOT_DUPLICATE) != 0) { - obs_source_addref(source); - return source; + return obs_source_get_ref(source); } settings = obs_data_create(); @@ -2265,8 +2266,7 @@ static inline void obs_source_render_filters(obs_source_t *source) obs_source_t *first_filter; pthread_mutex_lock(&source->filter_mutex); - first_filter = source->filters.array[0]; - obs_source_addref(first_filter); + first_filter = obs_source_get_ref(source->filters.array[0]); pthread_mutex_unlock(&source->filter_mutex); source->rendering_filter = true; @@ -2386,9 +2386,11 @@ void obs_source_video_render(obs_source_t *source) if (!obs_source_valid(source, "obs_source_video_render")) return; - obs_source_addref(source); - render_video(source); - obs_source_release(source); + source = obs_source_get_ref(source); + if (source) { + render_video(source); + obs_source_release(source); + } } static inline uint32_t get_async_width(const obs_source_t *source) @@ -2556,7 +2558,9 @@ void obs_source_filter_add(obs_source_t *source, obs_source_t *filter) return; } - obs_source_addref(filter); + filter = obs_source_get_ref(filter); + if (!obs_ptr_valid(filter, "obs_source_filter_add")) + return; filter->filter_parent = source; filter->filter_target = !source->filters.num ? source @@ -4071,7 +4075,9 @@ void obs_source_enum_active_sources(obs_source_t *source, if (!is_transition && !source->info.enum_active_sources) return; - obs_source_addref(source); + source = obs_source_get_ref(source); + if (!data_valid(source, "obs_source_enum_active_sources")) + return; if (is_transition) obs_transition_enum_sources(source, enum_callback, param); @@ -4096,7 +4102,9 @@ void obs_source_enum_active_tree(obs_source_t *source, if (!is_transition && !source->info.enum_active_sources) return; - obs_source_addref(source); + source = obs_source_get_ref(source); + if (!data_valid(source, "obs_source_enum_active_tree")) + return; if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_enum_sources( @@ -4149,7 +4157,9 @@ void obs_source_enum_full_tree(obs_source_t *source, if (!is_transition && !source->info.enum_active_sources) return; - obs_source_addref(source); + source = obs_source_get_ref(source); + if (!data_valid(source, "obs_source_enum_full_tree")) + return; if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_enum_sources( @@ -4486,8 +4496,7 @@ obs_source_t *obs_source_get_filter_by_name(obs_source_t *source, for (size_t i = 0; i < source->filters.num; i++) { struct obs_source *cur_filter = source->filters.array[i]; if (strcmp(cur_filter->context.name, name) == 0) { - filter = cur_filter; - obs_source_addref(filter); + filter = obs_source_get_ref(cur_filter); break; } } @@ -5441,8 +5450,7 @@ void obs_source_restore_filters(obs_source_t *source, obs_data_array_t *array) obs_source_t *cur = cur_filters.array[j]; const char *cur_name = cur->context.name; if (cur_name && strcmp(cur_name, name) == 0) { - filter = cur; - obs_source_addref(cur); + filter = obs_source_get_ref(cur); break; } } diff --git a/libobs/obs-view.c b/libobs/obs-view.c index c8c389d0a..69cf1dcde 100644 --- a/libobs/obs-view.c +++ b/libobs/obs-view.c @@ -81,11 +81,7 @@ obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel) return NULL; pthread_mutex_lock(&view->channels_mutex); - - source = view->channels[channel]; - if (source) - obs_source_addref(source); - + source = obs_source_get_ref(view->channels[channel]); pthread_mutex_unlock(&view->channels_mutex); return source; @@ -104,9 +100,7 @@ void obs_view_set_source(obs_view_t *view, uint32_t channel, return; pthread_mutex_lock(&view->channels_mutex); - - obs_source_addref(source); - + source = obs_source_get_ref(source); prev_source = view->channels[channel]; view->channels[channel] = source; diff --git a/libobs/obs.c b/libobs/obs.c index 9cdf103ba..82df26d14 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -1441,7 +1441,7 @@ void obs_set_output_source(uint32_t channel, obs_source_t *source) pthread_mutex_lock(&view->channels_mutex); - obs_source_addref(source); + source = obs_source_get_ref(source); prev_source = view->channels[channel]; From 03d9bda3875be34086f884794d5719763a9fcb87 Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 24 Jan 2022 12:07:02 -0800 Subject: [PATCH 7/7] libobs: Deprecate obs object addref functions Deprecates: obs_source_addref() obs_output_addref() obs_encoder_addref() obs_service_addref() obs_scene_addref() These functions should be considered unsafe and not used. Instead, use: obs_source_get_ref() obs_output_get_ref() obs_encoder_get_ref() obs_service_get_ref() obs_scene_get_ref() These functions return a pointer to the incremented object only if the object is still valid, otherwise they will return null, indicating that the object is no longer valid or is unsafe to use. The reason why this is being done is because certain third party plugins seem to be using addref, and are somehow managing to call addref on sources that have already been fully released. For the sake of safety, almost all usage of these functions within OBS have also been replaced as well. --- deps/obs-scripting/obslua/obslua.i | 1 + deps/obs-scripting/obspython/obspython.i | 1 + docs/sphinx/reference-encoders.rst | 10 ++++++++++ docs/sphinx/reference-outputs.rst | 10 ++++++++++ docs/sphinx/reference-scenes.rst | 10 ++++++++++ docs/sphinx/reference-services.rst | 10 ++++++++++ docs/sphinx/reference-sources.rst | 12 +++++++++++- libobs/CMakeLists.txt | 2 ++ libobs/obs.h | 10 +++++----- libobs/util/c99defs.h | 6 ++++++ 10 files changed, 66 insertions(+), 6 deletions(-) diff --git a/deps/obs-scripting/obslua/obslua.i b/deps/obs-scripting/obslua/obslua.i index 33bbdd49f..e800dcbbf 100644 --- a/deps/obs-scripting/obslua/obslua.i +++ b/deps/obs-scripting/obslua/obslua.i @@ -34,6 +34,7 @@ #define DEPRECATED_START #define DEPRECATED_END +#define OBS_EXTERNAL_DEPRECATED #define EXPORT %rename(blog) wrap_blog; diff --git a/deps/obs-scripting/obspython/obspython.i b/deps/obs-scripting/obspython/obspython.i index 86ea1688b..1b6e45413 100644 --- a/deps/obs-scripting/obspython/obspython.i +++ b/deps/obs-scripting/obspython/obspython.i @@ -34,6 +34,7 @@ #define DEPRECATED_START #define DEPRECATED_END +#define OBS_EXTERNAL_DEPRECATED #define EXPORT %rename(blog) wrap_blog; diff --git a/docs/sphinx/reference-encoders.rst b/docs/sphinx/reference-encoders.rst index d264b43a7..a8b65a632 100644 --- a/docs/sphinx/reference-encoders.rst +++ b/docs/sphinx/reference-encoders.rst @@ -326,6 +326,16 @@ General Encoder Functions Adds/releases a reference to an encoder. When the last reference is released, the encoder is destroyed. +.. deprecated:: 27.2.0 + Use :c:func:`obs_encoder_get_ref()` instead. + +--------------------- + +.. function:: obs_encoder_t *obs_encoder_get_ref(obs_encoder_t *encoder) + + Returns an incremented reference if still valid, otherwise returns + *NULL*. + --------------------- .. function:: obs_weak_encoder_t *obs_encoder_get_weak_encoder(obs_encoder_t *encoder) diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index fb7c6a8ea..1670693fb 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -339,6 +339,16 @@ General Output Functions Adds/releases a reference to an output. When the last reference is released, the output is destroyed. +.. deprecated:: 27.2.0 + Use :c:func:`obs_output_get_ref()` instead. + +--------------------- + +.. function:: obs_output_t *obs_output_get_ref(obs_output_t *output) + + Returns an incremented reference if still valid, otherwise returns + *NULL*. + --------------------- .. function:: obs_weak_output_t *obs_output_get_weak_output(obs_output_t *output) diff --git a/docs/sphinx/reference-scenes.rst b/docs/sphinx/reference-scenes.rst index 9aac61ea1..78f22b5ca 100644 --- a/docs/sphinx/reference-scenes.rst +++ b/docs/sphinx/reference-scenes.rst @@ -201,6 +201,16 @@ General Scene Functions Adds/releases a reference to a scene. +.. deprecated:: 27.2.0 + Use :c:func:`obs_scene_get_ref()` instead. + +--------------------- + +.. function:: obs_scene_t *obs_scene_get_ref(obs_scene_t *scene) + + Returns an incremented reference if still valid, otherwise returns + *NULL*. + --------------------- .. function:: obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source) diff --git a/docs/sphinx/reference-services.rst b/docs/sphinx/reference-services.rst index fdfb85e41..b9017b284 100644 --- a/docs/sphinx/reference-services.rst +++ b/docs/sphinx/reference-services.rst @@ -185,6 +185,16 @@ General Service Functions Adds/releases a reference to a service. When the last reference is released, the service is destroyed. +.. deprecated:: 27.2.0 + Use :c:func:`obs_service_get_ref()` instead. + +--------------------- + +.. function:: obs_service_t *obs_service_get_ref(obs_service_t *service) + + Returns an incremented reference if still valid, otherwise returns + *NULL*. + --------------------- .. function:: obs_weak_service_t *obs_service_get_weak_service(obs_service_t *service) diff --git a/docs/sphinx/reference-sources.rst b/docs/sphinx/reference-sources.rst index ef29dde43..5b52c7365 100644 --- a/docs/sphinx/reference-sources.rst +++ b/docs/sphinx/reference-sources.rst @@ -165,7 +165,7 @@ Source Definition Structure (obs_source_info) - **OBS_SOURCE_SRGB** - Source understands SRGB rendering - **OBS_SOURCE_CAP_DONT_SHOW_PROPERTIES** - Source type prefers not - to have its properties shown on creation (prefers to rely on + to have its properties shown on creation (prefers to rely on defaults first) .. member:: const char *(*obs_source_info.get_name)(void *type_data) @@ -737,6 +737,16 @@ General Source Functions Adds/releases a reference to a source. When the last reference is released, the source is destroyed. +.. deprecated:: 27.2.0 + Use :c:func:`obs_source_get_ref()` instead. + +--------------------- + +.. function:: obs_source_t *obs_source_get_ref(obs_source_t *source) + + Returns an incremented reference if still valid, otherwise returns + *NULL*. + --------------------- .. function:: obs_weak_source_t *obs_source_get_weak_source(obs_source_t *source) diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index 8645c0452..b21012c42 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -11,6 +11,8 @@ if (NOT "${FFMPEG_AVCODEC_LIBRARIES}" STREQUAL "") list(REMOVE_ITEM FFMPEG_LIBRARIES ${FFMPEG_AVCODEC_LIBRARIES}) endif() +add_definitions(-DIS_LIBOBS=1) + if(DEBUG_FFMPEG_MUX) add_definitions(-DSHOW_SUBPROCESSES) endif() diff --git a/libobs/obs.h b/libobs/obs.h index 17189b5a1..4d9ac45f2 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -919,7 +919,7 @@ EXPORT obs_source_t *obs_source_duplicate(obs_source_t *source, * Adds/releases a reference to a source. When the last reference is * released, the source is destroyed. */ -EXPORT void obs_source_addref(obs_source_t *source); +OBS_EXTERNAL_DEPRECATED EXPORT void obs_source_addref(obs_source_t *source); EXPORT void obs_source_release(obs_source_t *source); EXPORT void obs_weak_source_addref(obs_weak_source_t *weak); @@ -1590,7 +1590,7 @@ enum obs_scene_duplicate_type { EXPORT obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name, enum obs_scene_duplicate_type type); -EXPORT void obs_scene_addref(obs_scene_t *scene); +OBS_EXTERNAL_DEPRECATED EXPORT void obs_scene_addref(obs_scene_t *scene); EXPORT void obs_scene_release(obs_scene_t *scene); EXPORT obs_scene_t *obs_scene_get_ref(obs_scene_t *scene); @@ -1869,7 +1869,7 @@ EXPORT obs_output_t *obs_output_create(const char *id, const char *name, * Adds/releases a reference to an output. When the last reference is * released, the output is destroyed. */ -EXPORT void obs_output_addref(obs_output_t *output); +OBS_EXTERNAL_DEPRECATED EXPORT void obs_output_addref(obs_output_t *output); EXPORT void obs_output_release(obs_output_t *output); EXPORT void obs_weak_output_addref(obs_weak_output_t *weak); @@ -2160,7 +2160,7 @@ EXPORT obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name, * Adds/releases a reference to an encoder. When the last reference is * released, the encoder is destroyed. */ -EXPORT void obs_encoder_addref(obs_encoder_t *encoder); +OBS_EXTERNAL_DEPRECATED EXPORT void obs_encoder_addref(obs_encoder_t *encoder); EXPORT void obs_encoder_release(obs_encoder_t *encoder); EXPORT void obs_weak_encoder_addref(obs_weak_encoder_t *weak); @@ -2319,7 +2319,7 @@ EXPORT obs_service_t *obs_service_create_private(const char *id, * Adds/releases a reference to a service. When the last reference is * released, the service is destroyed. */ -EXPORT void obs_service_addref(obs_service_t *service); +OBS_EXTERNAL_DEPRECATED EXPORT void obs_service_addref(obs_service_t *service); EXPORT void obs_service_release(obs_service_t *service); EXPORT void obs_weak_service_addref(obs_weak_service_t *weak); diff --git a/libobs/util/c99defs.h b/libobs/util/c99defs.h index e2cf89158..5208bf0cb 100644 --- a/libobs/util/c99defs.h +++ b/libobs/util/c99defs.h @@ -33,6 +33,12 @@ #define FORCE_INLINE inline __attribute__((always_inline)) #endif +#if defined(IS_LIBOBS) || defined(SWIG) +#define OBS_EXTERNAL_DEPRECATED +#else +#define OBS_EXTERNAL_DEPRECATED OBS_DEPRECATED +#endif + #ifdef _MSC_VER #define EXPORT __declspec(dllexport) #else