pad: Set caps on pad before checking if the pad is linked
authorStas Sergeev <stsp@users.sourceforge.net>
Tue, 13 Sep 2011 13:04:31 +0000 (17:04 +0400)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 19 Sep 2011 12:08:16 +0000 (14:08 +0200)
This allows the setcaps handler and notify::caps to link
the pad downstream and doesn't require hacks to always
provide a peer to the pad, like in decodebin2.

gst/gstpad.c

index 4a2396a..1f66650 100644 (file)
@@ -4479,27 +4479,30 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
     GST_OBJECT_LOCK (pad);
   }
 
-  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
-    goto not_linked;
-
   /* Before pushing the buffer to the peer pad, ensure that caps
    * are set on this pad */
   caps = gst_pad_data_get_caps (is_buffer, data);
   caps_changed = caps && caps != GST_PAD_CAPS (pad);
 
-  /* take ref to peer pad before releasing the lock */
-  gst_object_ref (peer);
-  GST_OBJECT_UNLOCK (pad);
-
   /* we got a new datatype from the pad, it had better handle it */
   if (G_UNLIKELY (caps_changed)) {
+    /* unlock before setting */
+    GST_OBJECT_UNLOCK (pad);
     GST_DEBUG_OBJECT (pad,
         "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
         GST_PAD_CAPS (pad), caps, caps);
     if (G_UNLIKELY (!gst_pad_set_caps (pad, caps)))
       goto not_negotiated;
+    GST_OBJECT_LOCK (pad);
   }
 
+  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
+    goto not_linked;
+
+  /* take ref to peer pad before releasing the lock */
+  gst_object_ref (peer);
+  GST_OBJECT_UNLOCK (pad);
+
   ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, cache);
 
   gst_object_unref (peer);
@@ -4564,7 +4567,6 @@ not_linked:
 not_negotiated:
   {
     gst_pad_data_unref (is_buffer, data);
-    gst_object_unref (peer);
     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
         "element pushed data then refused to accept the caps");
     return GST_FLOW_NOT_NEGOTIATED;