mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 16:18:16 +00:00
gst: Add a filter caps parameter to all get_caps() functions
This is used to pass the possible caps and preferences to the pad and to allow better negotiation decisions.
This commit is contained in:
parent
bdbc069348
commit
3fa1594aaf
6 changed files with 126 additions and 38 deletions
|
@ -84,6 +84,10 @@ The 0.11 porting guide
|
|||
Removed GST_PAD_CAPS() use gst_pad_get_current_caps() to get a handle to the
|
||||
currently configured caps.
|
||||
|
||||
GstPadGetCapsFunction, gst_pad_get_caps(), gst_pad_peer_get_caps(),
|
||||
gst_pad_proxy_getcaps() now takes a GstCaps* parameter to inform
|
||||
the other side about the possible caps and preferences.
|
||||
|
||||
* GstMiniObject
|
||||
A miniobject is now a simple refcounted structure holding the information
|
||||
common to buffers, events, messages, queries and caps.
|
||||
|
|
|
@ -188,7 +188,7 @@ gst_proxy_pad_do_checkgetrange (GstPad * pad)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_proxy_pad_do_getcaps (GstPad * pad)
|
||||
gst_proxy_pad_do_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstPad *target = gst_proxy_pad_get_target (pad);
|
||||
GstCaps *res;
|
||||
|
@ -196,7 +196,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 (target, filter);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
|
||||
GST_DEBUG_PAD_NAME (target), res);
|
||||
|
@ -209,7 +209,7 @@ gst_proxy_pad_do_getcaps (GstPad * pad)
|
|||
|
||||
filt = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
if (filt) {
|
||||
tmp = gst_caps_intersect (filt, res);
|
||||
tmp = gst_caps_intersect_full (res, filt, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (res);
|
||||
res = tmp;
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
|
@ -224,6 +224,15 @@ gst_proxy_pad_do_getcaps (GstPad * pad)
|
|||
"using pad template %p with caps %p %" GST_PTR_FORMAT, templ, res,
|
||||
res);
|
||||
res = gst_caps_ref (res);
|
||||
|
||||
if (filter) {
|
||||
GstCaps *intersection =
|
||||
gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
|
||||
|
||||
gst_caps_unref (res);
|
||||
res = intersection;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
114
gst/gstpad.c
114
gst/gstpad.c
|
@ -124,7 +124,7 @@ static void gst_pad_get_property (GObject * object, guint prop_id,
|
|||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstFlowReturn handle_pad_block (GstPad * pad);
|
||||
static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad);
|
||||
static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter);
|
||||
static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
|
||||
static gboolean gst_pad_activate_default (GstPad * pad);
|
||||
static gboolean gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps);
|
||||
|
@ -1796,8 +1796,8 @@ gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
|
|||
|
||||
/* Doing the expensive caps checking takes priority over only checking the template caps */
|
||||
if (flags & GST_PAD_LINK_CHECK_CAPS) {
|
||||
srccaps = gst_pad_get_caps_unlocked (src);
|
||||
sinkcaps = gst_pad_get_caps_unlocked (sink);
|
||||
srccaps = gst_pad_get_caps_unlocked (src, NULL);
|
||||
sinkcaps = gst_pad_get_caps_unlocked (sink, NULL);
|
||||
} else {
|
||||
/* If one of the two pads doesn't have a template, consider the intersection
|
||||
* as valid.*/
|
||||
|
@ -2188,7 +2188,7 @@ gst_pad_get_pad_template (GstPad * pad)
|
|||
/* should be called with the pad LOCK held */
|
||||
/* refs the caps, so caller is responsible for getting it unreffed */
|
||||
static GstCaps *
|
||||
gst_pad_get_caps_unlocked (GstPad * pad)
|
||||
gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
GstPadTemplate *templ;
|
||||
|
@ -2200,11 +2200,12 @@ gst_pad_get_caps_unlocked (GstPad * pad)
|
|||
|
||||
if (!fixed_caps && GST_PAD_GETCAPSFUNC (pad)) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"dispatching to pad getcaps function");
|
||||
"dispatching to pad getcaps function with "
|
||||
"filter %" GST_PTR_FORMAT, filter);
|
||||
|
||||
GST_OBJECT_FLAG_SET (pad, GST_PAD_IN_GETCAPS);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
result = GST_PAD_GETCAPSFUNC (pad) (pad);
|
||||
result = GST_PAD_GETCAPSFUNC (pad) (pad, filter);
|
||||
GST_OBJECT_LOCK (pad);
|
||||
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
|
||||
|
||||
|
@ -2234,29 +2235,80 @@ gst_pad_get_caps_unlocked (GstPad * pad)
|
|||
result = temp;
|
||||
}
|
||||
}
|
||||
if (filter) {
|
||||
if (!gst_caps_is_subset (result, filter)) {
|
||||
GstCaps *temp;
|
||||
|
||||
GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
|
||||
"pad returned caps %" GST_PTR_FORMAT
|
||||
" which are not a real subset of the filter caps %"
|
||||
GST_PTR_FORMAT, result, filter);
|
||||
g_warning ("pad %s:%s returned caps which are not a real "
|
||||
"subset of the filter caps", GST_DEBUG_PAD_NAME (pad));
|
||||
/* FIXME: Order? But shouldn't happen anyway... */
|
||||
temp =
|
||||
gst_caps_intersect_full (filter, result,
|
||||
GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (result);
|
||||
result = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (fixed_caps && (result = get_pad_caps (pad))) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
if (filter) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT " with filter %p %"
|
||||
GST_PTR_FORMAT, result, result, filter, filter);
|
||||
result =
|
||||
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
|
||||
result);
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
|
||||
result = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
|
||||
result);
|
||||
|
||||
result = gst_caps_ref (result);
|
||||
if (filter) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad template %p with caps %p %" GST_PTR_FORMAT
|
||||
" and filter %p %" GST_PTR_FORMAT, templ, result, result, filter,
|
||||
filter);
|
||||
result =
|
||||
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
|
||||
result);
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
|
||||
result);
|
||||
result = gst_caps_ref (result);
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
if (!fixed_caps && (result = get_pad_caps (pad))) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
if (filter) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT " with filter %p %"
|
||||
GST_PTR_FORMAT, result, result, filter, filter);
|
||||
result =
|
||||
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
|
||||
result);
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using pad caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2319,6 +2371,7 @@ gst_pad_get_current_caps (GstPad * pad)
|
|||
/**
|
||||
* gst_pad_get_caps:
|
||||
* @pad: a #GstPad to get the capabilities of.
|
||||
* @filter: suggested #GstCaps.
|
||||
*
|
||||
* Gets the capabilities this pad can produce or consume.
|
||||
* Note that this method doesn't necessarily return the caps set by
|
||||
|
@ -2327,23 +2380,30 @@ gst_pad_get_current_caps (GstPad * pad)
|
|||
* the pad's get_caps function;
|
||||
* this returns the pad template caps if not explicitly set.
|
||||
*
|
||||
* When called on sinkpads @filter contains the caps that
|
||||
* upstream could produce in the order preferred by upstream. When
|
||||
* called on srcpads @filter contains the caps accepted by
|
||||
* downstream in the preffered order. @filter might be %NULL but
|
||||
* if it is not %NULL the returned caps will be a subset of @filter.
|
||||
*
|
||||
* Note that this function does not return writable #GstCaps, use
|
||||
* gst_caps_make_writable() before modifying the caps.
|
||||
*
|
||||
* Returns: the caps of the pad with incremented ref-count.
|
||||
*/
|
||||
GstCaps *
|
||||
gst_pad_get_caps (GstPad * pad)
|
||||
gst_pad_get_caps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||
g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), NULL);
|
||||
|
||||
GST_OBJECT_LOCK (pad);
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
|
||||
|
||||
result = gst_pad_get_caps_unlocked (pad);
|
||||
result = gst_pad_get_caps_unlocked (pad, filter);
|
||||
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
|
@ -2354,20 +2414,28 @@ gst_pad_get_caps (GstPad * pad)
|
|||
/**
|
||||
* gst_pad_peer_get_caps:
|
||||
* @pad: a #GstPad to get the capabilities of.
|
||||
* @filter: a #GstCaps filter.
|
||||
*
|
||||
* Gets the capabilities of the peer connected to this pad. Similar to
|
||||
* gst_pad_get_caps().
|
||||
*
|
||||
* When called on srcpads @filter contains the caps that
|
||||
* upstream could produce in the order preferred by upstream. When
|
||||
* called on sinkpads @filter contains the caps accepted by
|
||||
* downstream in the preffered order. @filter might be %NULL but
|
||||
* if it is not %NULL the returned caps will be a subset of @filter.
|
||||
*
|
||||
* Returns: the caps of the peer pad with incremented ref-count. This function
|
||||
* returns %NULL when there is no peer pad.
|
||||
*/
|
||||
GstCaps *
|
||||
gst_pad_peer_get_caps (GstPad * pad)
|
||||
gst_pad_peer_get_caps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstPad *peerpad;
|
||||
GstCaps *result = NULL;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||
g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), NULL);
|
||||
|
||||
GST_OBJECT_LOCK (pad);
|
||||
|
||||
|
@ -2380,7 +2448,7 @@ gst_pad_peer_get_caps (GstPad * pad)
|
|||
gst_object_ref (peerpad);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
result = gst_pad_get_caps (peerpad);
|
||||
result = gst_pad_get_caps (peerpad, filter);
|
||||
|
||||
gst_object_unref (peerpad);
|
||||
|
||||
|
@ -2503,7 +2571,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 (pad, NULL);
|
||||
if (!allowed)
|
||||
goto nothing_allowed;
|
||||
|
||||
|
@ -2826,9 +2894,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 (pad, NULL);
|
||||
|
||||
peercaps = gst_pad_get_caps (peer);
|
||||
peercaps = gst_pad_get_caps (peer, NULL);
|
||||
gst_object_unref (peer);
|
||||
|
||||
caps = gst_caps_intersect (mycaps, peercaps);
|
||||
|
|
13
gst/gstpad.h
13
gst/gstpad.h
|
@ -420,6 +420,13 @@ typedef void (*GstPadUnlinkFunction) (GstPad *pad);
|
|||
/**
|
||||
* GstPadGetCapsFunction:
|
||||
* @pad: the #GstPad to get the capabilities of.
|
||||
* @filter: filter #GstCaps.
|
||||
*
|
||||
* When called on sinkpads @filter contains the caps that
|
||||
* upstream could produce in the order preferred by upstream. When
|
||||
* called on srcpads @filter contains the caps accepted by
|
||||
* downstream in the preffered order. @filter might be %NULL but if
|
||||
* it is not %NULL only a subset of @filter must be returned.
|
||||
*
|
||||
* Returns a copy of the capabilities of the specified pad. By default this
|
||||
* function will return the pad template capabilities, but can optionally
|
||||
|
@ -427,7 +434,7 @@ typedef void (*GstPadUnlinkFunction) (GstPad *pad);
|
|||
*
|
||||
* Returns: a newly allocated copy #GstCaps of the pad.
|
||||
*/
|
||||
typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad);
|
||||
typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad, GstCaps *filter);
|
||||
|
||||
/**
|
||||
* GstPadSetCapsFunction:
|
||||
|
@ -845,12 +852,12 @@ G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad);
|
|||
/* capsnego function for linked/unlinked pads */
|
||||
GstCaps * gst_pad_get_current_caps (GstPad * pad);
|
||||
gboolean gst_pad_has_current_caps (GstPad * pad);
|
||||
GstCaps * gst_pad_get_caps (GstPad * pad);
|
||||
GstCaps * gst_pad_get_caps (GstPad * pad, GstCaps *filter);
|
||||
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 (GstPad * pad);
|
||||
GstCaps * gst_pad_peer_get_caps (GstPad * pad, GstCaps *filter);
|
||||
gboolean gst_pad_peer_accept_caps (GstPad * pad, GstCaps *caps);
|
||||
|
||||
/* capsnego for linked pads */
|
||||
|
|
|
@ -1140,7 +1140,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
|
|||
gboolean compatible;
|
||||
|
||||
/* Now check if the two pads' caps are compatible */
|
||||
temp = gst_pad_get_caps (pad);
|
||||
temp = gst_pad_get_caps (pad, NULL);
|
||||
if (caps) {
|
||||
intersection = gst_caps_intersect (temp, caps);
|
||||
gst_caps_unref (temp);
|
||||
|
@ -1148,7 +1148,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
|
|||
intersection = temp;
|
||||
}
|
||||
|
||||
temp = gst_pad_get_caps (current);
|
||||
temp = gst_pad_get_caps (current, NULL);
|
||||
compatible = gst_caps_can_intersect (temp, intersection);
|
||||
gst_caps_unref (temp);
|
||||
gst_caps_unref (intersection);
|
||||
|
@ -1198,7 +1198,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
|
|||
/* try to create a new one */
|
||||
/* requesting is a little crazy, we need a template. Let's create one */
|
||||
/* FIXME: why not gst_pad_get_pad_template (pad); */
|
||||
templcaps = gst_pad_get_caps (pad);
|
||||
templcaps = gst_pad_get_caps (pad, NULL);
|
||||
|
||||
templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
|
||||
GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
|
||||
|
@ -2691,16 +2691,15 @@ gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
getcaps_fold_func (const GValue * vpad, GValue * ret, GstPad * orig)
|
||||
getcaps_fold_func (const GValue * vpad, GValue * ret, GstCaps * filter)
|
||||
{
|
||||
GstPad *pad = g_value_get_object (vpad);
|
||||
gboolean empty = FALSE;
|
||||
GstCaps *peercaps, *existing;
|
||||
|
||||
existing = g_value_get_pointer (ret);
|
||||
peercaps = gst_pad_peer_get_caps (pad);
|
||||
peercaps = gst_pad_peer_get_caps (pad, filter);
|
||||
if (G_LIKELY (peercaps)) {
|
||||
GstCaps *intersection = gst_caps_intersect (existing, peercaps);
|
||||
|
||||
|
@ -2716,6 +2715,7 @@ getcaps_fold_func (const GValue * vpad, GValue * ret, GstPad * orig)
|
|||
/**
|
||||
* gst_pad_proxy_getcaps:
|
||||
* @pad: a #GstPad to proxy.
|
||||
* @filter: a #GstCaps filter.
|
||||
*
|
||||
* Calls gst_pad_get_allowed_caps() for every other pad belonging to the
|
||||
* same element as @pad, and returns the intersection of the results.
|
||||
|
@ -2729,7 +2729,7 @@ getcaps_fold_func (const GValue * vpad, GValue * ret, GstPad * orig)
|
|||
* Returns: (transfer full): the intersection of the other pads' allowed caps.
|
||||
*/
|
||||
GstCaps *
|
||||
gst_pad_proxy_getcaps (GstPad * pad)
|
||||
gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstElement *element;
|
||||
GstCaps *caps, *intersected;
|
||||
|
@ -2760,7 +2760,7 @@ gst_pad_proxy_getcaps (GstPad * pad)
|
|||
while (1) {
|
||||
res =
|
||||
gst_iterator_fold (iter, (GstIteratorFoldFunction) getcaps_fold_func,
|
||||
&ret, pad);
|
||||
&ret, filter);
|
||||
switch (res) {
|
||||
case GST_ITERATOR_RESYNC:
|
||||
/* unref any value stored */
|
||||
|
|
|
@ -907,7 +907,7 @@ void gst_element_class_install_std_props (GstElementClass * klass,
|
|||
|
||||
/* pad functions */
|
||||
void gst_pad_use_fixed_caps (GstPad *pad);
|
||||
GstCaps* gst_pad_proxy_getcaps (GstPad * pad);
|
||||
GstCaps* gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter);
|
||||
gboolean gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps);
|
||||
|
||||
GstElement* gst_pad_get_parent_element (GstPad *pad);
|
||||
|
|
Loading…
Reference in a new issue