2003-12-23 David Schleef <ds@schleef.org>
+ * gst/elements/gstaggregator.c:
+ * gst/elements/gsttee.c:
+ Use gst_pad_proxy_getcaps().
+ * gst/gstpad.c:
+ * gst/gstpad.h:
+ Add gst_pad_proxy_getcaps(), which filter elements can use
+ as a generic getcaps implementation.
+ Fix gst_pad_get_allowed_caps(). It just wasn't doing what
+ was advertised.
+
+2003-12-23 David Schleef <ds@schleef.org>
+
* gst/gstpad.c:
Rearrange/rewrite much of the pad negotiation code, since it
resembled pasta. This actually changes the way some
gst_aggregator_init (GstAggregator *aggregator)
{
aggregator->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+ gst_pad_set_getcaps_function (aggregator->srcpad, gst_pad_proxy_getcaps);
gst_element_add_pad (GST_ELEMENT (aggregator), aggregator->srcpad);
aggregator->numsinkpads = 0;
if (!AGGREGATOR_IS_LOOP_BASED (aggregator)) {
gst_pad_set_chain_function (sinkpad, gst_aggregator_chain);
}
+ gst_pad_set_getcaps_function (sinkpad, gst_pad_proxy_getcaps);
gst_element_add_pad (GST_ELEMENT (aggregator), sinkpad);
aggregator->sinkpads = g_list_prepend (aggregator->sinkpads, sinkpad);
return gst_pad_proxy_link (tee->sinkpad, caps);
}
-static GstCaps*
-gst_tee_getcaps (GstPad *pad)
-{
- GstCaps *caps = GST_CAPS_ANY;
- GstTee *tee;
- const GList *pads;
-
- GST_DEBUG ( "gst_tee_getcaps");
-
- tee = GST_TEE (gst_pad_get_parent (pad));
-
- pads = gst_element_get_pad_list (GST_ELEMENT (tee));
-
- while (pads) {
- GstPad *srcpad = GST_PAD (pads->data);
- GstPad *peer;
- const GstCaps *peercaps;
- GstCaps *newcaps;
-
- pads = g_list_next (pads);
-
- peer = gst_pad_get_peer(srcpad);
- if(!peer){
- continue;
- }
-
- peercaps = gst_pad_get_caps (peer);
- newcaps = gst_caps_intersect (caps, peercaps);
- gst_caps_free (caps);
- caps = newcaps;
- }
-
- return caps;
-}
-
static void
gst_tee_init (GstTee *tee)
{
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_sinklink));
- gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps));
+ gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
tee->silent = FALSE;
tee->last_message = NULL;
srcpad = gst_pad_new_from_template (templ, name);
g_free (name);
gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_srclink));
- gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps));
+ gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (tee), srcpad);
GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;
}
/**
+ * gst_pad_proxy_getcaps:
+ * @pad: a #GstPad to proxy.
+ *
+ * Calls gst_pad_get_allowed_caps() for every other pad 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
+ * that can handle any stream format, but requires all its pads to have
+ * the same caps. Two such elements are tee and aggregator.
+ *
+ * Returns: the intersection of the other pads' allowed caps.
+ */
+GstCaps *
+gst_pad_proxy_getcaps (GstPad *pad)
+{
+ GstElement *element;
+ const GList *pads;
+ GstCaps *caps;
+
+ element = gst_pad_get_parent (pad);
+
+ pads = gst_element_get_pad_list (element);
+
+ caps = gst_caps_new_any ();
+ while (pads) {
+ GstPad *otherpad = GST_PAD (pads->data);
+ GstCaps *temp;
+
+ if (otherpad != pad) {
+ temp = gst_caps_intersect (caps, gst_pad_get_allowed_caps (pad));
+ gst_caps_free (caps);
+ caps = temp;
+ }
+
+ pads = g_list_next (pads);
+ }
+
+ return caps;
+}
+
+/**
* gst_pad_proxy_link:
* @pad: a #GstPad to proxy to.
* @caps: the #GstCaps to use in proxying.
gst_pad_get_allowed_caps (GstPad *pad)
{
GstRealPad *realpad;
- GstCaps *mycaps;
+ const GstCaps *mycaps;
GstCaps *caps;
- GstCaps *filtercaps;
GstCaps *peercaps;
+ GstCaps *icaps;
+ GstPadLink *link;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
GST_CAT_DEBUG (GST_CAT_PROPERTIES, "get allowed caps of %s:%s",
GST_DEBUG_PAD_NAME (pad));
- mycaps = gst_pad_get_caps (pad);
+ mycaps = gst_pad_get_pad_template_caps (pad);
if (GST_RPAD_PEER (realpad) == NULL) {
- return mycaps;
+ return gst_caps_copy (mycaps);
}
peercaps = gst_pad_get_caps (GST_PAD_PEER (realpad));
caps = gst_caps_intersect (mycaps, peercaps);
- gst_caps_free (mycaps);
gst_caps_free (peercaps);
- filtercaps = GST_RPAD_APPFILTER (realpad);
- if (filtercaps) {
- return gst_caps_intersect (caps, filtercaps);
+ link = GST_RPAD_LINK (realpad);
+ if (link->filtercaps) {
+ icaps = gst_caps_intersect (caps, link->filtercaps);
+ gst_caps_free (caps);
+ return icaps;
} else {
- return gst_caps_copy (caps);
+ return caps;
}
}
void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps);
void gst_pad_set_fixate_function (GstPad *pad, GstPadFixateFunction fixate);
+GstCaps * gst_pad_proxy_getcaps (GstPad *pad);
GstPadLinkReturn gst_pad_proxy_link (GstPad *pad, const GstCaps *caps);
gboolean gst_pad_relink_filtered (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps);
gboolean gst_pad_perform_negotiate (GstPad *srcpad, GstPad *sinkpad);
gst_aggregator_init (GstAggregator *aggregator)
{
aggregator->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+ gst_pad_set_getcaps_function (aggregator->srcpad, gst_pad_proxy_getcaps);
gst_element_add_pad (GST_ELEMENT (aggregator), aggregator->srcpad);
aggregator->numsinkpads = 0;
if (!AGGREGATOR_IS_LOOP_BASED (aggregator)) {
gst_pad_set_chain_function (sinkpad, gst_aggregator_chain);
}
+ gst_pad_set_getcaps_function (sinkpad, gst_pad_proxy_getcaps);
gst_element_add_pad (GST_ELEMENT (aggregator), sinkpad);
aggregator->sinkpads = g_list_prepend (aggregator->sinkpads, sinkpad);
return gst_pad_proxy_link (tee->sinkpad, caps);
}
-static GstCaps*
-gst_tee_getcaps (GstPad *pad)
-{
- GstCaps *caps = GST_CAPS_ANY;
- GstTee *tee;
- const GList *pads;
-
- GST_DEBUG ( "gst_tee_getcaps");
-
- tee = GST_TEE (gst_pad_get_parent (pad));
-
- pads = gst_element_get_pad_list (GST_ELEMENT (tee));
-
- while (pads) {
- GstPad *srcpad = GST_PAD (pads->data);
- GstPad *peer;
- const GstCaps *peercaps;
- GstCaps *newcaps;
-
- pads = g_list_next (pads);
-
- peer = gst_pad_get_peer(srcpad);
- if(!peer){
- continue;
- }
-
- peercaps = gst_pad_get_caps (peer);
- newcaps = gst_caps_intersect (caps, peercaps);
- gst_caps_free (caps);
- caps = newcaps;
- }
-
- return caps;
-}
-
static void
gst_tee_init (GstTee *tee)
{
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_sinklink));
- gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps));
+ gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
tee->silent = FALSE;
tee->last_message = NULL;
srcpad = gst_pad_new_from_template (templ, name);
g_free (name);
gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_srclink));
- gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps));
+ gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
gst_element_add_pad (GST_ELEMENT (tee), srcpad);
GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL;