diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2012-08-05 00:41:10 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2012-08-05 00:41:10 +0100 |
commit | 24478261a26a464ecf827787b94cc04061c2a88f (patch) | |
tree | fd502d81d523be44b84985037ccbda23364b193f /gst | |
parent | ec13933aaaa15cc7c0b83fd13abf8ccd12e47b9b (diff) | |
download | gstreamer-plugins-base-24478261a26a464ecf827787b94cc04061c2a88f.tar.gz |
adder: send CAPS event downstream fixing not-negotiated errors
Make sure to send a CAPS event downstream when we get our
first input caps. This fixes not-negotiated errors and
adder use with downstream elements other than fakesink.
Even gst-launch-1.0 audiotestsrc ! adder ! pulsesink works now.
Also, flag the other sink pads as FIXED_CAPS when we receive
the first CAPS event on one of the sink pads (in addition to
setting those caps on the the sink pads), so that a caps query
will just return the fixed caps from now on.
There's still a race between other upstreams checking if
caps are accepted and sending a first buffer with possibly
different caps than the first caps we receive on some other
pad, but such is life.
Also need to take into account optional fields better/properly.
https://bugzilla.gnome.org/show_bug.cgi?id=679545
Diffstat (limited to 'gst')
-rw-r--r-- | gst/adder/gstadder.c | 40 | ||||
-rw-r--r-- | gst/adder/gstadder.h | 5 |
2 files changed, 37 insertions, 8 deletions
diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index 8efb682f8..b8e4b7e28 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -252,8 +252,12 @@ setcapsfunc (const GValue * item, IterData * data) { GstPad *otherpad = g_value_get_object (item); - if (otherpad != data->pad) + if (otherpad != data->pad) { + GST_LOG_OBJECT (data->pad, "calling set_caps with %" GST_PTR_FORMAT, + data->caps); gst_pad_set_caps (data->pad, data->caps); + gst_pad_use_fixed_caps (data->pad); + } } /* the first caps we receive on any of the sinkpads will define the caps for all @@ -267,13 +271,32 @@ gst_adder_setcaps (GstAdder * adder, GstPad * pad, GstCaps * caps) IterData idata; gboolean done; - /* this get called recursively due to gst_iterator_foreach calling + /* this gets called recursively due to gst_iterator_foreach calling * gst_pad_set_caps() */ if (adder->in_setcaps) return TRUE; - GST_LOG_OBJECT (adder, "setting caps pad %p,%s to %" GST_PTR_FORMAT, pad, - GST_PAD_NAME (pad), caps); + /* don't allow reconfiguration for now; there's still a race between the + * different upstream threads doing query_caps + accept_caps + sending + * (possibly different) CAPS events, but there's not much we can do about + * that, upstream needs to deal with it. */ + if (adder->current_caps != NULL) { + /* FIXME: not quite right for optional fields such as channel-mask, which + * may or may not be present for mono/stereo */ + if (gst_caps_is_equal (caps, adder->current_caps)) { + return TRUE; + } else { + GST_DEBUG_OBJECT (pad, "got input caps %" GST_PTR_FORMAT ", but " + "current caps are %" GST_PTR_FORMAT, caps, adder->current_caps); + gst_pad_push_event (pad, gst_event_new_reconfigure ()); + return FALSE; + } + } + + GST_INFO_OBJECT (pad, "setting caps to %" GST_PTR_FORMAT, caps); + + adder->current_caps = gst_caps_ref (caps); + gst_pad_push_event (adder->srcpad, gst_event_new_caps (adder->current_caps)); it = gst_element_iterate_pads (GST_ELEMENT_CAST (adder)); @@ -300,8 +323,7 @@ gst_adder_setcaps (GstAdder * adder, GstPad * pad, GstCaps * caps) adder->in_setcaps = FALSE; gst_iterator_free (it); - GST_LOG_OBJECT (adder, "handle caps changes on pad %p,%s to %" GST_PTR_FORMAT, - pad, GST_PAD_NAME (pad), caps); + GST_INFO_OBJECT (pad, "handle caps change to %" GST_PTR_FORMAT, caps); if (!gst_audio_info_from_caps (&adder->info, caps)) goto invalid_format; @@ -339,7 +361,7 @@ gst_adder_setcaps (GstAdder * adder, GstPad * pad, GstCaps * caps) /* ERRORS */ invalid_format: { - GST_DEBUG_OBJECT (adder, "invalid format set as caps"); + GST_WARNING_OBJECT (adder, "invalid format set as caps"); return FALSE; } } @@ -889,6 +911,7 @@ gst_adder_init (GstAdder * adder) GST_PAD_SET_PROXY_CAPS (adder->srcpad); gst_element_add_pad (GST_ELEMENT (adder), adder->srcpad); + adder->current_caps = NULL; gst_audio_info_init (&adder->info); adder->padcount = 0; adder->func = NULL; @@ -915,6 +938,8 @@ gst_adder_dispose (GObject * object) adder->collect = NULL; } gst_caps_replace (&adder->filter_caps, NULL); + gst_caps_replace (&adder->current_caps, NULL); + if (adder->pending_events) { g_list_foreach (adder->pending_events, (GFunc) gst_event_unref, NULL); g_list_free (adder->pending_events); @@ -1313,6 +1338,7 @@ gst_adder_change_state (GstElement * element, GstStateChange transition) adder->flush_stop_pending = FALSE; adder->new_segment_pending = TRUE; adder->wait_for_new_segment = FALSE; + gst_caps_replace (&adder->current_caps, NULL); gst_segment_init (&adder->segment, GST_FORMAT_TIME); gst_collect_pads_start (adder->collect); break; diff --git a/gst/adder/gstadder.h b/gst/adder/gstadder.h index 7aa0fa36b..59d6f9bec 100644 --- a/gst/adder/gstadder.h +++ b/gst/adder/gstadder.h @@ -71,7 +71,10 @@ struct _GstAdder { /* src event handling */ volatile gboolean flush_stop_pending; - /* target caps */ + /* current caps */ + GstCaps *current_caps; + + /* target caps (set via property) */ GstCaps *filter_caps; /* Pending inline events */ |