diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2009-02-18 15:20:58 -0500 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2009-02-21 17:48:57 +0100 |
commit | f5a8eb59afee4caf434a74fb27a504350f6fc753 (patch) | |
tree | 0fda775173bc1f61938b8238fecd75368a3cb43e /gst | |
parent | 44b6071bd72cd4596f7275cea8f3105d9832f8ac (diff) | |
download | gstreamer-plugins-bad-f5a8eb59afee4caf434a74fb27a504350f6fc753.tar.gz |
[MOVED FROM GST-P-FARSIGHT] Have getcaps to force the same clockrate on all pads
Diffstat (limited to 'gst')
-rw-r--r-- | gst/rtpmux/gstrtpmux.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/gst/rtpmux/gstrtpmux.c b/gst/rtpmux/gstrtpmux.c index f46008519..1b8181359 100644 --- a/gst/rtpmux/gstrtpmux.c +++ b/gst/rtpmux/gstrtpmux.c @@ -93,6 +93,7 @@ static void gst_rtp_mux_release_pad (GstElement * element, GstPad *pad); static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer); static gboolean gst_rtp_mux_setcaps (GstPad *pad, GstCaps *caps); +static GstCaps * gst_rtp_mux_getcaps (GstPad *pad); static GstStateChangeReturn gst_rtp_mux_change_state (GstElement * element, GstStateChange transition); @@ -284,6 +285,7 @@ gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad) /* setup some pad functions */ gst_pad_set_setcaps_function (sinkpad, gst_rtp_mux_setcaps); + gst_pad_set_getcaps_function (sinkpad, gst_rtp_mux_getcaps); if (klass->chain_func) gst_pad_set_chain_function (sinkpad, klass->chain_func); if (klass->sink_event_func) @@ -428,6 +430,106 @@ gst_rtp_mux_setcaps (GstPad *pad, GstCaps *caps) } static void +clear_caps (GstCaps *caps) +{ + gint i, j; + + /* Lets only match on the clock-rate */ + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstStructure *s = gst_caps_get_structure (caps, i); + + for (j = 0; j < gst_structure_n_fields (s); j++) { + const gchar *name = gst_structure_nth_field_name (s, j); + + if (strcmp (name, "clock-rate")) { + gst_structure_remove_field (s, name); + j--; + } + } + } +} + +static gboolean +same_clock_rate_fold (gpointer item, GValue *ret, gpointer user_data) +{ + GstPad *mypad = user_data; + GstPad *pad = item; + GstCaps *peercaps; + GstCaps *othercaps; + const GstCaps *accumcaps; + GstCaps *intersect; + + if (pad == mypad) + return TRUE; + + peercaps = gst_pad_peer_get_caps (pad); + if (!peercaps) + return TRUE; + + othercaps = gst_caps_intersect (peercaps, + gst_pad_get_pad_template_caps (pad)); + gst_caps_unref (peercaps); + + accumcaps = gst_value_get_caps (ret); + + clear_caps (othercaps); + + intersect = gst_caps_intersect (accumcaps, othercaps); + + g_value_take_boxed (ret, intersect); + + gst_caps_unref (othercaps); + + return !gst_caps_is_empty (intersect); +} + +static GstCaps * +gst_rtp_mux_getcaps (GstPad *pad) +{ + GstRTPMux *mux = GST_RTP_MUX (gst_pad_get_parent (pad)); + GstCaps *caps = NULL; + GstIterator *iter = NULL; + GValue v = {0}; + GstIteratorResult res; + GstCaps *peercaps = gst_pad_peer_get_caps (mux->srcpad); + GstCaps *othercaps = NULL; + + if (peercaps) { + othercaps = gst_caps_intersect (peercaps, + gst_pad_get_pad_template_caps (pad)); + gst_caps_unref (peercaps); + } + else { + othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (mux->srcpad)); + } + + clear_caps (othercaps); + + g_value_init (&v, GST_TYPE_CAPS); + + iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux)); + do { + gst_value_set_caps (&v, othercaps); + res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad); + } while (res == GST_ITERATOR_RESYNC); + gst_iterator_free (iter); + + caps = (GstCaps*) gst_value_get_caps (&v); + + if (res == GST_ITERATOR_ERROR) { + gst_caps_unref (caps); + caps = gst_caps_new_empty (); + } + + if (othercaps) + gst_caps_unref (othercaps); + gst_object_unref (mux); + + return caps; +} + + +static void gst_rtp_mux_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { |