(API Change) libobs: Make obs_service refcounted
parent
ba0b8eb0e1
commit
71abed387f
|
@ -586,9 +586,15 @@ void obs_encoder_destroy(obs_encoder_t *encoder);
|
|||
/* ------------------------------------------------------------------------- */
|
||||
/* services */
|
||||
|
||||
struct obs_weak_service {
|
||||
struct obs_weak_ref ref;
|
||||
struct obs_service *service;
|
||||
};
|
||||
|
||||
struct obs_service {
|
||||
struct obs_context_data context;
|
||||
struct obs_service_info info;
|
||||
struct obs_weak_service *control;
|
||||
|
||||
bool active;
|
||||
bool destroy;
|
||||
|
@ -601,3 +607,6 @@ extern void obs_service_activate(struct obs_service *service);
|
|||
extern void obs_service_deactivate(struct obs_service *service, bool remove);
|
||||
extern bool obs_service_initialize(struct obs_service *service,
|
||||
struct obs_output *output);
|
||||
|
||||
void obs_service_destroy(obs_service_t *service);
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@ obs_service_t *obs_service_create(const char *id, const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
service->control = bzalloc(sizeof(obs_weak_service_t));
|
||||
service->control->service = service;
|
||||
|
||||
obs_context_data_insert(&service->context,
|
||||
&obs->data.services_mutex,
|
||||
&obs->data.first_service);
|
||||
|
@ -247,3 +250,78 @@ void obs_service_apply_encoder_settings(obs_service_t *service,
|
|||
service->info.apply_encoder_settings(service->context.data,
|
||||
video_encoder_settings, audio_encoder_settings);
|
||||
}
|
||||
|
||||
void obs_service_addref(obs_service_t *service)
|
||||
{
|
||||
if (!service)
|
||||
return;
|
||||
|
||||
obs_ref_addref(&service->control->ref);
|
||||
}
|
||||
|
||||
void obs_service_release(obs_service_t *service)
|
||||
{
|
||||
if (!service)
|
||||
return;
|
||||
|
||||
obs_weak_service_t *control = service->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_service_destroy(service);
|
||||
obs_weak_service_release(control);
|
||||
}
|
||||
}
|
||||
|
||||
void obs_weak_service_addref(obs_weak_service_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
obs_weak_ref_addref(&weak->ref);
|
||||
}
|
||||
|
||||
void obs_weak_service_release(obs_weak_service_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
if (obs_weak_ref_release(&weak->ref))
|
||||
bfree(weak);
|
||||
}
|
||||
|
||||
obs_service_t *obs_service_get_ref(obs_service_t *service)
|
||||
{
|
||||
if (!service)
|
||||
return NULL;
|
||||
|
||||
return obs_weak_service_get_service(service->control);
|
||||
}
|
||||
|
||||
obs_weak_service_t *obs_service_get_weak_service(obs_service_t *service)
|
||||
{
|
||||
if (!service)
|
||||
return NULL;
|
||||
|
||||
obs_weak_service_t *weak = service->control;
|
||||
obs_weak_service_addref(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_service_t *obs_weak_service_get_service(obs_weak_service_t *weak)
|
||||
{
|
||||
if (!weak)
|
||||
return NULL;
|
||||
|
||||
if (obs_weak_ref_get_ref(&weak->ref))
|
||||
return weak->service;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool obs_weak_service_references_service(obs_weak_service_t *weak,
|
||||
obs_service_t *service)
|
||||
{
|
||||
return weak && service && weak->service == service;
|
||||
}
|
||||
|
|
|
@ -1194,6 +1194,11 @@ static inline void *obs_encoder_addref_safe_(void *ref)
|
|||
return obs_encoder_get_ref(ref);
|
||||
}
|
||||
|
||||
static inline void *obs_service_addref_safe_(void *ref)
|
||||
{
|
||||
return obs_service_get_ref(ref);
|
||||
}
|
||||
|
||||
static inline void *obs_id_(void *data)
|
||||
{
|
||||
return data;
|
||||
|
@ -1217,7 +1222,7 @@ obs_service_t *obs_get_service_by_name(const char *name)
|
|||
{
|
||||
if (!obs) return NULL;
|
||||
return get_context_by_name(&obs->data.first_service, name,
|
||||
&obs->data.services_mutex, obs_id_);
|
||||
&obs->data.services_mutex, obs_service_addref_safe_);
|
||||
}
|
||||
|
||||
gs_effect_t *obs_get_default_effect(void)
|
||||
|
|
19
libobs/obs.h
19
libobs/obs.h
|
@ -65,6 +65,7 @@ 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;
|
||||
typedef struct obs_weak_encoder obs_weak_encoder_t;
|
||||
typedef struct obs_weak_service obs_weak_service_t;
|
||||
|
||||
#include "obs-source.h"
|
||||
#include "obs-encoder.h"
|
||||
|
@ -1433,7 +1434,23 @@ EXPORT const char *obs_service_get_display_name(const char *id);
|
|||
|
||||
EXPORT obs_service_t *obs_service_create(const char *id, const char *name,
|
||||
obs_data_t *settings);
|
||||
EXPORT void obs_service_destroy(obs_service_t *service);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
EXPORT void obs_service_release(obs_service_t *service);
|
||||
|
||||
EXPORT void obs_weak_service_addref(obs_weak_service_t *weak);
|
||||
EXPORT void obs_weak_service_release(obs_weak_service_t *weak);
|
||||
|
||||
EXPORT obs_service_t *obs_service_get_ref(obs_service_t *service);
|
||||
EXPORT obs_weak_service_t *obs_service_get_weak_service(obs_service_t *service);
|
||||
EXPORT obs_service_t *obs_weak_service_get_service(obs_weak_service_t *weak);
|
||||
|
||||
EXPORT bool obs_weak_service_references_service(obs_weak_service_t *weak,
|
||||
obs_service_t *service);
|
||||
|
||||
EXPORT const char *obs_service_get_name(const obs_service_t *service);
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ using OBSDataArray = OBSRef<obs_data_array_t*, obs_data_array_addref,
|
|||
using OBSOutput = OBSRef<obs_output_t*, obs_output_addref, obs_output_release>;
|
||||
using OBSEncoder = OBSRef<obs_encoder_t*, obs_encoder_addref,
|
||||
obs_encoder_release>;
|
||||
using OBSService = OBSRef<obs_service_t*, obs_service_addref,
|
||||
obs_service_release>;
|
||||
|
||||
using OBSWeakSource = OBSRef<obs_weak_source_t*, obs_weak_source_addref,
|
||||
obs_weak_source_release>;
|
||||
|
@ -43,6 +45,8 @@ using OBSWeakOutput = OBSRef<obs_weak_output_t*, obs_weak_output_addref,
|
|||
obs_weak_output_release>;
|
||||
using OBSWeakEncoder = OBSRef<obs_weak_encoder_t*, obs_weak_encoder_addref,
|
||||
obs_weak_encoder_release>;
|
||||
using OBSWeakService = OBSRef<obs_weak_service_t*, obs_weak_service_addref,
|
||||
obs_weak_service_release>;
|
||||
|
||||
template<typename T, void addref(T), void release(T)>
|
||||
class OBSRef {
|
||||
|
@ -94,6 +98,9 @@ public:
|
|||
|
||||
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);
|
||||
};
|
||||
|
||||
inline OBSSource OBSGetStrongRef(obs_weak_source_t *weak)
|
||||
|
@ -130,6 +137,18 @@ inline OBSWeakEncoder OBSGetWeakRef(obs_encoder_t *encoder)
|
|||
OBSWeakEncoder::TakeOwnership()};
|
||||
}
|
||||
|
||||
inline OBSService OBSGetStrongRef(obs_weak_service_t *weak)
|
||||
{
|
||||
return {obs_weak_service_get_service(weak),
|
||||
OBSService::TakeOwnership()};
|
||||
}
|
||||
|
||||
inline OBSWeakService OBSGetWeakRef(obs_service_t *service)
|
||||
{
|
||||
return {obs_service_get_weak_service(service),
|
||||
OBSWeakService::TakeOwnership()};
|
||||
}
|
||||
|
||||
/* objects that are not meant to be instanced */
|
||||
template<typename T, void destroy(T)> class OBSObj {
|
||||
T obj;
|
||||
|
|
|
@ -387,11 +387,6 @@ bool OBSBasic::LoadService()
|
|||
{
|
||||
const char *type;
|
||||
|
||||
if (service) {
|
||||
obs_service_destroy(service);
|
||||
service = nullptr;
|
||||
}
|
||||
|
||||
char serviceJsonPath[512];
|
||||
int ret = os_get_config_path(serviceJsonPath, sizeof(serviceJsonPath),
|
||||
SERVICE_PATH);
|
||||
|
@ -410,6 +405,7 @@ bool OBSBasic::LoadService()
|
|||
obs_data_t *settings = obs_data_get_obj(data, "settings");
|
||||
|
||||
service = obs_service_create(type, "default_service", settings);
|
||||
obs_service_release(service);
|
||||
|
||||
obs_data_release(settings);
|
||||
obs_data_release(data);
|
||||
|
@ -425,6 +421,7 @@ bool OBSBasic::InitService()
|
|||
service = obs_service_create("rtmp_common", "default_service", nullptr);
|
||||
if (!service)
|
||||
return false;
|
||||
obs_service_release(service);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -690,6 +687,7 @@ OBSBasic::~OBSBasic()
|
|||
delete cpuUsageTimer;
|
||||
os_cpu_usage_info_destroy(cpuUsageInfo);
|
||||
|
||||
service = nullptr;
|
||||
outputHandler.reset();
|
||||
|
||||
if (interaction)
|
||||
|
@ -1447,18 +1445,17 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy)
|
|||
|
||||
obs_service_t *OBSBasic::GetService()
|
||||
{
|
||||
if (!service)
|
||||
if (!service) {
|
||||
service = obs_service_create("rtmp_common", NULL, NULL);
|
||||
obs_service_release(service);
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
void OBSBasic::SetService(obs_service_t *newService)
|
||||
{
|
||||
if (newService) {
|
||||
if (service)
|
||||
obs_service_destroy(service);
|
||||
if (newService)
|
||||
service = newService;
|
||||
}
|
||||
}
|
||||
|
||||
bool OBSBasic::StreamingActive()
|
||||
|
|
|
@ -82,7 +82,7 @@ private:
|
|||
QPointer<QTimer> cpuUsageTimer;
|
||||
os_cpu_usage_info_t *cpuUsageInfo = nullptr;
|
||||
|
||||
obs_service_t *service = nullptr;
|
||||
OBSService service;
|
||||
std::unique_ptr<BasicOutputHandler> outputHandler;
|
||||
|
||||
gs_vertbuffer_t *box = nullptr;
|
||||
|
|
Loading…
Reference in New Issue