diff --git a/ChangeLog b/ChangeLog index 375f46bb8a..1703b72670 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-05-18 Jan Schmidt + + * plugins/elements/gstcapsfilter.c: (gst_capsfilter_prepare_buf): + The caps intersection algorithm can produce multiple copies of the + caps. Until that is fixed, we need to simplify the result to be + sure whether the allowed caps are fixed or not. + + * plugins/elements/gstqueue.c: (gst_queue_init), + (gst_queue_bufferalloc), (gst_queue_acceptcaps), + (gst_queue_push_one): + Proxied buffer alloc should not set the caps on the source pad. + When pushing buffers, we always accept the caps change that triggers. + This prevents negotiation errors caused by caps changing mid-stream + and then being refused on our source pad (because upstream is now + refusing those caps). + 2006-05-18 Tim-Philipp Müller * tests/examples/helloworld/helloworld.c: (main): diff --git a/plugins/elements/gstcapsfilter.c b/plugins/elements/gstcapsfilter.c index f8ce429ed3..f01abf712e 100644 --- a/plugins/elements/gstcapsfilter.c +++ b/plugins/elements/gstcapsfilter.c @@ -257,6 +257,9 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input, g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR); } + out_caps = gst_caps_make_writable (out_caps); + gst_caps_do_simplify (out_caps); + if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) { GST_DEBUG_OBJECT (trans, "Have fixed output caps %" GST_PTR_FORMAT " to apply to buffer with no caps", out_caps); @@ -272,6 +275,8 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input, if (GST_PAD_CAPS (trans->srcpad) == NULL) gst_pad_set_caps (trans->srcpad, out_caps); } else { + GST_DEBUG_OBJECT (trans, "Have unfixed output caps %" GST_PTR_FORMAT, + out_caps); gst_caps_unref (out_caps); } } diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index b399f07599..8b7c4ff782 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -146,6 +146,7 @@ static void gst_queue_get_property (GObject * object, static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); +static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps); static gboolean gst_queue_push_one (GstQueue * queue); static void gst_queue_loop (GstPad * pad); @@ -357,6 +358,8 @@ gst_queue_init (GstQueue * queue) GST_DEBUG_FUNCPTR (gst_queue_src_activate_push)); gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link_src)); + gst_pad_set_acceptcaps_function (queue->srcpad, + GST_DEBUG_FUNCPTR (gst_queue_acceptcaps)); gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); gst_pad_set_event_function (queue->srcpad, @@ -476,13 +479,19 @@ gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, queue = GST_QUEUE (GST_PAD_PARENT (pad)); - result = - gst_pad_alloc_buffer_and_set_caps (queue->srcpad, offset, size, caps, - buf); + /* Forward to src pad, without setting caps on the src pad */ + result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf); return result; } +static gboolean +gst_queue_acceptcaps (GstPad * pad, GstCaps * caps) +{ + /* The only time our acceptcaps method should be called is on the srcpad + * when we push a buffer, in which case we always accept those caps */ + return TRUE; +} static void gst_queue_locked_flush (GstQueue * queue) @@ -767,6 +776,11 @@ gst_queue_push_one (GstQueue * queue) queue->cur_level.time -= GST_BUFFER_DURATION (data); GST_QUEUE_MUTEX_UNLOCK (queue); + /* Set caps on the src pad first, because otherwise when we push it will + * check that we accept the caps which checks upstream, whereas + * explicitly setting the caps doesn't */ + gst_pad_set_caps (queue->srcpad, GST_BUFFER_CAPS (data)); + result = gst_pad_push (queue->srcpad, GST_BUFFER (data)); /* need to check for srcresult here as well */ GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);