patch to fix 110962

Original commit message from CVS:
patch to fix 110962
- caps refcounting backport from HEAD
- queue caspnego fix

also:
- do not inform the scheduler of a scheduling_change when nothing really
happened (element changed from loop based to loop based).
This commit is contained in:
Wim Taymans 2003-04-16 19:19:46 +00:00
parent eb8cdb1c1e
commit 0bba2966b7
6 changed files with 520 additions and 343 deletions

View file

@ -25,10 +25,10 @@
#include "gstcaps.h"
#include "gsttype.h"
#include "gstmemchunk.h"
#include "gstlog.h"
static GMemChunk *_gst_caps_chunk;
static GMutex *_gst_caps_chunk_lock;
static GstMemChunk *_gst_caps_chunk;
GType _gst_caps_type;
@ -52,6 +52,7 @@ transform_func (const GValue *src_value,
g_value_set_boxed (&value, caps->properties);
props = g_strdup_value_contents (&value);
g_value_unset (&value);
g_string_append (result, props);
g_free (props);
@ -65,10 +66,9 @@ transform_func (const GValue *src_value,
void
_gst_caps_initialize (void)
{
_gst_caps_chunk = g_mem_chunk_new ("GstCaps",
_gst_caps_chunk = gst_mem_chunk_new ("GstCaps",
sizeof (GstCaps), sizeof (GstCaps) * 256,
G_ALLOC_AND_FREE);
_gst_caps_chunk_lock = g_mutex_new ();
_gst_caps_type = g_boxed_type_register_static ("GstCaps",
(GBoxedCopyFunc) gst_caps_ref,
@ -77,6 +77,13 @@ _gst_caps_initialize (void)
g_value_register_transform_func (_gst_caps_type,
G_TYPE_STRING,
transform_func);
}
GType
gst_caps_get_type (void)
{
return _gst_caps_type;
}
static guint16
@ -134,9 +141,12 @@ gst_caps_new_id (const gchar *name, const guint16 id, GstProps *props)
{
GstCaps *caps;
g_mutex_lock (_gst_caps_chunk_lock);
caps = g_mem_chunk_alloc (_gst_caps_chunk);
g_mutex_unlock (_gst_caps_chunk_lock);
caps = gst_mem_chunk_alloc (_gst_caps_chunk);
GST_DEBUG (GST_CAT_CAPS, "new %p", caps);
gst_props_ref (props);
gst_props_sink (props);
caps->name = g_strdup (name);
caps->id = id;
@ -153,6 +163,14 @@ gst_caps_new_id (const gchar *name, const guint16 id, GstProps *props)
return caps;
}
/**
* gst_caps_replace:
* @oldcaps: the caps to take replace
* @newcaps: the caps to take replace
*
* Replace the pointer to the caps, doing proper
* refcounting.
*/
void
gst_caps_replace (GstCaps **oldcaps, GstCaps *newcaps)
{
@ -195,11 +213,12 @@ gst_caps_destroy (GstCaps *caps)
next = caps->next;
GST_DEBUG (GST_CAT_CAPS, "destroy %p", caps);
gst_props_unref (caps->properties);
g_free (caps->name);
g_mutex_lock (_gst_caps_chunk_lock);
g_mem_chunk_free (_gst_caps_chunk, caps);
g_mutex_unlock (_gst_caps_chunk_lock);
gst_mem_chunk_free (_gst_caps_chunk, caps);
if (next)
gst_caps_unref (next);
@ -217,8 +236,8 @@ gst_caps_debug (GstCaps *caps, const gchar *label)
{
GST_DEBUG_ENTER ("caps debug: %s", label);
while (caps) {
GST_DEBUG (GST_CAT_CAPS, "caps: %p %s %s (%sfixed) (refcount %d) %s",
caps, caps->name, gst_caps_get_mime (caps),
GST_DEBUG (GST_CAT_CAPS, "caps: %p %s %s (%sfixed) (refcount %d) %s",
caps, caps->name, gst_caps_get_mime (caps),
GST_CAPS_IS_FIXED (caps) ? "" : "NOT ", caps->refcount,
GST_CAPS_IS_FLOATING (caps) ? "FLOATING" : "");
@ -253,6 +272,9 @@ gst_caps_unref (GstCaps *caps)
g_return_val_if_fail (caps->refcount > 0, NULL);
GST_DEBUG (GST_CAT_CAPS, "unref %p (%d->%d) %d",
caps, caps->refcount, caps->refcount-1, GST_CAPS_FLAGS (caps));
caps->refcount--;
zero = (caps->refcount == 0);
@ -274,7 +296,13 @@ gst_caps_unref (GstCaps *caps)
GstCaps*
gst_caps_ref (GstCaps *caps)
{
g_return_val_if_fail (caps != NULL, NULL);
if (caps == NULL)
return NULL;
g_return_val_if_fail (caps->refcount > 0, NULL);
GST_DEBUG (GST_CAT_CAPS, "ref %p (%d->%d) %d",
caps, caps->refcount, caps->refcount+1, GST_CAPS_FLAGS (caps));
caps->refcount++;
@ -307,7 +335,7 @@ gst_caps_sink (GstCaps *caps)
*
* Copies the caps, not copying any chained caps.
*
* Returns: a copy of the GstCaps structure.
* Returns: a floating copy of the GstCaps structure.
*/
GstCaps*
gst_caps_copy_1 (GstCaps *caps)
@ -331,7 +359,7 @@ gst_caps_copy_1 (GstCaps *caps)
*
* Copies the caps.
*
* Returns: a copy of the GstCaps structure.
* Returns: a floating copy of the GstCaps structure.
*/
GstCaps*
gst_caps_copy (GstCaps *caps)
@ -362,7 +390,7 @@ gst_caps_copy (GstCaps *caps)
* Copies the caps if the refcount is greater than 1
*
* Returns: a pointer to a GstCaps strcuture that can
* be safely written to
* be safely written to.
*/
GstCaps*
gst_caps_copy_on_write (GstCaps *caps)
@ -410,9 +438,7 @@ gst_caps_set_name (GstCaps *caps, const gchar *name)
{
g_return_if_fail (caps != NULL);
if (caps->name)
g_free (caps->name);
g_free (caps->name);
caps->name = g_strdup (name);
}
@ -499,10 +525,13 @@ GstCaps*
gst_caps_set_props (GstCaps *caps, GstProps *props)
{
g_return_val_if_fail (caps != NULL, caps);
g_return_val_if_fail (props != NULL, caps);
g_return_val_if_fail (caps->properties == NULL, caps);
caps->properties = props;
gst_props_replace_sink (&caps->properties, props);
if (props && !GST_PROPS_IS_FIXED (props))
GST_CAPS_FLAG_UNSET (caps, GST_CAPS_FIXED);
else
GST_CAPS_FLAG_SET (caps, GST_CAPS_FIXED);
return caps;
}
@ -590,7 +619,7 @@ gst_caps_append (GstCaps *caps, GstCaps *capstoadd)
while (caps->next) {
caps = caps->next;
}
caps->next = capstoadd;
gst_caps_replace_sink (&caps->next, capstoadd);
return orig;
}
@ -617,7 +646,7 @@ gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd)
while (capstoadd->next) {
capstoadd = capstoadd->next;
}
capstoadd->next = caps;
gst_caps_replace_sink (&capstoadd->next, caps);
return orig;
}
@ -746,6 +775,8 @@ gst_caps_intersect_func (GstCaps *caps1, GstCaps *caps2)
props = gst_props_intersect (caps1->properties, caps2->properties);
if (props) {
result = gst_caps_new_id ("intersect", caps1->id, props);
gst_caps_ref (result);
gst_caps_sink (result);
}
return result;
@ -759,7 +790,7 @@ gst_caps_intersect_func (GstCaps *caps1, GstCaps *caps2)
* Make the intersection between two caps.
*
* Returns: The intersection of the two caps or NULL if the intersection
* is empty.
* is empty. unref the caps after use.
*/
GstCaps*
gst_caps_intersect (GstCaps *caps1, GstCaps *caps2)
@ -771,11 +802,16 @@ gst_caps_intersect (GstCaps *caps1, GstCaps *caps2)
if (caps1 == NULL) {
GST_DEBUG (GST_CAT_CAPS, "first caps is NULL, return other caps");
return gst_caps_copy (caps2);
return gst_caps_ref (caps2);
}
if (caps2 == NULL) {
GST_DEBUG (GST_CAT_CAPS, "second caps is NULL, return other caps");
return gst_caps_copy (caps1);
return gst_caps_ref (caps1);
}
/* same caps */
if (caps1 == caps2) {
return gst_caps_ref (caps1);
}
while (caps1) {
@ -796,7 +832,27 @@ gst_caps_intersect (GstCaps *caps1, GstCaps *caps2)
}
othercaps = othercaps->next;
}
caps1 = caps1->next;
caps1 = caps1->next;
}
return result;
}
GstCaps*
gst_caps_union (GstCaps *caps1, GstCaps *caps2)
{
GstCaps *result = NULL;
/* printing the name is not useful here since caps can be chained */
GST_DEBUG (GST_CAT_CAPS, "making union of caps %p and %p", caps1, caps2);
if (caps1 == NULL) {
GST_DEBUG (GST_CAT_CAPS, "first caps is NULL, return other caps");
return gst_caps_ref (caps2);
}
if (caps2 == NULL) {
GST_DEBUG (GST_CAT_CAPS, "second caps is NULL, return other caps");
return gst_caps_ref (caps1);
}
return result;
@ -809,43 +865,40 @@ gst_caps_intersect (GstCaps *caps1, GstCaps *caps2)
* Make the normalisation of the caps. This will return a new caps
* that is equivalent to the input caps with the exception that all
* lists are unrolled. This function is useful when you want to iterate
* the caps.
* the caps. unref the caps after use.
*
* Returns: The normalisation of the caps.
* Returns: The normalisation of the caps. Unref after usage.
*/
GstCaps*
gst_caps_normalize (GstCaps *caps)
{
GstCaps *result = NULL, *walk = caps;
GstCaps *result = NULL, *walk;
if (caps == NULL)
return caps;
GST_DEBUG (GST_CAT_CAPS, "normalizing caps %p ", caps);
walk = caps;
while (caps) {
GList *proplist;
proplist = gst_props_normalize (caps->properties);
if (proplist && g_list_next (proplist) == NULL) {
if (result == NULL)
walk = result = caps;
else {
walk = walk->next = caps;
}
goto next;
}
while (proplist) {
GstProps *props = (GstProps *) proplist->data;
GstCaps *newcaps = gst_caps_new_id (caps->name, caps->id, props);
gst_caps_ref (newcaps);
gst_caps_sink (newcaps);
if (result == NULL)
walk = result = newcaps;
else {
walk = walk->next = newcaps;
walk = walk->next = newcaps;
}
proplist = g_list_next (proplist);
}
next:
caps = caps->next;
}
return result;
@ -905,9 +958,7 @@ gst_caps_load_thyself (xmlNodePtr parent)
gchar *content;
GstCapsFlags fixed = GST_CAPS_FIXED;
g_mutex_lock (_gst_caps_chunk_lock);
caps = g_mem_chunk_alloc0 (_gst_caps_chunk);
g_mutex_unlock (_gst_caps_chunk_lock);
caps = gst_mem_chunk_alloc0 (_gst_caps_chunk);
caps->refcount = 1;
GST_CAPS_FLAG_SET (caps, GST_CAPS_FLOATING);
@ -923,7 +974,12 @@ gst_caps_load_thyself (xmlNodePtr parent)
g_free (content);
}
else if (!strcmp (subfield->name, "properties")) {
caps->properties = gst_props_load_thyself (subfield);
GstProps *props = gst_props_load_thyself (subfield);
gst_props_ref (props);
gst_props_sink (props);
caps->properties = props;
fixed &= (GST_PROPS_IS_FIXED (caps->properties) ? GST_CAPS_FIXED : 0 );
}

View file

@ -1362,7 +1362,7 @@ gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
if (templcaps == NULL)
return NULL;
} else {
templcaps = gst_caps_copy (gst_pad_get_caps (pad));
templcaps = gst_pad_get_caps (pad);
}
templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
@ -2238,9 +2238,8 @@ gst_element_clear_pad_caps (GstElement *element)
while (pads) {
GstRealPad *pad = GST_PAD_REALIZE (pads->data);
if (GST_PAD_CAPS (pad)) {
GST_PAD_CAPS (pad) = NULL;
}
gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
pads = g_list_next (pads);
}
}
@ -2639,16 +2638,28 @@ void
gst_element_set_loop_function (GstElement *element,
GstElementLoopFunction loop)
{
gboolean need_notify = FALSE;
g_return_if_fail (GST_IS_ELEMENT (element));
/* if the element changed from loop based to chain/get based
* or vice versa, we need to inform the scheduler about that */
if ((element->loopfunc == NULL && loop != NULL) ||
(element->loopfunc != NULL && loop == NULL))
{
need_notify = TRUE;
}
/* set the loop function */
element->loopfunc = loop;
/* set the NEW_LOOPFUNC flag so everyone knows to go try again */
GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
if (need_notify) {
/* set the NEW_LOOPFUNC flag so everyone knows to go try again */
GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC);
if (GST_ELEMENT_SCHED (element)) {
gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
if (GST_ELEMENT_SCHED (element)) {
gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element);
}
}
}

View file

@ -861,9 +861,8 @@ gst_pad_unlink (GstPad *srcpad,
/* reset the filters, both filters are refcounted once */
if (GST_RPAD_FILTER (realsrc)) {
gst_caps_unref (GST_RPAD_FILTER (realsrc));
GST_RPAD_FILTER (realsink) = NULL;
GST_RPAD_FILTER (realsrc) = NULL;
gst_caps_replace (&GST_RPAD_FILTER (realsink), NULL);
gst_caps_replace (&GST_RPAD_FILTER (realsrc), NULL);
}
/* now tell the scheduler */
@ -1084,11 +1083,14 @@ gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
gst_scheduler_pad_link (src_sched,
GST_PAD_CAST (realsrc), GST_PAD_CAST (realsink));
}
else {
GST_INFO (GST_CAT_PADS, "not telling link to scheduler %s:%s and %s:%s, %p %p",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
src_sched, sink_sched);
}
GST_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
gst_caps_debug (gst_pad_get_caps (GST_PAD_CAST (realsrc)),
"caps of newly linked src pad");
return TRUE;
}
@ -1310,7 +1312,7 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
caps, GST_DEBUG_PAD_NAME (pad));
/* first see if we have to check against a filter */
if (!(allowed = GST_RPAD_FILTER (pad))) {
if (!(allowed = gst_caps_ref (GST_RPAD_FILTER (pad)))) {
/* no filter, make sure we check against the padtemplate then */
if ((template = gst_pad_get_pad_template (GST_PAD_CAST (pad)))) {
allowed = gst_pad_template_get_caps (template);
@ -1331,10 +1333,12 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
gst_caps_debug (caps, "caps themselves (attemped to set)");
gst_caps_debug (allowed,
"allowed caps that did not agree with caps");
gst_caps_unref (allowed);
return GST_PAD_LINK_REFUSED;
}
/* caps checks out fine, we can unref the intersection now */
gst_caps_unref (intersection);
gst_caps_unref (allowed);
/* given that the caps are fixed, we know that their intersection with the
* padtemplate caps is the same as caps itself */
}
@ -1402,10 +1406,7 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
GST_INFO (GST_CAT_CAPS, "setting caps on pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
/* if we got this far all is ok, remove the old caps, set the new one */
oldcaps = GST_PAD_CAPS (pad);
if (caps) gst_caps_ref (caps);
GST_PAD_CAPS (pad) = caps;
if (oldcaps) gst_caps_unref (oldcaps);
gst_caps_replace_sink (&GST_PAD_CAPS (pad), caps);
g_object_notify (G_OBJECT (pad), "caps");
}
@ -1441,6 +1442,10 @@ gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
gst_caps_debug (caps, "caps that we are trying to set");
/* try to take ownership */
gst_caps_ref (caps);
gst_caps_sink (caps);
/* setting non fixed caps on a pad is not allowed */
if (!GST_CAPS_IS_FIXED (caps)) {
GST_INFO (GST_CAT_CAPS,
@ -1449,7 +1454,8 @@ gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
GST_DEBUG_PAD_NAME (realpad));
gst_caps_debug (caps, "unfixed caps");
return GST_PAD_LINK_DELAYED;
set_retval = GST_PAD_LINK_DELAYED;
goto done;
}
/* if we have a peer try to set the caps, notifying the peerpad
@ -1458,7 +1464,7 @@ gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
{
GST_INFO (GST_CAT_CAPS, "tried to set caps on peerpad %s:%s but couldn't, return value %d",
GST_DEBUG_PAD_NAME (peer), set_retval);
return set_retval;
goto done;
}
/* then try to set our own caps, we don't need to be notified */
@ -1466,11 +1472,14 @@ gst_pad_try_set_caps (GstPad *pad, GstCaps *caps)
{
GST_INFO (GST_CAT_CAPS, "tried to set own caps on pad %s:%s but couldn't, return value %d",
GST_DEBUG_PAD_NAME (realpad), set_retval);
return set_retval;
goto done;
}
GST_INFO (GST_CAT_CAPS, "succeeded setting caps %p on pad %s:%s, return value %d",
caps, GST_DEBUG_PAD_NAME (realpad), set_retval);
g_assert (GST_PAD_CAPS (pad));
done:
gst_caps_unref (caps);
return set_retval;
}
@ -1504,8 +1513,11 @@ gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
"start relink filtered %s:%s and %s:%s, clearing caps",
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
GST_PAD_CAPS (GST_PAD (realsrc)) = NULL;
GST_PAD_CAPS (GST_PAD (realsink)) = NULL;
/* FIXME does this leak? */
gst_caps_replace (&GST_PAD_CAPS (GST_PAD (realsrc)), NULL);
gst_caps_replace (&GST_PAD_CAPS (GST_PAD (realsink)), NULL);
gst_caps_replace (&GST_RPAD_FILTER (realsrc), NULL);
gst_caps_replace (&GST_RPAD_FILTER (realsink), NULL);
}
else {
GST_INFO (GST_CAT_PADS, "start relink filtered %s:%s and %s:%s",
@ -1531,6 +1543,9 @@ gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
* this means they have no common format */
GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s have no common type",
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
/* make sure any floating caps from gst_pad_get_caps are freed here */
gst_caps_sink (srccaps);
gst_caps_sink (sinkcaps);
return FALSE;
} else {
GST_INFO (GST_CAT_PADS, "pads %s:%s and %s:%s intersected to %s caps",
@ -1539,10 +1554,16 @@ gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
(GST_CAPS_IS_FIXED (intersection) ? "fixed" : "variable") :
"NULL"));
/* we don't need those anymore, as the caps can be floating */
gst_caps_sink (srccaps);
gst_caps_sink (sinkcaps);
/* then filter this against the app filter */
if (filtercaps) {
GstCaps *filtered_intersection = gst_caps_intersect (intersection,
filtercaps);
GstCaps *filtered_intersection;
filtered_intersection = gst_caps_intersect (intersection,
filtercaps);
/* get rid of the old intersection here */
gst_caps_unref (intersection);
@ -1556,8 +1577,8 @@ gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
intersection = filtered_intersection;
/* keep a reference to the app caps */
GST_RPAD_APPFILTER (realsink) = filtercaps;
GST_RPAD_APPFILTER (realsrc) = filtercaps;
gst_caps_replace_sink (&GST_RPAD_APPFILTER (realsink), filtercaps);
gst_caps_replace_sink (&GST_RPAD_APPFILTER (realsrc), filtercaps);
}
}
GST_DEBUG (GST_CAT_CAPS, "setting filter for link to:");
@ -1565,8 +1586,9 @@ gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
/* both the app filter and the filter, while stored on both peer pads,
* are equal to the same thing on both */
GST_RPAD_FILTER (realsrc) = intersection;
GST_RPAD_FILTER (realsink) = intersection;
gst_caps_replace_sink (&GST_RPAD_FILTER (realsrc), intersection);
gst_caps_replace_sink (&GST_RPAD_FILTER (realsink), intersection);
gst_caps_unref (intersection);
return gst_pad_perform_negotiate (GST_PAD (realsrc), GST_PAD (realsink));
}
@ -1586,6 +1608,8 @@ gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
GstCaps *intersection, *filtered_intersection;
GstRealPad *realsrc, *realsink;
GstCaps *srccaps, *sinkcaps, *filter;
gboolean res = TRUE;
GstElement *parent;
g_return_val_if_fail (srcpad != NULL, FALSE);
g_return_val_if_fail (sinkpad != NULL, FALSE);
@ -1596,6 +1620,24 @@ gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
g_return_val_if_fail (GST_RPAD_PEER (realsrc) != NULL, FALSE);
g_return_val_if_fail (GST_RPAD_PEER (realsink) == realsrc, FALSE);
/* shortcut negotiation */
parent = GST_PAD_PARENT (realsrc);
if (parent && GST_STATE (parent) < GST_STATE_READY) {
GST_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not READY",
GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (realsrc));
return TRUE;
}
parent = GST_PAD_PARENT (realsink);
if (parent && GST_STATE (parent) < GST_STATE_READY) {
GST_DEBUG (GST_CAT_CAPS, "parent %s of pad %s:%s is not READY",
GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (realsink));
return TRUE;
}
GST_INFO (GST_CAT_PADS, "perform negotiate for link %s:%s-%s:%s",
GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
filter = GST_RPAD_APPFILTER (realsrc);
if (filter) {
GST_INFO (GST_CAT_PADS, "dumping filter for link %s:%s-%s:%s",
@ -1616,28 +1658,39 @@ gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad)
"sink caps, awaiting negotiation, after applying filter");
intersection = gst_caps_intersect (srccaps, sinkcaps);
filtered_intersection = gst_caps_intersect (intersection, filter);
if (filtered_intersection) {
gst_caps_unref (intersection);
intersection = filtered_intersection;
}
gst_caps_unref (intersection);
/* no negotiation is performed if the pads have filtercaps */
if (intersection) {
GstPadLinkReturn res;
if (filtered_intersection) {
GstPadLinkReturn link_res;
res = gst_pad_try_set_caps_func (realsrc, intersection, TRUE);
if (res == GST_PAD_LINK_REFUSED)
return FALSE;
if (res == GST_PAD_LINK_DONE)
return TRUE;
link_res = gst_pad_try_set_caps_func (realsrc, filtered_intersection, TRUE);
if (link_res == GST_PAD_LINK_REFUSED)
goto error;
if (link_res == GST_PAD_LINK_DONE)
goto success;
res = gst_pad_try_set_caps_func (realsink, intersection, TRUE);
if (res == GST_PAD_LINK_REFUSED)
return FALSE;
if (res == GST_PAD_LINK_DONE)
return TRUE;
link_res = gst_pad_try_set_caps_func (realsink, filtered_intersection, TRUE);
if (link_res == GST_PAD_LINK_REFUSED)
goto error;
if (link_res == GST_PAD_LINK_DONE)
goto success;
}
return TRUE;
/* no filtered_intersection, some pads had caps and ther was a filter */
else if ((srccaps || sinkcaps) && filter) {
goto error;
}
success:
cleanup:
gst_caps_sink (srccaps);
gst_caps_sink (sinkcaps);
gst_caps_unref (filtered_intersection);
return res;
error:
res = FALSE;
goto cleanup;
}
/**
@ -1731,6 +1784,16 @@ gst_pad_proxy_link (GstPad *pad, GstCaps *caps)
if (gst_pad_try_set_caps_func (realpad, caps, FALSE) < 0)
return GST_PAD_LINK_REFUSED;
if (peer) {
gst_caps_debug (caps, "proxy link filter");
GST_INFO (GST_CAT_CAPS, "setting filter on %s:%s and %s:%s",
GST_DEBUG_PAD_NAME (peer), GST_DEBUG_PAD_NAME (realpad));
gst_caps_replace_sink (&GST_RPAD_FILTER (peer), caps);
gst_caps_replace_sink (&GST_RPAD_FILTER (realpad), caps);
}
return GST_PAD_LINK_OK;
}
@ -1740,7 +1803,9 @@ gst_pad_proxy_link (GstPad *pad, GstCaps *caps)
*
* Gets the capabilities of this pad.
*
* Returns: the #GstCaps of this pad.
* Returns: the #GstCaps of this pad. This function potentially
* returns a floating caps, so use gst_caps_sink to get rid of
* it.
*/
GstCaps*
gst_pad_get_caps (GstPad *pad)
@ -1780,7 +1845,8 @@ gst_pad_get_caps (GstPad *pad)
*
* Gets the template capabilities of this pad.
*
* Returns: the template #GstCaps of this pad.
* Returns: the template #GstCaps of this pad. unref the caps
* if you no longer need it.
*/
GstCaps*
gst_pad_get_pad_template_caps (GstPad *pad)
@ -1789,7 +1855,7 @@ gst_pad_get_pad_template_caps (GstPad *pad)
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
if (GST_PAD_PAD_TEMPLATE (pad))
return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
return gst_caps_ref (GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad)));
return NULL;
}
@ -1801,7 +1867,8 @@ gst_pad_get_pad_template_caps (GstPad *pad)
*
* Gets the capability with the given name from this pad template.
*
* Returns: the #GstCaps, or NULL if not found or in case of an error.
* Returns: the #GstCaps, or NULL if not found or in case of an error. unref the caps
* if you no longer need it.
*/
GstCaps*
gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
@ -1814,7 +1881,7 @@ gst_pad_template_get_caps_by_name (GstPadTemplate *templ, const gchar *name)
if (!caps)
return NULL;
return gst_caps_get_by_name (caps, name);
return gst_caps_ref (gst_caps_get_by_name (caps, name));
}
/**
@ -1877,7 +1944,8 @@ gst_pad_get_peer (GstPad *pad)
* Gets the capabilities of the allowed media types that can
* flow through this pad. The caller must free the resulting caps.
*
* Returns: a newly allocated copy of the allowed #GstCaps.
* Returns: a newly allocated copy of the allowed #GstCaps. unref the caps if
* you no longer need it.
*/
GstCaps*
gst_pad_get_allowed_caps (GstPad *pad)
@ -1890,7 +1958,7 @@ gst_pad_get_allowed_caps (GstPad *pad)
GST_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s",
GST_DEBUG_PAD_NAME (pad));
caps = gst_caps_copy (GST_RPAD_FILTER (pad));
caps = gst_caps_ref (GST_RPAD_FILTER (pad));
return caps;
}
@ -1919,7 +1987,7 @@ gst_pad_recalc_allowed_caps (GstPad *pad)
peer = GST_RPAD_PEER (pad);
if (peer)
return gst_pad_try_relink_filtered (pad, GST_PAD (peer),
GST_RPAD_APPFILTER (pad));
GST_RPAD_APPFILTER (pad));
return TRUE;
}
@ -2002,6 +2070,9 @@ gst_real_pad_dispose (GObject *object)
g_list_free (GST_REAL_PAD(pad)->ghostpads);
}
gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
gst_caps_replace (&GST_RPAD_APPFILTER (pad), NULL);
if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
GST_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
@ -2329,6 +2400,7 @@ gst_pad_selectv (GstPad *pad, ...)
*/
static void gst_pad_template_class_init (GstPadTemplateClass *klass);
static void gst_pad_template_init (GstPadTemplate *templ);
static void gst_pad_template_dispose (GObject *object);
GType
gst_pad_template_get_type (void)
@ -2366,6 +2438,8 @@ gst_pad_template_class_init (GstPadTemplateClass *klass)
NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gobject_class->dispose = gst_pad_template_dispose;
gstobject_class->path_string_separator = "*";
}
@ -2374,6 +2448,17 @@ gst_pad_template_init (GstPadTemplate *templ)
{
}
static void
gst_pad_template_dispose (GObject *object)
{
GstPadTemplate *templ = GST_PAD_TEMPLATE (object);
g_free (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
gst_caps_unref (GST_PAD_TEMPLATE_CAPS (templ));
G_OBJECT_CLASS (padtemplate_parent_class)->dispose (object);
}
/* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
* sense.
* SOMETIMES padtemplates can do whatever they want, they are provided by the
@ -2454,13 +2539,17 @@ gst_pad_template_new (const gchar *name_template,
GST_FLAG_SET (GST_OBJECT (new), GST_PAD_TEMPLATE_FIXED);
while (caps) {
GST_FLAGS (GST_OBJECT (new)) &= (GST_CAPS_IS_FIXED (caps) ? GST_PAD_TEMPLATE_FIXED : 0);
thecaps = gst_caps_append (thecaps, gst_caps_ref (caps));
if (!GST_CAPS_IS_FIXED (caps)) {
GST_FLAG_UNSET (GST_OBJECT (new), GST_PAD_TEMPLATE_FIXED);
}
thecaps = gst_caps_append (thecaps, caps);
caps = va_arg (var_args, GstCaps*);
}
va_end (var_args);
GST_PAD_TEMPLATE_CAPS (new) = thecaps;
gst_caps_ref (thecaps);
gst_caps_sink (thecaps);
return new;
}
@ -2478,7 +2567,7 @@ gst_pad_template_get_caps (GstPadTemplate *templ)
{
g_return_val_if_fail (templ != NULL, NULL);
return GST_PAD_TEMPLATE_CAPS (templ);
return gst_caps_ref (GST_PAD_TEMPLATE_CAPS (templ));
}
/**

File diff suppressed because it is too large Load diff

View file

@ -194,11 +194,14 @@ gst_queue_getcaps (GstPad *pad, GstCaps *caps)
GstPad *otherpad;
if (pad == queue->srcpad)
otherpad = queue->sinkpad;
otherpad = GST_PAD_PEER (queue->sinkpad);
else
otherpad = queue->srcpad;
otherpad = GST_PAD_PEER (queue->srcpad);
return gst_pad_get_allowed_caps (otherpad);
if (otherpad)
return gst_pad_get_caps (otherpad);
return NULL;
}
static void

View file

@ -194,11 +194,14 @@ gst_queue_getcaps (GstPad *pad, GstCaps *caps)
GstPad *otherpad;
if (pad == queue->srcpad)
otherpad = queue->sinkpad;
otherpad = GST_PAD_PEER (queue->sinkpad);
else
otherpad = queue->srcpad;
otherpad = GST_PAD_PEER (queue->srcpad);
return gst_pad_get_allowed_caps (otherpad);
if (otherpad)
return gst_pad_get_caps (otherpad);
return NULL;
}
static void