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 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-scene.c b/libobs/obs-scene.c index c5ce68636..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, @@ -1649,6 +1647,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) @@ -1945,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; @@ -1952,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)); @@ -1984,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); @@ -2030,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) @@ -2424,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; @@ -2484,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); @@ -2757,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; @@ -2795,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); @@ -3432,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)) { @@ -3574,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, @@ -3609,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]; diff --git a/libobs/obs.h b/libobs/obs.h index ade027525..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,9 +1590,11 @@ 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); + /** Gets the scene's source context */ EXPORT obs_source_t *obs_scene_get_source(const obs_scene_t *scene); @@ -1867,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); @@ -2158,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); @@ -2317,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/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()}; 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 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; } } 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);