diff options
author | Thiago Santos <thiagoss@osg.samsung.com> | 2016-01-14 12:34:21 -0300 |
---|---|---|
committer | Thiago Santos <thiagoss@osg.samsung.com> | 2016-01-14 12:35:28 -0300 |
commit | bc3b29706e5181d0b58277dc2e1f02fd1f201f84 (patch) | |
tree | abf864d5baf568e23d719ab3ec0ce153a3a8e7f9 | |
parent | 98dec6d3ddfa58177a128163427590941a987c5e (diff) |
pad: implement a default recursive-accept-caps handler
The handler will act similar to the default accept-caps one.
If it is a proxy pad, will proxy the query and, if accepted, then compare
with the pad template. Otherwise does a caps query and uses
gst_caps_is_subset() to check if the caps would be acceptable.
is_subset() is always used in this case because it is more restrictive
than an intersect, even if a pad is marked with ACCEPT_INTERSECT flag
it might be that one of the downstream pads aren't intersect and would
use is_subset() so always default to subset checks when a downstream
query was made.
-rw-r--r-- | gst/gstpad.c | 57 | ||||
-rw-r--r-- | gst/gstutils.c | 56 | ||||
-rw-r--r-- | gst/gstutils.h | 1 | ||||
-rw-r--r-- | win32/common/libgstreamer.def | 1 |
4 files changed, 115 insertions, 0 deletions
diff --git a/gst/gstpad.c b/gst/gstpad.c index f9822ea55..d14d3e867 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -3076,6 +3076,59 @@ done: return TRUE; } +/* Default recursive accept caps implementation just checks against + * the allowed caps for the pad */ +static gboolean +gst_pad_query_recursive_accept_caps_default (GstPad * pad, GstQuery * query) +{ + /* get the caps and see if it intersects to something not empty */ + GstCaps *caps, *allowed = NULL; + gboolean result; + gboolean allowed_is_template = FALSE; + + GST_DEBUG_OBJECT (pad, "query recursive-accept-caps %" GST_PTR_FORMAT, query); + + /* first forward the query to internally linked pads when we are dealing with + * a PROXY CAPS */ + if (GST_PAD_IS_PROXY_CAPS (pad)) { + result = gst_pad_proxy_query_recursive_accept_caps (pad, query); + if (result) { + allowed = gst_pad_get_pad_template_caps (pad); + allowed_is_template = TRUE; + } else + goto done; + } + + gst_query_parse_recursive_accept_caps (query, &caps); + if (!allowed) { + GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pad, + "fallback RECURSIVE_ACCEPT_CAPS query, consider implementing a specialized version"); + allowed = gst_pad_query_caps (pad, caps); + } + + if (allowed) { + if (allowed_is_template && GST_PAD_IS_ACCEPT_INTERSECT (pad)) { + GST_DEBUG_OBJECT (pad, + "allowed caps intersect %" GST_PTR_FORMAT ", caps %" GST_PTR_FORMAT, + allowed, caps); + result = gst_caps_can_intersect (caps, allowed); + } else { + GST_DEBUG_OBJECT (pad, "allowed caps subset %" GST_PTR_FORMAT ", caps %" + GST_PTR_FORMAT, allowed, caps); + result = gst_caps_is_subset (caps, allowed); + } + gst_caps_unref (allowed); + } else { + GST_DEBUG_OBJECT (pad, "no compatible caps allowed on the pad"); + result = FALSE; + } + gst_query_set_recursive_accept_caps_result (query, result); + +done: + return TRUE; +} + + /* Default caps implementation */ static gboolean gst_pad_query_caps_default (GstPad * pad, GstQuery * query) @@ -3320,6 +3373,10 @@ gst_pad_query_default (GstPad * pad, GstObject * parent, GstQuery * query) ret = gst_pad_query_caps_default (pad, query); forward = FALSE; break; + case GST_QUERY_RECURSIVE_ACCEPT_CAPS: + ret = gst_pad_query_recursive_accept_caps_default (pad, query); + forward = FALSE; + break; case GST_QUERY_LATENCY: ret = gst_pad_query_latency_default (pad, query); forward = FALSE; diff --git a/gst/gstutils.c b/gst/gstutils.c index 076de1ca6..43340e5e5 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -2543,6 +2543,62 @@ gst_pad_proxy_query_accept_caps (GstPad * pad, GstQuery * query) return data.ret; } +static gboolean +query_recursive_accept_caps_func (GstPad * pad, QueryAcceptCapsData * data) +{ + if (G_LIKELY (gst_pad_peer_query (pad, data->query))) { + gboolean result; + + gst_query_parse_recursive_accept_caps_result (data->query, &result); + data->ret &= result; + } + return FALSE; +} + +/** + * gst_pad_proxy_query_recursive_accept_caps: + * @pad: a #GstPad to proxy. + * @query: an RECURSIVE_ACCEPT_CAPS #GstQuery. + * + * Checks if all internally linked pads of @pad accepts the caps in @query and + * returns the intersection of the results. + * + * This function is useful as a default recursive accept caps query + * function for an element that can handle any stream format, + * but requires caps that are acceptable for all opposite pads. + * + * Returns: %TRUE if @query could be executed + * Since: 1.8 + */ +gboolean +gst_pad_proxy_query_recursive_accept_caps (GstPad * pad, GstQuery * query) +{ + QueryAcceptCapsData data; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (GST_IS_QUERY (query), FALSE); + g_return_val_if_fail (GST_QUERY_TYPE (query) == + GST_QUERY_RECURSIVE_ACCEPT_CAPS, FALSE); + + GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, + "proxying recursive accept caps query for %s:%s", + GST_DEBUG_PAD_NAME (pad)); + + data.query = query; + /* value to hold the return, by default it holds TRUE */ + /* FIXME: TRUE is wrong when there are no pads */ + data.ret = TRUE; + + gst_pad_forward (pad, + (GstPadForwardFunction) query_recursive_accept_caps_func, &data); + gst_query_set_recursive_accept_caps_result (query, data.ret); + + GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, + "proxying recursive accept caps query: %d", data.ret); + + return data.ret; +} + typedef struct { GstQuery *query; diff --git a/gst/gstutils.h b/gst/gstutils.h index 457a76a0f..a929d8458 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -915,6 +915,7 @@ GstElement* gst_pad_get_parent_element (GstPad *pad); /* util query functions */ gboolean gst_pad_proxy_query_accept_caps (GstPad *pad, GstQuery *query); +gboolean gst_pad_proxy_query_recursive_accept_caps (GstPad *pad, GstQuery *query); gboolean gst_pad_proxy_query_caps (GstPad *pad, GstQuery *query); gboolean gst_pad_query_position (GstPad *pad, GstFormat format, gint64 *cur); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 196b158e6..933f56960 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -880,6 +880,7 @@ EXPORTS gst_pad_probe_type_get_type gst_pad_proxy_query_accept_caps gst_pad_proxy_query_caps + gst_pad_proxy_query_recursive_accept_caps gst_pad_pull_range gst_pad_push gst_pad_push_event |