From 7018c6039d0b052e52580d63c5bf5091c6a4926d Mon Sep 17 00:00:00 2001 From: jp9000 Date: Mon, 20 Jun 2016 17:09:21 -0700 Subject: [PATCH] libobs: Do not allow output stop calls more than once --- libobs/obs-internal.h | 1 + libobs/obs-output.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 386f64a0a..031b724f5 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -785,6 +785,7 @@ struct obs_output { int64_t audio_offsets[MAX_AUDIO_MIXES]; int64_t highest_audio_ts; int64_t highest_video_ts; + os_event_t *stopping_event; pthread_mutex_t interleaved_mutex; DARRAY(struct encoder_packet) interleaved_packets; diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 7e43933b1..ae458db44 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -30,6 +30,11 @@ static inline bool reconnecting(const struct obs_output *output) return os_atomic_load_bool(&output->reconnecting); } +static inline bool stopping(const struct obs_output *output) +{ + return os_event_try(output->stopping_event) == EAGAIN; +} + static inline bool delay_active(const struct obs_output *output) { return os_atomic_load_bool(&output->delay_active); @@ -96,9 +101,13 @@ obs_output_t *obs_output_create(const char *id, const char *name, goto fail; if (pthread_mutex_init(&output->delay_mutex, NULL) != 0) goto fail; + if (os_event_init(&output->stopping_event, OS_EVENT_TYPE_MANUAL) != 0) + goto fail; if (!init_output_handlers(output, name, settings, hotkey_data)) goto fail; + os_event_signal(output->stopping_event); + if (!info) { blog(LOG_ERROR, "Output ID '%s' not found", id); @@ -179,6 +188,7 @@ void obs_output_destroy(obs_output_t *output) } } + os_event_destroy(output->stopping_event); pthread_mutex_destroy(&output->interleaved_mutex); pthread_mutex_destroy(&output->delay_mutex); os_event_destroy(output->reconnect_stop_event); @@ -200,7 +210,7 @@ bool obs_output_actual_start(obs_output_t *output) { bool success = false; - output->stopped = false; + os_event_wait(output->stopping_event); if (output->context.data) success = output->info.start(output->context.data); @@ -294,7 +304,9 @@ static void log_frame_info(struct obs_output *output) void obs_output_actual_stop(obs_output_t *output, bool force) { - output->stopped = true; + if (stopping(output)) + return; + os_event_reset(output->stopping_event); os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) @@ -328,7 +340,7 @@ void obs_output_stop(obs_output_t *output) if (encoded && output->active_delay_ns) { obs_output_delay_stop(output); - } else { + } else if (!stopping(output)) { obs_output_actual_stop(output, false); do_output_signal(output, "stopping"); } @@ -1615,6 +1627,7 @@ void obs_output_end_data_capture(obs_output_t *output) if (delay_active(output)) { os_atomic_set_bool(&output->delay_capturing, false); + os_event_signal(output->stopping_event); return; } @@ -1653,6 +1666,7 @@ void obs_output_end_data_capture(obs_output_t *output) do_output_signal(output, "deactivate"); os_atomic_set_bool(&output->active, false); + os_event_signal(output->stopping_event); } static void *reconnect_thread(void *param) -- GitLab