From: David Schleef Date: Fri, 2 Jan 2004 23:04:14 +0000 (+0000) Subject: gst/gstcaps.c: Add new function. X-Git-Tag: BRANCH-RELEASE-0_7_4-ROOT~194 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a77e6e35e41a95ae37c5096726f33a5888eeea34;p=platform%2Fupstream%2Fgstreamer.git gst/gstcaps.c: Add new function. 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. --- diff --git a/ChangeLog b/ChangeLog index c4b8201..09a1202 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-01-02 David Schleef + + * 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 * gst/gstpad.c: (gst_pad_try_relink_filtered): diff --git a/gst/gstcaps.c b/gst/gstcaps.c index c85b2ec..3d446d7 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -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) { diff --git a/gst/gstcaps.h b/gst/gstcaps.h index a7c14fe..b345ca2 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -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); diff --git a/gst/gstpad.c b/gst/gstpad.c index 37da29a..aec4d5c 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -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