Delay pad negotiation until the element is in READY or higher. this will gice the...
authorWim Taymans <wim.taymans@gmail.com>
Sun, 20 Jan 2002 11:55:35 +0000 (11:55 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sun, 20 Jan 2002 11:55:35 +0000 (11:55 +0000)
Original commit message from CVS:
Delay pad negotiation until the element is in READY or higher. this will
gice the element a chance to open its devices before we start calling the
connect functions.
Make sure we use the real pad in the negotiation.
Some other small cleanups.

gst/gstcaps.c
gst/gstcaps.h
gst/gstelement.c
gst/gstpad.c
gst/gstpad.h
gst/gstprops.c
gst/gsttypefind.c

index d0e41e5..8bf725f 100644 (file)
@@ -219,6 +219,30 @@ gst_caps_ref (GstCaps *caps)
 }
 
 /**
+ * gst_caps_copy_1:
+ * @caps: the caps to copy
+ *
+ * Copies the caps, not copying any chained caps.
+ *
+ * Returns: a copy of the GstCaps structure.
+ */
+GstCaps*
+gst_caps_copy_1 (GstCaps *caps)
+{
+  GstCaps *newcaps;
+  
+  if (!caps)
+    return NULL;
+
+  newcaps = gst_caps_new_id (
+                 caps->name,
+                 caps->id,
+                 gst_props_copy (caps->properties));
+
+  return newcaps;
+}
+
+/**
  * gst_caps_copy:
  * @caps: the caps to copy
  *
@@ -234,10 +258,7 @@ gst_caps_copy (GstCaps *caps)
   while (caps) {
     GstCaps *newcaps;
 
-    newcaps = gst_caps_new_id (
-                 caps->name,
-                 caps->id,
-                 gst_props_copy (caps->properties));
+    newcaps = gst_caps_copy_1 (caps);
 
     if (new == NULL) {
       new = walk = newcaps;
index d96f2cb..8fb8be0 100644 (file)
@@ -88,6 +88,7 @@ void          gst_caps_destroy                        (GstCaps *caps);
 void           gst_caps_debug                          (GstCaps *caps);
 
 GstCaps*       gst_caps_copy                           (GstCaps *caps);
+GstCaps*       gst_caps_copy_1                         (GstCaps *caps);
 GstCaps*       gst_caps_copy_on_write                  (GstCaps *caps);
 
 const gchar*   gst_caps_get_name                       (GstCaps *caps);
@@ -109,7 +110,9 @@ GstProps*   gst_caps_get_props                      (GstCaps *caps);
 #define                gst_caps_get_fourcc_int(caps, name)     gst_props_get_fourcc_int ((caps)->properties, name)
 #define                gst_caps_get_boolean(caps, name)        gst_props_get_boolean ((caps)->properties, name)
 #define                gst_caps_get_string(caps, name)         gst_props_get_string ((caps)->properties, name)
+
 #define                gst_caps_has_property(caps, name)       gst_props_has_property ((caps)->properties, name)
+#define                gst_caps_has_fixed_property(caps, name) gst_props_has_fixed_property ((caps)->properties, name)
 
 GstCaps*       gst_caps_get_by_name                    (GstCaps *caps, const gchar *name);
 
index 398c9e8..deddf02 100644 (file)
@@ -387,7 +387,6 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, gchar *name)
  * @pad: ghost pad to remove
  *
  * removes a ghost pad from an element
- *
  */
 void
 gst_element_remove_ghost_pad (GstElement *element, GstPad *pad)
@@ -1005,6 +1004,34 @@ gst_element_set_state (GstElement *element, GstElementState state)
   return return_val;
 }
 
+static gboolean
+gst_element_negotiate_pads (GstElement *element)
+{
+  GList *pads = GST_ELEMENT_PADS (element);
+
+  while (pads) {
+    GstRealPad *srcpad = GST_PAD_REALIZE (pads->data);
+
+    if (GST_PAD_IS_CONNECTED (srcpad) && !GST_PAD_CAPS (srcpad)) {
+      GstRealPad *sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
+
+      if (!GST_PAD_IS_SRC (srcpad)) {
+        GstRealPad *temp;
+
+       temp = srcpad;
+       srcpad = sinkpad;
+       sinkpad = temp;
+      }
+
+      if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
+       return FALSE;
+    }
+    pads = g_list_next (pads);
+  }
+
+  return TRUE;
+}
+
 static GstElementStateReturn
 gst_element_change_state (GstElement *element)
 {
@@ -1025,6 +1052,12 @@ gst_element_change_state (GstElement *element)
                      gst_element_statename (GST_STATE_PENDING (element)),
                     GST_STATE_TRANSITION (element));
 
+  /*"we get here after the plugin went to the ready state */
+  if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY) {
+    if (!gst_element_negotiate_pads (element)) 
+      return GST_STATE_FAILURE;
+  }
+
   /* tell the scheduler if we have one */
   if (element->sched) {
     if (gst_scheduler_state_transition (element->sched, element, GST_STATE_TRANSITION (element)) 
@@ -1036,6 +1069,9 @@ gst_element_change_state (GstElement *element)
   GST_STATE (element) = GST_STATE_PENDING (element);
   GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
 
+  g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
+                 0, old_state, GST_STATE (element));
+
   parent = GST_ELEMENT_PARENT (element);
 
   if (parent && GST_IS_BIN (parent)) {
index bfa3196..4368c2f 100644 (file)
@@ -37,7 +37,8 @@ GType _gst_pad_type = 0;
 static void            gst_pad_class_init              (GstPadClass *klass);
 static void            gst_pad_init                    (GstPad *pad);
 
-static gboolean        gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *caps, gboolean clear);
+static gboolean        gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, 
+                                                        GstCaps *caps, gboolean clear);
 
 #ifndef GST_DISABLE_LOADSAVE
 static xmlNodePtr      gst_pad_save_thyself            (GstObject *object, xmlNodePtr parent);
@@ -366,8 +367,9 @@ gst_pad_get_name (GstPad *pad)
  *
  * Set the given chain function for the pad.
  */
-void gst_pad_set_chain_function (GstPad *pad,
-                                GstPadChainFunction chain)
+void 
+gst_pad_set_chain_function (GstPad *pad,
+                           GstPadChainFunction chain)
 {
   g_return_if_fail (pad != NULL);
   g_return_if_fail (GST_IS_REAL_PAD (pad));
@@ -602,9 +604,10 @@ gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
   realsrc = GST_PAD_REALIZE (srcpad);
   realsink = GST_PAD_REALIZE (sinkpad);
 
-  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad))
+  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
     GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+  }
 
   g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
   g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
@@ -639,7 +642,8 @@ gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
   GST_RPAD_PEER (realsrc) = realsink;
   GST_RPAD_PEER (realsink) = realsrc;
 
-  if (!gst_pad_try_reconnect_filtered_func (GST_PAD (realsrc), filtercaps, FALSE)) {
+  /* try to negotiate the pads, we don't need to clear the caps here */
+  if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, FALSE)) {
     GST_DEBUG (GST_CAT_CAPS, "pads cannot connect\n");
 
     GST_RPAD_PEER (realsrc) = NULL;
@@ -866,14 +870,27 @@ gst_pad_get_ghost_pad_list (GstPad *pad)
   return GST_PAD_REALIZE(pad)->ghostpads;
 }
 
+/* an internal caps negotiation helper function does:
+ * 
+ * 1. optinally calls the pad connect function with the provided caps
+ * 2. deal with the result code of the connect function
+ * 3. set fixed caps on the pad.
+ */
 static GstPadConnectReturn
-gst_pad_try_set_caps_func (GstPad *pad, GstCaps *caps, gboolean notify, gboolean set_caps)
+gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
 {
   GstCaps *oldcaps;
+  GstElement *parent = GST_PAD_PARENT (pad);
 
+  /* if this pad has a parent and the parent is not READY, delay the
+   * negotiation */
+  if (parent && GST_STATE (parent) < GST_STATE_READY)
+    return GST_PAD_CONNECT_DELAYED;
+         
   GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
             caps, GST_DEBUG_PAD_NAME (pad));
 
+  /* we need to notify the connect function */
   if (notify && GST_RPAD_CONNECTFUNC (pad)) {
     GstPadConnectReturn res;
     gchar *debug_string;
@@ -881,7 +898,8 @@ gst_pad_try_set_caps_func (GstPad *pad, GstCaps *caps, gboolean notify, gboolean
     GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
             GST_DEBUG_PAD_NAME (pad));
 
-    res = GST_RPAD_CONNECTFUNC (pad) (pad, caps);
+    /* call the connect function */
+    res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
 
     switch (res) {
       case GST_PAD_CONNECT_REFUSED:
@@ -905,6 +923,8 @@ gst_pad_try_set_caps_func (GstPad *pad, GstCaps *caps, gboolean notify, gboolean
     GST_INFO (GST_CAT_CAPS, "got reply %s (%d) from connect function on pad %s:%s",
             debug_string, res, GST_DEBUG_PAD_NAME (pad));
 
+    /* done means the connect function called another caps negotiate function
+     * on this pad that succeeded, we dont need to continue */
     if (res == GST_PAD_CONNECT_DONE) {
       GST_INFO (GST_CAT_CAPS, "pad %s:%s is done", GST_DEBUG_PAD_NAME (pad));
       return GST_PAD_CONNECT_DONE;
@@ -918,19 +938,13 @@ gst_pad_try_set_caps_func (GstPad *pad, GstCaps *caps, gboolean notify, gboolean
   /* we can only set caps on the pad if they are ficed */
   if (GST_CAPS_IS_FIXED (caps)) {
 
-    if (set_caps) {
-      GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
+    GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
               GST_DEBUG_PAD_NAME (pad));
-      /* if we got this far all is ok */
-      oldcaps = GST_PAD_CAPS (pad);
-      if (caps) gst_caps_ref (caps);
-      GST_PAD_CAPS (pad) = caps;
-      if (oldcaps) gst_caps_unref (oldcaps);
-    }
-    else {
-      GST_INFO (GST_CAT_CAPS, "NOT setting caps on pad %s:%s, as requested",
-              GST_DEBUG_PAD_NAME (pad));
-    }
+    /* if we got this far all is ok, remove the old caps, set the new one */
+    oldcaps = GST_PAD_CAPS (pad);
+    if (caps) gst_caps_ref (caps);
+    GST_PAD_CAPS (pad) = caps;
+    if (oldcaps) gst_caps_unref (oldcaps);
   }
   else {
     GST_INFO (GST_CAT_CAPS, "caps are not fixed on pad %s:%s, not setting them yet",
@@ -940,50 +954,68 @@ gst_pad_try_set_caps_func (GstPad *pad, GstCaps *caps, gboolean notify, gboolean
   return GST_PAD_CONNECT_OK;
 }
 
+/**
+ * gst_pad_try_set_caps:
+ * @pad: the pad to try to set the caps on
+ * @caps: the caps to set
+ *
+ * Try to set the caps on the given pad.
+ *
+ * Returns: TRUE if the caps could be set
+ */
 gboolean
 gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
 {
   GstCaps *oldcaps;
-  GstPad *peer;
+  GstRealPad *peer, *realpad;
 
-  peer = GST_PAD (GST_RPAD_PEER (pad));
+  realpad = GST_PAD_REALIZE (pad);
+  peer = GST_RPAD_PEER (realpad);
 
   GST_INFO (GST_CAT_CAPS, "trying to set caps %p on pad %s:%s",
-            caps, GST_DEBUG_PAD_NAME (pad));
+            caps, GST_DEBUG_PAD_NAME (realpad));
 
+  /* setting non fixed caps on a pad is not allowed */
   if (!GST_CAPS_IS_FIXED (caps)) {
-    g_warning ("trying to set non fixed caps on pad %s:%s, caps dump follow",
-            GST_DEBUG_PAD_NAME (pad));
+    g_warning ("trying to set non fixed caps on pad %s:%s",
+            GST_DEBUG_PAD_NAME (realpad));
     gst_caps_debug (caps);
     return FALSE;
   }
-  if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE, TRUE))
+  /* if we have a peer try to set the caps, notifying the peerpad
+   * if it has a connect function */
+  if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
     return FALSE;
-  if (!gst_pad_try_set_caps_func (pad, caps, FALSE, TRUE))
+  /* then try to set our own caps, we don't need to be notified */
+  if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
     return FALSE;
          
   return TRUE;
 }
 
-
+/* this is a caps negotiation convenience routine, it performs:
+ *
+ * 1. optionally clear any pad caps
+ * 2. calculate the intersection between the two pad tamplate/getcaps caps
+ * 3. calculate the intersection with the (optional) filtercaps.
+ * 4. store the intersection in the pad filter
+ * 5. store the app filtercaps in the pad appfilter.
+ * 6. start the caps negotiation.
+ */
 static gboolean
-gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean clear)
+gst_pad_try_reconnect_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, GstCaps *filtercaps, gboolean clear)
 {
   GstCaps *srccaps, *sinkcaps;
   GstCaps *intersection = NULL;
   GstRealPad *realsrc, *realsink;
 
-  g_return_val_if_fail (pad != NULL, FALSE);
-
-  realsrc = GST_PAD_REALIZE (pad);
-  realsink = GST_PAD_REALIZE (GST_RPAD_PEER (realsrc));
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
 
   g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
-  g_return_val_if_fail (GST_RPAD_PEER (realsink) != NULL, FALSE);
-
-  GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s",
-        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+  g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
 
+  /* optinally clear the caps */
   if (clear) {
     GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s, clearing caps",
         GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
@@ -991,6 +1023,10 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
     GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
     GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
   }
+  else {
+    GST_INFO (GST_CAT_PADS, "reconnect filtered %s:%s and %s:%s",
+        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+  }
 
   srccaps = gst_pad_get_caps (GST_PAD (realsrc));
   GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsrc));
@@ -999,11 +1035,13 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
   GST_INFO (GST_CAT_PADS, "dumping caps of pad %s:%s", GST_DEBUG_PAD_NAME (realsink));
   gst_caps_debug (sinkcaps);
 
+  /* first take the intersection of the pad caps */
   intersection = gst_caps_intersect (srccaps, sinkcaps);
 
   /* if we have no intersection but one of the caps was not NULL.. */
   if (!intersection && (srccaps || sinkcaps )) {
-    /* the intersection is NULL, this means they have no common format */
+    /* the intersection is NULL but the pad caps were not both NULL,
+     * this means they have no common format */
     GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
          GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
     return FALSE;
@@ -1013,6 +1051,7 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
          GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink), 
         ((intersection && GST_CAPS_IS_FIXED (intersection)) ? "fixed" : "variable"));
 
+    /* then filter this against the app filter */
     if (filtercaps) {
       GstCaps *filtered_intersection = gst_caps_intersect (intersection, filtercaps);
 
@@ -1020,12 +1059,13 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
       gst_caps_unref (intersection);
 
       if (!filtered_intersection) {
-        GST_INFO (GST_CAT_PADS, "filtered connection between pads %s:%s and %s:%s is empty, disconnecting",
+        GST_INFO (GST_CAT_PADS, "filtered connection between pads %s:%s and %s:%s is empty",
              GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
         return FALSE;
       }
       intersection = filtered_intersection;
 
+      /* keep a reference to the app caps */
       GST_RPAD_APPFILTER (realsink) = filtercaps;
       GST_RPAD_APPFILTER (realsrc) = filtercaps;
     }
@@ -1036,22 +1076,52 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
   GST_RPAD_FILTER (realsrc) = intersection; 
   GST_RPAD_FILTER (realsink) = intersection; 
 
+  return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
+}
+
+/**
+ * gst_pad_perform_negotiate:
+ * @srcpad: a srcpad
+ * @sinkpad: a sinkpad 
+ *
+ * Try to negotiate the pads.
+ *
+ * Returns: a boolean indicating the pad succesfully negotiated.
+ */
+gboolean
+gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad) 
+{
+  GstCaps *intersection;
+  GstRealPad *realsrc, *realsink;
+
+  g_return_val_if_fail (srcpad != NULL, FALSE);
+  g_return_val_if_fail (sinkpad != NULL, FALSE);
+  
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
+    
+  g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
+  g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
+
+  /* it doesn't matter which filter we take */
+  intersection = GST_RPAD_FILTER (realsrc);
+
+  /* no negotiation is performed it the pads have filtercaps */
   if (intersection) {
     GstPadConnectReturn res;
 
-    res = gst_pad_try_set_caps_func (GST_PAD (realsrc), intersection, TRUE, TRUE);
+    res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
     if (res == GST_PAD_CONNECT_REFUSED) 
       return FALSE;
     if (res == GST_PAD_CONNECT_DONE) 
       return TRUE;
 
-    res = gst_pad_try_set_caps_func (GST_PAD (realsink), intersection, TRUE, TRUE);
+    res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
     if (res == GST_PAD_CONNECT_REFUSED) 
       return FALSE;
     if (res == GST_PAD_CONNECT_DONE) 
       return TRUE;
   }
-
   return TRUE;
 }
 
@@ -1065,13 +1135,20 @@ gst_pad_try_reconnect_filtered_func (GstPad *pad, GstCaps *filtercaps, gboolean
  * Returns: a boolean indicating the peer pad could accept the caps.
  */
 gboolean
-gst_pad_try_reconnect_filtered (GstPad *pad, GstCaps *filtercaps)
+gst_pad_try_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
 {
-  g_return_val_if_fail (pad != NULL, FALSE);
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); 
-  g_return_val_if_fail (GST_PAD_IS_CONNECTED (pad), FALSE);
+  GstRealPad *realsrc, *realsink;
+
+  g_return_val_if_fail (srcpad != NULL, FALSE);
+  g_return_val_if_fail (sinkpad != NULL, FALSE);
+
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
+
+  g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
+  g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
   
-  return gst_pad_try_reconnect_filtered_func (pad, filtercaps, TRUE);
+  return gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE);
 }
 
 /**
@@ -1085,14 +1162,21 @@ gst_pad_try_reconnect_filtered (GstPad *pad, GstCaps *filtercaps)
  *    if FALSE is returned, the pads are disconnected.
  */
 gboolean
-gst_pad_reconnect_filtered (GstPad *pad, GstCaps *filtercaps)
+gst_pad_reconnect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
 {
-  g_return_val_if_fail (pad != NULL, FALSE);
-  g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);
-  g_return_val_if_fail (GST_PAD_IS_CONNECTED (pad), FALSE);
+  GstRealPad *realsrc, *realsink;
 
-  if (!gst_pad_try_reconnect_filtered_func (pad, filtercaps, TRUE)) {
-    gst_pad_disconnect (pad, GST_PAD (GST_PAD_PEER (pad)));
+  g_return_val_if_fail (srcpad != NULL, FALSE);
+  g_return_val_if_fail (sinkpad != NULL, FALSE);
+
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
+
+  g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
+  g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
+  
+  if (!gst_pad_try_reconnect_filtered_func (realsrc, realsink, filtercaps, TRUE)) {
+    gst_pad_disconnect (srcpad, GST_PAD (GST_PAD_PEER (srcpad)));
     return FALSE;
   }
   return TRUE;
@@ -1110,16 +1194,18 @@ gst_pad_reconnect_filtered (GstPad *pad, GstCaps *filtercaps)
 GstPadConnectReturn
 gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
 {
-  GstPad *peer;
+  GstRealPad *peer, *realpad;
+
+  realpad = GST_PAD_REALIZE (pad);
 
-  peer = GST_PAD (GST_RPAD_PEER (pad));
+  peer = GST_RPAD_PEER (realpad);
 
   GST_INFO (GST_CAT_CAPS, "proxy connect to pad %s:%s",
-            GST_DEBUG_PAD_NAME (pad));
+            GST_DEBUG_PAD_NAME (realpad));
 
-  if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE, TRUE))
+  if (peer && !gst_pad_try_set_caps_func (peer, caps, TRUE))
     return GST_PAD_CONNECT_REFUSED;
-  if (!gst_pad_try_set_caps_func (pad, caps, FALSE, TRUE))
+  if (!gst_pad_try_set_caps_func (realpad, caps, FALSE))
     return GST_PAD_CONNECT_REFUSED;
 
   return GST_PAD_CONNECT_OK;
@@ -1136,23 +1222,27 @@ gst_pad_proxy_connect (GstPad *pad, GstCaps *caps)
 GstCaps*
 gst_pad_get_caps (GstPad *pad)
 {
+  GstRealPad *realpad;
+
   g_return_val_if_fail (pad != NULL, NULL);
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
+  realpad = GST_PAD_REALIZE (pad);
+
   GST_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)\n",
-            GST_DEBUG_PAD_NAME (pad), pad);
+            GST_DEBUG_PAD_NAME (realpad), realpad);
 
-  if (GST_PAD_CAPS (pad)) {
+  if (GST_PAD_CAPS (realpad)) {
     GST_DEBUG (GST_CAT_CAPS, "using pad real caps\n");
-    return GST_PAD_CAPS (pad);
+    return GST_PAD_CAPS (realpad);
   }
-  else if GST_RPAD_GETCAPSFUNC (pad) {
+  else if GST_RPAD_GETCAPSFUNC (realpad) {
     GST_DEBUG (GST_CAT_CAPS, "using pad get function\n");
-    return GST_RPAD_GETCAPSFUNC (pad) (pad, NULL);
+    return GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad), NULL);
   }
-  else if (GST_PAD_PADTEMPLATE (pad)) {
+  else if (GST_PAD_PADTEMPLATE (realpad)) {
     GST_DEBUG (GST_CAT_CAPS, "using pad template\n");
-    return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
+    return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (realpad));
   }
   GST_DEBUG (GST_CAT_CAPS, "pad has no caps\n");
 
@@ -1266,21 +1356,11 @@ gst_pad_get_peer (GstPad *pad)
 GstCaps*
 gst_pad_get_allowed_caps (GstPad *pad)
 {
-  GstRealPad *peer;
-  
   g_return_val_if_fail (pad != NULL, NULL);
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  peer = GST_RPAD_PEER (pad);
-
   GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s\n", GST_DEBUG_PAD_NAME (pad));
-  /* this is not very correct: ... 
-  if (peer && GST_RPAD_GETCAPSFUNC (peer)) {
-    GST_DEBUG (GST_CAT_PROPERTIES, "using getcaps function of peer %s:%s\n", 
-                   GST_DEBUG_PAD_NAME (peer));
-    return GST_RPAD_GETCAPSFUNC (peer) (GST_PAD (peer), NULL);
-  }
-  */
+
   return gst_caps_copy (GST_RPAD_FILTER (pad));
 }
 
@@ -1305,7 +1385,7 @@ gst_pad_recalc_allowed_caps (GstPad *pad)
 
   peer = GST_RPAD_PEER (pad);
   if (peer)
-    gst_pad_try_reconnect_filtered (pad, GST_RPAD_APPFILTER (pad));
+    gst_pad_try_reconnect_filtered (pad, GST_PAD (peer), GST_RPAD_APPFILTER (pad));
 }
 
 /**
@@ -1502,9 +1582,9 @@ gst_pad_ghost_save_thyself (GstPad *pad,
 
   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
 
-  self = xmlNewChild(parent,NULL,"ghostpad",NULL);
-  xmlNewChild(self,NULL,"name", GST_PAD_NAME (pad));
-  xmlNewChild(self,NULL,"parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
+  self = xmlNewChild (parent, NULL, "ghostpad", NULL);
+  xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
+  xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
 
   /* FIXME FIXME FIXME! */
 
@@ -2079,7 +2159,6 @@ gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, GstEvent *even
     if (GST_PAD_DIRECTION (eventpad) != GST_PAD_DIRECTION (pad) && GST_PAD_IS_CONNECTED (eventpad)) {
       if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
         gst_pad_push (eventpad, GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event))));
-       
       }
       else {
        GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad));
index 1038bff..22fdcf2 100644 (file)
@@ -390,8 +390,9 @@ gboolean                gst_pad_connect_filtered                    (GstPad *srcpad, GstPad
 void                   gst_pad_disconnect                      (GstPad *srcpad, GstPad *sinkpad);
 
 GstPadConnectReturn     gst_pad_proxy_connect                          (GstPad *pad, GstCaps *caps);
-gboolean               gst_pad_reconnect_filtered              (GstPad *pad, GstCaps *filtercaps);
-gboolean               gst_pad_try_reconnect_filtered          (GstPad *pad, GstCaps *filtercaps);
+gboolean               gst_pad_reconnect_filtered              (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps);
+gboolean               gst_pad_perform_negotiate               (GstPad *srcpad, GstPad *sinkpad);
+gboolean               gst_pad_try_reconnect_filtered          (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps);
 GstCaps*               gst_pad_get_allowed_caps                (GstPad *pad);
 gboolean               gst_pad_recalc_allowed_caps             (GstPad *pad);
 
index 0afc106..1af2e94 100644 (file)
@@ -964,6 +964,8 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry
       switch (entry2->propstype) {
        /* t   <--->   t */
         case GST_PROPS_STRING_ID:
+          GST_DEBUG(GST_CAT_PROPERTIES,"\"%s\" <--> \"%s\" ?\n",
+                         entry2->data.string_data.string, entry1->data.string_data.string);
           return (!strcmp (entry2->data.string_data.string, entry1->data.string_data.string));
       }
   }
@@ -1294,7 +1296,7 @@ end:
   else if (props2list)
     leftovers = props2list;
   else 
-    goto finish;
+    leftovers = NULL;
 
   while (leftovers) {
     GstPropsEntry *entry;
@@ -1307,7 +1309,6 @@ end:
     leftovers = g_list_next (leftovers);
   }
 
-finish:
   intersection->properties = g_list_reverse (intersection->properties);
 
   return intersection;
index 5962807..ef7e70b 100644 (file)
@@ -187,7 +187,7 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf)
                        gst_caps_get_name (caps));
        typefind->caps = caps;
 
-       if (!gst_pad_try_reconnect_filtered (pad, caps)) {
+       if (!gst_pad_try_set_caps (pad, caps)) {
           g_warning ("typefind: found type but peer didn't accept it");
        }