plugins/elements/gstmultiqueue.c: Make it so that pads are considered linked until a buffer is pushed and discovered ...

Original commit message from CVS:
* plugins/elements/gstmultiqueue.c: (gst_multi_queue_set_property),
(gst_multi_queue_request_new_pad), (gst_single_queue_flush),
(gst_multi_queue_loop), (gst_multi_queue_sink_activate_push):
Make it so that pads are considered linked until a buffer is pushed
and discovered otherwise. This avoids problems with decodebin2 hanging
after a seek in the filesrc ! decodebin2 name=d ! fakesink d. ! fakesink
case.
Make sure we lock the multiqueue when updating the max-size properties.
Fix a crash on Solaris in a debug statement in get_request_pad that
passes a NULL string to GST_DEBUG.
* tests/check/elements/multiqueue.c: (mq_dummypad_chain),
(run_output_order_test):
Fix the test to allow the first buffer on not-linked pads to come out
of sequence while multiqueue discovers that they are not-linked.
This commit is contained in:
Jan Schmidt 2007-10-25 15:14:02 +00:00
parent d7cbd5de33
commit f37e97764b
3 changed files with 49 additions and 9 deletions

View file

@ -1,3 +1,23 @@
2007-10-25 Jan Schmidt <Jan.Schmidt@sun.com>
* plugins/elements/gstmultiqueue.c: (gst_multi_queue_set_property),
(gst_multi_queue_request_new_pad), (gst_single_queue_flush),
(gst_multi_queue_loop), (gst_multi_queue_sink_activate_push):
Make it so that pads are considered linked until a buffer is pushed
and discovered otherwise. This avoids problems with decodebin2 hanging
after a seek in the filesrc ! decodebin2 name=d ! fakesink d. ! fakesink
case.
Make sure we lock the multiqueue when updating the max-size properties.
Fix a crash on Solaris in a debug statement in get_request_pad that
passes a NULL string to GST_DEBUG.
* tests/check/elements/multiqueue.c: (mq_dummypad_chain),
(run_output_order_test):
Fix the test to allow the first buffer on not-linked pads to come out
of sequence while multiqueue discovers that they are not-linked.
2007-10-25 Jan Schmidt <Jan.Schmidt@sun.com>
* configure.ac:

View file

