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
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
}
}
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",
}
/* 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++;
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.
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);
}
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);
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)
{
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);
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);
}
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 ())
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
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,
}
/**
- * 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.
* @sinkpad: the sink #GstPad to unlink.
/* 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.*/
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
* 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
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;
}
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;
- }
}
/**
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);
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);
}
* @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;
}
/**
* 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.
*
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);
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);
/* 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);
}
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;
}
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:
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:
* 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
* 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
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;
* @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
GCond *block_cond;
GHookList probes;
- /* the pad capabilities */
- GstPadGetCapsFunction getcapsfunc;
-
GstPadActivateMode mode;
GstPadActivateFunction activatefunc;
GstPadActivateModeFunction activatepushfunc;
#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)
#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))
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 */
"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];
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];
/**
* 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);
}
/**
- * 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;
}
/**
- * 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;
*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);
+}
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
}
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);
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 */
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:
{
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;
}
}
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;
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;
}
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;
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;
}
}
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;
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;
}
/* 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);
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);
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,
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");
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.
}
static gboolean
-gst_base_parse_query (GstPad * pad, GstQuery * query)
+gst_base_parse_src_query (GstPad * pad, GstQuery * query)
{
GstBaseParse *parse;
gboolean res = FALSE;
}
}
-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)
{
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);
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);
}
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) {
}
}
}
- gst_object_unref (bsink);
return caps;
}
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);
/* 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);
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;
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);
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);
}
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;
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)
{
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;
}
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,
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,
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,
* 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 */
if (peercaps)
gst_caps_unref (peercaps);
- gst_object_unref (trans);
-
return caps;
}
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);
}
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;
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);
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);
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)
{
}
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)
{
GstElement *funnel;
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);
{
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
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);
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;
{
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:
{
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)
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,
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);
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)
{
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;
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);
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);
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);
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);
}
}
-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)
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
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
}
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;
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);
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);
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;
+}
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);
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_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_sink_event);
+ GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_sink_query);
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
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");
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);
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)
{
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);
next:
if (is_buffer) {
GstBuffer *buffer;
-#if 0
- GstCaps *caps;
-#endif
buffer = GST_BUFFER_CAST (data);
}
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);
}
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);
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");
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 */
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
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);
}
default:
/* peer handled other queries */
- if (!gst_pad_peer_query (queue->sinkpad, query))
+ if (!gst_pad_query_default (pad, query))
goto peer_failed;
break;
}
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);
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;
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));
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;
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;
}
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");
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);
}
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
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;
+
+ otherpad = (pad == valve->sinkpad ? valve->srcpad : valve->sinkpad);
- if (caps == NULL)
- caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
+ 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;
}
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
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);
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;
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);
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);
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;
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);
#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;
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;
}
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);