mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
pad: improve the getcaps function
Refactor calling the GETCAPS function and checks. Move the filter code in one place. When using fixed pad caps, get the currently configured caps and then fallback to the GETCAPS function. We used to simply ignore the GETCAPS function, which resulted in transform elements returning the template caps instead of doing the caps transform.
This commit is contained in:
parent
cea4b4c7d5
commit
5e330fa456
1 changed files with 106 additions and 107 deletions
135
gst/gstpad.c
135
gst/gstpad.c
|
@ -2195,20 +2195,14 @@ gst_pad_get_pad_template (GstPad * pad)
|
|||
return (templ ? gst_object_ref (templ) : NULL);
|
||||
}
|
||||
|
||||
/* 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, GstCaps * filter)
|
||||
caps_with_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
GstPadTemplate *templ;
|
||||
gboolean fixed_caps;
|
||||
GstCaps *result;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
|
||||
if (GST_PAD_GETCAPSFUNC (pad) == NULL)
|
||||
return NULL;
|
||||
|
||||
fixed_caps = GST_PAD_IS_FIXED_CAPS (pad);
|
||||
|
||||
if (!fixed_caps && GST_PAD_GETCAPSFUNC (pad)) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"dispatching to pad getcaps function with "
|
||||
"filter %" GST_PTR_FORMAT, filter);
|
||||
|
@ -2219,12 +2213,12 @@ gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter)
|
|||
GST_OBJECT_LOCK (pad);
|
||||
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
|
||||
|
||||
if (result == NULL) {
|
||||
g_critical ("pad %s:%s returned NULL caps from getcaps function",
|
||||
GST_DEBUG_PAD_NAME (pad));
|
||||
} else {
|
||||
if (G_UNLIKELY (result == NULL))
|
||||
goto null_caps;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"pad getcaps returned %" GST_PTR_FORMAT, result);
|
||||
|
||||
#ifndef G_DISABLE_ASSERT
|
||||
/* check that the returned caps are a real subset of the template caps */
|
||||
if (GST_PAD_PAD_TEMPLATE (pad)) {
|
||||
|
@ -2256,76 +2250,81 @@ gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * 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);
|
||||
temp = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (result);
|
||||
result = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
||||
/* ERRORS */
|
||||
null_caps:
|
||||
{
|
||||
g_critical ("pad %s:%s returned NULL caps from getcaps function",
|
||||
GST_DEBUG_PAD_NAME (pad));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
GstPadTemplate *templ;
|
||||
gboolean fixed_caps;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
|
||||
|
||||
fixed_caps = GST_PAD_IS_FIXED_CAPS (pad);
|
||||
|
||||
if (fixed_caps) {
|
||||
/* fixed caps, try the negotiated caps first */
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "fixed pad caps: trying pad caps");
|
||||
if ((result = get_pad_caps (pad)))
|
||||
goto filter_done;
|
||||
}
|
||||
|
||||
/* try the getcaps function next */
|
||||
if ((result = caps_with_getcaps (pad, filter)))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (fixed_caps && (result = get_pad_caps (pad))) {
|
||||
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);
|
||||
|
||||
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);
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "trying pad template caps");
|
||||
if ((result = GST_PAD_TEMPLATE_CAPS (templ)))
|
||||
goto filter_done;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
if (!fixed_caps && (result = get_pad_caps (pad))) {
|
||||
if (filter) {
|
||||
if (!fixed_caps) {
|
||||
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;
|
||||
"non-fixed pad caps: trying pad caps");
|
||||
/* non fixed caps, try the negotiated caps */
|
||||
if ((result = get_pad_caps (pad)))
|
||||
goto filter_done;
|
||||
}
|
||||
|
||||
/* this almost never happens */
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad has no caps");
|
||||
result = gst_caps_new_empty ();
|
||||
goto done;
|
||||
|
||||
filter_done:
|
||||
/* run the filter on the result */
|
||||
if (filter) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using 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 caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
}
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue