From f37e97764bb324ebe7ca3d82f2813d2584e5a070 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 25 Oct 2007 15:14:02 +0000 Subject: [PATCH] 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. --- ChangeLog | 20 ++++++++++++++++++++ plugins/elements/gstmultiqueue.c | 19 +++++++++++++------ tests/check/elements/multiqueue.c | 19 ++++++++++++++++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa4fdef..865fc4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2007-10-25 Jan Schmidt + * 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 + * configure.ac: * libs/gst/check/Makefile.am: Use a custom export symbol regex for libgstcheck, as it needs diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index be2808e..83378e8 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -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); diff --git a/tests/check/elements/multiqueue.c b/tests/check/elements/multiqueue.c index e5f0047..bf59926 100644 --- a/tests/check/elements/multiqueue.c +++ b/tests/check/elements/multiqueue.c @@ -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); -- 2.7.4