From a31faecb8b82414bc51ed460f1f85e893d98c0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 19 Nov 2014 17:03:41 +0100 Subject: [PATCH] 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 --- gst-libs/gst/base/gstaggregator.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/base/gstaggregator.c b/gst-libs/gst/base/gstaggregator.c index 5a5a06eef4..6e2f8b0439 100644 --- a/gst-libs/gst/base/gstaggregator.c +++ b/gst-libs/gst/base/gstaggregator.c @@ -1563,7 +1563,7 @@ _chain (GstPad * pad, GstObject * object, GstBuffer * buffer) PAD_LOCK_EVENT (aggpad); - if (aggpad->buffer) { + while (aggpad->buffer) { GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed"); PAD_WAIT_EVENT (aggpad); } @@ -1617,8 +1617,18 @@ eos: static gboolean pad_query_func (GstPad * pad, GstObject * parent, GstQuery * query) { + GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad); 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), GST_AGGREGATOR_PAD (pad), query); } @@ -1626,8 +1636,19 @@ pad_query_func (GstPad * pad, GstObject * parent, GstQuery * query) static gboolean pad_event_func (GstPad * pad, GstObject * parent, GstEvent * event) { + GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad); 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), GST_AGGREGATOR_PAD (pad), event); }