@ -287,16 +287,22 @@ gst_multi_queue_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case ARG_MAX_SIZE_BYTES:
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
mq->max_size.bytes = g_value_get_uint (value);
SET_CHILD_PROPERTY (mq, bytes);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
break;
case ARG_MAX_SIZE_BUFFERS:
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
mq->max_size.visible = g_value_get_uint (value);
SET_CHILD_PROPERTY (mq, visible);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
break;
case ARG_MAX_SIZE_TIME:
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
mq->max_size.time = g_value_get_uint64 (value);
SET_CHILD_PROPERTY (mq, time);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
break;
case ARG_EXTRA_SIZE_BYTES:
mq->extra_size.bytes = g_value_get_uint (value);
@ -398,7 +404,7 @@ gst_multi_queue_request_new_pad (GstElement * element, GstPadTemplate * temp,
GstMultiQueue *mqueue = GST_MULTI_QUEUE (element);
GstSingleQueue *squeue;
GST_LOG_OBJECT (element, "name : %s", name);
GST_LOG_OBJECT (element, "name : %s", GST_STR_NULL (name));
/* Create a new single queue, add the sink and source pad and return the sink pad */
squeue = gst_single_queue_new (mqueue);
@ -482,7 +488,7 @@ gst_single_queue_flush (GstMultiQueue * mq, GstSingleQueue * sq, gboolean flush)
gst_segment_init (&sq->sink_segment, GST_FORMAT_TIME);
gst_segment_init (&sq->src_segment, GST_FORMAT_TIME);
/* All pads start off not-linked for a smooth kick-off */
sq->srcresult = GST_FLOW_NOT_LINKED;
sq->srcresult = GST_FLOW_OK;
sq->cur_time = 0;
sq->max_size.visible = mq->max_size.visible;
sq->is_eos = FALSE;
@ -743,7 +749,8 @@ gst_multi_queue_loop (GstPad * pad)
* we might need to wake some sleeping pad up, so there's extra work
* there too */
if (sq->srcresult == GST_FLOW_NOT_LINKED ||
(oldid == -1) || (newid != (oldid + 1)) || oldid > mq->highid) {
(oldid == G_MAXUINT32) || (newid != (oldid + 1)) ||
oldid > mq->highid) {
GST_LOG_OBJECT (mq, "CHECKING sq->srcresult: %s",
gst_flow_get_name (sq->srcresult));
@ -753,7 +760,7 @@ gst_multi_queue_loop (GstPad * pad)
sq->nextid = newid;
/* Update the oldid (the last ID we output) for highid tracking */
if (oldid != -1)
if (oldid != G_MAXUINT32)
sq->oldid = oldid;
if (sq->srcresult == GST_FLOW_NOT_LINKED) {
@ -888,8 +895,8 @@ gst_multi_queue_sink_activate_push (GstPad * pad, gboolean active)
sq = (GstSingleQueue *) gst_pad_get_element_private (pad);
if (active) {
/* All pads start off not-linked for a smooth kick-off */
sq->srcresult = GST_FLOW_NOT_LINKED;
/* All pads start off linked until they push one buffer */
sq->srcresult = GST_FLOW_OK;
} else {
sq->srcresult = GST_FLOW_WRONG_STATE;
gst_data_queue_flush (sq->queue);

View file

@ -284,6 +284,7 @@ struct PadData
guint32 *max_linked_id_ptr;
guint32 *eos_count_ptr;
gboolean is_linked;
gboolean first_buf;
gint n_linked;
GMutex *mutex;
@ -309,10 +310,11 @@ mq_dummypad_chain (GstPad * sinkpad, GstBuffer * buf)
g_mutex_lock (pad_data->mutex);
/* For not-linked pads, ensure that we're not running ahead of the 'linked'
* pads */
* pads. The first buffer is allowed to get ahead, because otherwise things can't
* always pre-roll correctly */
if (!pad_data->is_linked) {
/* If there are no linked pads, we can't track a max_id for them :) */
if (pad_data->n_linked > 0) {
if (pad_data->n_linked > 0 && !pad_data->first_buf) {
g_static_mutex_lock (&_check_lock);
fail_unless (cur_id <= *(pad_data->max_linked_id_ptr) + 1,
"Got buffer %u on pad %u before buffer %u was seen on a "
@ -325,6 +327,7 @@ mq_dummypad_chain (GstPad * sinkpad, GstBuffer * buf)
if (cur_id > *(pad_data->max_linked_id_ptr))
*(pad_data->max_linked_id_ptr) = cur_id;
}
pad_data->first_buf = FALSE;
g_mutex_unlock (pad_data->mutex);
@ -390,6 +393,14 @@ run_output_order_test (gint n_linked)
fail_unless (mq != NULL);
gst_bin_add (GST_BIN (pipe), mq);
/* No limits */
g_object_set (mq,
"max-size-bytes", (guint) 0,
"max-size-buffers", (guint) 0,
"max-size-time", (guint64) 0,
"extra-size-bytes", (guint) 0,
"extra-size-buffers", (guint) 0, "extra-size-time", (guint64) 0, NULL);
/* Construct NPADS dummy output pads. The first 'n_linked' return FLOW_OK, the rest
* return NOT_LINKED. The not-linked ones check the expected ordering of
* output buffers */
@ -424,6 +435,7 @@ run_output_order_test (gint n_linked)
pad_data[i].n_linked = n_linked;
pad_data[i].cond = cond;
pad_data[i].mutex = mutex;
pad_data[i].first_buf = TRUE;
gst_pad_set_element_private (sinkpads[i], pad_data + i);
gst_pad_link (mq_srcpad, sinkpads[i]);
@ -453,7 +465,8 @@ run_output_order_test (gint n_linked)
g_static_mutex_lock (&_check_lock);
fail_if (buf == NULL);
g_static_mutex_unlock (&_check_lock);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), i);
GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), i + 1);
GST_BUFFER_TIMESTAMP (buf) = (i + 1) * GST_SECOND;
ret = gst_pad_push (inputpads[cur_pad], buf);
g_static_mutex_lock (&_check_lock);