(API Change) libobs: Make obs_service refcounted

master
Palana 2015-05-04 02:07:43 +02:00
parent ba0b8eb0e1
commit 71abed387f
7 changed files with 138 additions and 13 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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()

View File

@ -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;