gst/gstcaps.c: Add new function.
authorDavid Schleef <ds@schleef.org>
Fri, 2 Jan 2004 23:04:14 +0000 (23:04 +0000)
committerDavid Schleef <ds@schleef.org>
Fri, 2 Jan 2004 23:04:14 +0000 (23:04 +0000)
Original commit message from CVS:
* gst/gstcaps.c: (_gst_structure_is_equal_foreach),
(gst_caps_is_equal_fixed): Add new function.
* gst/gstcaps.h: ditto.
* gst/gstpad.c: (gst_real_pad_class_init),
(gst_pad_link_call_link_functions), (gst_pad_try_set_caps),
(gst_pad_set_explicit_caps), (gst_pad_get_caps):  In try_set_caps,
check new caps against existing caps -- if they're the same, return
OK without renegotiating.  caps-nego-failed signal fixed so that
the marshaller isn't VOID__OBJECT.  Also changed to G_TYPE_POINTER
to save an extra caps copy.  Don't complete negotiation if a pad
link function returns DELAYED.

ChangeLog
gst/gstcaps.c
gst/gstcaps.h
gst/gstpad.c

index c4b8201..09a1202 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-01-02  David Schleef  <ds@schleef.org>
+
+       * gst/gstcaps.c: (_gst_structure_is_equal_foreach),
+       (gst_caps_is_equal_fixed): Add new function.
+       * gst/gstcaps.h: ditto.
+       * gst/gstpad.c: (gst_real_pad_class_init),
+       (gst_pad_link_call_link_functions), (gst_pad_try_set_caps),
+       (gst_pad_set_explicit_caps), (gst_pad_get_caps):  In try_set_caps,
+       check new caps against existing caps -- if they're the same, return
+       OK without renegotiating.  caps-nego-failed signal fixed so that
+       the marshaller isn't VOID__OBJECT.  Also changed to G_TYPE_POINTER
+       to save an extra caps copy.  Don't complete negotiation if a pad
+       link function returns DELAYED.
+
 2004-01-02  Benjamin Otte  <in7y118@public.uni-hamburg.de>
 
        * gst/gstpad.c: (gst_pad_try_relink_filtered):
index c85b2ec..3d446d7 100644 (file)
@@ -347,6 +347,42 @@ gboolean gst_caps_is_fixed (const GstCaps *caps)
 }
 
 static gboolean
+_gst_structure_is_equal_foreach (GQuark field_id, 
+    GValue *val2, gpointer data)
+{
+  GstStructure *struct1 = (GstStructure *) data;
+  const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
+
+  if (val1 == NULL) return FALSE;
+  if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+gboolean gst_caps_is_equal_fixed (const GstCaps *caps1, const GstCaps *caps2)
+{
+  GstStructure *struct1, *struct2;
+
+  g_return_val_if_fail (gst_caps_is_fixed(caps1), FALSE);
+  g_return_val_if_fail (gst_caps_is_fixed(caps2), FALSE);
+
+  struct1 = gst_caps_get_structure (caps1, 0);
+  struct2 = gst_caps_get_structure (caps2, 0);
+
+  if (struct1->name != struct2->name) {
+    return FALSE;
+  }
+  if (struct1->fields->len != struct2->fields->len) {
+    return FALSE;
+  }
+
+  return gst_structure_foreach (struct1, _gst_structure_is_equal_foreach,
+      struct2);
+}
+
+static gboolean
 _gst_structure_field_has_compatible (GQuark field_id, 
     GValue *val2, gpointer data)
 {
index a7c14fe..b345ca2 100644 (file)
@@ -94,6 +94,7 @@ gboolean gst_caps_is_any (const GstCaps *caps);
 gboolean gst_caps_is_empty (const GstCaps *caps);
 gboolean gst_caps_is_chained (const GstCaps *caps);
 gboolean gst_caps_is_fixed (const GstCaps *caps);
+gboolean gst_caps_is_equal_fixed (const GstCaps *caps1, const GstCaps *caps2);
 gboolean gst_caps_is_always_compatible (const GstCaps *caps1,
     const GstCaps *caps2);
 
index 37da29a..aec4d5c 100644 (file)
@@ -178,8 +178,8 @@ gst_real_pad_class_init (GstRealPadClass *klass)
   gst_real_pad_signals[REAL_CAPS_NEGO_FAILED] =
     g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
-                  gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
-                  GST_TYPE_CAPS);
+                  gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
+                  G_TYPE_POINTER);
   gst_real_pad_signals[REAL_LINKED] =
     g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
@@ -1116,7 +1116,7 @@ gst_pad_link_call_link_functions (GstPadLink *link)
     GST_DEBUG ("got reply %d from link function on pad %s:%s",
         res, GST_DEBUG_PAD_NAME (link->srcpad));
 
-    if (res == GST_PAD_LINK_REFUSED) {
+    if (GST_PAD_LINK_FAILED (res)) {
       GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
                GST_DEBUG_PAD_NAME (link->srcpad));
       return FALSE;
@@ -1142,7 +1142,7 @@ gst_pad_link_call_link_functions (GstPadLink *link)
     GST_DEBUG ("got reply %d from link function on pad %s:%s",
         res, GST_DEBUG_PAD_NAME (link->sinkpad));
 
-    if (res == GST_PAD_LINK_REFUSED) {
+    if (GST_PAD_LINK_FAILED (res)) {
       GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps",
                GST_DEBUG_PAD_NAME (link->sinkpad));
       return FALSE;
@@ -1286,6 +1286,12 @@ gst_pad_try_set_caps (GstPad *pad, const GstCaps *caps)
     return GST_PAD_LINK_OK;
   }
 
+  /* if the desired caps are already there, it's trivially ok */
+  if (GST_PAD_CAPS (pad) && gst_caps_is_equal_fixed (caps,
+        GST_PAD_CAPS (pad))) {
+    return GST_PAD_LINK_OK;
+  }
+
   g_return_val_if_fail (GST_PAD_LINK_SRC (pad), GST_PAD_LINK_REFUSED);
   g_return_val_if_fail (GST_PAD_LINK_SINK (pad), GST_PAD_LINK_REFUSED);
 
@@ -2281,14 +2287,27 @@ gst_pad_get_caps (GstPad *pad)
     return caps;
   } else if (GST_PAD_PAD_TEMPLATE (realpad)) {
     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
+    const GstCaps *caps;
+
     GST_CAT_DEBUG (GST_CAT_CAPS, "using pad template %p with caps %p", 
               templ, GST_PAD_TEMPLATE_CAPS (templ));
+
+    caps = GST_PAD_TEMPLATE_CAPS (templ);
+#if 0
+    /* FIXME we should enable something like this someday, but this is
+     * a bit buggy */
+    if (!gst_caps_is_fixed (caps)) {
+      g_warning("pad %s:%s (%p) has no getcaps function and the pad template returns non-fixed caps.  Element is probably broken.\n",
+          GST_DEBUG_PAD_NAME (realpad), realpad);
+    }
+#endif
+
     return gst_caps_copy (GST_PAD_TEMPLATE_CAPS (templ));
   }
   GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
 
 #if 0
-  /* FIXME this should be enabled some day */
+  /* FIXME enable */
   g_warning("pad %s:%s (%p) has no pad template\n",
       GST_DEBUG_PAD_NAME (realpad), realpad);
 #endif