+2007-10-15 Wim Taymans <wim.taymans@gmail.com>
+
+ * plugins/elements/gstmultiqueue.c: (gst_single_queue_push_one),
+ (gst_single_queue_new):
+ * plugins/elements/gstqueue.c: (gst_queue_init),
+ (gst_queue_push_one):
+ Fix queue negotiation. If acceptcaps unconditionally returns TRUE,
+ upstream is tricked into thinking it can suggest a format downstream
+ while downstream does not support that format. The real problem is that
+ core calls acceptcaps when pushing a buffer with new caps, for which we
+ do a little workaround by setting the caps on the srcpad ourselves
+ before pushing the buffer (until this is figured out). Fixes #486758.
+
2007-10-15 Stefan Kost <ensonic@users.sf.net>
* gst/gststructure.c:
if (GST_IS_BUFFER (object)) {
GstBuffer *buffer;
GstClockTime timestamp, duration;
+ GstCaps *caps;
buffer = GST_BUFFER_CAST (object);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
+ caps = GST_BUFFER_CAPS (buffer);
apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
"SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
sq->id, buffer, GST_TIME_ARGS (timestamp));
+ /* Set caps on pad before pushing, this avoids core calling the accpetcaps
+ * function on the srcpad, which will call acceptcaps upstream, which might
+ * not accept these caps (anymore). */
+ if (caps && caps != GST_PAD_CAPS (sq->srcpad))
+ gst_pad_set_caps (sq->srcpad, caps);
+
result = gst_pad_push (sq->srcpad, buffer);
} else if (GST_IS_EVENT (object)) {
GstEvent *event;
}
static gboolean
-gst_multi_queue_acceptcaps (GstPad * pad, GstCaps * caps)
-{
- return TRUE;
-}
-
-static gboolean
gst_multi_queue_src_event (GstPad * pad, GstEvent * event)
{
GstSingleQueue *sq = gst_pad_get_element_private (pad);
gst_pad_set_activatepush_function (sq->srcpad,
GST_DEBUG_FUNCPTR (gst_multi_queue_src_activate_push));
- gst_pad_set_acceptcaps_function (sq->srcpad,
- GST_DEBUG_FUNCPTR (gst_multi_queue_acceptcaps));
gst_pad_set_getcaps_function (sq->srcpad,
GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
gst_pad_set_event_function (sq->srcpad,
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 GstFlowReturn gst_queue_push_one (GstQueue * queue);
static void gst_queue_loop (GstPad * pad);
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,
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;
-}
-
/* calculate the diff between running time on the sink and src of the queue.
* This is the total amount of time in the queue. */
static void
next:
if (GST_IS_BUFFER (data)) {
- GstBuffer *buffer = GST_BUFFER_CAST (data);
+ GstBuffer *buffer;
+ GstCaps *caps;
+
+ buffer = GST_BUFFER_CAST (data);
+ caps = GST_BUFFER_CAPS (buffer);
GST_QUEUE_MUTEX_UNLOCK (queue);
+ /* set the right caps on the pad now. We do this before pushing the buffer
+ * because the pad_push call will check (using acceptcaps) if the buffer can
+ * be set on the pad, which might fail because this will be propagated
+ * upstream. Also note that if the buffer has NULL caps, it means that the
+ * caps did not change, so we don't have to change caps on the pad. */
+ if (caps && caps != GST_PAD_CAPS (queue->srcpad))
+ gst_pad_set_caps (queue->srcpad, caps);
result = gst_pad_push (queue->srcpad, buffer);