From: Stefan Kost Date: Wed, 7 Oct 2009 08:43:54 +0000 (+0300) Subject: pad: add variants of gst_pad_get_caps() that don't copy caps. Fixes #590941 X-Git-Tag: RELEASE-0.10.26~397 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fcc5d783df0a8461250da1e0434132d580ec8adf;p=platform%2Fupstream%2Fgstreamer.git pad: add variants of gst_pad_get_caps() that don't copy caps. Fixes #590941 In most places in core and baseclasses we just need the caps to do caps- intersections. In that case ref'ed caps are enough (no need to copy). This patch also switches the code to use the new functions. API: gst_pad_get_caps_refed(), gst_pad_peer_get_caps_refed() --- diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 9b712c3..c7b3d87 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1343,6 +1343,7 @@ gst_pad_is_linked gst_pad_can_link gst_pad_get_caps +gst_pad_get_caps_refed gst_pad_get_allowed_caps gst_pad_get_negotiated_caps gst_pad_get_pad_template_caps @@ -1350,6 +1351,7 @@ gst_pad_set_caps gst_pad_get_peer gst_pad_peer_get_caps +gst_pad_peer_get_caps_refed gst_pad_use_fixed_caps gst_pad_is_active diff --git a/gst/gstghostpad.c b/gst/gstghostpad.c index 6d52789..4998718 100644 --- a/gst/gstghostpad.c +++ b/gst/gstghostpad.c @@ -224,7 +224,7 @@ gst_proxy_pad_do_getcaps (GstPad * pad) if (target) { /* if we have a real target, proxy the call */ - res = gst_pad_get_caps (target); + res = gst_pad_get_caps_refed (target); GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (target), res); diff --git a/gst/gstpad.c b/gst/gstpad.c index 4d2232f..755a95e 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -2170,6 +2170,7 @@ gst_pad_get_caps_unlocked (GstPad * pad) goto done; } + /* this almost never happens */ GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad has no caps"); result = gst_caps_new_empty (); @@ -2177,6 +2178,38 @@ done: return result; } +/* FIXME-0.11: what about making this the default and using + * gst_caps_make_writable() explicitely where needed + */ +/** + * gst_pad_get_caps_refed: + * @pad: a #GstPad to get the capabilities of. + * + * Gets the capabilities this pad can produce or consume. Preferred function if + * one only wants to read or intersect the caps. + * + * Returns: the caps of the pad with incremented ref-count. + * + * Since: 0.10.25 + */ +GstCaps * +gst_pad_get_caps_refed (GstPad * pad) +{ + GstCaps *result = NULL; + + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + GST_OBJECT_LOCK (pad); + + GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps"); + + result = gst_pad_get_caps_unlocked (pad); + + GST_OBJECT_UNLOCK (pad); + + return result; +} + /** * gst_pad_get_caps: * @pad: a #GstPad to get the capabilities of. @@ -2195,33 +2228,70 @@ done: GstCaps * gst_pad_get_caps (GstPad * pad) { + GstCaps *result = gst_pad_get_caps_refed (pad); + + /* be sure that we have a copy */ + if (G_LIKELY (result)) + result = gst_caps_make_writable (result); + + return result; +} + +/* FIXME-0.11: what about making this the default and using + * gst_caps_make_writable() explicitely where needed + */ +/** + * gst_pad_peer_get_caps_refed: + * @pad: a #GstPad to get the capabilities of. + * + * Gets the capabilities of the peer connected to this pad. Preferred function + * if one only wants to read or intersect the caps. + * + * Returns: the caps of the pad with incremented ref-count. + * + * Since: 0.10.25 + */ +GstCaps * +gst_pad_peer_get_caps_refed (GstPad * pad) +{ + GstPad *peerpad; GstCaps *result = NULL; g_return_val_if_fail (GST_IS_PAD (pad), NULL); GST_OBJECT_LOCK (pad); - GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps"); - - result = gst_pad_get_caps_unlocked (pad); + GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get peer caps"); - /* be sure that we have a copy */ - if (result) - result = gst_caps_make_writable (result); + peerpad = GST_PAD_PEER (pad); + if (G_UNLIKELY (peerpad == NULL)) + goto no_peer; + gst_object_ref (peerpad); GST_OBJECT_UNLOCK (pad); + result = gst_pad_get_caps_refed (peerpad); + + gst_object_unref (peerpad); + return result; + +no_peer: + { + GST_OBJECT_UNLOCK (pad); + return NULL; + } } /** * gst_pad_peer_get_caps: * @pad: a #GstPad to get the peer capabilities of. * - * Gets the capabilities of the peer connected to this pad. + * Gets the capabilities of the peer connected to this pad. Similar to + * gst_pad_get_caps(). * - * Returns: the #GstCaps of the peer pad. This function returns a new caps, so - * use gst_caps_unref to get rid of it. this function returns NULL if there is + * Returns: a newly allocated copy of the #GstCaps of the peer pad. Use + * gst_caps_unref() to get rid of it. This function returns %NULL if there is * no peer pad. */ GstCaps * @@ -2367,7 +2437,7 @@ gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps); - allowed = gst_pad_get_caps (pad); + allowed = gst_pad_get_caps_refed (pad); if (!allowed) goto nothing_allowed; @@ -2703,9 +2773,9 @@ gst_pad_get_allowed_caps (GstPad * pad) gst_object_ref (peer); GST_OBJECT_UNLOCK (pad); - mycaps = gst_pad_get_caps (pad); + mycaps = gst_pad_get_caps_refed (pad); - peercaps = gst_pad_get_caps (peer); + peercaps = gst_pad_get_caps_refed (peer); gst_object_unref (peer); caps = gst_caps_intersect (mycaps, peercaps); diff --git a/gst/gstpad.h b/gst/gstpad.h index e79adb2..835ea0a 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -890,11 +890,13 @@ void gst_pad_set_setcaps_function (GstPad *pad, GstPadSetCapsFunction setcaps G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad); /* capsnego function for linked/unlinked pads */ +GstCaps * gst_pad_get_caps_refed (GstPad * pad); GstCaps * gst_pad_get_caps (GstPad * pad); void gst_pad_fixate_caps (GstPad * pad, GstCaps *caps); gboolean gst_pad_accept_caps (GstPad * pad, GstCaps *caps); gboolean gst_pad_set_caps (GstPad * pad, GstCaps *caps); +GstCaps * gst_pad_peer_get_caps_refed (GstPad * pad); GstCaps * gst_pad_peer_get_caps (GstPad * pad); gboolean gst_pad_peer_accept_caps (GstPad * pad, GstCaps *caps); diff --git a/gst/gstutils.c b/gst/gstutils.c index d212f0f..87a06a8 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -2634,7 +2634,7 @@ intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig) GstCaps *peercaps, *existing; existing = g_value_get_pointer (ret); - peercaps = gst_pad_peer_get_caps (pad); + peercaps = gst_pad_peer_get_caps_refed (pad); if (G_LIKELY (peercaps)) { g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps)); gst_caps_unref (existing); diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 91fc27b..8c78ba9 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -2407,7 +2407,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc) gboolean result = FALSE; /* first see what is possible on our source pad */ - thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc)); + thiscaps = gst_pad_get_caps_refed (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps); /* nothing or anything is allowed, we're done */ if (thiscaps == NULL || gst_caps_is_any (thiscaps)) @@ -2417,7 +2417,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc) goto no_caps; /* get the peer caps */ - peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc)); + peercaps = gst_pad_peer_get_caps_refed (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); if (peercaps) { GstCaps *icaps; diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 2e56962..19fbdfd 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -613,14 +613,14 @@ gst_base_transform_getcaps (GstPad * pad) otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad; /* we can do what the peer can */ - caps = gst_pad_peer_get_caps (otherpad); + caps = gst_pad_peer_get_caps_refed (otherpad); if (caps) { GstCaps *temp; const GstCaps *templ; GST_DEBUG_OBJECT (pad, "peer caps %" GST_PTR_FORMAT, caps); - /* filtered against our padtemplate */ + /* filtered against our padtemplate on the other side */ templ = gst_pad_get_pad_template_caps (otherpad); GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ); temp = gst_caps_intersect (caps, templ); @@ -635,7 +635,7 @@ gst_base_transform_getcaps (GstPad * pad) if (caps == NULL) goto done; - /* and filter against the template again */ + /* and filter against the template of this pad */ templ = gst_pad_get_pad_template_caps (pad); GST_DEBUG_OBJECT (pad, "our template %" GST_PTR_FORMAT, templ); temp = gst_caps_intersect (caps, templ); @@ -856,7 +856,7 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad, GST_DEBUG_OBJECT (trans, "othercaps now %" GST_PTR_FORMAT, othercaps); - peercaps = gst_pad_get_caps (otherpeer); + peercaps = gst_pad_get_caps_refed (otherpeer); intersect = gst_caps_intersect (peercaps, othercaps); gst_caps_unref (peercaps); gst_caps_unref (othercaps); @@ -1002,7 +1002,7 @@ gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (pad, "non fixed accept caps %" GST_PTR_FORMAT, caps); /* get all the formats we can handle on this pad */ - allowed = gst_pad_get_caps (pad); + allowed = gst_pad_get_caps_refed (pad); if (!allowed) { GST_DEBUG_OBJECT (pad, "gst_pad_get_caps() failed"); goto no_transform_possible; diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index d3567d3..0a6bf68 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -586,6 +586,7 @@ EXPORTS gst_pad_flags_get_type gst_pad_get_allowed_caps gst_pad_get_caps + gst_pad_get_caps_refed gst_pad_get_direction gst_pad_get_element_private gst_pad_get_fixed_caps_func @@ -615,6 +616,7 @@ EXPORTS gst_pad_pause_task gst_pad_peer_accept_caps gst_pad_peer_get_caps + gst_pad_peer_get_caps_refed gst_pad_peer_query gst_pad_presence_get_type gst_pad_proxy_getcaps