libobs: Allow object creation if id not found

Allows objects to be created regardless of whether the actual id exists
or not.  This is a precaution that preserves objects/settings if for
some reason the id was removed for whatever reason (plugin removed, or
hardware encoder that disappeared).  This was already added for sources,
but really needs to be added for other libobs objects as well: outputs,
encoders, services.
master
jp9000 2015-09-13 11:55:06 -07:00
parent a746c8cdd1
commit af310fb556
4 changed files with 62 additions and 21 deletions

View File

@ -70,13 +70,22 @@ static struct obs_encoder *create_encoder(const char *id,
struct obs_encoder_info *ei = find_encoder(id);
bool success;
if (!ei || ei->type != type)
if (ei && ei->type != type)
return NULL;
encoder = bzalloc(sizeof(struct obs_encoder));
encoder->info = *ei;
encoder->mixer_idx = mixer_idx;
if (!ei) {
blog(LOG_ERROR, "Encoder ID '%s' not found", id);
encoder->info.id = bstrdup(id);
encoder->info.type = type;
encoder->owns_info_id = true;
} else {
encoder->info = *ei;
}
success = init_encoder(encoder, name, settings, hotkey_data);
if (!success) {
blog(LOG_ERROR, "creating encoder '%s' (%s) failed", name, id);
@ -221,6 +230,8 @@ static void obs_encoder_actually_destroy(obs_encoder_t *encoder)
pthread_mutex_destroy(&encoder->callbacks_mutex);
pthread_mutex_destroy(&encoder->outputs_mutex);
obs_context_data_free(&encoder->context);
if (encoder->owns_info_id)
bfree((void*)encoder->info.id);
bfree(encoder);
}
}
@ -361,8 +372,9 @@ bool obs_encoder_initialize(obs_encoder_t *encoder)
if (encoder->context.data)
encoder->info.destroy(encoder->context.data);
encoder->context.data = encoder->info.create(encoder->context.settings,
encoder);
if (encoder->info.create)
encoder->context.data = encoder->info.create(
encoder->context.settings, encoder);
if (!encoder->context.data)
return false;

View File

@ -620,6 +620,9 @@ struct obs_output {
struct obs_output_info info;
struct obs_weak_output *control;
/* indicates ownership of the info.id buffer */
bool owns_info_id;
bool received_video;
bool received_audio;
int64_t video_offset;
@ -731,6 +734,9 @@ struct obs_encoder {
bool active;
/* indicates ownership of the info.id buffer */
bool owns_info_id;
uint32_t timebase_num;
uint32_t timebase_den;
@ -792,6 +798,9 @@ struct obs_service {
struct obs_service_info info;
struct obs_weak_service *control;
/* indicates ownership of the info.id buffer */
bool owns_info_id;
bool active;
bool destroy;
struct obs_output *output;

View File

@ -68,11 +68,6 @@ obs_output_t *obs_output_create(const char *id, const char *name,
struct obs_output *output;
int ret;
if (!info) {
blog(LOG_ERROR, "Output '%s' not found", id);
return NULL;
}
output = bzalloc(sizeof(struct obs_output));
pthread_mutex_init_value(&output->interleaved_mutex);
pthread_mutex_init_value(&output->delay_mutex);
@ -84,7 +79,14 @@ obs_output_t *obs_output_create(const char *id, const char *name,
if (!init_output_handlers(output, name, settings, hotkey_data))
goto fail;
output->info = *info;
if (!info) {
blog(LOG_ERROR, "Output ID '%s' not found", id);
output->info.id = bstrdup(id);
output->owns_info_id = true;
} else {
output->info = *info;
}
output->video = obs_get_video();
output->audio = obs_get_audio();
if (output->info.get_defaults)
@ -95,9 +97,11 @@ obs_output_t *obs_output_create(const char *id, const char *name,
if (ret < 0)
goto fail;
output->context.data = info->create(output->context.settings, output);
if (info)
output->context.data = info->create(output->context.settings,
output);
if (!output->context.data)
goto fail;
blog(LOG_ERROR, "Failed to create output '%s'!", name);
output->reconnect_retry_sec = 2;
output->reconnect_retry_max = 20;
@ -160,6 +164,8 @@ void obs_output_destroy(obs_output_t *output)
os_event_destroy(output->reconnect_stop_event);
obs_context_data_free(&output->context);
circlebuf_free(&output->delay_data);
if (output->owns_info_id)
bfree((void*)output->info.id);
bfree(output);
}
}
@ -171,11 +177,12 @@ const char *obs_output_get_name(const obs_output_t *output)
bool obs_output_actual_start(obs_output_t *output)
{
bool success;
bool success = false;
output->stopped = false;
success = output->info.start(output->context.data);
if (output->context.data)
success = output->info.start(output->context.data);
if (success && output->video) {
output->starting_frame_count =
@ -195,6 +202,8 @@ bool obs_output_start(obs_output_t *output)
bool encoded;
if (!obs_output_valid(output, "obs_output_start"))
return false;
if (!output->context.data)
return false;
encoded = (output->info.flags & OBS_OUTPUT_ENCODED) != 0;
@ -251,7 +260,8 @@ void obs_output_actual_stop(obs_output_t *output, bool force)
if (output->reconnect_thread_active)
pthread_join(output->reconnect_thread, NULL);
output->info.stop(output->context.data);
if (output->context.data)
output->info.stop(output->context.data);
if (output->video)
log_frame_info(output);
@ -270,6 +280,8 @@ void obs_output_stop(obs_output_t *output)
bool encoded;
if (!obs_output_valid(output, "obs_output_stop"))
return;
if (!output->context.data)
return;
encoded = (output->info.flags & OBS_OUTPUT_ENCODED) != 0;

View File

@ -52,15 +52,21 @@ obs_service_t *obs_service_create(const char *id, const char *name,
return NULL;
}
service->info = *info;
if (!info) {
blog(LOG_ERROR, "Service ID '%s' not found", id);
service->context.data = service->info.create(service->context.settings,
service);
if (!service->context.data) {
obs_service_destroy(service);
return NULL;
service->info.id = bstrdup(id);
service->owns_info_id = true;
} else {
service->info = *info;
}
if (info)
service->context.data = service->info.create(
service->context.settings, service);
if (!service->context.data)
blog(LOG_ERROR, "Failed to create service '%s'!", name);
service->control = bzalloc(sizeof(obs_weak_service_t));
service->control->service = service;
@ -83,6 +89,8 @@ static void actually_destroy_service(struct obs_service *service)
blog(LOG_INFO, "service '%s' destroyed", service->context.name);
obs_context_data_free(&service->context);
if (service->owns_info_id)
bfree((void*)service->info.id);
bfree(service);
}