Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / playback / gstplaysink.c
index 23e9526..e0a540b 100644 (file)
@@ -127,6 +127,19 @@ typedef struct
   g_static_rec_mutex_unlock (GST_PLAY_SINK_GET_LOCK (playsink)); \
 } G_STMT_END
 
+#define PENDING_FLAG_SET(playsink, flagtype) \
+  ((playsink->pending_blocked_pads) |= (1 << flagtype))
+#define PENDING_FLAG_UNSET(playsink, flagtype) \
+  ((playsink->pending_blocked_pads) &= ~(1 << flagtype))
+#define PENDING_FLAG_IS_SET(playsink, flagtype) \
+  ((playsink->pending_blocked_pads) & (1 << flagtype))
+#define PENDING_VIDEO_BLOCK(playsink) \
+  ((playsink->pending_blocked_pads) & (1 << GST_PLAY_SINK_TYPE_VIDEO_RAW | 1 << GST_PLAY_SINK_TYPE_VIDEO))
+#define PENDING_AUDIO_BLOCK(playsink) \
+  ((playsink->pending_blocked_pads) & (1 << GST_PLAY_SINK_TYPE_AUDIO_RAW | 1 << GST_PLAY_SINK_TYPE_AUDIO))
+#define PENDING_TEXT_BLOCK(playsink) \
+  PENDING_FLAG_IS_SET(playsink, GST_PLAY_SINK_TYPE_TEXT)
+
 struct _GstPlaySink
 {
   GstBin bin;
@@ -173,6 +186,8 @@ struct _GstPlaySink
   GstPad *text_sinkpad_stream_synchronizer;
   gulong text_block_id;
 
+  guint32 pending_blocked_pads;
+
   /* properties */
   GstElement *audio_sink;
   GstElement *video_sink;
@@ -2880,6 +2895,8 @@ video_set_blocked (GstPlaySink * playsink, gboolean blocked)
           gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
     } else if (!blocked && playsink->video_block_id) {
       gst_pad_remove_probe (opad, playsink->video_block_id);
+      PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_VIDEO_RAW);
+      PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_VIDEO);
       playsink->video_block_id = 0;
       playsink->video_pad_blocked = FALSE;
     }
@@ -2900,6 +2917,8 @@ audio_set_blocked (GstPlaySink * playsink, gboolean blocked)
           gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
     } else if (!blocked && playsink->audio_block_id) {
       gst_pad_remove_probe (opad, playsink->audio_block_id);
+      PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO_RAW);
+      PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO);
       playsink->audio_block_id = 0;
       playsink->audio_pad_blocked = FALSE;
     }
@@ -2920,6 +2939,7 @@ text_set_blocked (GstPlaySink * playsink, gboolean blocked)
           gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
     } else if (!blocked && playsink->text_block_id) {
       gst_pad_remove_probe (opad, playsink->text_block_id);
+      PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_TEXT);
       playsink->text_block_id = 0;
       playsink->text_pad_blocked = FALSE;
     }
@@ -2948,9 +2968,17 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstProbeType type, gpointer type_data,
     GST_DEBUG_OBJECT (pad, "Text pad blocked");
   }
 
-  if ((!playsink->video_pad || playsink->video_pad_blocked) &&
-      (!playsink->audio_pad || playsink->audio_pad_blocked) &&
-      (!playsink->text_pad || playsink->text_pad_blocked)) {
+  /* We reconfigure when for ALL streams:
+   * * there isn't a pad
+   * * OR the pad is blocked
+   * * OR there are no pending blocks on that pad
+   */
+
+  if ((!playsink->video_pad || playsink->video_pad_blocked
+          || !PENDING_VIDEO_BLOCK (playsink)) && (!playsink->audio_pad
+          || playsink->audio_pad_blocked || !PENDING_AUDIO_BLOCK (playsink))
+      && (!playsink->text_pad || playsink->text_pad_blocked
+          || !PENDING_TEXT_BLOCK (playsink))) {
     GST_DEBUG_OBJECT (playsink, "All pads blocked -- reconfiguring");
 
     if (playsink->video_pad) {
@@ -2992,14 +3020,14 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink)
 
   if (pad == playsink->audio_pad) {
     raw = is_raw_pad (pad);
-    reconfigure = (!!playsink->audio_pad_raw != !!raw)
+    reconfigure = (! !playsink->audio_pad_raw != ! !raw)
         && playsink->audiochain;
     GST_DEBUG_OBJECT (pad,
         "Audio caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
         reconfigure, caps);
   } else if (pad == playsink->video_pad) {
     raw = is_raw_pad (pad);
-    reconfigure = (!!playsink->video_pad_raw != !!raw)
+    reconfigure = (! !playsink->video_pad_raw != ! !raw)
         && playsink->videochain;
     GST_DEBUG_OBJECT (pad,
         "Video caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
@@ -3131,6 +3159,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
       *block_id =
           gst_pad_add_probe (blockpad, GST_PROBE_TYPE_BLOCK, sinkpad_blocked_cb,
           gst_object_ref (playsink), (GDestroyNotify) gst_object_unref);
+      PENDING_FLAG_SET (playsink, type);
       gst_object_unref (blockpad);
     }
     if (!activate)