From 02e4d92cbf781a5d3c19b34d81f2fee812acd6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 22 Nov 2017 10:42:37 +0200 Subject: [PATCH] decklinkvideosink: Wait until scheduled playback is actually stopped before continuing Otherwise we might "start" again, just to get finally stopped and then getting errors all over the place. https://bugzilla.gnome.org/show_bug.cgi?id=790114 --- sys/decklink/gstdecklink.cpp | 4 ++++ sys/decklink/gstdecklink.h | 4 +++- sys/decklink/gstdecklinkvideosink.cpp | 22 +++++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp index 85498c9b13..d7d9e503ed 100644 --- a/sys/decklink/gstdecklink.cpp +++ b/sys/decklink/gstdecklink.cpp @@ -1152,6 +1152,10 @@ init_devices (gpointer data) i = 0; ret = iterator->Next (&decklink); while (ret == S_OK) { + g_mutex_init (&devices[i].input.lock); + g_mutex_init (&devices[i].output.lock); + g_cond_init (&devices[i].output.cond); + ret = decklink->QueryInterface (IID_IDeckLinkInput, (void **) &devices[i].input.input); if (ret != S_OK) { diff --git a/sys/decklink/gstdecklink.h b/sys/decklink/gstdecklink.h index 29809716eb..af98a03246 100644 --- a/sys/decklink/gstdecklink.h +++ b/sys/decklink/gstdecklink.h @@ -215,10 +215,12 @@ struct _GstDecklinkOutput { GstClock *clock; GstClockTime clock_start_time, clock_last_time, clock_epoch; GstClockTimeDiff clock_offset; - gboolean started, clock_restart; + gboolean started; + gboolean clock_restart; /* Everything below protected by mutex */ GMutex lock; + GCond cond; /* Set by the video source */ /* Configured mode or NULL */ diff --git a/sys/decklink/gstdecklinkvideosink.cpp b/sys/decklink/gstdecklinkvideosink.cpp index 9096c5fcdf..ac61637ba8 100644 --- a/sys/decklink/gstdecklinkvideosink.cpp +++ b/sys/decklink/gstdecklinkvideosink.cpp @@ -100,6 +100,12 @@ public: { GST_LOG_OBJECT (m_sink, "Scheduled playback stopped"); + if (m_sink->output) { + g_mutex_lock (&m_sink->output->lock); + g_cond_signal (&m_sink->output->cond); + g_mutex_unlock (&m_sink->output->lock); + } + return S_OK; } @@ -900,6 +906,12 @@ gst_decklink_video_sink_start_scheduled_playback (GstElement * element) gst_object_unref (clock); return; } + + // Wait until scheduled playback actually stopped + do { + g_cond_wait (&self->output->cond, &self->output->lock); + self->output->output->IsScheduledPlaybackRunning (&active); + } while (active); } GST_DEBUG_OBJECT (self, @@ -976,16 +988,24 @@ gst_decklink_video_sink_stop_scheduled_playback (GstDecklinkVideoSink * self) g_mutex_lock (&self->output->lock); self->output->started = FALSE; - g_mutex_unlock (&self->output->lock); res = self->output->output->StopScheduledPlayback (start_time, 0, GST_SECOND); if (res != S_OK) { GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), ("Failed to stop scheduled playback: 0x%08lx", (unsigned long) res)); ret = GST_STATE_CHANGE_FAILURE; + } else { + bool active = false; + + // Wait until scheduled playback actually stopped + do { + g_cond_wait (&self->output->cond, &self->output->lock); + self->output->output->IsScheduledPlaybackRunning (&active); + } while (active); } self->internal_base_time = GST_CLOCK_TIME_NONE; self->external_base_time = GST_CLOCK_TIME_NONE; + g_mutex_unlock (&self->output->lock); return ret; }