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
parent
a746c8cdd1
commit
af310fb556
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue