decklinkaudiosink: Start scheduled playback when going to PLAYING
authorSebastian Dröge <sebastian@centricular.com>
Mon, 9 Feb 2015 14:19:11 +0000 (15:19 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 9 Feb 2015 15:22:39 +0000 (16:22 +0100)
The ringbuffer's acquire() is too early, and ringbuffer's start() will only be
called after the clock has advanced a bit... which it won't unless we start
scheduled playback.

sys/decklink/gstdecklinkaudiosink.cpp

index 7dcd59b..2e6d871 100644 (file)
@@ -361,12 +361,6 @@ gst_decklink_audio_sink_ringbuffer_acquire (GstAudioRingBuffer * rb,
     return FALSE;
   }
 
-  g_mutex_lock (&self->output->lock);
-  self->output->audio_enabled = TRUE;
-  if (self->output->start_scheduled_playback)
-    self->output->start_scheduled_playback (self->output->videosink);
-  g_mutex_unlock (&self->output->lock);
-
   ret =
       self->output->
       output->SetAudioCallback (new GStreamerAudioOutputCallback (self));
@@ -473,6 +467,9 @@ static void gst_decklink_audio_sink_get_property (GObject * object,
     guint property_id, GValue * value, GParamSpec * pspec);
 static void gst_decklink_audio_sink_finalize (GObject * object);
 
+static GstStateChangeReturn gst_decklink_audio_sink_change_state (GstElement *
+    element, GstStateChange transition);
+
 static GstAudioRingBuffer
     * gst_decklink_audio_sink_create_ringbuffer (GstAudioBaseSink * absink);
 
@@ -492,6 +489,9 @@ gst_decklink_audio_sink_class_init (GstDecklinkAudioSinkClass * klass)
   gobject_class->get_property = gst_decklink_audio_sink_get_property;
   gobject_class->finalize = gst_decklink_audio_sink_finalize;
 
+  element_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_change_state);
+
   audiobasesink_class->create_ringbuffer =
       GST_DEBUG_FUNCPTR (gst_decklink_audio_sink_create_ringbuffer);
 
@@ -563,6 +563,35 @@ gst_decklink_audio_sink_finalize (GObject * object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static GstStateChangeReturn
+gst_decklink_audio_sink_change_state (GstElement * element,
+    GstStateChange transition)
+{
+  GstDecklinkAudioSink *self = GST_DECKLINK_AUDIO_SINK_CAST (element);
+  GstDecklinkAudioSinkRingBuffer *buf =
+      GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (GST_AUDIO_BASE_SINK_CAST
+      (self)->ringbuffer);
+  GstStateChangeReturn ret;
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+      g_mutex_lock (&buf->output->lock);
+      buf->output->audio_enabled = TRUE;
+      if (buf->output->start_scheduled_playback)
+        buf->output->start_scheduled_playback (buf->output->videosink);
+      g_mutex_unlock (&buf->output->lock);
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
 static GstAudioRingBuffer *
 gst_decklink_audio_sink_create_ringbuffer (GstAudioBaseSink * absink)
 {