diff --git a/ChangeLog b/ChangeLog index fefc8bf615..748a77d845 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2004-07-14 Andy Wingo + + * gst/gsttag.c: Add a tag merge func for pointers. The header was + there all along, but the function wasn't. (guile-gstreamer's build + system uses the address of the function -- I wasn't actually + trying to use this.) + +2004-07-14 Andy Wingo + + * gst/gstpad.c (gst_pad_try_set_caps): Naive link functions (such + as gst_pad_proxy_pad_link) just link to every other pad when they + are called. In the case where the graph has cycles, this will mean + that a call to try_set_caps will recurse. Allow this recursion + and return OK, while we wait for the first try_set_caps to give a + proper return value. + (gst_pad_link_call_link_functions): Since this function is the + only one to set the NEGOTIATING flag on a pad, if the flag is set + it means that the link functions have indirectly recursed. If this + happens, error out to avoid infinite recursion and an eventual + SEGV. + (gst_real_pad_class_init): Remove a crufty GtkObject comment. + (gst_pad_proxy_getcaps): Intersect the result with the template + caps to ensure that the return value is valid. + +2004-07-14 Andy Wingo + + * gst/gstdata.c (gst_data_is_writable): s/>=/>/. If there is only + one refcount, the calling function is the owner of the buffer. + 2004-07-14 Wim Taymans * gst/schedulers/gstoptimalscheduler.c: (group_dec_link), @@ -128,6 +157,7 @@ * testsuite/clock/signedness.c: (main): make sure it never will again +>>>>>>> 1.669 2004-07-11 Andy Wingo * gst/gstbin.c (gst_bin_add_func): If we're adding an element diff --git a/gst/gstdata.c b/gst/gstdata.c index 29b1bd1611..52b8ce766f 100644 --- a/gst/gstdata.c +++ b/gst/gstdata.c @@ -128,7 +128,7 @@ gst_data_is_writable (GstData * data) refcount = gst_atomic_int_read (&data->refcount); - if (refcount >= 1) + if (refcount > 1) return FALSE; if (GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY)) return FALSE; diff --git a/gst/gstpad.c b/gst/gstpad.c index d8bddd32af..c3a0a3ca53 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -230,8 +230,6 @@ gst_real_pad_class_init (GstRealPadClass * klass) gst_marshal_BOXED__BOXED, GST_TYPE_CAPS, 1, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE); -/* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */ -/* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */ g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE, g_param_spec_boolean ("active", "Active", "Whether the pad is active.", TRUE, G_PARAM_READWRITE)); @@ -1255,26 +1253,28 @@ gst_pad_link_fixate (GstPadLink * link) static GstPadLinkReturn gst_pad_link_call_link_functions (GstPadLink * link) { - gboolean negotiating; - GstPadLinkReturn res; + GstPadLinkReturn res = GST_PAD_LINK_OK; + /* Detect recursion. */ + if (GST_PAD_IS_NEGOTIATING (link->srcpad) || + GST_PAD_IS_NEGOTIATING (link->sinkpad)) { + GST_ERROR ("The link functions have recursed, please file a bug!"); + return GST_PAD_LINK_REFUSED; + } + + /* Both of the pads are in negotiation, so we set the NEGOTIATING flag on both + * of them now to avoid recursion from either pad. */ + GST_FLAG_SET (link->srcpad, GST_PAD_NEGOTIATING); + GST_FLAG_SET (link->sinkpad, GST_PAD_NEGOTIATING); + + /* If this doesn't run, the status is left to the default OK value. */ if (link->srcnotify && GST_RPAD_LINKFUNC (link->srcpad)) { GST_DEBUG ("calling link function on pad %s:%s", GST_DEBUG_PAD_NAME (link->srcpad)); - negotiating = GST_FLAG_IS_SET (link->srcpad, GST_PAD_NEGOTIATING); - - /* set the NEGOTIATING flag if not already done */ - if (!negotiating) - GST_FLAG_SET (link->srcpad, GST_PAD_NEGOTIATING); - /* call the link function */ res = GST_RPAD_LINKFUNC (link->srcpad) (GST_PAD (link->srcpad), link->caps); - /* unset again after negotiating only if we set it */ - if (!negotiating) - GST_FLAG_UNSET (link->srcpad, GST_PAD_NEGOTIATING); - GST_DEBUG ("got reply %d from link function on pad %s:%s", res, GST_DEBUG_PAD_NAME (link->srcpad)); @@ -1282,28 +1282,18 @@ gst_pad_link_call_link_functions (GstPadLink * link) GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (link->srcpad), link->caps); - return res; } } - if (link->sinknotify && GST_RPAD_LINKFUNC (link->sinkpad)) { + if (GST_PAD_LINK_SUCCESSFUL (res) && + link->sinknotify && GST_RPAD_LINKFUNC (link->sinkpad)) { GST_DEBUG ("calling link function on pad %s:%s", GST_DEBUG_PAD_NAME (link->sinkpad)); - negotiating = GST_FLAG_IS_SET (link->sinkpad, GST_PAD_NEGOTIATING); - - /* set the NEGOTIATING flag if not already done */ - if (!negotiating) - GST_FLAG_SET (link->sinkpad, GST_PAD_NEGOTIATING); - /* call the link function */ res = GST_RPAD_LINKFUNC (link->sinkpad) (GST_PAD (link->sinkpad), link->caps); - /* unset again after negotiating only if we set it */ - if (!negotiating) - GST_FLAG_UNSET (link->sinkpad, GST_PAD_NEGOTIATING); - GST_DEBUG ("got reply %d from link function on pad %s:%s", res, GST_DEBUG_PAD_NAME (link->sinkpad)); @@ -1311,11 +1301,12 @@ gst_pad_link_call_link_functions (GstPadLink * link) GST_CAT_INFO (GST_CAT_CAPS, "pad %s:%s doesn't accept caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (link->sinkpad), link->caps); - return res; } } - return GST_PAD_LINK_OK; + GST_FLAG_UNSET (link->srcpad, GST_PAD_NEGOTIATING); + GST_FLAG_UNSET (link->sinkpad, GST_PAD_NEGOTIATING); + return res; } static GstPadLinkReturn @@ -1483,7 +1474,13 @@ gst_pad_try_set_caps (GstPad * pad, const GstCaps * caps) GstPadLinkReturn ret; g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_PAD_LINK_REFUSED); - g_return_val_if_fail (!GST_PAD_IS_NEGOTIATING (pad), GST_PAD_LINK_REFUSED); + + GST_LOG_OBJECT (pad, "Trying to set %" GST_PTR_FORMAT, caps); + + if (GST_PAD_IS_NEGOTIATING (pad)) { + GST_DEBUG_OBJECT (pad, "Detected a recursion, just returning OK"); + return GST_PAD_LINK_OK; + } /* setting non-fixed caps on a pad is not allowed */ if (!gst_caps_is_fixed (caps)) { @@ -2316,7 +2313,7 @@ gst_pad_proxy_getcaps (GstPad * pad) { GstElement *element; const GList *pads; - GstCaps *caps; + GstCaps *caps, *intersected; g_return_val_if_fail (GST_IS_PAD (pad), NULL); @@ -2343,7 +2340,9 @@ gst_pad_proxy_getcaps (GstPad * pad) pads = g_list_next (pads); } - return caps; + intersected = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad)); + gst_caps_free (caps); + return intersected; } /** @@ -2618,11 +2617,19 @@ gst_pad_get_caps (GstPad * pad) GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)", GST_DEBUG_PAD_NAME (realpad), realpad); - if (GST_RPAD_GETCAPSFUNC (realpad)) { + if (GST_PAD_IS_DISPATCHING (realpad)) + GST_CAT_DEBUG (GST_CAT_CAPS, + "pad %s:%s is already dispatching -- looking for a template", + GST_DEBUG_PAD_NAME (realpad)); + + if (GST_RPAD_GETCAPSFUNC (realpad) && !GST_PAD_IS_DISPATCHING (realpad)) { GstCaps *caps; - GST_CAT_DEBUG (GST_CAT_CAPS, "using pad getcaps function"); + GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function"); + + GST_FLAG_SET (realpad, GST_PAD_DISPATCHING); caps = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad)); + GST_FLAG_UNSET (realpad, GST_PAD_DISPATCHING); if (caps == NULL) { g_critical ("pad %s:%s returned NULL caps from getcaps function\n", diff --git a/gst/gstpad.h b/gst/gstpad.h index ea79dafad6..b3b661fe00 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -140,6 +140,7 @@ typedef enum { typedef enum { GST_PAD_DISABLED = GST_OBJECT_FLAG_LAST, GST_PAD_NEGOTIATING, + GST_PAD_DISPATCHING, GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4 } GstPadFlags; @@ -280,6 +281,7 @@ struct _GstGhostPadClass { #define GST_PAD_IS_LINKED(pad) (GST_PAD_PEER(pad) != NULL) #define GST_PAD_IS_ACTIVE(pad) (!GST_FLAG_IS_SET(GST_PAD_REALIZE(pad), GST_PAD_DISABLED)) #define GST_PAD_IS_NEGOTIATING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING)) +#define GST_PAD_IS_DISPATCHING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_DISPATCHING)) #define GST_PAD_IS_USABLE(pad) (GST_PAD_IS_LINKED (pad) && \ GST_PAD_IS_ACTIVE(pad) && GST_PAD_IS_ACTIVE(GST_PAD_PEER (pad))) #define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->gethandler != NULL) diff --git a/gst/gsttag.c b/gst/gsttag.c index 6285c67f76..79a780619a 100644 --- a/gst/gsttag.c +++ b/gst/gsttag.c @@ -970,6 +970,7 @@ TAG_MERGE_FUNCS (int64, gint64) TAG_MERGE_FUNCS (uint64, guint64) TAG_MERGE_FUNCS (float, gfloat) TAG_MERGE_FUNCS (double, gdouble) +TAG_MERGE_FUNCS (pointer, gpointer) #undef COPY_FUNC #define COPY_FUNC g_strdup TAG_MERGE_FUNCS (string, gchar *) diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c index 6285c67f76..79a780619a 100644 --- a/gst/gsttaglist.c +++ b/gst/gsttaglist.c @@ -970,6 +970,7 @@ TAG_MERGE_FUNCS (int64, gint64) TAG_MERGE_FUNCS (uint64, guint64) TAG_MERGE_FUNCS (float, gfloat) TAG_MERGE_FUNCS (double, gdouble) +TAG_MERGE_FUNCS (pointer, gpointer) #undef COPY_FUNC #define COPY_FUNC g_strdup TAG_MERGE_FUNCS (string, gchar *)