提交 f094bf19 编写于 作者: P Palana

(API Change) libobs: Make obs_output refcounted

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