aggregator: Block serialized events/queries until the pad has consumed all buffers

Otherwise the caps of the pad might change while the subclass still works with
a buffer of the old caps, assuming the the current pad caps apply to that
buffer. Which then leads to crashes and other nice effects.

https://bugzilla.gnome.org/show_bug.cgi?id=740376
This commit is contained in:
Sebastian Dröge 2014-11-19 17:03:41 +01:00 committed by Tim-Philipp Müller
parent e3b42c8acb
commit 0ad159dfb4

View file

@ -1563,7 +1563,7 @@ _chain (GstPad * pad, GstObject * object, GstBuffer * buffer)
PAD_LOCK_EVENT (aggpad); PAD_LOCK_EVENT (aggpad);
if (aggpad->buffer) { while (aggpad->buffer) {
GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed"); GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
PAD_WAIT_EVENT (aggpad); PAD_WAIT_EVENT (aggpad);
} }
@ -1617,8 +1617,18 @@ eos:
static gboolean static gboolean
pad_query_func (GstPad * pad, GstObject * parent, GstQuery * query) pad_query_func (GstPad * pad, GstObject * parent, GstQuery * query)
{ {
GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
GstAggregatorClass *klass = GST_AGGREGATOR_GET_CLASS (parent); GstAggregatorClass *klass = GST_AGGREGATOR_GET_CLASS (parent);
if (GST_QUERY_IS_SERIALIZED (query)) {
PAD_LOCK_EVENT (aggpad);
while (aggpad->buffer) {
GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
PAD_WAIT_EVENT (aggpad);
}
PAD_UNLOCK_EVENT (aggpad);
}
return klass->sink_query (GST_AGGREGATOR (parent), return klass->sink_query (GST_AGGREGATOR (parent),
GST_AGGREGATOR_PAD (pad), query); GST_AGGREGATOR_PAD (pad), query);
} }
@ -1626,8 +1636,19 @@ pad_query_func (GstPad * pad, GstObject * parent, GstQuery * query)
static gboolean static gboolean
pad_event_func (GstPad * pad, GstObject * parent, GstEvent * event) pad_event_func (GstPad * pad, GstObject * parent, GstEvent * event)
{ {
GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
GstAggregatorClass *klass = GST_AGGREGATOR_GET_CLASS (parent); GstAggregatorClass *klass = GST_AGGREGATOR_GET_CLASS (parent);
if (GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_TYPE (event) != GST_EVENT_EOS
&& GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT_DONE) {
PAD_LOCK_EVENT (aggpad);
while (aggpad->buffer) {
GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
PAD_WAIT_EVENT (aggpad);
}
PAD_UNLOCK_EVENT (aggpad);
}
return klass->sink_event (GST_AGGREGATOR (parent), return klass->sink_event (GST_AGGREGATOR (parent),
GST_AGGREGATOR_PAD (pad), event); GST_AGGREGATOR_PAD (pad), event);
} }