mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
pad: remove getcaps and use caps query
Remove the getcaps function on the pad and use the CAPS query for the same effect. Add PROXY_CAPS to the pad flags. This instructs the default caps event and query handlers to pass on the CAPS related queries and events. This simplifies a lot of elements that passtrough caps negotiation. Make two utility functions to proxy caps queries and aggregate the result. Needs to use the pad forward function instead later. Make the _query_peer_ utility functions use the gst_pad_peer_query() function to make sure the probes are emited properly.
This commit is contained in:
parent
d162d97e1f
commit
b5c3e254b1
29 changed files with 748 additions and 881 deletions
|
@ -1014,7 +1014,6 @@ gst_proxy_pad_iterate_internal_links_default
|
|||
gst_proxy_pad_chain_default
|
||||
gst_proxy_pad_chain_list_default
|
||||
gst_proxy_pad_getrange_default
|
||||
gst_proxy_pad_getcaps_default
|
||||
gst_proxy_pad_unlink_default
|
||||
<SUBSECTION Standard>
|
||||
GstGhostPadClass
|
||||
|
@ -1643,9 +1642,8 @@ GstPadUnlinkFunction
|
|||
|
||||
gst_pad_accept_caps
|
||||
|
||||
gst_pad_set_getcaps_function
|
||||
GstPadGetCapsFunction
|
||||
gst_pad_proxy_getcaps
|
||||
gst_pad_proxy_query_caps
|
||||
gst_pad_proxy_query_accept_caps
|
||||
|
||||
gst_pad_peer_accept_caps
|
||||
|
||||
|
|
|
@ -161,15 +161,14 @@ debug_dump_pad (GstPad * pad, const gchar * color_name,
|
|||
}
|
||||
}
|
||||
if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
|
||||
gchar pad_flags[5];
|
||||
gchar pad_flags[4];
|
||||
const gchar *activation_mode = "-><";
|
||||
|
||||
/* check if pad flags */
|
||||
pad_flags[0] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKED) ? 'B' : 'b';
|
||||
pad_flags[1] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING) ? 'F' : 'f';
|
||||
pad_flags[2] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS) ? 'G' : 'g';
|
||||
pad_flags[3] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING) ? 'B' : 'b';
|
||||
pad_flags[4] = '\0';
|
||||
pad_flags[2] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING) ? 'B' : 'b';
|
||||
pad_flags[3] = '\0';
|
||||
|
||||
fprintf (out,
|
||||
"%s %s_%s [color=black, fillcolor=\"%s\", label=\"%s\\n[%c][%s]\", height=\"0.2\", style=\"%s\"];\n",
|
||||
|
|
|
@ -1267,7 +1267,7 @@ gst_element_class_add_pad_template (GstElementClass * klass,
|
|||
}
|
||||
|
||||
/* Take ownership of the floating ref */
|
||||
g_object_ref_sink (templ);
|
||||
gst_object_ref_sink (templ);
|
||||
|
||||
klass->padtemplates = g_list_append (klass->padtemplates, templ);
|
||||
klass->numpadtemplates++;
|
||||
|
|
|
@ -92,6 +92,87 @@ gst_proxy_pad_event_default (GstPad * pad, GstEvent * event)
|
|||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_proxy_pad_query_caps (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res;
|
||||
GstPad *target;
|
||||
GstCaps *result;
|
||||
GstPadTemplate *templ;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
|
||||
|
||||
templ = GST_PAD_PAD_TEMPLATE (pad);
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
if (target) {
|
||||
/* if we have a real target, proxy the call */
|
||||
res = gst_pad_query (target, query);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
|
||||
GST_DEBUG_PAD_NAME (target), query);
|
||||
|
||||
gst_object_unref (target);
|
||||
|
||||
/* filter against the template */
|
||||
if (templ && res) {
|
||||
GstCaps *filt, *tmp;
|
||||
|
||||
filt = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
if (filt) {
|
||||
gst_query_parse_caps_result (query, &result);
|
||||
tmp = gst_caps_intersect_full (result, filt, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_query_set_caps_result (query, tmp);
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"filtered against template gives %" GST_PTR_FORMAT, tmp);
|
||||
gst_caps_unref (tmp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GstCaps *filter;
|
||||
|
||||
res = TRUE;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
|
||||
/* else, if we have a template, use its caps. */
|
||||
if (templ) {
|
||||
result = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
|
||||
result);
|
||||
|
||||
if (filter) {
|
||||
GstCaps *intersection;
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "intersect with filter");
|
||||
intersection =
|
||||
gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_query_set_caps_result (query, intersection);
|
||||
gst_caps_unref (intersection);
|
||||
} else {
|
||||
gst_query_set_caps_result (query, result);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If there's a filter, return that */
|
||||
if (filter != NULL) {
|
||||
GST_DEBUG_OBJECT (pad, "return filter");
|
||||
gst_query_set_caps_result (query, filter);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* last resort, any caps */
|
||||
GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
|
||||
result = gst_caps_new_any ();
|
||||
gst_query_set_caps_result (query, result);
|
||||
gst_caps_unref (result);
|
||||
}
|
||||
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_proxy_pad_query_default:
|
||||
* @pad: a #GstPad to invoke the default query on.
|
||||
|
@ -112,11 +193,11 @@ gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
|
|||
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
|
||||
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
{
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
if (target) {
|
||||
res = gst_pad_query (target, query);
|
||||
gst_object_unref (target);
|
||||
|
@ -128,8 +209,14 @@ gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
res = gst_proxy_pad_query_caps (pad, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
if (target) {
|
||||
res = gst_pad_query (target, query);
|
||||
gst_object_unref (target);
|
||||
|
@ -256,119 +343,6 @@ gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_proxy_pad_getcaps_default:
|
||||
* @pad: a #GstPad to get the capabilities of.
|
||||
* @filter: a #GstCaps filter.
|
||||
*
|
||||
* Invoke the default getcaps function of the proxy pad.
|
||||
*
|
||||
* Returns: (transfer full): the caps of the pad with incremented ref-count
|
||||
*
|
||||
* Since: 0.10.36
|
||||
*/
|
||||
GstCaps *
|
||||
gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstPad *target;
|
||||
GstCaps *res;
|
||||
GstPadTemplate *templ;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
|
||||
|
||||
templ = GST_PAD_PAD_TEMPLATE (pad);
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
if (target) {
|
||||
/* if we have a real target, proxy the call */
|
||||
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);
|
||||
|
||||
gst_object_unref (target);
|
||||
|
||||
/* filter against the template */
|
||||
if (templ && res) {
|
||||
GstCaps *filt, *tmp;
|
||||
|
||||
filt = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
if (filt) {
|
||||
tmp = gst_caps_intersect_full (res, filt, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (res);
|
||||
res = tmp;
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"filtered against template gives %" GST_PTR_FORMAT, res);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* else, if we have a template, use its caps. */
|
||||
if (templ) {
|
||||
res = GST_PAD_TEMPLATE_CAPS (templ);
|
||||
GST_DEBUG_OBJECT (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;
|
||||
}
|
||||
|
||||
/* If there's a filter, return that */
|
||||
if (filter != NULL) {
|
||||
res = gst_caps_ref (filter);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* last resort, any caps */
|
||||
GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
|
||||
res = gst_caps_new_any ();
|
||||
}
|
||||
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_proxy_pad_acceptcaps_default:
|
||||
* @pad: a #GstPad to check
|
||||
* @caps: a #GstCaps to check on the pad
|
||||
*
|
||||
* Invoke the default acceptcaps function of the proxy pad.
|
||||
*
|
||||
* Returns: TRUE if the pad can accept the caps.
|
||||
*
|
||||
* Since: 0.10.36
|
||||
*/
|
||||
gboolean
|
||||
gst_proxy_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstPad *target;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
|
||||
|
||||
target = gst_proxy_pad_get_target (pad);
|
||||
if (target) {
|
||||
res = gst_pad_accept_caps (target, caps);
|
||||
gst_object_unref (target);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "no target");
|
||||
/* We don't have a target, we return TRUE and we assume that any future
|
||||
* target will be able to deal with any configured caps. */
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstPad *
|
||||
gst_proxy_pad_get_target (GstPad * pad)
|
||||
{
|
||||
|
@ -437,8 +411,6 @@ gst_proxy_pad_class_init (GstProxyPadClass * klass)
|
|||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getcaps_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_acceptcaps_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
|
||||
|
@ -458,7 +430,6 @@ gst_proxy_pad_init (GstProxyPad * ppad)
|
|||
gst_pad_set_iterate_internal_links_function (pad,
|
||||
gst_proxy_pad_iterate_internal_links_default);
|
||||
|
||||
gst_pad_set_getcaps_function (pad, gst_proxy_pad_getcaps_default);
|
||||
gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,6 @@ GstIterator* gst_proxy_pad_iterate_internal_links_default (GstPad *pad);
|
|||
GstFlowReturn gst_proxy_pad_chain_default (GstPad *pad, GstBuffer *buffer);
|
||||
GstFlowReturn gst_proxy_pad_chain_list_default (GstPad *pad, GstBufferList *list);
|
||||
GstFlowReturn gst_proxy_pad_getrange_default (GstPad *pad, guint64 offset, guint size, GstBuffer **buffer);
|
||||
GstCaps* gst_proxy_pad_getcaps_default (GstPad *pad, GstCaps * filter);
|
||||
gboolean gst_proxy_pad_acceptcaps_default (GstPad *pad, GstCaps *caps);
|
||||
void gst_proxy_pad_unlink_default (GstPad * pad);
|
||||
|
||||
#define GST_TYPE_GHOST_PAD (gst_ghost_pad_get_type ())
|
||||
|
|
|
@ -748,7 +748,7 @@ gst_object_set_parent (GstObject * object, GstObject * parent)
|
|||
goto had_parent;
|
||||
|
||||
object->parent = parent;
|
||||
g_object_ref_sink (object);
|
||||
gst_object_ref_sink (object);
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
|
||||
/* FIXME, this does not work, the deep notify takes the lock from the parent
|
||||
|
|
380
gst/gstpad.c
380
gst/gstpad.c
|
@ -139,7 +139,6 @@ static void gst_pad_set_property (GObject * object, guint prop_id,
|
|||
static void gst_pad_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
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 GstFlowReturn gst_pad_chain_list_default (GstPad * pad,
|
||||
|
@ -1503,42 +1502,6 @@ gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
|
|||
GST_DEBUG_FUNCPTR_NAME (unlink));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pad_set_getcaps_function:
|
||||
* @pad: a #GstPad.
|
||||
* @getcaps: the #GstPadGetCapsFunction to set.
|
||||
*
|
||||
* Sets the given getcaps function for the pad. @getcaps should return the
|
||||
* allowable caps for a pad in the context of the element's state, its link to
|
||||
* other elements, and the devices or files it has opened. These caps must be a
|
||||
* subset of the pad template caps. In the NULL state with no links, @getcaps
|
||||
* should ideally return the same caps as the pad template. In rare
|
||||
* circumstances, an object property can affect the caps returned by @getcaps,
|
||||
* but this is discouraged.
|
||||
*
|
||||
* You do not need to call this function if @pad's allowed caps are always the
|
||||
* same as the pad template caps. This can only be true if the padtemplate
|
||||
* has fixed simple caps.
|
||||
*
|
||||
* For most filters, the caps returned by @getcaps is directly affected by the
|
||||
* allowed caps on other pads. For demuxers and decoders, the caps returned by
|
||||
* the srcpad's getcaps function is directly related to the stream data. Again,
|
||||
* @getcaps should return the most specific caps it reasonably can, since this
|
||||
* helps with autoplugging.
|
||||
*
|
||||
* Note that the return value from @getcaps is owned by the caller, so the
|
||||
* caller should unref the caps after usage.
|
||||
*/
|
||||
void
|
||||
gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
|
||||
{
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
|
||||
GST_PAD_GETCAPSFUNC (pad) = getcaps;
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getcapsfunc set to %s",
|
||||
GST_DEBUG_FUNCPTR_NAME (getcaps));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pad_unlink:
|
||||
* @srcpad: the source #GstPad to unlink.
|
||||
|
@ -1679,8 +1642,12 @@ 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, NULL);
|
||||
sinkcaps = gst_pad_get_caps_unlocked (sink, NULL);
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
srccaps = gst_pad_get_caps (src, NULL);
|
||||
GST_OBJECT_LOCK (src);
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
sinkcaps = gst_pad_get_caps (sink, NULL);
|
||||
GST_OBJECT_LOCK (sink);
|
||||
} else {
|
||||
/* If one of the two pads doesn't have a template, consider the intersection
|
||||
* as valid.*/
|
||||
|
@ -2087,140 +2054,6 @@ gst_pad_get_pad_template (GstPad * pad)
|
|||
return (templ ? gst_object_ref (templ) : NULL);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
caps_with_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result;
|
||||
|
||||
if (GST_PAD_GETCAPSFUNC (pad) == NULL)
|
||||
return NULL;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"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, filter);
|
||||
GST_OBJECT_LOCK (pad);
|
||||
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
|
||||
|
||||
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)) {
|
||||
const GstCaps *templ_caps =
|
||||
GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
|
||||
if (!gst_caps_is_subset (result, templ_caps)) {
|
||||
GstCaps *temp;
|
||||
|
||||
GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
|
||||
"pad returned caps %" GST_PTR_FORMAT
|
||||
" which are not a real subset of its template caps %"
|
||||
GST_PTR_FORMAT, result, templ_caps);
|
||||
g_warning
|
||||
("pad %s:%s returned caps which are not a real "
|
||||
"subset of its template caps", GST_DEBUG_PAD_NAME (pad));
|
||||
temp = gst_caps_intersect (templ_caps, result);
|
||||
gst_caps_unref (result);
|
||||
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
|
||||
|
||||
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 ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "trying pad template caps");
|
||||
if ((result = GST_PAD_TEMPLATE_CAPS (templ)))
|
||||
goto filter_done;
|
||||
}
|
||||
|
||||
if (!fixed_caps) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"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, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pad_has_current_caps:
|
||||
* @pad: a #GstPad to check
|
||||
|
@ -2282,8 +2115,8 @@ gst_pad_get_current_caps (GstPad * pad)
|
|||
* Note that this method doesn't necessarily return the caps set by
|
||||
* gst_pad_set_caps() - use gst_pad_get_current_caps() for that instead.
|
||||
* gst_pad_get_caps returns all possible caps a pad can operate with, using
|
||||
* the pad's get_caps function;
|
||||
* this returns the pad template caps if not explicitly set.
|
||||
* the pad's CAPS query function, If the query fails, this function will return
|
||||
* @filter, if not #NULL, otherwise ANY.
|
||||
*
|
||||
* When called on sinkpads @filter contains the caps that
|
||||
* upstream could produce in the order preferred by upstream. When
|
||||
|
@ -2300,17 +2133,24 @@ GstCaps *
|
|||
gst_pad_get_caps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
GstQuery *query;
|
||||
|
||||
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, filter);
|
||||
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
query = gst_query_new_caps (filter);
|
||||
if (gst_pad_query (pad, query)) {
|
||||
gst_query_parse_caps_result (query, &result);
|
||||
gst_caps_ref (result);
|
||||
GST_DEBUG_OBJECT (pad, "query returned %" GST_PTR_FORMAT, result);
|
||||
} else if (filter) {
|
||||
result = gst_caps_ref (filter);
|
||||
} else {
|
||||
result = gst_caps_new_any ();
|
||||
}
|
||||
gst_query_unref (query);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -2336,34 +2176,25 @@ gst_pad_get_caps (GstPad * pad, GstCaps * filter)
|
|||
GstCaps *
|
||||
gst_pad_peer_get_caps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstPad *peerpad;
|
||||
GstCaps *result = NULL;
|
||||
GstQuery *query;
|
||||
|
||||
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 peer caps");
|
||||
|
||||
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 (peerpad, filter);
|
||||
|
||||
gst_object_unref (peerpad);
|
||||
query = gst_query_new_caps (filter);
|
||||
if (gst_pad_peer_query (pad, query)) {
|
||||
gst_query_parse_caps_result (query, &result);
|
||||
gst_caps_ref (result);
|
||||
GST_DEBUG_OBJECT (pad, "peer query returned %d", result);
|
||||
} else if (filter) {
|
||||
result = gst_caps_ref (filter);
|
||||
} else {
|
||||
result = gst_caps_new_any ();
|
||||
}
|
||||
gst_query_unref (query);
|
||||
|
||||
return result;
|
||||
|
||||
no_peer:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2378,7 +2209,7 @@ no_peer:
|
|||
gboolean
|
||||
gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
gboolean res;
|
||||
gboolean res = TRUE;
|
||||
GstQuery *query;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
|
@ -2387,8 +2218,7 @@ gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
|
|||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
|
||||
|
||||
query = gst_query_new_accept_caps (caps);
|
||||
res = gst_pad_query (pad, query);
|
||||
if (res) {
|
||||
if (gst_pad_query (pad, query)) {
|
||||
GST_DEBUG_OBJECT (pad, "query returned %d", res);
|
||||
gst_query_parse_accept_caps_result (query, &res);
|
||||
}
|
||||
|
@ -2403,24 +2233,27 @@ gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
|
|||
* @caps: a #GstCaps to check on the pad
|
||||
*
|
||||
* Check if the peer of @pad accepts @caps. If @pad has no peer, this function
|
||||
* returns FALSE.
|
||||
* returns TRUE.
|
||||
*
|
||||
* Returns: TRUE if the peer of @pad can accept the caps or @pad has no peer.
|
||||
*/
|
||||
gboolean
|
||||
gst_pad_peer_accept_caps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
gboolean result;
|
||||
gboolean res = TRUE;
|
||||
GstQuery *query;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
|
||||
query = gst_query_new_accept_caps (caps);
|
||||
result = gst_pad_peer_query (pad, query);
|
||||
if (gst_pad_peer_query (pad, query)) {
|
||||
GST_DEBUG_OBJECT (pad, "query returned %d", res);
|
||||
gst_query_parse_accept_caps_result (query, &res);
|
||||
}
|
||||
gst_query_unref (query);
|
||||
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2886,8 +2719,6 @@ event_forward_func (GstPad * pad, EventData * data)
|
|||
* The EOS event will pause the task associated with @pad before it is forwarded
|
||||
* to all internally linked pads,
|
||||
*
|
||||
* The CAPS event will never be forwarded.
|
||||
*
|
||||
* The the event is sent to all pads internally linked to @pad. This function
|
||||
* takes ownership of @event.
|
||||
*
|
||||
|
@ -2896,8 +2727,7 @@ event_forward_func (GstPad * pad, EventData * data)
|
|||
gboolean
|
||||
gst_pad_event_default (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean result;
|
||||
EventData data;
|
||||
gboolean result, forward = TRUE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
@ -2911,22 +2741,30 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
|
|||
gst_pad_pause_task (pad);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_CAPS:
|
||||
forward = GST_PAD_IS_PROXY_CAPS (pad);
|
||||
result = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
data.event = event;
|
||||
data.dispatched = FALSE;
|
||||
data.result = FALSE;
|
||||
if (forward) {
|
||||
EventData data;
|
||||
|
||||
gst_pad_forward (pad, (GstPadForwardFunction) event_forward_func, &data);
|
||||
data.event = event;
|
||||
data.dispatched = FALSE;
|
||||
data.result = FALSE;
|
||||
|
||||
/* for sinkpads without a parent element or without internal links, nothing
|
||||
* will be dispatched but we still want to return TRUE. */
|
||||
if (data.dispatched)
|
||||
result = data.result;
|
||||
else
|
||||
result = TRUE;
|
||||
gst_pad_forward (pad, (GstPadForwardFunction) event_forward_func, &data);
|
||||
|
||||
/* for sinkpads without a parent element or without internal links, nothing
|
||||
* will be dispatched but we still want to return TRUE. */
|
||||
if (data.dispatched)
|
||||
result = data.result;
|
||||
else
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
gst_event_unref (event);
|
||||
|
||||
|
@ -2936,17 +2774,25 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
|
|||
/* Default accept caps implementation just checks against
|
||||
* the allowed caps for the pad */
|
||||
static gboolean
|
||||
gst_pad_query_accept_caps (GstPad * pad, GstQuery * query)
|
||||
gst_pad_query_accept_caps_default (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
/* get the caps and see if it intersects to something not empty */
|
||||
GstCaps *caps, *allowed;
|
||||
gboolean result;
|
||||
|
||||
gst_query_parse_accept_caps (query, &caps);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
/* first forward the query to internally linked pads when we are dealing with
|
||||
* a PROXY CAPS */
|
||||
if (GST_PAD_IS_PROXY_CAPS (pad)) {
|
||||
if ((result = gst_pad_proxy_query_accept_caps (pad, query))) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
allowed = gst_pad_get_caps (pad, NULL);
|
||||
gst_query_parse_accept_caps (query, &caps);
|
||||
|
||||
if (allowed) {
|
||||
GST_DEBUG_OBJECT (pad, "allowed caps %" GST_PTR_FORMAT, allowed);
|
||||
result = gst_caps_is_subset (caps, allowed);
|
||||
|
@ -2957,6 +2803,84 @@ gst_pad_query_accept_caps (GstPad * pad, GstQuery * query)
|
|||
}
|
||||
gst_query_set_accept_caps_result (query, result);
|
||||
|
||||
done:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Default caps implementation */
|
||||
static gboolean
|
||||
gst_pad_query_caps_default (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstCaps *result = NULL, *filter;
|
||||
GstPadTemplate *templ;
|
||||
gboolean fixed_caps;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
|
||||
/* first try to proxy if we must */
|
||||
if (GST_PAD_IS_PROXY_CAPS (pad)) {
|
||||
if ((gst_pad_proxy_query_caps (pad, query))) {
|
||||
gst_query_parse_caps_result (query, &result);
|
||||
goto filter_done;
|
||||
}
|
||||
}
|
||||
|
||||
/* no proxy or it failed, do default handling */
|
||||
fixed_caps = GST_PAD_IS_FIXED_CAPS (pad);
|
||||
|
||||
GST_OBJECT_LOCK (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_unlock;
|
||||
}
|
||||
|
||||
if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "trying pad template caps");
|
||||
if ((result = GST_PAD_TEMPLATE_CAPS (templ)))
|
||||
goto filter_done_unlock;
|
||||
}
|
||||
|
||||
if (!fixed_caps) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"non-fixed pad caps: trying pad caps");
|
||||
/* non fixed caps, try the negotiated caps */
|
||||
if ((result = get_pad_caps (pad)))
|
||||
goto filter_done_unlock;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
/* 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_unlock:
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
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, result);
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
|
||||
"using caps %p %" GST_PTR_FORMAT, result, result);
|
||||
result = gst_caps_ref (result);
|
||||
}
|
||||
|
||||
done:
|
||||
gst_query_set_caps_result (query, result);
|
||||
gst_caps_unref (result);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2983,7 +2907,11 @@ gst_pad_query_default (GstPad * pad, GstQuery * query)
|
|||
forward = FALSE;
|
||||
break;
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
ret = gst_pad_query_accept_caps (pad, query);
|
||||
ret = gst_pad_query_accept_caps_default (pad, query);
|
||||
forward = FALSE;
|
||||
break;
|
||||
case GST_QUERY_CAPS:
|
||||
ret = gst_pad_query_caps_default (pad, query);
|
||||
forward = FALSE;
|
||||
break;
|
||||
case GST_QUERY_POSITION:
|
||||
|
|
46
gst/gstpad.h
46
gst/gstpad.h
|
@ -398,26 +398,6 @@ typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstPad *peer);
|
|||
typedef void (*GstPadUnlinkFunction) (GstPad *pad);
|
||||
|
||||
|
||||
/* caps nego */
|
||||
/**
|
||||
* 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
|
||||
* be overridden by elements.
|
||||
*
|
||||
* Returns: a newly allocated copy #GstCaps of the pad.
|
||||
*/
|
||||
typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad, GstCaps *filter);
|
||||
|
||||
/* misc */
|
||||
/**
|
||||
* GstPadForwardFunction:
|
||||
|
@ -566,7 +546,6 @@ typedef GstFlowReturn (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEve
|
|||
* GstPadFlags:
|
||||
* @GST_PAD_BLOCKED: is dataflow on a pad blocked
|
||||
* @GST_PAD_FLUSHING: is pad refusing buffers
|
||||
* @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() is running now
|
||||
* @GST_PAD_BLOCKING: is pad currently blocking on a buffer or event
|
||||
* @GST_PAD_NEED_RECONFIGURE: the pad should be reconfigured/renegotiated.
|
||||
* The flag has to be unset manually after
|
||||
|
@ -574,8 +553,11 @@ typedef GstFlowReturn (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEve
|
|||
* Since: 0.10.34.
|
||||
* @GST_PAD_NEED_EVENTS: the pad has pending events
|
||||
* @GST_PAD_FIXED_CAPS: the pad is using fixed caps this means that once the
|
||||
* caps are set on the pad, the getcaps function only
|
||||
* caps are set on the pad, the caps query function only
|
||||
* returns those caps.
|
||||
* @GST_PAD_PROXY_CAPS: the default event and query handler will forward
|
||||
* all events and queries to the internally linked pads
|
||||
* instead of discarding them.
|
||||
* @GST_PAD_FLAG_LAST: offset to define more flags
|
||||
*
|
||||
* Pad state flags
|
||||
|
@ -583,11 +565,11 @@ typedef GstFlowReturn (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEve
|
|||
typedef enum {
|
||||
GST_PAD_BLOCKED = (GST_OBJECT_FLAG_LAST << 0),
|
||||
GST_PAD_FLUSHING = (GST_OBJECT_FLAG_LAST << 1),
|
||||
GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
|
||||
GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
|
||||
GST_PAD_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 5),
|
||||
GST_PAD_NEED_EVENTS = (GST_OBJECT_FLAG_LAST << 6),
|
||||
GST_PAD_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 7),
|
||||
GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 2),
|
||||
GST_PAD_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 3),
|
||||
GST_PAD_NEED_EVENTS = (GST_OBJECT_FLAG_LAST << 4),
|
||||
GST_PAD_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 5),
|
||||
GST_PAD_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 6),
|
||||
/* padding */
|
||||
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
|
||||
} GstPadFlags;
|
||||
|
@ -603,7 +585,6 @@ typedef enum {
|
|||
* @task: task for this pad if the pad is actively driving dataflow.
|
||||
* @block_cond: conditional to signal pad block
|
||||
* @probes: installed probes
|
||||
* @getcapsfunc: function to get caps of the pad
|
||||
* @mode: current activation mode of the pad
|
||||
* @activatefunc: pad activation function
|
||||
* @activatepushfunc: function to activate/deactivate pad in push mode
|
||||
|
@ -641,9 +622,6 @@ struct _GstPad {
|
|||
GCond *block_cond;
|
||||
GHookList probes;
|
||||
|
||||
/* the pad capabilities */
|
||||
GstPadGetCapsFunction getcapsfunc;
|
||||
|
||||
GstPadActivateMode mode;
|
||||
GstPadActivateFunction activatefunc;
|
||||
GstPadActivateModeFunction activatepushfunc;
|
||||
|
@ -715,8 +693,6 @@ struct _GstPadClass {
|
|||
#define GST_PAD_LINKFUNC(pad) (GST_PAD_CAST(pad)->linkfunc)
|
||||
#define GST_PAD_UNLINKFUNC(pad) (GST_PAD_CAST(pad)->unlinkfunc)
|
||||
|
||||
#define GST_PAD_GETCAPSFUNC(pad) (GST_PAD_CAST(pad)->getcapsfunc)
|
||||
|
||||
#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
|
||||
#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
|
||||
|
||||
|
@ -731,6 +707,7 @@ struct _GstPadClass {
|
|||
#define GST_PAD_NEEDS_RECONFIGURE(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_NEED_RECONFIGURE))
|
||||
#define GST_PAD_NEEDS_EVENTS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_NEED_EVENTS))
|
||||
#define GST_PAD_IS_FIXED_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FIXED_CAPS))
|
||||
#define GST_PAD_IS_PROXY_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_PROXY_CAPS))
|
||||
|
||||
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLUSHING))
|
||||
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLUSHING))
|
||||
|
@ -849,9 +826,6 @@ gboolean gst_pad_is_linked (GstPad *pad);
|
|||
|
||||
GstPad* gst_pad_get_peer (GstPad *pad);
|
||||
|
||||
/* capsnego functions */
|
||||
void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps);
|
||||
|
||||
GstCaps* gst_pad_get_pad_template_caps (GstPad *pad);
|
||||
|
||||
/* capsnego function for linked/unlinked pads */
|
||||
|
|
|
@ -55,7 +55,7 @@ static const gchar *_quark_strings[] = {
|
|||
"GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
|
||||
"GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode",
|
||||
"random-access", "sequential", "allocator", "GstEventFlushStop", "options",
|
||||
"GstQueryAcceptCaps", "result", "GstQueryCaps"
|
||||
"GstQueryAcceptCaps", "result", "GstQueryCaps", "filter"
|
||||
};
|
||||
|
||||
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||
|
|
|
@ -158,8 +158,9 @@ typedef enum _GstQuarkId
|
|||
GST_QUARK_QUERY_ACCEPT_CAPS = 129,
|
||||
GST_QUARK_RESULT = 130,
|
||||
GST_QUARK_QUERY_CAPS = 131,
|
||||
GST_QUARK_FILTER = 132,
|
||||
|
||||
GST_QUARK_MAX = 132
|
||||
GST_QUARK_MAX = 133
|
||||
} GstQuarkId;
|
||||
|
||||
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||
|
|
|
@ -2076,20 +2076,35 @@ gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
|
|||
|
||||
/**
|
||||
* gst_query_new_caps
|
||||
* @filer: a filter
|
||||
*
|
||||
* Constructs a new query object for querying the caps.
|
||||
*
|
||||
* The CAPS query should return the* allowable caps for a pad in the context
|
||||
* of the element's state, its link to other elements, and the devices or files
|
||||
* it has opened. These caps must be a subset of the pad template caps. In the
|
||||
* NULL state with no links, the CAPS query should ideally return the same caps
|
||||
* as the pad template. In rare circumstances, an object property can affect
|
||||
* the caps returned by the CAPS query, but this is discouraged.
|
||||
*
|
||||
* For most filters, the caps returned by CAPS query is directly affected by the
|
||||
* allowed caps on other pads. For demuxers and decoders, the caps returned by
|
||||
* the srcpad's getcaps function is directly related to the stream data. Again,
|
||||
* the CAPS query should return the most specific caps it reasonably can, since this
|
||||
* helps with autoplugging.
|
||||
*
|
||||
* Free-function: gst_query_unref
|
||||
*
|
||||
* Returns: (transfer full): a new #GstQuery
|
||||
*/
|
||||
GstQuery *
|
||||
gst_query_new_caps (void)
|
||||
gst_query_new_caps (GstCaps * filter)
|
||||
{
|
||||
GstQuery *query;
|
||||
GstStructure *structure;
|
||||
|
||||
structure = gst_structure_new_id (GST_QUARK (QUERY_CAPS),
|
||||
GST_QUARK (FILTER), GST_TYPE_CAPS, filter,
|
||||
GST_QUARK (CAPS), GST_TYPE_CAPS, NULL, NULL);
|
||||
query = gst_query_new (GST_QUERY_CAPS, structure);
|
||||
|
||||
|
@ -2097,14 +2112,34 @@ gst_query_new_caps (void)
|
|||
}
|
||||
|
||||
/**
|
||||
* gst_query_set_caps:
|
||||
* gst_query_parse_caps:
|
||||
* @query: The query to parse
|
||||
* @filter: (out): A pointer to the caps filter
|
||||
*
|
||||
* Get the filter from the caps @query. The caps remains valid as long as
|
||||
* @query remains valid.
|
||||
*/
|
||||
void
|
||||
gst_query_parse_caps (GstQuery * query, GstCaps ** filter)
|
||||
{
|
||||
GstStructure *structure;
|
||||
|
||||
g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
|
||||
|
||||
structure = GST_QUERY_STRUCTURE (query);
|
||||
*filter = g_value_get_boxed (gst_structure_id_get_value (structure,
|
||||
GST_QUARK (FILTER)));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_query_set_caps_result:
|
||||
* @query: The query to use
|
||||
* @caps: (in): A pointer to the caps
|
||||
*
|
||||
* Set the @caps in @query.
|
||||
* Set the @caps result in @query.
|
||||
*/
|
||||
void
|
||||
gst_query_set_caps (GstQuery * query, GstCaps * caps)
|
||||
gst_query_set_caps_result (GstQuery * query, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
|
||||
|
@ -2116,15 +2151,15 @@ gst_query_set_caps (GstQuery * query, GstCaps * caps)
|
|||
}
|
||||
|
||||
/**
|
||||
* gst_query_parse_caps:
|
||||
* gst_query_parse_caps_result:
|
||||
* @query: The query to parse
|
||||
* @caps: (out): A pointer to the caps
|
||||
*
|
||||
* Get the caps from @query. The caps remains valid as long as @query remains
|
||||
* valid.
|
||||
* Get the caps result from @query. The caps remains valid as long as
|
||||
* @query remains valid.
|
||||
*/
|
||||
void
|
||||
gst_query_parse_caps (GstQuery * query, GstCaps ** caps)
|
||||
gst_query_parse_caps_result (GstQuery * query, GstCaps ** caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
|
||||
|
@ -2134,3 +2169,15 @@ gst_query_parse_caps (GstQuery * query, GstCaps ** caps)
|
|||
*caps = g_value_get_boxed (gst_structure_id_get_value (structure,
|
||||
GST_QUARK (CAPS)));
|
||||
}
|
||||
|
||||
void
|
||||
gst_query_intersect_caps_result (GstQuery * query, GstCaps * filter,
|
||||
GstCapsIntersectMode mode)
|
||||
{
|
||||
GstCaps *res, *caps;
|
||||
|
||||
gst_query_parse_caps_result (query, &caps);
|
||||
res = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_query_set_caps_result (query, res);
|
||||
gst_caps_unref (res);
|
||||
}
|
||||
|
|
|
@ -389,9 +389,14 @@ void gst_query_set_accept_caps_result (GstQuery *query, gboolean re
|
|||
void gst_query_parse_accept_caps_result (GstQuery *query, gboolean *result);
|
||||
|
||||
/* caps query */
|
||||
GstQuery * gst_query_new_caps (void);
|
||||
void gst_query_set_caps (GstQuery *query, GstCaps *caps);
|
||||
void gst_query_parse_caps (GstQuery *query, GstCaps **caps);
|
||||
GstQuery * gst_query_new_caps (GstCaps *filter);
|
||||
void gst_query_parse_caps (GstQuery *query, GstCaps **filter);
|
||||
|
||||
void gst_query_set_caps_result (GstQuery *query, GstCaps *caps);
|
||||
void gst_query_parse_caps_result (GstQuery *query, GstCaps **caps);
|
||||
|
||||
void gst_query_intersect_caps_result (GstQuery *query, GstCaps *filter,
|
||||
GstCapsIntersectMode mode);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
207
gst/gstutils.c
207
gst/gstutils.c
|
@ -2697,54 +2697,161 @@ gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
getcaps_fold_func (const GValue * vpad, GValue * ret, GstCaps * filter)
|
||||
query_accept_caps_fold_func (const GValue * vpad, GValue * ret,
|
||||
GstQuery * query)
|
||||
{
|
||||
GstPad *pad = g_value_get_object (vpad);
|
||||
gboolean result = TRUE;
|
||||
|
||||
if (G_LIKELY (gst_pad_peer_query (pad, query))) {
|
||||
gst_query_parse_accept_caps_result (query, &result);
|
||||
result &= g_value_get_boolean (ret);
|
||||
g_value_set_boolean (ret, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pad_proxy_query_accept_caps:
|
||||
* @pad: a #GstPad to proxy.
|
||||
* @query: an ACCEPT_CAPS #GstQuery.
|
||||
*
|
||||
* Calls gst_pad_accept_caps() for every pad with oposite direction belonging
|
||||
* to the same element as @pad, and returns the intersection of the results.
|
||||
*
|
||||
* This function is useful as a default accept caps query function for an element
|
||||
* that can handle any stream format, but requires caps that are acceptable for
|
||||
* all oposite pads.
|
||||
*
|
||||
* Returns: TRUE if @query could be executed
|
||||
*/
|
||||
gboolean
|
||||
gst_pad_proxy_query_accept_caps (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstElement *element;
|
||||
GstIterator *iter;
|
||||
GstIteratorResult res;
|
||||
GValue ret = { 0, };
|
||||
|
||||
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_ACCEPT_CAPS, FALSE);
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_PADS, "proxying accept caps query for %s:%s",
|
||||
GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
element = gst_pad_get_parent_element (pad);
|
||||
if (element == NULL)
|
||||
goto no_parent;
|
||||
|
||||
/* value to hold the return, by default it holds TRUE */
|
||||
g_value_init (&ret, G_TYPE_BOOLEAN);
|
||||
g_value_set_boolean (&ret, TRUE);
|
||||
|
||||
/* only iterate the pads in the oposite direction */
|
||||
if (GST_PAD_IS_SRC (pad))
|
||||
iter = gst_element_iterate_sink_pads (element);
|
||||
else
|
||||
iter = gst_element_iterate_src_pads (element);
|
||||
|
||||
while (1) {
|
||||
res =
|
||||
gst_iterator_fold (iter,
|
||||
(GstIteratorFoldFunction) query_accept_caps_fold_func, &ret, query);
|
||||
switch (res) {
|
||||
case GST_ITERATOR_RESYNC:
|
||||
/* need to reset the result again to TRUE */
|
||||
g_value_set_boolean (&ret, TRUE);
|
||||
gst_iterator_resync (iter);
|
||||
break;
|
||||
case GST_ITERATOR_DONE:
|
||||
/* all pads iterated, return collected value */
|
||||
goto done;
|
||||
case GST_ITERATOR_OK:
|
||||
/* premature exit (happens if caps intersection is empty) */
|
||||
goto done;
|
||||
default:
|
||||
/* iterator returned _ERROR, mark an error and exit */
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
done:
|
||||
gst_iterator_free (iter);
|
||||
gst_object_unref (element);
|
||||
|
||||
gst_query_set_accept_caps_result (query, g_value_get_boolean (&ret));
|
||||
g_value_unset (&ret);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_parent:
|
||||
{
|
||||
GST_DEBUG_OBJECT (pad, "no parent");
|
||||
return FALSE;
|
||||
}
|
||||
error:
|
||||
{
|
||||
g_warning ("Pad list returned error on element %s",
|
||||
GST_ELEMENT_NAME (element));
|
||||
gst_iterator_free (iter);
|
||||
gst_object_unref (element);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
query_caps_fold_func (const GValue * vpad, GValue * ret, GstQuery * query)
|
||||
{
|
||||
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, filter);
|
||||
if (G_LIKELY (peercaps)) {
|
||||
GstCaps *intersection = gst_caps_intersect (existing, peercaps);
|
||||
if (G_LIKELY (gst_pad_peer_query (pad, query))) {
|
||||
GstCaps *existing, *peercaps, *intersection;
|
||||
|
||||
existing = g_value_get_pointer (ret);
|
||||
gst_query_parse_caps_result (query, &peercaps);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "intersect with result %" GST_PTR_FORMAT, peercaps);
|
||||
intersection = gst_caps_intersect (existing, peercaps);
|
||||
GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, intersection);
|
||||
empty = gst_caps_is_empty (intersection);
|
||||
|
||||
g_value_set_pointer (ret, intersection);
|
||||
gst_caps_unref (existing);
|
||||
gst_caps_unref (peercaps);
|
||||
}
|
||||
return !empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pad_proxy_getcaps:
|
||||
* gst_pad_proxy_query_caps:
|
||||
* @pad: a #GstPad to proxy.
|
||||
* @filter: a #GstCaps filter.
|
||||
* @query: a CAPS #GstQuery.
|
||||
*
|
||||
* Calls gst_pad_get_allowed_caps() for every other pad belonging to the
|
||||
* same element as @pad, and returns the intersection of the results.
|
||||
* Calls gst_pad_get_caps() for every pad with oposite direction belonging
|
||||
* to the same element as @pad, and returns the intersection of the results.
|
||||
*
|
||||
* This function is useful as a default getcaps function for an element
|
||||
* This function is useful as a default caps query function for an element
|
||||
* that can handle any stream format, but requires all its pads to have
|
||||
* the same caps. Two such elements are tee and adder.
|
||||
*
|
||||
* Free-function: gst_caps_unref
|
||||
*
|
||||
* Returns: (transfer full): the intersection of the other pads' allowed caps.
|
||||
* Returns: TRUE if @query could be executed
|
||||
*/
|
||||
GstCaps *
|
||||
gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter)
|
||||
gboolean
|
||||
gst_pad_proxy_query_caps (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean result = TRUE;
|
||||
GstElement *element;
|
||||
GstCaps *caps, *intersected;
|
||||
GstIterator *iter;
|
||||
GstIteratorResult res;
|
||||
GValue ret = { 0, };
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
|
||||
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_CAPS, FALSE);
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_PADS, "proxying getcaps for %s:%s",
|
||||
GST_CAT_DEBUG (GST_CAT_PADS, "proxying caps query for %s:%s",
|
||||
GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
element = gst_pad_get_parent_element (pad);
|
||||
|
@ -2764,8 +2871,8 @@ gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter)
|
|||
|
||||
while (1) {
|
||||
res =
|
||||
gst_iterator_fold (iter, (GstIteratorFoldFunction) getcaps_fold_func,
|
||||
&ret, filter);
|
||||
gst_iterator_fold (iter, (GstIteratorFoldFunction) query_caps_fold_func,
|
||||
&ret, query);
|
||||
switch (res) {
|
||||
case GST_ITERATOR_RESYNC:
|
||||
/* unref any value stored */
|
||||
|
@ -2805,13 +2912,16 @@ done:
|
|||
intersected = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
}
|
||||
|
||||
return intersected;
|
||||
gst_query_set_caps_result (query, intersected);
|
||||
gst_caps_unref (intersected);
|
||||
|
||||
return result;
|
||||
|
||||
/* ERRORS */
|
||||
no_parent:
|
||||
{
|
||||
GST_DEBUG_OBJECT (pad, "no parent");
|
||||
return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
return FALSE;
|
||||
}
|
||||
error:
|
||||
{
|
||||
|
@ -2819,7 +2929,7 @@ error:
|
|||
GST_ELEMENT_NAME (element));
|
||||
gst_iterator_free (iter);
|
||||
gst_object_unref (element);
|
||||
return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2843,11 +2953,8 @@ gst_pad_query_position (GstPad * pad, GstFormat format, gint64 * cur)
|
|||
g_return_val_if_fail (format != GST_FORMAT_UNDEFINED, FALSE);
|
||||
|
||||
query = gst_query_new_position (format);
|
||||
ret = gst_pad_query (pad, query);
|
||||
|
||||
if (ret)
|
||||
if ((ret = gst_pad_query (pad, query)))
|
||||
gst_query_parse_position (query, NULL, cur);
|
||||
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
|
@ -2868,18 +2975,17 @@ gst_pad_query_position (GstPad * pad, GstFormat format, gint64 * cur)
|
|||
gboolean
|
||||
gst_pad_query_peer_position (GstPad * pad, GstFormat format, gint64 * cur)
|
||||
{
|
||||
GstQuery *query;
|
||||
gboolean ret = FALSE;
|
||||
GstPad *peer;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
|
||||
g_return_val_if_fail (format != GST_FORMAT_UNDEFINED, FALSE);
|
||||
|
||||
peer = gst_pad_get_peer (pad);
|
||||
if (peer) {
|
||||
ret = gst_pad_query_position (peer, format, cur);
|
||||
gst_object_unref (peer);
|
||||
}
|
||||
query = gst_query_new_position (format);
|
||||
if ((ret = gst_pad_peer_query (pad, query)))
|
||||
gst_query_parse_position (query, NULL, cur);
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2905,11 +3011,8 @@ gst_pad_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
|
|||
g_return_val_if_fail (format != GST_FORMAT_UNDEFINED, FALSE);
|
||||
|
||||
query = gst_query_new_duration (format);
|
||||
ret = gst_pad_query (pad, query);
|
||||
|
||||
if (ret)
|
||||
if ((ret = gst_pad_query (pad, query)))
|
||||
gst_query_parse_duration (query, NULL, duration);
|
||||
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
|
@ -2930,18 +3033,17 @@ gst_pad_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
|
|||
gboolean
|
||||
gst_pad_query_peer_duration (GstPad * pad, GstFormat format, gint64 * duration)
|
||||
{
|
||||
GstQuery *query;
|
||||
gboolean ret = FALSE;
|
||||
GstPad *peer;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
|
||||
g_return_val_if_fail (format != GST_FORMAT_UNDEFINED, FALSE);
|
||||
|
||||
peer = gst_pad_get_peer (pad);
|
||||
if (peer) {
|
||||
ret = gst_pad_query_duration (peer, format, duration);
|
||||
gst_object_unref (peer);
|
||||
}
|
||||
query = gst_query_new_duration (format);
|
||||
if ((ret = gst_pad_peer_query (pad, query)))
|
||||
gst_query_parse_duration (query, NULL, duration);
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2975,11 +3077,8 @@ gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
|
|||
}
|
||||
|
||||
query = gst_query_new_convert (src_format, src_val, dest_format);
|
||||
ret = gst_pad_query (pad, query);
|
||||
|
||||
if (ret)
|
||||
if ((ret = gst_pad_query (pad, query)))
|
||||
gst_query_parse_convert (query, NULL, NULL, NULL, dest_val);
|
||||
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
|
@ -3003,20 +3102,18 @@ gboolean
|
|||
gst_pad_query_peer_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
|
||||
GstFormat dest_format, gint64 * dest_val)
|
||||
{
|
||||
GstQuery *query;
|
||||
gboolean ret = FALSE;
|
||||
GstPad *peer;
|
||||
|
||||
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
|
||||
g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
|
||||
g_return_val_if_fail (dest_format != GST_FORMAT_UNDEFINED, FALSE);
|
||||
g_return_val_if_fail (dest_val != NULL, FALSE);
|
||||
|
||||
peer = gst_pad_get_peer (pad);
|
||||
if (peer) {
|
||||
ret = gst_pad_query_convert (peer, src_format, src_val, dest_format,
|
||||
dest_val);
|
||||
gst_object_unref (peer);
|
||||
}
|
||||
query = gst_query_new_convert (src_format, src_val, dest_format);
|
||||
if ((ret = gst_pad_peer_query (pad, query)))
|
||||
gst_query_parse_convert (query, NULL, NULL, NULL, dest_val);
|
||||
gst_query_unref (query);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -891,7 +891,8 @@ void gst_element_class_install_std_props (GstElementClass * k
|
|||
|
||||
/* pad functions */
|
||||
void gst_pad_use_fixed_caps (GstPad *pad);
|
||||
GstCaps* gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter);
|
||||
gboolean gst_pad_proxy_query_accept_caps (GstPad *pad, GstQuery *query);
|
||||
gboolean gst_pad_proxy_query_caps (GstPad *pad, GstQuery *query);
|
||||
|
||||
GstElement* gst_pad_get_parent_element (GstPad *pad);
|
||||
|
||||
|
|
|
@ -384,9 +384,10 @@ static gboolean gst_base_parse_handle_seek (GstBaseParse * parse,
|
|||
static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
|
||||
|
||||
static gboolean gst_base_parse_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_base_parse_src_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static gboolean gst_base_parse_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_base_parse_query (GstPad * pad, GstQuery * query);
|
||||
static GstCaps *gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_base_parse_sink_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static void gst_base_parse_loop (GstPad * pad);
|
||||
|
@ -522,8 +523,8 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
|
|||
parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
gst_pad_set_event_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
|
||||
gst_pad_set_getcaps_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_sink_getcaps));
|
||||
gst_pad_set_query_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_sink_query));
|
||||
gst_pad_set_chain_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_chain));
|
||||
gst_pad_set_activate_function (parse->sinkpad,
|
||||
|
@ -543,7 +544,7 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
|
|||
gst_pad_set_event_function (parse->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_src_event));
|
||||
gst_pad_set_query_function (parse->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_query));
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_src_query));
|
||||
gst_pad_use_fixed_caps (parse->srcpad);
|
||||
gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
|
||||
GST_DEBUG_OBJECT (parse, "src created");
|
||||
|
@ -1117,6 +1118,45 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
|
|||
return handled;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_base_parse_sink_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstBaseParse *parse;
|
||||
GstBaseParseClass *bclass;
|
||||
gboolean res;
|
||||
|
||||
parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
|
||||
bclass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
if (bclass->get_sink_caps) {
|
||||
GstCaps *caps, *filter;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = bclass->get_sink_caps (parse, filter);
|
||||
GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT,
|
||||
caps);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
res = TRUE;
|
||||
} else
|
||||
res = gst_pad_peer_query (parse->srcpad, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
gst_object_unref (parse);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* gst_base_parse_src_event:
|
||||
* @pad: #GstPad that received the event.
|
||||
|
@ -3270,7 +3310,7 @@ gst_base_parse_get_duration (GstBaseParse * parse, GstFormat format,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_base_parse_query (GstPad * pad, GstQuery * query)
|
||||
gst_base_parse_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstBaseParse *parse;
|
||||
gboolean res = FALSE;
|
||||
|
@ -3949,29 +3989,6 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
|
|||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseParse *parse;
|
||||
GstBaseParseClass *klass;
|
||||
GstCaps *caps;
|
||||
|
||||
parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
|
||||
klass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||
g_assert (pad == GST_BASE_PARSE_SINK_PAD (parse));
|
||||
|
||||
if (klass->get_sink_caps)
|
||||
caps = klass->get_sink_caps (parse, filter);
|
||||
else
|
||||
caps = gst_pad_proxy_getcaps (pad, filter);
|
||||
gst_object_unref (parse);
|
||||
|
||||
GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
return caps;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_parse_set_index (GstElement * element, GstIndex * index)
|
||||
{
|
||||
|
|
|
@ -399,7 +399,6 @@ static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
|
|||
static gboolean default_sink_query (GstBaseSink * sink, GstQuery * query);
|
||||
|
||||
static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
|
||||
static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static void gst_base_sink_default_fixate (GstBaseSink * bsink, GstCaps * caps);
|
||||
static void gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps);
|
||||
|
||||
|
@ -553,7 +552,6 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
|
|||
klass->query = GST_DEBUG_FUNCPTR (default_sink_query);
|
||||
|
||||
/* Registering debug symbols for function pointers */
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_getcaps);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_fixate);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_push);
|
||||
|
@ -565,17 +563,18 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
|
|||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter)
|
||||
gst_base_sink_query_caps (GstBaseSink * bsink, GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseSinkClass *bclass;
|
||||
GstBaseSink *bsink;
|
||||
GstCaps *caps = NULL;
|
||||
gboolean fixed;
|
||||
|
||||
bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
||||
bclass = GST_BASE_SINK_GET_CLASS (bsink);
|
||||
fixed = GST_PAD_IS_FIXED_CAPS (pad);
|
||||
|
||||
if (bsink->pad_mode == GST_PAD_ACTIVATE_PULL) {
|
||||
/* if we are operating in pull mode we only accept the negotiated caps */
|
||||
if (fixed || bsink->pad_mode == GST_PAD_ACTIVATE_PULL) {
|
||||
/* if we are operating in pull mode or fixed caps, we only accept the
|
||||
* currently negotiated caps */
|
||||
caps = gst_pad_get_current_caps (pad);
|
||||
}
|
||||
if (caps == NULL) {
|
||||
|
@ -602,7 +601,6 @@ gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter)
|
|||
}
|
||||
}
|
||||
}
|
||||
gst_object_unref (bsink);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
@ -639,7 +637,6 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
|
|||
|
||||
basesink->sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
|
||||
gst_pad_set_getcaps_function (basesink->sinkpad, gst_base_sink_pad_getcaps);
|
||||
gst_pad_set_activate_function (basesink->sinkpad, gst_base_sink_pad_activate);
|
||||
gst_pad_set_activatepush_function (basesink->sinkpad,
|
||||
gst_base_sink_pad_activate_push);
|
||||
|
@ -2059,8 +2056,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
|
|||
/* FIXME: Casting to GstClockEntry only works because the types
|
||||
* are the same */
|
||||
if (G_LIKELY (sink->priv->cached_clock_id != NULL
|
||||
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
|
||||
cached_clock_id) == clock)) {
|
||||
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->
|
||||
priv->cached_clock_id) == clock)) {
|
||||
if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
|
||||
time)) {
|
||||
gst_clock_id_unref (sink->priv->cached_clock_id);
|
||||
|
@ -4851,6 +4848,17 @@ default_sink_query (GstBaseSink * basesink, GstQuery * query)
|
|||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
GstCaps *caps, *filter;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = gst_base_sink_query_caps (basesink, basesink->sinkpad, filter);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (basesink->sinkpad, query);
|
||||
break;
|
||||
|
|
|
@ -280,7 +280,6 @@ gst_base_src_get_type (void)
|
|||
|
||||
static GstCaps *gst_base_src_default_get_caps (GstBaseSrc * bsrc,
|
||||
GstCaps * filter);
|
||||
static GstCaps *gst_base_src_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static void gst_base_src_default_fixate (GstBaseSrc * src, GstCaps * caps);
|
||||
static void gst_base_src_fixate (GstBaseSrc * src, GstCaps * caps);
|
||||
|
||||
|
@ -386,7 +385,6 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
|
|||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_event_handler);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_query);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_pad_get_range);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_getcaps);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_fixate);
|
||||
}
|
||||
|
||||
|
@ -419,7 +417,6 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
|
|||
gst_pad_set_event_function (pad, gst_base_src_event_handler);
|
||||
gst_pad_set_query_function (pad, gst_base_src_query);
|
||||
gst_pad_set_getrange_function (pad, gst_base_src_pad_get_range);
|
||||
gst_pad_set_getcaps_function (pad, gst_base_src_getcaps);
|
||||
|
||||
/* hold pointer to pad */
|
||||
basesrc->srcpad = pad;
|
||||
|
@ -836,21 +833,6 @@ gst_base_src_default_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_src_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseSrcClass *bclass;
|
||||
GstBaseSrc *bsrc;
|
||||
GstCaps *caps = NULL;
|
||||
|
||||
bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
|
||||
bclass = GST_BASE_SRC_GET_CLASS (bsrc);
|
||||
if (bclass->get_caps)
|
||||
caps = bclass->get_caps (bsrc, filter);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_src_default_fixate (GstBaseSrc * bsrc, GstCaps * caps)
|
||||
{
|
||||
|
@ -1136,12 +1118,29 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
|
|||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
GstBaseSrcClass *bclass;
|
||||
GstCaps *caps, *filter;
|
||||
|
||||
bclass = GST_BASE_SRC_GET_CLASS (src);
|
||||
if (bclass->get_caps) {
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = bclass->get_caps (src, filter);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
res = TRUE;
|
||||
} else
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
GST_DEBUG_OBJECT (src, "query %s returns %d", GST_QUERY_TYPE_NAME (query),
|
||||
res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -321,7 +321,8 @@ static GstCaps *gst_base_transform_default_transform_caps (GstBaseTransform *
|
|||
trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
||||
static void gst_base_transform_default_fixate (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
|
||||
static GstCaps *gst_base_transform_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static GstCaps *gst_base_transform_query_caps (GstBaseTransform * trans,
|
||||
GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps);
|
||||
static gboolean gst_base_transform_setcaps (GstBaseTransform * trans,
|
||||
|
@ -410,8 +411,6 @@ gst_base_transform_init (GstBaseTransform * trans,
|
|||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
|
||||
g_return_if_fail (pad_template != NULL);
|
||||
trans->sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
gst_pad_set_getcaps_function (trans->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
|
||||
gst_pad_set_event_function (trans->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_transform_sink_event));
|
||||
gst_pad_set_chain_function (trans->sinkpad,
|
||||
|
@ -426,8 +425,6 @@ gst_base_transform_init (GstBaseTransform * trans,
|
|||
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
|
||||
g_return_if_fail (pad_template != NULL);
|
||||
trans->srcpad = gst_pad_new_from_template (pad_template, "src");
|
||||
gst_pad_set_getcaps_function (trans->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
|
||||
gst_pad_set_event_function (trans->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_transform_src_event));
|
||||
gst_pad_set_getrange_function (trans->srcpad,
|
||||
|
@ -637,15 +634,13 @@ gst_base_transform_transform_size (GstBaseTransform * trans,
|
|||
* If there is no peer, we simply return the caps of the padtemplate of pad.
|
||||
*/
|
||||
static GstCaps *
|
||||
gst_base_transform_getcaps (GstPad * pad, GstCaps * filter)
|
||||
gst_base_transform_query_caps (GstBaseTransform * trans, GstPad * pad,
|
||||
GstCaps * filter)
|
||||
{
|
||||
GstBaseTransform *trans;
|
||||
GstPad *otherpad;
|
||||
GstCaps *peercaps, *caps, *temp, *peerfilter = NULL;
|
||||
GstCaps *templ;
|
||||
|
||||
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||
|
||||
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
|
||||
|
||||
/* we can do what the peer can */
|
||||
|
@ -743,8 +738,6 @@ done:
|
|||
if (peercaps)
|
||||
gst_caps_unref (peercaps);
|
||||
|
||||
gst_object_unref (trans);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
@ -1288,10 +1281,16 @@ gst_base_transform_default_query (GstBaseTransform * trans,
|
|||
GstPadDirection direction, GstQuery * query)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GstPad *otherpad;
|
||||
GstPad *pad, *otherpad;
|
||||
GstBaseTransformClass *klass;
|
||||
|
||||
otherpad = (direction == GST_PAD_SRC) ? trans->sinkpad : trans->srcpad;
|
||||
if (direction == GST_PAD_SRC) {
|
||||
pad = trans->srcpad;
|
||||
otherpad = trans->sinkpad;
|
||||
} else {
|
||||
pad = trans->sinkpad;
|
||||
otherpad = trans->srcpad;
|
||||
}
|
||||
|
||||
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
||||
|
||||
|
@ -1360,6 +1359,17 @@ gst_base_transform_default_query (GstBaseTransform * trans,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
GstCaps *filter, *caps;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = gst_base_transform_query_caps (trans, pad, filter);
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = gst_pad_peer_query (otherpad, query);
|
||||
break;
|
||||
|
|
|
@ -118,7 +118,7 @@ static void gst_funnel_release_pad (GstElement * element, GstPad * pad);
|
|||
|
||||
static GstFlowReturn gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_funnel_sink_event (GstPad * pad, GstEvent * event);
|
||||
static GstCaps *gst_funnel_sink_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_funnel_sink_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static gboolean gst_funnel_src_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
|
@ -189,8 +189,8 @@ gst_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|||
GST_DEBUG_FUNCPTR (gst_funnel_sink_chain));
|
||||
gst_pad_set_event_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_funnel_sink_event));
|
||||
gst_pad_set_getcaps_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_funnel_sink_getcaps));
|
||||
gst_pad_set_query_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_funnel_sink_query));
|
||||
|
||||
gst_pad_set_active (sinkpad, TRUE);
|
||||
|
||||
|
@ -211,24 +211,6 @@ gst_funnel_release_pad (GstElement * element, GstPad * pad)
|
|||
gst_element_remove_pad (GST_ELEMENT_CAST (funnel), pad);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_funnel_sink_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstFunnel *funnel = GST_FUNNEL (gst_pad_get_parent (pad));
|
||||
GstCaps *caps;
|
||||
|
||||
if (G_UNLIKELY (funnel == NULL))
|
||||
return gst_caps_new_any ();
|
||||
|
||||
caps = gst_pad_peer_get_caps (funnel->srcpad, filter);
|
||||
if (caps == NULL)
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
gst_object_unref (funnel);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
|
@ -343,6 +325,26 @@ gst_funnel_sink_event (GstPad * pad, GstEvent * event)
|
|||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_funnel_sink_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstFunnel *funnel = GST_FUNNEL (gst_pad_get_parent (pad));
|
||||
gboolean forward = TRUE;
|
||||
gboolean res = TRUE;
|
||||
|
||||
if (G_UNLIKELY (funnel == NULL)) {
|
||||
gst_query_unref (query);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (forward)
|
||||
res = gst_pad_peer_query (funnel->srcpad, query);
|
||||
|
||||
gst_object_unref (funnel);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_funnel_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
|
|
|
@ -179,7 +179,6 @@ static void gst_selector_pad_set_property (GObject * object,
|
|||
static gint64 gst_selector_pad_get_running_time (GstSelectorPad * pad);
|
||||
static void gst_selector_pad_reset (GstSelectorPad * pad);
|
||||
static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event);
|
||||
static GstCaps *gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_selector_pad_query (GstPad * pad, GstQuery * query);
|
||||
static GstIterator *gst_selector_pad_iterate_linked_pads (GstPad * pad);
|
||||
static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
|
||||
|
@ -496,49 +495,22 @@ gst_selector_pad_query (GstPad * pad, GstQuery * query)
|
|||
{
|
||||
gboolean res = FALSE;
|
||||
GstInputSelector *sel;
|
||||
GstPad *otherpad;
|
||||
|
||||
sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (sel == NULL))
|
||||
return FALSE;
|
||||
|
||||
otherpad = gst_input_selector_get_linked_pad (sel, pad, TRUE);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
default:
|
||||
if (otherpad)
|
||||
res = gst_pad_peer_query (otherpad, query);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
if (otherpad)
|
||||
gst_object_unref (otherpad);
|
||||
|
||||
gst_object_unref (sel);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstInputSelector *sel;
|
||||
GstCaps *caps;
|
||||
|
||||
sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (sel == NULL))
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
GST_DEBUG_OBJECT (sel, "Getting caps of srcpad peer");
|
||||
caps = gst_pad_peer_get_caps (sel->srcpad, filter);
|
||||
if (caps == NULL)
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
gst_object_unref (sel);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* must be called with the SELECTOR_LOCK, will block while the pad is blocked
|
||||
* or return TRUE when flushing */
|
||||
static gboolean
|
||||
|
@ -797,7 +769,6 @@ static void gst_input_selector_release_pad (GstElement * element, GstPad * pad);
|
|||
static GstStateChangeReturn gst_input_selector_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstCaps *gst_input_selector_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_input_selector_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_input_selector_query (GstPad * pad, GstQuery * query);
|
||||
static gint64 gst_input_selector_block (GstInputSelector * self);
|
||||
|
@ -914,12 +885,11 @@ gst_input_selector_init (GstInputSelector * sel)
|
|||
sel->srcpad = gst_pad_new ("src", GST_PAD_SRC);
|
||||
gst_pad_set_iterate_internal_links_function (sel->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
|
||||
gst_pad_set_getcaps_function (sel->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_input_selector_getcaps));
|
||||
gst_pad_set_query_function (sel->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_input_selector_query));
|
||||
gst_pad_set_event_function (sel->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_input_selector_event));
|
||||
GST_OBJECT_FLAG_SET (sel->srcpad, GST_PAD_PROXY_CAPS);
|
||||
gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad);
|
||||
/* sinkpad management */
|
||||
sel->active_sinkpad = NULL;
|
||||
|
@ -1139,14 +1109,11 @@ gst_input_selector_query (GstPad * pad, GstQuery * query)
|
|||
{
|
||||
gboolean res = FALSE;
|
||||
GstInputSelector *sel;
|
||||
GstPad *otherpad;
|
||||
|
||||
sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (sel == NULL))
|
||||
return FALSE;
|
||||
|
||||
otherpad = gst_input_selector_get_linked_pad (sel, pad, TRUE);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_LATENCY:
|
||||
{
|
||||
|
@ -1203,48 +1170,15 @@ gst_input_selector_query (GstPad * pad, GstQuery * query)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
if (otherpad)
|
||||
res = gst_pad_peer_query (otherpad, query);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
if (otherpad)
|
||||
gst_object_unref (otherpad);
|
||||
|
||||
gst_object_unref (sel);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_input_selector_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstPad *otherpad;
|
||||
GstInputSelector *sel;
|
||||
GstCaps *caps;
|
||||
|
||||
sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (sel == NULL))
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
otherpad = gst_input_selector_get_linked_pad (sel, pad, FALSE);
|
||||
|
||||
if (!otherpad) {
|
||||
GST_DEBUG_OBJECT (pad, "Pad not linked, returning ANY");
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "Pad is linked (to %s:%s), returning peer caps",
|
||||
GST_DEBUG_PAD_NAME (otherpad));
|
||||
/* if the peer has caps, use those. If the pad is not linked, this function
|
||||
* returns NULL and we return ANY */
|
||||
if (!(caps = gst_pad_peer_get_caps (otherpad, filter)))
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
gst_object_unref (otherpad);
|
||||
}
|
||||
|
||||
gst_object_unref (sel);
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* check if the pad is the active sinkpad */
|
||||
static inline gboolean
|
||||
gst_input_selector_is_active_sinkpad (GstInputSelector * sel, GstPad * pad)
|
||||
|
@ -1304,8 +1238,6 @@ gst_input_selector_request_new_pad (GstElement * element,
|
|||
|
||||
gst_pad_set_event_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_event));
|
||||
gst_pad_set_getcaps_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_getcaps));
|
||||
gst_pad_set_query_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_query));
|
||||
gst_pad_set_chain_function (sinkpad,
|
||||
|
@ -1313,6 +1245,7 @@ gst_input_selector_request_new_pad (GstElement * element,
|
|||
gst_pad_set_iterate_internal_links_function (sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
|
||||
|
||||
GST_OBJECT_FLAG_SET (sinkpad, GST_PAD_PROXY_CAPS);
|
||||
gst_pad_set_active (sinkpad, TRUE);
|
||||
gst_element_add_pad (GST_ELEMENT (sel), sinkpad);
|
||||
GST_INPUT_SELECTOR_UNLOCK (sel);
|
||||
|
|
|
@ -1507,37 +1507,19 @@ was_eos:
|
|||
static gboolean
|
||||
gst_multi_queue_sink_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstSingleQueue *sq = gst_pad_get_element_private (pad);
|
||||
gboolean res;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
case GST_QUERY_CAPS:
|
||||
default:
|
||||
/* default handling */
|
||||
res = gst_pad_peer_query (sq->srcpad, query);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_multi_queue_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstSingleQueue *sq = gst_pad_get_element_private (pad);
|
||||
GstPad *otherpad;
|
||||
GstCaps *result;
|
||||
|
||||
otherpad = (pad == sq->srcpad) ? sq->sinkpad : sq->srcpad;
|
||||
|
||||
GST_LOG_OBJECT (otherpad, "Getting caps from the peer of this pad");
|
||||
|
||||
result = gst_pad_peer_get_caps (otherpad, filter);
|
||||
if (result == NULL)
|
||||
result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_multi_queue_src_activate_push (GstPad * pad, gboolean active)
|
||||
{
|
||||
|
@ -1571,15 +1553,15 @@ gst_multi_queue_src_event (GstPad * pad, GstEvent * event)
|
|||
static gboolean
|
||||
gst_multi_queue_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstSingleQueue *sq = gst_pad_get_element_private (pad);
|
||||
gboolean res;
|
||||
|
||||
/* FIXME, Handle position offset depending on queue size */
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
case GST_QUERY_CAPS:
|
||||
default:
|
||||
/* default handling */
|
||||
res = gst_pad_peer_query (sq->sinkpad, query);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
|
@ -1923,12 +1905,11 @@ gst_single_queue_new (GstMultiQueue * mqueue, guint id)
|
|||
GST_DEBUG_FUNCPTR (gst_multi_queue_sink_activate_push));
|
||||
gst_pad_set_event_function (sq->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_sink_event));
|
||||
gst_pad_set_getcaps_function (sq->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
|
||||
gst_pad_set_query_function (sq->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_sink_query));
|
||||
gst_pad_set_iterate_internal_links_function (sq->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_iterate_internal_links));
|
||||
GST_OBJECT_FLAG_SET (sq->sinkpad, GST_PAD_PROXY_CAPS);
|
||||
|
||||
name = g_strdup_printf ("src_%u", sq->id);
|
||||
sq->srcpad = gst_pad_new_from_static_template (&srctemplate, name);
|
||||
|
@ -1936,14 +1917,13 @@ gst_single_queue_new (GstMultiQueue * mqueue, guint id)
|
|||
|
||||
gst_pad_set_activatepush_function (sq->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_src_activate_push));
|
||||
gst_pad_set_getcaps_function (sq->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
|
||||
gst_pad_set_event_function (sq->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_src_event));
|
||||
gst_pad_set_query_function (sq->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_src_query));
|
||||
gst_pad_set_iterate_internal_links_function (sq->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_multi_queue_iterate_internal_links));
|
||||
GST_OBJECT_FLAG_SET (sq->srcpad, GST_PAD_PROXY_CAPS);
|
||||
|
||||
gst_pad_set_element_private (sq->sinkpad, (gpointer) sq);
|
||||
gst_pad_set_element_private (sq->srcpad, (gpointer) sq);
|
||||
|
|
|
@ -105,8 +105,8 @@ static void gst_output_selector_release_pad (GstElement * element,
|
|||
static GstFlowReturn gst_output_selector_chain (GstPad * pad, GstBuffer * buf);
|
||||
static GstStateChangeReturn gst_output_selector_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
static gboolean gst_output_selector_handle_sink_event (GstPad * pad,
|
||||
GstEvent * event);
|
||||
static gboolean gst_output_selector_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_output_selector_query (GstPad * pad, GstQuery * query);
|
||||
static void gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector *
|
||||
sel, gint mode);
|
||||
|
||||
|
@ -161,7 +161,9 @@ gst_output_selector_init (GstOutputSelector * sel)
|
|||
gst_pad_set_chain_function (sel->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_output_selector_chain));
|
||||
gst_pad_set_event_function (sel->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_output_selector_handle_sink_event));
|
||||
GST_DEBUG_FUNCPTR (gst_output_selector_event));
|
||||
gst_pad_set_query_function (sel->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_output_selector_query));
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (sel), sel->sinkpad);
|
||||
|
||||
|
@ -280,15 +282,10 @@ gst_output_selector_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_output_selector_sink_getcaps (GstPad * pad, GstCaps * filter)
|
||||
static GstPad *
|
||||
gst_output_selector_get_active (GstOutputSelector * sel)
|
||||
{
|
||||
GstOutputSelector *sel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
GstPad *active = NULL;
|
||||
GstCaps *caps = NULL;
|
||||
|
||||
if (G_UNLIKELY (sel == NULL))
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
GST_OBJECT_LOCK (sel);
|
||||
if (sel->pending_srcpad)
|
||||
|
@ -297,16 +294,7 @@ gst_output_selector_sink_getcaps (GstPad * pad, GstCaps * filter)
|
|||
active = gst_object_ref (sel->active_srcpad);
|
||||
GST_OBJECT_UNLOCK (sel);
|
||||
|
||||
if (active) {
|
||||
caps = gst_pad_peer_get_caps (active, filter);
|
||||
gst_object_unref (active);
|
||||
}
|
||||
if (caps == NULL) {
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
}
|
||||
|
||||
gst_object_unref (sel);
|
||||
return caps;
|
||||
return active;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -314,14 +302,6 @@ gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector * sel,
|
|||
gint mode)
|
||||
{
|
||||
sel->pad_negotiation_mode = mode;
|
||||
if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL) {
|
||||
gst_pad_set_getcaps_function (sel->sinkpad, gst_pad_proxy_getcaps);
|
||||
} else if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE) {
|
||||
gst_pad_set_getcaps_function (sel->sinkpad, NULL);
|
||||
} else { /* active */
|
||||
gst_pad_set_getcaps_function (sel->sinkpad,
|
||||
gst_output_selector_sink_getcaps);
|
||||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -520,7 +500,7 @@ gst_output_selector_change_state (GstElement * element,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
|
||||
gst_output_selector_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstOutputSelector *sel;
|
||||
|
@ -544,13 +524,7 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
|
|||
gst_event_unref (event);
|
||||
break;
|
||||
default:
|
||||
GST_OBJECT_LOCK (sel);
|
||||
if (sel->pending_srcpad)
|
||||
active = gst_object_ref (sel->pending_srcpad);
|
||||
else if (sel->active_srcpad)
|
||||
active = gst_object_ref (sel->active_srcpad);
|
||||
GST_OBJECT_UNLOCK (sel);
|
||||
|
||||
active = gst_output_selector_get_active (sel);
|
||||
if (active) {
|
||||
res = gst_pad_push_event (active, event);
|
||||
gst_object_unref (active);
|
||||
|
@ -578,14 +552,8 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
|
|||
break;
|
||||
default:
|
||||
{
|
||||
GST_OBJECT_LOCK (sel);
|
||||
if (sel->pending_srcpad)
|
||||
active = gst_object_ref (sel->pending_srcpad);
|
||||
else if (sel->active_srcpad)
|
||||
active = gst_object_ref (sel->active_srcpad);
|
||||
GST_OBJECT_UNLOCK (sel);
|
||||
|
||||
/* Send other events to pending or active src pad */
|
||||
active = gst_output_selector_get_active (sel);
|
||||
if (active) {
|
||||
res = gst_pad_push_event (active, event);
|
||||
gst_object_unref (active);
|
||||
|
@ -600,3 +568,47 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_output_selector_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstOutputSelector *sel;
|
||||
GstPad *active = NULL;
|
||||
|
||||
sel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (sel == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
switch (sel->pad_negotiation_mode) {
|
||||
case GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL:
|
||||
/* Send caps to all src pads */
|
||||
res = gst_pad_proxy_query_caps (pad, query);
|
||||
break;
|
||||
case GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE:
|
||||
res = FALSE;
|
||||
break;
|
||||
default:
|
||||
active = gst_output_selector_get_active (sel);
|
||||
if (active) {
|
||||
res = gst_pad_peer_query (active, query);
|
||||
gst_object_unref (active);
|
||||
} else {
|
||||
res = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gst_object_unref (sel);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -202,8 +202,6 @@ static gboolean gst_queue_handle_sink_query (GstPad * pad, GstQuery * query);
|
|||
static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstCaps *gst_queue_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer);
|
||||
static GstPadLinkReturn gst_queue_link_src (GstPad * pad, GstPad * peer);
|
||||
static void gst_queue_locked_flush (GstQueue * queue);
|
||||
|
@ -368,17 +366,15 @@ gst_queue_class_init (GstQueueClass * klass)
|
|||
gst_static_pad_template_get (&sinktemplate));
|
||||
|
||||
/* Registering debug symbols for function pointers */
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_chain);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_src_activate_push);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_sink_activate_push);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_sink);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_src);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_sink_event);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_sink_query);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_sink);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_getcaps);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_acceptcaps);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_src_activate_push);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_src);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_src_event);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_src_query);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_queue_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -392,7 +388,6 @@ gst_queue_init (GstQueue * queue)
|
|||
gst_pad_set_event_function (queue->sinkpad, gst_queue_handle_sink_event);
|
||||
gst_pad_set_query_function (queue->sinkpad, gst_queue_handle_sink_query);
|
||||
gst_pad_set_link_function (queue->sinkpad, gst_queue_link_sink);
|
||||
gst_pad_set_getcaps_function (queue->sinkpad, gst_queue_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
||||
|
||||
queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
|
||||
|
@ -400,7 +395,6 @@ gst_queue_init (GstQueue * queue)
|
|||
gst_pad_set_activatepush_function (queue->srcpad,
|
||||
gst_queue_src_activate_push);
|
||||
gst_pad_set_link_function (queue->srcpad, gst_queue_link_src);
|
||||
gst_pad_set_getcaps_function (queue->srcpad, gst_queue_getcaps);
|
||||
gst_pad_set_event_function (queue->srcpad, gst_queue_handle_src_event);
|
||||
gst_pad_set_query_function (queue->srcpad, gst_queue_handle_src_query);
|
||||
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
||||
|
@ -456,46 +450,6 @@ gst_queue_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_queue_acceptcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
gboolean result;
|
||||
GstQueue *queue;
|
||||
GstPad *otherpad;
|
||||
|
||||
queue = GST_QUEUE (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (queue == NULL))
|
||||
return FALSE;
|
||||
|
||||
otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
|
||||
result = gst_pad_peer_accept_caps (otherpad, caps);
|
||||
|
||||
gst_object_unref (queue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_queue_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstQueue *queue;
|
||||
GstPad *otherpad;
|
||||
GstCaps *result;
|
||||
|
||||
queue = GST_QUEUE (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (queue == NULL))
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
|
||||
result = gst_pad_peer_get_caps (otherpad, filter);
|
||||
if (result == NULL)
|
||||
result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
gst_object_unref (queue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_queue_link_sink (GstPad * pad, GstPad * peer)
|
||||
{
|
||||
|
@ -874,8 +828,10 @@ gst_queue_handle_sink_query (GstPad * pad, GstQuery * query)
|
|||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
case GST_QUERY_CAPS:
|
||||
default:
|
||||
res = gst_pad_peer_query (queue->srcpad, query);
|
||||
if (!(res = gst_pad_peer_query (queue->srcpad, query)))
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
gst_object_unref (queue);
|
||||
|
@ -1093,9 +1049,6 @@ gst_queue_push_one (GstQueue * queue)
|
|||
next:
|
||||
if (is_buffer) {
|
||||
GstBuffer *buffer;
|
||||
#if 0
|
||||
GstCaps *caps;
|
||||
#endif
|
||||
|
||||
buffer = GST_BUFFER_CAST (data);
|
||||
|
||||
|
@ -1110,21 +1063,8 @@ next:
|
|||
}
|
||||
queue->head_needs_discont = FALSE;
|
||||
}
|
||||
#if 0
|
||||
caps = GST_BUFFER_CAPS (buffer);
|
||||
#endif
|
||||
|
||||
GST_QUEUE_MUTEX_UNLOCK (queue);
|
||||
#if 0
|
||||
/* set the right caps on the pad now. We do this before pushing the buffer
|
||||
* because the pad_push call will check (using acceptcaps) if the buffer can
|
||||
* be set on the pad, which might fail because this will be propagated
|
||||
* upstream. Also note that if the buffer has NULL caps, it means that the
|
||||
* caps did not change, so we don't have to change caps on the pad. */
|
||||
if (caps && caps != GST_PAD_CAPS (queue->srcpad))
|
||||
gst_pad_set_caps (queue->srcpad, caps);
|
||||
#endif
|
||||
|
||||
if (queue->push_newsegment) {
|
||||
gst_queue_push_newsegment (queue);
|
||||
}
|
||||
|
|
|
@ -235,8 +235,6 @@ static gboolean gst_queue2_handle_src_query (GstPad * pad, GstQuery * query);
|
|||
static gboolean gst_queue2_handle_query (GstElement * element,
|
||||
GstQuery * query);
|
||||
|
||||
static GstCaps *gst_queue2_getcaps (GstPad * pad, GstCaps * filter);
|
||||
|
||||
static GstFlowReturn gst_queue2_get_range (GstPad * pad, guint64 offset,
|
||||
guint length, GstBuffer ** buffer);
|
||||
|
||||
|
@ -381,8 +379,7 @@ gst_queue2_init (GstQueue2 * queue)
|
|||
GST_DEBUG_FUNCPTR (gst_queue2_handle_sink_event));
|
||||
gst_pad_set_query_function (queue->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_handle_sink_query));
|
||||
gst_pad_set_getcaps_function (queue->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_getcaps));
|
||||
GST_OBJECT_FLAG_SET (queue->sinkpad, GST_PAD_PROXY_CAPS);
|
||||
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
|
||||
|
||||
queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
|
||||
|
@ -393,12 +390,11 @@ gst_queue2_init (GstQueue2 * queue)
|
|||
GST_DEBUG_FUNCPTR (gst_queue2_src_activate_push));
|
||||
gst_pad_set_getrange_function (queue->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_get_range));
|
||||
gst_pad_set_getcaps_function (queue->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_getcaps));
|
||||
gst_pad_set_event_function (queue->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_handle_src_event));
|
||||
gst_pad_set_query_function (queue->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_queue2_handle_src_query));
|
||||
GST_OBJECT_FLAG_SET (queue->srcpad, GST_PAD_PROXY_CAPS);
|
||||
gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad);
|
||||
|
||||
/* levels */
|
||||
|
@ -609,27 +605,6 @@ init_ranges (GstQueue2 * queue)
|
|||
queue->current = add_range (queue, 0);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_queue2_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstQueue2 *queue;
|
||||
GstPad *otherpad;
|
||||
GstCaps *result;
|
||||
|
||||
queue = GST_QUEUE2 (gst_pad_get_parent (pad));
|
||||
if (G_UNLIKELY (queue == NULL))
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
|
||||
result = gst_pad_peer_get_caps (otherpad, filter);
|
||||
if (result == NULL)
|
||||
result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
|
||||
gst_object_unref (queue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* calculate the diff between running time on the sink and src of the queue.
|
||||
* This is the total amount of time in the queue. */
|
||||
static void
|
||||
|
@ -2050,7 +2025,7 @@ gst_queue2_handle_sink_query (GstPad * pad, GstQuery * query)
|
|||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
default:
|
||||
res = gst_pad_peer_query (queue->srcpad, query);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
gst_object_unref (queue);
|
||||
|
@ -2594,7 +2569,7 @@ gst_queue2_handle_src_query (GstPad * pad, GstQuery * query)
|
|||
}
|
||||
default:
|
||||
/* peer handled other queries */
|
||||
if (!gst_pad_peer_query (queue->sinkpad, query))
|
||||
if (!gst_pad_query_default (pad, query))
|
||||
goto peer_failed;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@ static GstFlowReturn gst_tee_chain (GstPad * pad, GstBuffer * buffer);
|
|||
static GstFlowReturn gst_tee_chain_list (GstPad * pad, GstBufferList * list);
|
||||
static gboolean gst_tee_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_tee_sink_query (GstPad * pad, GstQuery * query);
|
||||
static gboolean gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps);
|
||||
static gboolean gst_tee_sink_activate_push (GstPad * pad, gboolean active);
|
||||
static gboolean gst_tee_src_query (GstPad * pad, GstQuery * query);
|
||||
static gboolean gst_tee_src_activate_pull (GstPad * pad, gboolean active);
|
||||
|
@ -252,13 +251,12 @@ gst_tee_init (GstTee * tee)
|
|||
GST_DEBUG_FUNCPTR (gst_tee_sink_event));
|
||||
gst_pad_set_query_function (tee->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_tee_sink_query));
|
||||
gst_pad_set_getcaps_function (tee->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
|
||||
gst_pad_set_activatepush_function (tee->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_tee_sink_activate_push));
|
||||
gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
|
||||
gst_pad_set_chain_list_function (tee->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_tee_chain_list));
|
||||
GST_OBJECT_FLAG_SET (tee->sinkpad, GST_PAD_PROXY_CAPS);
|
||||
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
|
||||
|
||||
tee->last_message = NULL;
|
||||
|
@ -332,8 +330,6 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|||
if (!res)
|
||||
goto activate_failed;
|
||||
|
||||
gst_pad_set_getcaps_function (srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
|
||||
gst_pad_set_activatepull_function (srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_tee_src_activate_pull));
|
||||
gst_pad_set_query_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_src_query));
|
||||
|
@ -341,6 +337,7 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|||
GST_DEBUG_FUNCPTR (gst_tee_src_get_range));
|
||||
/* Forward sticky events to the new srcpad */
|
||||
gst_pad_sticky_events_foreach (tee->sinkpad, forward_sticky_events, srcpad);
|
||||
GST_OBJECT_FLAG_SET (srcpad, GST_PAD_PROXY_CAPS);
|
||||
gst_element_add_pad (GST_ELEMENT_CAST (tee), srcpad);
|
||||
|
||||
return srcpad;
|
||||
|
@ -494,67 +491,16 @@ gst_tee_sink_event (GstPad * pad, GstEvent * event)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* on the sink we accept caps that are acceptable to all srcpads */
|
||||
static gboolean
|
||||
gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstTee *tee;
|
||||
gboolean res, done;
|
||||
GstIterator *it;
|
||||
GValue item = { 0, };
|
||||
|
||||
tee = GST_TEE_CAST (GST_PAD_PARENT (pad));
|
||||
|
||||
it = gst_element_iterate_src_pads (GST_ELEMENT_CAST (tee));
|
||||
|
||||
res = TRUE;
|
||||
done = FALSE;
|
||||
while (!done && res) {
|
||||
switch (gst_iterator_next (it, &item)) {
|
||||
case GST_ITERATOR_OK:
|
||||
res &= gst_pad_peer_accept_caps (g_value_get_object (&item), caps);
|
||||
g_value_reset (&item);
|
||||
break;
|
||||
case GST_ITERATOR_RESYNC:
|
||||
res = TRUE;
|
||||
gst_iterator_resync (it);
|
||||
break;
|
||||
case GST_ITERATOR_ERROR:
|
||||
res = FALSE;
|
||||
done = TRUE;
|
||||
break;
|
||||
case GST_ITERATOR_DONE:
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_value_unset (&item);
|
||||
gst_iterator_free (it);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_tee_sink_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ACCEPT_CAPS:
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_query_parse_accept_caps (query, &caps);
|
||||
res = gst_tee_sink_acceptcaps (pad, caps);
|
||||
gst_query_set_accept_caps_result (query, res);
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ static void gst_valve_set_property (GObject * object,
|
|||
static void gst_valve_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_valve_event (GstPad * pad, GstEvent * event);
|
||||
static GstFlowReturn gst_valve_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static GstCaps *gst_valve_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static gboolean gst_valve_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_valve_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
#define _do_init \
|
||||
GST_DEBUG_CATEGORY_INIT (valve_debug, "valve", 0, "Valve");
|
||||
|
@ -115,17 +115,17 @@ gst_valve_init (GstValve * valve)
|
|||
valve->discont = FALSE;
|
||||
|
||||
valve->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
|
||||
gst_pad_set_getcaps_function (valve->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_getcaps));
|
||||
gst_pad_set_query_function (valve->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_query));
|
||||
gst_element_add_pad (GST_ELEMENT (valve), valve->srcpad);
|
||||
|
||||
valve->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
|
||||
gst_pad_set_chain_function (valve->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_chain));
|
||||
gst_pad_set_event_function (valve->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_event));
|
||||
gst_pad_set_getcaps_function (valve->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_getcaps));
|
||||
GST_DEBUG_FUNCPTR (gst_valve_sink_event));
|
||||
gst_pad_set_query_function (valve->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_valve_query));
|
||||
gst_element_add_pad (GST_ELEMENT (valve), valve->sinkpad);
|
||||
}
|
||||
|
||||
|
@ -193,11 +193,15 @@ gst_valve_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
|
||||
static gboolean
|
||||
gst_valve_event (GstPad * pad, GstEvent * event)
|
||||
gst_valve_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad));
|
||||
GstValve *valve;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
valve = GST_VALVE (gst_pad_get_parent (pad));
|
||||
if (valve == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (g_atomic_int_get (&valve->drop))
|
||||
gst_event_unref (event);
|
||||
else
|
||||
|
@ -213,21 +217,30 @@ gst_valve_event (GstPad * pad, GstEvent * event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_valve_getcaps (GstPad * pad, GstCaps * filter)
|
||||
static gboolean
|
||||
gst_valve_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstValve *valve = GST_VALVE (gst_pad_get_parent (pad));
|
||||
GstCaps *caps;
|
||||
GstValve *valve;
|
||||
gboolean res;
|
||||
GstPad *otherpad;
|
||||
|
||||
if (pad == valve->sinkpad)
|
||||
caps = gst_pad_peer_get_caps (valve->srcpad, filter);
|
||||
else
|
||||
caps = gst_pad_peer_get_caps (valve->sinkpad, filter);
|
||||
valve = GST_VALVE (gst_pad_get_parent (pad));
|
||||
if (valve == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (caps == NULL)
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
otherpad = (pad == valve->sinkpad ? valve->srcpad : valve->sinkpad);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:
|
||||
if (!(res = gst_pad_peer_query (otherpad, query)))
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
default:
|
||||
res = gst_pad_peer_query (otherpad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_object_unref (valve);
|
||||
|
||||
return caps;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -289,10 +289,27 @@ GST_START_TEST (test_request_pads_named)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static GstCaps *
|
||||
mq_dummypad_getcaps (GstPad * sinkpad, GstCaps * filter)
|
||||
static gboolean
|
||||
mq_dummypad_query (GstPad * sinkpad, GstQuery * query)
|
||||
{
|
||||
return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
gboolean res = TRUE;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CAPS:
|
||||
{
|
||||
GstCaps *filter, *caps;
|
||||
|
||||
gst_query_parse_caps (query, &filter);
|
||||
caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
|
||||
gst_query_set_caps_result (query, caps);
|
||||
gst_caps_unref (caps);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (sinkpad, query);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct PadData
|
||||
|
@ -432,11 +449,11 @@ run_output_order_test (gint n_linked)
|
|||
name = g_strdup_printf ("dummysrc%d", i);
|
||||
inputpads[i] = gst_pad_new (name, GST_PAD_SRC);
|
||||
g_free (name);
|
||||
gst_pad_set_getcaps_function (inputpads[i], mq_dummypad_getcaps);
|
||||
gst_pad_set_query_function (inputpads[i], mq_dummypad_query);
|
||||
|
||||
mq_sinkpad = gst_element_get_request_pad (mq, "sink_%u");
|
||||
fail_unless (mq_sinkpad != NULL);
|
||||
gst_pad_link (inputpads[i], mq_sinkpad);
|
||||
fail_unless (gst_pad_link (inputpads[i], mq_sinkpad) == GST_PAD_LINK_OK);
|
||||
|
||||
gst_pad_set_active (inputpads[i], TRUE);
|
||||
|
||||
|
@ -447,7 +464,7 @@ run_output_order_test (gint n_linked)
|
|||
g_free (name);
|
||||
gst_pad_set_chain_function (sinkpads[i], mq_dummypad_chain);
|
||||
gst_pad_set_event_function (sinkpads[i], mq_dummypad_event);
|
||||
gst_pad_set_getcaps_function (sinkpads[i], mq_dummypad_getcaps);
|
||||
gst_pad_set_query_function (sinkpads[i], mq_dummypad_query);
|
||||
|
||||
pad_data[i].pad_num = i;
|
||||
pad_data[i].max_linked_id_ptr = &max_linked_id;
|
||||
|
@ -459,7 +476,7 @@ run_output_order_test (gint n_linked)
|
|||
pad_data[i].first_buf = TRUE;
|
||||
gst_pad_set_element_private (sinkpads[i], pad_data + i);
|
||||
|
||||
gst_pad_link (mq_srcpad, sinkpads[i]);
|
||||
fail_unless (gst_pad_link (mq_srcpad, sinkpads[i]) == GST_PAD_LINK_OK);
|
||||
gst_pad_set_active (sinkpads[i], TRUE);
|
||||
|
||||
gst_object_unref (mq_sinkpad);
|
||||
|
@ -588,11 +605,11 @@ GST_START_TEST (test_sparse_stream)
|
|||
name = g_strdup_printf ("dummysrc%d", i);
|
||||
inputpads[i] = gst_pad_new (name, GST_PAD_SRC);
|
||||
g_free (name);
|
||||
gst_pad_set_getcaps_function (inputpads[i], mq_dummypad_getcaps);
|
||||
gst_pad_set_query_function (inputpads[i], mq_dummypad_query);
|
||||
|
||||
mq_sinkpad = gst_element_get_request_pad (mq, "sink_%u");
|
||||
fail_unless (mq_sinkpad != NULL);
|
||||
gst_pad_link (inputpads[i], mq_sinkpad);
|
||||
fail_unless (gst_pad_link (inputpads[i], mq_sinkpad) == GST_PAD_LINK_OK);
|
||||
|
||||
gst_pad_set_active (inputpads[i], TRUE);
|
||||
|
||||
|
@ -603,7 +620,7 @@ GST_START_TEST (test_sparse_stream)
|
|||
g_free (name);
|
||||
gst_pad_set_chain_function (sinkpads[i], mq_dummypad_chain);
|
||||
gst_pad_set_event_function (sinkpads[i], mq_dummypad_event);
|
||||
gst_pad_set_getcaps_function (sinkpads[i], mq_dummypad_getcaps);
|
||||
gst_pad_set_query_function (sinkpads[i], mq_dummypad_query);
|
||||
|
||||
pad_data[i].pad_num = i;
|
||||
pad_data[i].max_linked_id_ptr = &max_linked_id;
|
||||
|
@ -615,7 +632,7 @@ GST_START_TEST (test_sparse_stream)
|
|||
pad_data[i].first_buf = TRUE;
|
||||
gst_pad_set_element_private (sinkpads[i], pad_data + i);
|
||||
|
||||
gst_pad_link (mq_srcpad, sinkpads[i]);
|
||||
fail_unless (gst_pad_link (mq_srcpad, sinkpads[i]) == GST_PAD_LINK_OK);
|
||||
gst_pad_set_active (sinkpads[i], TRUE);
|
||||
|
||||
gst_object_unref (mq_sinkpad);
|
||||
|
|
|
@ -975,7 +975,7 @@ GST_END_TEST;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
GST_START_TEST (test_pad_proxy_getcaps_aggregation)
|
||||
GST_START_TEST (test_pad_proxy_query_caps_aggregation)
|
||||
{
|
||||
GstElement *tee, *sink1, *sink2;
|
||||
GstCaps *caps;
|
||||
|
@ -1113,7 +1113,7 @@ gst_utils_suite (void)
|
|||
tcase_add_test (tc_chain, test_set_value_from_string);
|
||||
tcase_add_test (tc_chain, test_binary_search);
|
||||
|
||||
tcase_add_test (tc_chain, test_pad_proxy_getcaps_aggregation);
|
||||
tcase_add_test (tc_chain, test_pad_proxy_query_caps_aggregation);
|
||||
tcase_add_test (tc_chain, test_greatest_common_divisor);
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -773,10 +773,6 @@ print_pad_info (GstElement * element)
|
|||
n_print (" Has custom iterintlinkfunc(): %s\n",
|
||||
GST_DEBUG_FUNCPTR_NAME (pad->iterintlinkfunc));
|
||||
|
||||
if (pad->getcapsfunc)
|
||||
n_print (" Has getcapsfunc(): %s\n",
|
||||
GST_DEBUG_FUNCPTR_NAME (pad->getcapsfunc));
|
||||
|
||||
if (pad->padtemplate)
|
||||
n_print (" Pad Template: '%s'\n", pad->padtemplate->name_template);
|
||||
|
||||
|
|
Loading…
Reference in a new issue