mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
plugins/elements/: Fix queue negotiation. If acceptcaps unconditionally returns TRUE, upstream is tricked into thinki...
Original commit message from CVS: * 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.
This commit is contained in:
parent
68ba3b4384
commit
5363f86bb1
3 changed files with 33 additions and 20 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
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>
|
2007-10-15 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* gst/gststructure.c:
|
* gst/gststructure.c:
|
||||||
|
|
|
@ -601,10 +601,12 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
|
||||||
if (GST_IS_BUFFER (object)) {
|
if (GST_IS_BUFFER (object)) {
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstClockTime timestamp, duration;
|
GstClockTime timestamp, duration;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
buffer = GST_BUFFER_CAST (object);
|
buffer = GST_BUFFER_CAST (object);
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
duration = GST_BUFFER_DURATION (buffer);
|
duration = GST_BUFFER_DURATION (buffer);
|
||||||
|
caps = GST_BUFFER_CAPS (buffer);
|
||||||
|
|
||||||
apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
|
apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
|
||||||
|
|
||||||
|
@ -615,6 +617,12 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
|
||||||
"SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
|
"SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
|
||||||
sq->id, buffer, GST_TIME_ARGS (timestamp));
|
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);
|
result = gst_pad_push (sq->srcpad, buffer);
|
||||||
} else if (GST_IS_EVENT (object)) {
|
} else if (GST_IS_EVENT (object)) {
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
@ -1030,12 +1038,6 @@ gst_multi_queue_src_activate_push (GstPad * pad, gboolean active)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_multi_queue_acceptcaps (GstPad * pad, GstCaps * caps)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_multi_queue_src_event (GstPad * pad, GstEvent * event)
|
gst_multi_queue_src_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
@ -1345,8 +1347,6 @@ gst_single_queue_new (GstMultiQueue * mqueue)
|
||||||
|
|
||||||
gst_pad_set_activatepush_function (sq->srcpad,
|
gst_pad_set_activatepush_function (sq->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_multi_queue_src_activate_push));
|
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_pad_set_getcaps_function (sq->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
|
GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
|
||||||
gst_pad_set_event_function (sq->srcpad,
|
gst_pad_set_event_function (sq->srcpad,
|
||||||
|
|
|
@ -189,7 +189,6 @@ static void gst_queue_get_property (GObject * object,
|
||||||
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
|
||||||
static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
|
||||||
guint size, GstCaps * caps, GstBuffer ** buf);
|
guint size, GstCaps * caps, GstBuffer ** buf);
|
||||||
static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps);
|
|
||||||
static GstFlowReturn gst_queue_push_one (GstQueue * queue);
|
static GstFlowReturn gst_queue_push_one (GstQueue * queue);
|
||||||
static void gst_queue_loop (GstPad * pad);
|
static void gst_queue_loop (GstPad * pad);
|
||||||
|
|
||||||
|
@ -383,8 +382,6 @@ gst_queue_init (GstQueue * queue, GstQueueClass * g_class)
|
||||||
GST_DEBUG_FUNCPTR (gst_queue_src_activate_push));
|
GST_DEBUG_FUNCPTR (gst_queue_src_activate_push));
|
||||||
gst_pad_set_link_function (queue->srcpad,
|
gst_pad_set_link_function (queue->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_queue_link_src));
|
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_pad_set_getcaps_function (queue->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_queue_getcaps));
|
GST_DEBUG_FUNCPTR (gst_queue_getcaps));
|
||||||
gst_pad_set_event_function (queue->srcpad,
|
gst_pad_set_event_function (queue->srcpad,
|
||||||
|
@ -503,14 +500,6 @@ gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
|
||||||
return result;
|
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.
|
/* calculate the diff between running time on the sink and src of the queue.
|
||||||
* This is the total amount of time in the queue. */
|
* This is the total amount of time in the queue. */
|
||||||
static void
|
static void
|
||||||
|
@ -984,9 +973,20 @@ gst_queue_push_one (GstQueue * queue)
|
||||||
|
|
||||||
next:
|
next:
|
||||||
if (GST_IS_BUFFER (data)) {
|
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);
|
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);
|
result = gst_pad_push (queue->srcpad, buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue