gst/gstcaps.c: add sanity checks
authorBenjamin Otte <otte@gnome.org>
Sat, 27 Dec 2003 13:51:31 +0000 (13:51 +0000)
committerBenjamin Otte <otte@gnome.org>
Sat, 27 Dec 2003 13:51:31 +0000 (13:51 +0000)
Original commit message from CVS:
2003-12-27  Benjamin Otte  <in7y118@public.uni-hamburg.de>

* gst/gstcaps.c: (gst_caps_append):
add sanity checks
* gst/gstcaps.h: (gst_caps_debug):
remove, it doesn't exist anymore.
* gst/gstelement.c: (gst_element_threadsafe_properties_pre_run),
(gst_element_threadsafe_properties_post_run):
make debugging messages not clutter up THREAD debug category
(gst_element_negotiate_pads), (gst_element_clear_pad_caps),
(gst_element_change_state):
update to new caps API
* gst/gstinterface.c: (gst_implements_interface_cast):
don't put vital code in g_return_if_fail
* gst/gstpad.c: (gst_pad_link_try), (gst_pad_try_set_caps),
(gst_pad_link_filtered):
add pst_pad_try_link and use it.
(gst_pad_perform_negotiate), (gst_pad_renegotiate):
implement correctly, deprecate first one.
(gst_pad_link_unnegotiate), (gst_pad_unnegotiate):
add and implement.
(gst_pad_try_relink_filtered), (gst_pad_relink_filtered):
implement.
(gst_pad_get_negotiated_caps):
add and implement. Make GST_PAD_CAPS call this function.
(gst_pad_get_caps):
remove unneeded check..
(gst_pad_recover_caps_error):
disable, always return FALSE.
(gst_real_pad_dispose):
don't free caps and appfilter anymore, they're unused.
* gst/gstpad.h:
Reflect changes mentioned above.
* gst/gstsystemclock.c: (gst_system_clock_wait):
Make 'clock is way behind' a debugging message.
* gst/gstthread.c: (gst_thread_change_state):
Fix debugging message

gst/gstcaps.c
gst/gstcaps.h
gst/gstelement.c
gst/gstinterface.c
gst/gstpad.c
gst/gstpad.h
gst/gstsystemclock.c
gst/gstthread.c

index 5d29673..c61ded6 100644 (file)
@@ -206,7 +206,10 @@ void gst_caps_append (GstCaps *caps1, GstCaps *caps2)
 {
   GstStructure *structure;
   int i;
-  
+
+  g_return_if_fail (caps1 != NULL);
+  g_return_if_fail (caps2 != NULL);
+
   for(i=0;i<caps2->structs->len;i++){
     structure = gst_caps_get_structure (caps2, i);
     gst_caps_append_structure (caps1, structure);
index eb3a75c..8cabeb6 100644 (file)
@@ -111,7 +111,6 @@ GstCaps *gst_caps_load_thyself (xmlNodePtr parent);
 void gst_caps_replace (GstCaps **caps, GstCaps *newcaps);
 gchar *gst_caps_to_string (const GstCaps *caps);
 GstCaps *gst_caps_from_string (const gchar *string);
-void gst_caps_debug (const GstCaps *caps, const gchar *string);
 
 gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure,
     const char *field_name, int target);
index 3657dfa..6bd056d 100644 (file)
@@ -261,7 +261,7 @@ element_get_property (GstElement *element, const GParamSpec *pspec, GValue *valu
 static void
 gst_element_threadsafe_properties_pre_run (GstElement *element)
 {
-  GST_CAT_DEBUG (GST_CAT_THREAD, "locking element %s", GST_OBJECT_NAME (element));
+  GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element));
   g_mutex_lock (element->property_mutex);
   gst_element_set_pending_properties (element);
 }
@@ -269,7 +269,7 @@ gst_element_threadsafe_properties_pre_run (GstElement *element)
 static void
 gst_element_threadsafe_properties_post_run (GstElement *element)
 {
-  GST_CAT_DEBUG (GST_CAT_THREAD, "unlocking element %s", GST_OBJECT_NAME (element));
+  GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element));
   g_mutex_unlock (element->property_mutex);
 }
 
@@ -2495,7 +2495,7 @@ gst_element_negotiate_pads (GstElement *element)
                           "perform negotiate for %s:%s and %s:%s",
                           GST_DEBUG_PAD_NAME (srcpad), 
                           GST_DEBUG_PAD_NAME (sinkpad));
-        if (!gst_pad_perform_negotiate (GST_PAD (srcpad), GST_PAD (sinkpad)))
+        if (!gst_pad_renegotiate (pad))
          return FALSE;
       }
       else {
@@ -2518,9 +2518,9 @@ gst_element_clear_pad_caps (GstElement *element)
   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "clearing pad caps");
 
   while (pads) {
-    GstRealPad *pad = GST_PAD_REALIZE (pads->data);
+    GstPad *pad = GST_PAD (pads->data);
 
-    gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
+    gst_pad_unnegotiate (pad);
 
     pads = g_list_next (pads);
   }
@@ -2586,6 +2586,7 @@ gst_element_change_state (GstElement *element)
         goto failure;
       break;
     /* going to the READY state clears all pad caps */
+    /* FIXME: Why doesn't this happen on READY => NULL? -- Company */
     case GST_STATE_PAUSED_TO_READY:
       gst_element_clear_pad_caps (element);
       break;
index a6bb684..3b52984 100644 (file)
@@ -135,9 +135,9 @@ gst_implements_interface_cast (gpointer from,
   /* if we're an element, take care that this interface
    * is actually implemented */
   if (GST_IS_ELEMENT (from)) {
-    gboolean interface_is_implemented =
-       gst_element_implements_interface (GST_ELEMENT (from), iface_type);
-    g_return_val_if_fail (interface_is_implemented == TRUE, NULL);
+    g_return_val_if_fail (
+       gst_element_implements_interface (GST_ELEMENT (from), iface_type),
+       NULL);
   }
 
   return iface;
index 8eeaa42..4acbfd6 100644 (file)
@@ -56,6 +56,7 @@ static void           gst_pad_dispose                 (GObject *object);
 static void            gst_pad_set_pad_template        (GstPad *pad, GstPadTemplate *templ);
 static GstCaps *        _gst_pad_default_fixate_func    (GstPad *pad, GstCaps *caps, gpointer unused);
 
+static gboolean                gst_pad_link_try                (GstPadLink *link);
 static void             gst_pad_link_free               (GstPadLink *link);
 
 #ifndef GST_DISABLE_LOADSAVE
@@ -935,7 +936,7 @@ gst_pad_unlink (GstPad *srcpad,
 struct _GstPadLink {
   GType type;
 
-  gboolean negotiated;
+  gboolean bla;
   gboolean srcnotify;
   gboolean sinknotify;
 
@@ -1176,11 +1177,56 @@ gst_pad_link_negotiate (GstPadLink *link)
   return GST_PAD_LINK_OK;
 }
 
+/**
+ * gst_pad_link_try:
+ * @link link to try
+ *
+ * Tries to (re)link the pads with the given link. The function takes ownership
+ * of the supplied link. If the function returns FALSE and an old link existed,
+ * that link can be assumed to work unchanged.
+ *
+ * Returns: TRUE if the link succeeded, FALSE if not.
+ */
+static gboolean
+gst_pad_link_try (GstPadLink *link)
+{
+  GstPad *srcpad, *sinkpad;
+  GstPadLink *oldlink;
+  GstPadLinkReturn ret;
+  
+  /* we use assertions here, because this function is static */
+  g_assert (link);
+  srcpad = link->srcpad;
+  g_assert (srcpad);
+  sinkpad = link->sinkpad;
+  g_assert (sinkpad);
+  oldlink = GST_RPAD_LINK (srcpad);
+  g_assert (oldlink == GST_RPAD_LINK (sinkpad));
+  
+  ret = gst_pad_link_negotiate (link); 
+  if (ret == GST_PAD_LINK_REFUSED) {
+    if (oldlink && !gst_pad_link_call_link_functions (oldlink))
+      g_warning ("pads don't accept old caps. We assume they did though");
+    gst_pad_link_free (link);
+    return ret;
+  }
+
+  GST_RPAD_PEER (srcpad) = GST_REAL_PAD(link->sinkpad);
+  GST_RPAD_PEER (sinkpad) = GST_REAL_PAD(link->srcpad);
+  if (oldlink)
+    gst_pad_link_free (oldlink);
+  GST_RPAD_LINK (srcpad) = link;
+  GST_RPAD_LINK (sinkpad) = link;
+  g_object_notify (G_OBJECT (srcpad), "caps");
+  g_object_notify (G_OBJECT (sinkpad), "caps");
+  
+  return ret;
+}
+
 GstPadLinkReturn
 gst_pad_renegotiate (GstPad *pad)
 {
   GstPadLink *link;
-  GstPadLinkReturn ret;
 
   g_return_val_if_fail (pad != NULL, GST_PAD_LINK_REFUSED);
   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
@@ -1204,20 +1250,13 @@ gst_pad_renegotiate (GstPad *pad)
   link->srccaps = gst_pad_get_caps (link->srcpad);
   link->sinkcaps = gst_pad_get_caps (link->sinkpad);
 
-  ret = gst_pad_link_negotiate (link);
-
-  if (GST_PAD_LINK_FAILED (ret)) {
-    gst_pad_link_free (link);
-  }
-
-  return ret;
+  return gst_pad_link_try (link);
 }
 
 GstPadLinkReturn
 gst_pad_try_set_caps (GstPad *pad, const GstCaps *caps)
 {
   GstPadLink *link;
-  GstPadLinkReturn ret;
 
   g_return_val_if_fail (pad != NULL, GST_PAD_LINK_REFUSED);
   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
@@ -1267,13 +1306,7 @@ gst_pad_try_set_caps (GstPad *pad, const GstCaps *caps)
     link->sinknotify = FALSE;
   }
 
-  ret = gst_pad_link_negotiate (link);
-
-  if (GST_PAD_LINK_FAILED (ret)) {
-    gst_pad_link_free (link);
-  }
-
-  return ret;
+  return gst_pad_link_try (link);
 }
 
 
@@ -1422,7 +1455,6 @@ gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad,
   GstRealPad *realsrc, *realsink;
   GstScheduler *src_sched, *sink_sched;
   GstPadLink *link;
-  GstPadLinkReturn ret;
 
   /* generic checks */
   g_return_val_if_fail (srcpad != NULL, FALSE);
@@ -1498,16 +1530,8 @@ gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad,
   link->srccaps = gst_pad_get_caps (link->srcpad);
   link->sinkcaps = gst_pad_get_caps (link->sinkpad);
   if (filtercaps) link->filtercaps = gst_caps_copy (filtercaps);
-  ret = gst_pad_link_negotiate (link);
-  if (ret == GST_PAD_LINK_REFUSED) {
-    gst_pad_link_free (link);
+  if (gst_pad_link_try (link) == GST_PAD_LINK_REFUSED)
     return FALSE;
-  }
-
-  GST_RPAD_PEER (link->srcpad) = GST_REAL_PAD(link->sinkpad);
-  GST_RPAD_PEER (link->sinkpad) = GST_REAL_PAD(link->srcpad);
-  GST_RPAD_LINK (link->srcpad) = link;
-  GST_RPAD_LINK (link->sinkpad) = link;
 
   /* fire off a signal to each of the pads telling them 
    * that they've been linked */
@@ -1805,7 +1829,41 @@ _gst_pad_default_fixate_func (GstPad *pad, GstCaps *caps, gpointer unused)
 gboolean
 gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad) 
 {
-  return gst_pad_renegotiate (srcpad);
+  return gst_pad_renegotiate (srcpad) >= 0;
+}
+
+void
+gst_pad_link_unnegotiate (GstPadLink *link)
+{
+  if (link->caps) {
+    gst_caps_free (link->caps);
+    if (GST_RPAD_LINK (link->srcpad) != link) {
+      g_warning ("unnegotiating unset link");
+    } else {
+      g_object_notify (G_OBJECT (link->srcpad), "caps");
+    }
+    if (GST_RPAD_LINK (link->sinkpad) != link) {
+      g_warning ("unnegotiating unset link");
+    } else {
+      g_object_notify (G_OBJECT (link->sinkpad), "caps");
+    }
+  }
+}
+
+/**
+ * gst_pad_unnegotiate:
+ * @pad: pad to unnegotiate
+ *
+ * "Unnegotiates" a pad. The currently negotiated caps are cleared and the pad 
+ * needs renegotiation.
+ */
+void
+gst_pad_unnegotiate (GstPad *pad)
+{
+  g_return_if_fail (GST_IS_PAD (pad));
+
+  if (GST_RPAD_LINK (pad))
+    gst_pad_link_unnegotiate (GST_RPAD_LINK (pad));
 }
 
 /**
@@ -1823,8 +1881,61 @@ gboolean
 gst_pad_try_relink_filtered (GstPad *srcpad, GstPad *sinkpad, 
                                 const GstCaps *filtercaps)
 {
-  g_warning ("unimplemented");
-  return FALSE;
+  GstRealPad *realsrc, *realsink;
+  GstPadLink *link;
+  gchar *str;
+  
+  /* generic checks */
+  g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
+  g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
+
+  str = filtercaps ? gst_caps_to_string (filtercaps) : g_strdup ("");
+  GST_CAT_INFO (GST_CAT_PADS, "trying to relink %s:%s and %s:%s with filtercaps %s",
+            GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), str);
+  g_free (str);
+
+  /* now we need to deal with the real/ghost stuff */
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
+
+  g_return_val_if_fail (realsrc != NULL, FALSE);
+  g_return_val_if_fail (realsink != NULL, FALSE);
+  g_return_val_if_fail (GST_RPAD_PEER (realsrc) == GST_RPAD_PEER (realsink), FALSE);
+  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
+    GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
+              GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
+  }
+  
+  link = gst_pad_link_new ();
+
+  if (GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) {
+    link->srcpad = GST_PAD (realsrc);
+    link->sinkpad = GST_PAD (realsink);
+  } else {
+    link->srcpad = GST_PAD (realsink);
+    link->sinkpad = GST_PAD (realsrc);
+  }
+
+  if (GST_RPAD_DIRECTION (link->srcpad) != GST_PAD_SRC) {
+    GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s is not a source pad, failed",
+             GST_DEBUG_PAD_NAME (link->srcpad));
+    gst_pad_link_free (link);
+    return FALSE;
+  }    
+  if (GST_RPAD_DIRECTION (link->sinkpad) != GST_PAD_SINK) {
+    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not a sink pad, failed",
+             GST_DEBUG_PAD_NAME (link->sinkpad));
+    gst_pad_link_free (link);
+    return FALSE;
+  }
+
+  link->srccaps = gst_pad_get_caps (link->srcpad);
+  link->sinkcaps = gst_pad_get_caps (link->sinkpad);
+  if (filtercaps) link->filtercaps = gst_caps_copy (filtercaps);
+  if (GST_PAD_LINK_FAILED (gst_pad_link_try (link)))
+    return FALSE;
+
+  return TRUE;
 }
 
 /**
@@ -1843,7 +1954,10 @@ gboolean
 gst_pad_relink_filtered (GstPad *srcpad, GstPad *sinkpad, 
                             const GstCaps *filtercaps)
 {
-  g_warning ("unimplemented");
+  if (gst_pad_try_relink_filtered (srcpad, sinkpad, filtercaps))
+    return TRUE;
+
+  gst_pad_unlink (srcpad, sinkpad);
   return FALSE;
 }
 
@@ -1906,6 +2020,29 @@ gst_pad_proxy_link (GstPad *pad, const GstCaps *caps)
 }
 
 /**
+ * gst_pad_get_negotiated_caps:
+ * @pad: a #GstPad to get the negotiated capabilites of
+ *
+ * Gets the currently negotiated caps of a pad or NULL if the pad isn't
+ * negotiated.
+ *
+ * Returns: the currently negotiated caps of a pad or NULL if the pad isn't
+ *         negotiated.
+ */
+G_CONST_RETURN GstCaps *
+gst_pad_get_negotiated_caps (GstPad *pad)
+{
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+  if (!GST_PAD_REALIZE (pad))
+    return NULL;
+  if (!GST_RPAD_LINK (pad))
+    return NULL;
+
+  return GST_RPAD_LINK (pad)->caps;
+}
+
+/**
  * gst_pad_get_caps:
  * @pad: a  #GstPad to get the capabilities of.
  *
@@ -1919,7 +2056,6 @@ 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);
@@ -2136,6 +2272,8 @@ gst_pad_caps_change_notify (GstPad *pad)
 gboolean
 gst_pad_recover_caps_error (GstPad *pad, const GstCaps *allowed)
 {
+#if 0
+  /* FIXME */
   GstElement *parent;
   
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
@@ -2159,7 +2297,7 @@ gst_pad_recover_caps_error (GstPad *pad, const GstCaps *allowed)
   parent = gst_pad_get_parent (pad);
   gst_element_error (parent, "negotiation failed on pad %s:%s",
                  GST_DEBUG_PAD_NAME (pad));
-
+#endif
   return FALSE;
 }
 
@@ -2233,9 +2371,6 @@ gst_real_pad_dispose (GObject *object)
     g_list_free (GST_REAL_PAD(pad)->ghostpads);
   }
 
-  gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
-  gst_caps_replace (&GST_RPAD_APPFILTER (pad), NULL);
-
   if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
     GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
                GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
index 741ea77..935ba42 100644 (file)
@@ -268,7 +268,7 @@ struct _GstGhostPadClass {
 /* Generic */
 #define GST_PAD_REALIZE(pad)           (GST_IS_REAL_PAD(pad) ? ((GstRealPad *)(pad)) : GST_GPAD_REALPAD(pad))
 #define GST_PAD_DIRECTION(pad)         GST_RPAD_DIRECTION(GST_PAD_REALIZE(pad))
-#define GST_PAD_CAPS(pad)              GST_RPAD_CAPS(GST_PAD_REALIZE(pad))
+#define GST_PAD_CAPS(pad)              (gst_pad_get_negotiated_caps(GST_PAD (pad)))
 #define GST_PAD_PEER(pad)              GST_PAD(GST_RPAD_PEER(GST_PAD_REALIZE(pad)))
 
 /* Some check functions (unused?) */
@@ -401,8 +401,9 @@ void                        gst_pad_unlink                          (GstPad *srcpad, GstPad *sinkpad);
 GstPad*                        gst_pad_get_peer                        (GstPad *pad);
 
 /* capsnego functions */
+G_CONST_RETURN GstCaps*        gst_pad_get_negotiated_caps             (GstPad *pad);
 GstCaps*               gst_pad_get_caps                        (GstPad *pad);
-const GstCaps*         gst_pad_get_pad_template_caps           (GstPad *pad);
+G_CONST_RETURN GstCaps*        gst_pad_get_pad_template_caps           (GstPad *pad);
 GstPadLinkReturn       gst_pad_try_set_caps                    (GstPad *pad, const GstCaps *caps);
 gboolean               gst_pad_check_compatibility             (GstPad *srcpad, GstPad *sinkpad);
 
@@ -411,7 +412,11 @@ void                       gst_pad_set_fixate_function             (GstPad *pad, GstPadFixateFunction fixate);
 GstCaps *              gst_pad_proxy_getcaps                   (GstPad *pad);
 GstPadLinkReturn       gst_pad_proxy_link                      (GstPad *pad, const GstCaps *caps);
 gboolean               gst_pad_relink_filtered                 (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps);
+#ifndef GST_DISABLE_DEPRECATED
 gboolean               gst_pad_perform_negotiate               (GstPad *srcpad, GstPad *sinkpad);
+#endif
+GstPadLinkReturn       gst_pad_renegotiate                     (GstPad *pad);
+void                   gst_pad_unnegotiate                     (GstPad *pad);
 gboolean               gst_pad_try_relink_filtered             (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps);
 GstCaps*               gst_pad_get_allowed_caps                (GstPad *pad);
 void                    gst_pad_caps_change_notify              (GstPad *pad);
index ef087be..cd64e3c 100644 (file)
@@ -179,8 +179,8 @@ gst_system_clock_wait (GstClock *clock, GstClockEntry *entry)
   diff = GST_CLOCK_ENTRY_TIME (entry) - current;
 
   if (diff + clock->max_diff < 0) {
-    g_warning ("clock is way behind: %" G_GINT64_FORMAT
-               "s (max allowed is %" G_GINT64_FORMAT "s", -diff, clock->max_diff);
+    GST_WARNING_OBJECT (clock, "clock is way behind: %" G_GINT64_FORMAT
+       "s (max allowed is %" G_GINT64_FORMAT "s", -diff, clock->max_diff);
     return GST_CLOCK_ENTRY_EARLY;
   }
   
index d51ba7a..b28d892 100644 (file)
@@ -392,8 +392,8 @@ gst_thread_change_state (GstElement *element)
 
   thread = GST_THREAD (element);
 
-  GST_CAT_DEBUG (GST_CAT_STATES, "%s is changing state from %s to %s",
-            GST_ELEMENT_NAME (element), gst_element_state_get_name (GST_STATE (element)),
+  GST_DEBUG_OBJECT (element, "changing state from %s to %s",
+            gst_element_state_get_name (GST_STATE (element)),
             gst_element_state_get_name (GST_STATE_PENDING (element)));
 
   gst_thread_catch (thread);