playsink/streamsynchronizer: Remove and deactivate pads after calling the change_stat...
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 16 Jul 2010 16:51:35 +0000 (18:51 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 16 Jul 2010 16:51:35 +0000 (18:51 +0200)
Fixes some deadlocks.

gst/playback/gstplaysink.c
gst/playback/gststreamsynchronizer.c

index 774da377d86cc96368dfd057a647e7d4049c41a5..a908c9d57924e4b0cb3d843cc431846a256410c9 100644 (file)
@@ -3078,36 +3078,7 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
       do_async_start (playsink);
       ret = GST_STATE_CHANGE_ASYNC;
       break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:{
-      if (playsink->video_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->video_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
-        playsink->video_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->video_srcpad_stream_synchronizer);
-        playsink->video_srcpad_stream_synchronizer = NULL;
-      }
-      if (playsink->audio_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->audio_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
-        playsink->audio_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
-        playsink->audio_srcpad_stream_synchronizer = NULL;
-      }
-      if (playsink->text_sinkpad_stream_synchronizer) {
-        gst_element_release_request_pad (GST_ELEMENT_CAST
-            (playsink->stream_synchronizer),
-            playsink->text_sinkpad_stream_synchronizer);
-        gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
-        playsink->text_sinkpad_stream_synchronizer = NULL;
-        gst_object_unref (playsink->text_srcpad_stream_synchronizer);
-        playsink->text_srcpad_stream_synchronizer = NULL;
-      }
-    }
-      /* fall through */
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
     case GST_STATE_CHANGE_READY_TO_NULL:
       if (playsink->audiochain && playsink->audiochain->sink_volume) {
         /* remove our links to the mute and volume elements when they were
@@ -3157,7 +3128,36 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
       /* FIXME Release audio device when we implement that */
       playsink->need_async_start = TRUE;
       break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
+    case GST_STATE_CHANGE_PAUSED_TO_READY:{
+      if (playsink->video_sinkpad_stream_synchronizer) {
+        gst_element_release_request_pad (GST_ELEMENT_CAST
+            (playsink->stream_synchronizer),
+            playsink->video_sinkpad_stream_synchronizer);
+        gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
+        playsink->video_sinkpad_stream_synchronizer = NULL;
+        gst_object_unref (playsink->video_srcpad_stream_synchronizer);
+        playsink->video_srcpad_stream_synchronizer = NULL;
+      }
+      if (playsink->audio_sinkpad_stream_synchronizer) {
+        gst_element_release_request_pad (GST_ELEMENT_CAST
+            (playsink->stream_synchronizer),
+            playsink->audio_sinkpad_stream_synchronizer);
+        gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
+        playsink->audio_sinkpad_stream_synchronizer = NULL;
+        gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
+        playsink->audio_srcpad_stream_synchronizer = NULL;
+      }
+      if (playsink->text_sinkpad_stream_synchronizer) {
+        gst_element_release_request_pad (GST_ELEMENT_CAST
+            (playsink->stream_synchronizer),
+            playsink->text_sinkpad_stream_synchronizer);
+        gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
+        playsink->text_sinkpad_stream_synchronizer = NULL;
+        gst_object_unref (playsink->text_srcpad_stream_synchronizer);
+        playsink->text_srcpad_stream_synchronizer = NULL;
+      }
+    }
+      /* fall through */
     case GST_STATE_CHANGE_READY_TO_NULL:
       /* remove sinks we added */
       if (playsink->videodeinterlacechain) {
index cc581b7f914403f9c41186f37897d04f36b93b8d..1081eac9070086a3d136b24d9f17994c4c87c5d7 100644 (file)
@@ -417,7 +417,8 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
             GST_TIME_ARGS (stream->segment.accum));
         stream->running_time_diff = stream->segment.accum;
       } else if (stream) {
-        GST_ERROR_OBJECT (pad, "Non-TIME segment");
+        GST_WARNING_OBJECT (pad, "Non-TIME segment: %s",
+            gst_format_get_name (format));
         gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED);
       }
       GST_STREAM_SYNCHRONIZER_UNLOCK (self);
@@ -634,8 +635,8 @@ gst_stream_synchronizer_release_stream (GstStreamSynchronizer * self,
   gst_pad_set_element_private (stream->srcpad, NULL);
   gst_pad_set_element_private (stream->sinkpad, NULL);
   gst_pad_set_active (stream->srcpad, FALSE);
-  gst_pad_set_active (stream->sinkpad, FALSE);
   gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->srcpad);
+  gst_pad_set_active (stream->sinkpad, FALSE);
   gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->sinkpad);
 
   if (stream->segment.format == GST_FORMAT_TIME) {
@@ -689,21 +690,11 @@ gst_stream_synchronizer_change_state (GstElement * element,
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       GST_DEBUG_OBJECT (self, "State change READY->PAUSED");
+      self->group_start_time = 0;
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       GST_DEBUG_OBJECT (self, "State change PAUSED->PLAYING");
       break;
-    case GST_STATE_CHANGE_READY_TO_NULL:{
-      GST_DEBUG_OBJECT (self, "State change READY->NULL");
-
-      GST_STREAM_SYNCHRONIZER_LOCK (self);
-      g_cond_broadcast (self->stream_finish_cond);
-      while (self->streams)
-        gst_stream_synchronizer_release_stream (self, self->streams->data);
-      self->current_stream_number = 0;
-      GST_STREAM_SYNCHRONIZER_UNLOCK (self);
-      break;
-    }
     default:
       break;
   }
@@ -741,6 +732,13 @@ gst_stream_synchronizer_change_state (GstElement * element,
     }
     case GST_STATE_CHANGE_READY_TO_NULL:{
       GST_DEBUG_OBJECT (self, "State change READY->NULL");
+
+      GST_STREAM_SYNCHRONIZER_LOCK (self);
+      g_cond_broadcast (self->stream_finish_cond);
+      while (self->streams)
+        gst_stream_synchronizer_release_stream (self, self->streams->data);
+      self->current_stream_number = 0;
+      GST_STREAM_SYNCHRONIZER_UNLOCK (self);
       break;
     }
     default: