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.
This commit is contained in:
David Schleef 2004-01-02 23:04:14 +00:00
parent 62d2803d5d
commit a77e6e35e4
4 changed files with 75 additions and 5 deletions

View file

@ -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):

View file

@ -346,6 +346,42 @@ gboolean gst_caps_is_fixed (const GstCaps *caps)
return gst_structure_foreach (structure, _gst_caps_is_fixed_foreach, NULL);
}
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)

View 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);

View 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