提交 a563fbc0 编写于 作者: P Palana

libobs: Add weak reference type for obs_source

上级 99deb082
......@@ -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;
}
......
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册