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:
Wim Taymans 2011-11-15 11:20:48 +01:00
parent d162d97e1f
commit b5c3e254b1
29 changed files with 748 additions and 881 deletions

View file

@ -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

View file

@ -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",

View file

@ -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++;

View file

@ -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);
}

View file

@ -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 ())

View file

@ -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

View file

@ -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,10 +2741,17 @@ 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;
}
if (forward) {
EventData data;
data.event = event;
data.dispatched = FALSE;
data.result = FALSE;
@ -2927,6 +2764,7 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
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:

View file

@ -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 */

View file

@ -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];

View file

@ -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];

View file

@ -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);
}

View file

@ -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

View file

@ -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;
if (G_LIKELY (gst_pad_peer_query (pad, query))) {
GstCaps *existing, *peercaps, *intersection;
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);
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;
}

View file

@ -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);

View file

@ -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)
{

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);