mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs: Add weak reference type for obs_source
This commit is contained in:
parent
99deb0821f
commit
a563fbc05b
@ -326,10 +326,15 @@ struct async_frame {
|
||||
bool used;
|
||||
};
|
||||
|
||||
struct obs_weak_source {
|
||||
struct obs_weak_ref ref;
|
||||
struct obs_source *source;
|
||||
};
|
||||
|
||||
struct obs_source {
|
||||
struct obs_context_data context;
|
||||
struct obs_source_info info;
|
||||
volatile long refs;
|
||||
struct obs_weak_source *control;
|
||||
|
||||
/* general exposed flags that can be set for the source */
|
||||
uint32_t flags;
|
||||
|
@ -116,7 +116,6 @@ bool obs_source_init(struct obs_source *source,
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
source->refs = 1;
|
||||
source->user_volume = 1.0f;
|
||||
source->present_volume = 1.0f;
|
||||
source->base_volume = 0.0f;
|
||||
@ -146,6 +145,9 @@ bool obs_source_init(struct obs_source *source,
|
||||
}
|
||||
}
|
||||
|
||||
source->control = bzalloc(sizeof(obs_weak_source_t));
|
||||
source->control->source = source;
|
||||
|
||||
obs_context_data_insert(&source->context,
|
||||
&obs->data.sources_mutex,
|
||||
&obs->data.first_source);
|
||||
@ -302,8 +304,10 @@ void obs_source_destroy(struct obs_source *source)
|
||||
|
||||
void obs_source_addref(obs_source_t *source)
|
||||
{
|
||||
if (source)
|
||||
os_atomic_inc_long(&source->refs);
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
obs_ref_addref(&source->control->ref);
|
||||
}
|
||||
|
||||
void obs_source_release(obs_source_t *source)
|
||||
@ -317,8 +321,63 @@ void obs_source_release(obs_source_t *source)
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
if (os_atomic_dec_long(&source->refs) == 0)
|
||||
obs_weak_source_t *control = source->control;
|
||||
if (obs_ref_release(&control->ref)) {
|
||||
obs_source_destroy(source);
|
||||
obs_weak_source_release(control);
|
||||
}
|
||||
}
|
||||
|
||||
void obs_weak_source_addref(obs_weak_source_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
obs_weak_ref_addref(&weak->ref);
|
||||
}
|
||||
|
||||
void obs_weak_source_release(obs_weak_source_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
if (obs_weak_ref_release(&weak->ref))
|
||||
bfree(weak);
|
||||
}
|
||||
|
||||
obs_source_t *obs_source_get_ref(obs_source_t *source)
|
||||
{
|
||||
if (!source)
|
||||
return NULL;
|
||||
|
||||
return obs_weak_source_get_source(source->control);
|
||||
}
|
||||
|
||||
obs_weak_source_t *obs_source_get_weak_source(obs_source_t *source)
|
||||
{
|
||||
if (!source)
|
||||
return NULL;
|
||||
|
||||
obs_weak_source_t *weak = source->control;
|
||||
obs_weak_source_addref(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_source_t *obs_weak_source_get_source(obs_weak_source_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return NULL;
|
||||
|
||||
if (obs_weak_ref_get_ref(&weak->ref))
|
||||
return weak->source;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool obs_weak_source_references_source(obs_weak_source_t *weak,
|
||||
obs_source_t *source)
|
||||
{
|
||||
return weak && source && weak->source == source;
|
||||
}
|
||||
|
||||
void obs_source_remove(obs_source_t *source)
|
||||
|
@ -70,8 +70,7 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time)
|
||||
/* call the tick function of each source */
|
||||
source = data->first_source;
|
||||
while (source) {
|
||||
if (source->refs)
|
||||
obs_source_video_tick(source, seconds);
|
||||
obs_source_video_tick(source, seconds);
|
||||
source = (struct obs_source*)source->context.next;
|
||||
}
|
||||
|
||||
@ -80,8 +79,7 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time)
|
||||
|
||||
source = data->first_source;
|
||||
while (source) {
|
||||
if (source->refs)
|
||||
calculate_base_volume(data, view, source);
|
||||
calculate_base_volume(data, view, source);
|
||||
source = (struct obs_source*)source->context.next;
|
||||
}
|
||||
|
||||
|
15
libobs/obs.h
15
libobs/obs.h
@ -62,6 +62,8 @@ typedef struct obs_module obs_module_t;
|
||||
typedef struct obs_fader obs_fader_t;
|
||||
typedef struct obs_volmeter obs_volmeter_t;
|
||||
|
||||
typedef struct obs_weak_source obs_weak_source_t;
|
||||
|
||||
#include "obs-source.h"
|
||||
#include "obs-encoder.h"
|
||||
#include "obs-output.h"
|
||||
@ -458,6 +460,9 @@ EXPORT obs_source_t *obs_get_output_source(uint32_t channel);
|
||||
*
|
||||
* Callback function returns true to continue enumeration, or false to end
|
||||
* enumeration.
|
||||
*
|
||||
* Use obs_source_get_ref or obs_source_get_weak_source if you want to retain
|
||||
* a reference after obs_enum_sources finishes
|
||||
*/
|
||||
EXPORT void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*),
|
||||
void *param);
|
||||
@ -655,6 +660,16 @@ EXPORT obs_source_t *obs_source_create(enum obs_source_type type,
|
||||
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);
|
||||
EXPORT void obs_weak_source_release(obs_weak_source_t *weak);
|
||||
|
||||
EXPORT obs_source_t *obs_source_get_ref(obs_source_t *source);
|
||||
EXPORT obs_weak_source_t *obs_source_get_weak_source(obs_source_t *source);
|
||||
EXPORT obs_source_t *obs_weak_source_get_source(obs_weak_source_t *weak);
|
||||
|
||||
EXPORT bool obs_weak_source_references_source(obs_weak_source_t *weak,
|
||||
obs_source_t *source);
|
||||
|
||||
/** Notifies all references that the source should be released */
|
||||
EXPORT void obs_source_remove(obs_source_t *source);
|
||||
|
||||
|
@ -23,6 +23,20 @@
|
||||
|
||||
/* RAII wrappers */
|
||||
|
||||
template<typename T, void addref(T), void release(T)>
|
||||
class OBSRef;
|
||||
|
||||
using OBSSource = OBSRef<obs_source_t*, obs_source_addref, obs_source_release>;
|
||||
using OBSScene = OBSRef<obs_scene_t*, obs_scene_addref, obs_scene_release>;
|
||||
using OBSSceneItem = OBSRef<obs_sceneitem_t*, obs_sceneitem_addref,
|
||||
obs_sceneitem_release>;
|
||||
using OBSData = OBSRef<obs_data_t*, obs_data_addref, obs_data_release>;
|
||||
using OBSDataArray = OBSRef<obs_data_array_t*, obs_data_array_addref,
|
||||
obs_data_array_release>;
|
||||
|
||||
using OBSWeakSource = OBSRef<obs_weak_source_t*, obs_weak_source_addref,
|
||||
obs_weak_source_release>;
|
||||
|
||||
template<typename T, void addref(T), void release(T)>
|
||||
class OBSRef {
|
||||
T val;
|
||||
@ -35,6 +49,9 @@ class OBSRef {
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct TakeOwnership {};
|
||||
inline OBSRef(T val, TakeOwnership) : val(val) {}
|
||||
|
||||
public:
|
||||
inline OBSRef() : val(nullptr) {}
|
||||
inline OBSRef(T val_) : val(val_) {addref(val);}
|
||||
@ -61,15 +78,21 @@ public:
|
||||
|
||||
inline bool operator==(T p) const {return val == p;}
|
||||
inline bool operator!=(T p) const {return val != p;}
|
||||
|
||||
friend OBSSource OBSGetStrongRef(obs_weak_source_t *weak);
|
||||
friend OBSWeakSource OBSGetWeakRef(obs_source_t *source);
|
||||
};
|
||||
|
||||
using OBSSource = OBSRef<obs_source_t*, obs_source_addref, obs_source_release>;
|
||||
using OBSScene = OBSRef<obs_scene_t*, obs_scene_addref, obs_scene_release>;
|
||||
using OBSSceneItem = OBSRef<obs_sceneitem_t*, obs_sceneitem_addref,
|
||||
obs_sceneitem_release>;
|
||||
using OBSData = OBSRef<obs_data_t*, obs_data_addref, obs_data_release>;
|
||||
using OBSDataArray = OBSRef<obs_data_array_t*, obs_data_array_addref,
|
||||
obs_data_array_release>;
|
||||
inline OBSSource OBSGetStrongRef(obs_weak_source_t *weak)
|
||||
{
|
||||
return {obs_weak_source_get_source(weak), OBSSource::TakeOwnership()};
|
||||
}
|
||||
|
||||
inline OBSWeakSource OBSGetWeakRef(obs_source_t *source)
|
||||
{
|
||||
return {obs_source_get_weak_source(source),
|
||||
OBSWeakSource::TakeOwnership()};
|
||||
}
|
||||
|
||||
/* objects that are not meant to be instanced */
|
||||
template<typename T, void destroy(T)> class OBSObj {
|
||||
|
Loading…
Reference in New Issue
Block a user