(API Change) libobs: Make obs_output refcounted
This commit is contained in:
parent
a563fbc05b
commit
f094bf199d
@ -444,9 +444,15 @@ extern float obs_source_get_target_volume(obs_source_t *source,
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* outputs */
|
||||
|
||||
struct obs_weak_output {
|
||||
struct obs_weak_ref ref;
|
||||
struct obs_output *output;
|
||||
};
|
||||
|
||||
struct obs_output {
|
||||
struct obs_context_data context;
|
||||
struct obs_output_info info;
|
||||
struct obs_weak_output *control;
|
||||
|
||||
bool received_video;
|
||||
bool received_audio;
|
||||
@ -495,6 +501,8 @@ extern const struct obs_output_info *find_output(const char *id);
|
||||
extern void obs_output_remove_encoder(struct obs_output *output,
|
||||
struct obs_encoder *encoder);
|
||||
|
||||
void obs_output_destroy(obs_output_t *output);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* encoders */
|
||||
|
@ -95,6 +95,9 @@ obs_output_t *obs_output_create(const char *id, const char *name,
|
||||
output->reconnect_retry_max = 20;
|
||||
output->valid = true;
|
||||
|
||||
output->control = bzalloc(sizeof(obs_weak_output_t));
|
||||
output->control->output = output;
|
||||
|
||||
obs_context_data_insert(&output->context,
|
||||
&obs->data.outputs_mutex,
|
||||
&obs->data.first_output);
|
||||
@ -1273,3 +1276,78 @@ void obs_output_signal_stop(obs_output_t *output, int code)
|
||||
else
|
||||
signal_stop(output, code);
|
||||
}
|
||||
|
||||
void obs_output_addref(obs_output_t *output)
|
||||
{
|
||||
if (!output)
|
||||
return;
|
||||
|
||||
obs_ref_addref(&output->control->ref);
|
||||
}
|
||||
|
||||
void obs_output_release(obs_output_t *output)
|
||||
{
|
||||
if (!output)
|
||||
return;
|
||||
|
||||
obs_weak_output_t *control = output->control;
|
||||
if (obs_ref_release(&control->ref)) {
|
||||
// The order of operations is important here since
|
||||
// get_context_by_name in obs.c relies on weak refs
|
||||
// being alive while the context is listed
|
||||
obs_output_destroy(output);
|
||||
obs_weak_output_release(control);
|
||||
}
|
||||
}
|
||||
|
||||
void obs_weak_output_addref(obs_weak_output_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
obs_weak_ref_addref(&weak->ref);
|
||||
}
|
||||
|
||||
void obs_weak_output_release(obs_weak_output_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
if (obs_weak_ref_release(&weak->ref))
|
||||
bfree(weak);
|
||||
}
|
||||
|
||||
obs_output_t *obs_output_get_ref(obs_output_t *output)
|
||||
{
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
return obs_weak_output_get_output(output->control);
|
||||
}
|
||||
|
||||
obs_weak_output_t *obs_output_get_weak_output(obs_output_t *output)
|
||||
{
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
obs_weak_output_t *weak = output->control;
|
||||
obs_weak_output_addref(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_output_t *obs_weak_output_get_output(obs_weak_output_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return NULL;
|
||||
|
||||
if (obs_weak_ref_get_ref(&weak->ref))
|
||||
return weak->output;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool obs_weak_output_references_output(obs_weak_output_t *weak,
|
||||
obs_output_t *output)
|
||||
{
|
||||
return weak && output && weak->output == output;
|
||||
}
|
||||
|
@ -1184,6 +1184,11 @@ static inline void *get_context_by_name(void *vfirst, const char *name,
|
||||
return context;
|
||||
}
|
||||
|
||||
static inline void *obs_output_addref_safe_(void *ref)
|
||||
{
|
||||
return obs_output_get_ref(ref);
|
||||
}
|
||||
|
||||
static inline void *obs_id_(void *data)
|
||||
{
|
||||
return data;
|
||||
@ -1193,7 +1198,7 @@ obs_output_t *obs_get_output_by_name(const char *name)
|
||||
{
|
||||
if (!obs) return NULL;
|
||||
return get_context_by_name(&obs->data.first_output, name,
|
||||
&obs->data.outputs_mutex, obs_id_);
|
||||
&obs->data.outputs_mutex, obs_output_addref_safe_);
|
||||
}
|
||||
|
||||
obs_encoder_t *obs_get_encoder_by_name(const char *name)
|
||||
|
19
libobs/obs.h
19
libobs/obs.h
@ -63,6 +63,7 @@ typedef struct obs_fader obs_fader_t;
|
||||
typedef struct obs_volmeter obs_volmeter_t;
|
||||
|
||||
typedef struct obs_weak_source obs_weak_source_t;
|
||||
typedef struct obs_weak_output obs_weak_output_t;
|
||||
|
||||
#include "obs-source.h"
|
||||
#include "obs-encoder.h"
|
||||
@ -1089,7 +1090,23 @@ EXPORT const char *obs_output_get_display_name(const char *id);
|
||||
*/
|
||||
EXPORT obs_output_t *obs_output_create(const char *id, const char *name,
|
||||
obs_data_t *settings);
|
||||
EXPORT void obs_output_destroy(obs_output_t *output);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
EXPORT void obs_output_release(obs_output_t *output);
|
||||
|
||||
EXPORT void obs_weak_output_addref(obs_weak_output_t *weak);
|
||||
EXPORT void obs_weak_output_release(obs_weak_output_t *weak);
|
||||
|
||||
EXPORT obs_output_t *obs_output_get_ref(obs_output_t *output);
|
||||
EXPORT obs_weak_output_t *obs_output_get_weak_output(obs_output_t *output);
|
||||
EXPORT obs_output_t *obs_weak_output_get_output(obs_weak_output_t *weak);
|
||||
|
||||
EXPORT bool obs_weak_output_references_output(obs_weak_output_t *weak,
|
||||
obs_output_t *output);
|
||||
|
||||
EXPORT const char *obs_output_get_name(const obs_output_t *output);
|
||||
|
||||
|
@ -33,9 +33,12 @@ using OBSSceneItem = OBSRef<obs_sceneitem_t*, obs_sceneitem_addref,
|
||||
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 OBSOutput = OBSRef<obs_output_t*, obs_output_addref, obs_output_release>;
|
||||
|
||||
using OBSWeakSource = OBSRef<obs_weak_source_t*, obs_weak_source_addref,
|
||||
obs_weak_source_release>;
|
||||
using OBSWeakOutput = OBSRef<obs_weak_output_t*, obs_weak_output_addref,
|
||||
obs_weak_output_release>;
|
||||
|
||||
template<typename T, void addref(T), void release(T)>
|
||||
class OBSRef {
|
||||
@ -81,6 +84,9 @@ public:
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
inline OBSSource OBSGetStrongRef(obs_weak_source_t *weak)
|
||||
@ -94,6 +100,17 @@ inline OBSWeakSource OBSGetWeakRef(obs_source_t *source)
|
||||
OBSWeakSource::TakeOwnership()};
|
||||
}
|
||||
|
||||
inline OBSOutput OBSGetStrongRef(obs_weak_output_t *weak)
|
||||
{
|
||||
return {obs_weak_output_get_output(weak), OBSOutput::TakeOwnership()};
|
||||
}
|
||||
|
||||
inline OBSWeakOutput OBSGetWeakRef(obs_output_t *output)
|
||||
{
|
||||
return {obs_output_get_weak_output(output),
|
||||
OBSWeakOutput::TakeOwnership()};
|
||||
}
|
||||
|
||||
/* objects that are not meant to be instanced */
|
||||
template<typename T, void destroy(T)> class OBSObj {
|
||||
T obj;
|
||||
@ -132,7 +149,6 @@ public:
|
||||
using OBSDisplay = OBSObj<obs_display_t*, obs_display_destroy>;
|
||||
using OBSEncoder = OBSObj<obs_encoder_t*, obs_encoder_destroy>;
|
||||
using OBSView = OBSObj<obs_view_t*, obs_view_destroy>;
|
||||
using OBSOutput = OBSObj<obs_output_t*, obs_output_destroy>;
|
||||
|
||||
/* signal handler connection */
|
||||
class OBSSignal {
|
||||
|
@ -68,11 +68,13 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
||||
nullptr);
|
||||
if (!streamOutput)
|
||||
throw "Failed to create stream output (simple output)";
|
||||
obs_output_release(streamOutput);
|
||||
|
||||
fileOutput = obs_output_create("flv_output", "simple_file_output",
|
||||
nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording output (simple output)";
|
||||
obs_output_release(fileOutput);
|
||||
|
||||
h264 = obs_video_encoder_create("obs_x264", "simple_h264", nullptr);
|
||||
if (!h264)
|
||||
@ -321,6 +323,7 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
||||
nullptr);
|
||||
if (!streamOutput)
|
||||
throw "Failed to create stream output (advanced output)";
|
||||
obs_output_release(streamOutput);
|
||||
|
||||
if (ffmpegRecording) {
|
||||
fileOutput = obs_output_create("ffmpeg_output",
|
||||
@ -328,12 +331,14 @@ AdvancedOutput::AdvancedOutput(OBSBasic *main_) : BasicOutputHandler(main_)
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording FFmpeg output "
|
||||
"(advanced output)";
|
||||
obs_output_release(fileOutput);
|
||||
} else {
|
||||
fileOutput = obs_output_create("flv_output", "adv_file_output",
|
||||
nullptr);
|
||||
if (!fileOutput)
|
||||
throw "Failed to create recording output "
|
||||
"(advanced output)";
|
||||
obs_output_release(fileOutput);
|
||||
|
||||
if (!useStreamEncoder) {
|
||||
h264Recording = obs_video_encoder_create(recordEncoder,
|
||||
|
Loading…
x
Reference in New Issue
Block a user