mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 16:48:11 +00:00
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:
parent
d7cbd5de33
commit
f37e97764b
3 changed files with 49 additions and 9 deletions
20
ChangeLog
20
ChangeLog
|
@ -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>
|
2007-10-25 Jan Schmidt <Jan.Schmidt@sun.com>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -287,16 +287,22 @@ gst_multi_queue_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_MAX_SIZE_BYTES:
|
case ARG_MAX_SIZE_BYTES:
|
||||||
|
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
||||||
mq->max_size.bytes = g_value_get_uint (value);
|
mq->max_size.bytes = g_value_get_uint (value);
|
||||||
SET_CHILD_PROPERTY (mq, bytes);
|
SET_CHILD_PROPERTY (mq, bytes);
|
||||||
|
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
|
||||||
break;
|
break;
|
||||||
case ARG_MAX_SIZE_BUFFERS:
|
case ARG_MAX_SIZE_BUFFERS:
|
||||||
|
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
||||||
mq->max_size.visible = g_value_get_uint (value);
|
mq->max_size.visible = g_value_get_uint (value);
|
||||||
SET_CHILD_PROPERTY (mq, visible);
|
SET_CHILD_PROPERTY (mq, visible);
|
||||||
|
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
|
||||||
break;
|
break;
|
||||||
case ARG_MAX_SIZE_TIME:
|
case ARG_MAX_SIZE_TIME:
|
||||||
|
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
||||||
mq->max_size.time = g_value_get_uint64 (value);
|
mq->max_size.time = g_value_get_uint64 (value);
|
||||||
SET_CHILD_PROPERTY (mq, time);
|
SET_CHILD_PROPERTY (mq, time);
|
||||||
|
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
|
||||||
break;
|
break;
|
||||||
case ARG_EXTRA_SIZE_BYTES:
|
case ARG_EXTRA_SIZE_BYTES:
|
||||||
mq->extra_size.bytes = g_value_get_uint (value);
|
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);
|
GstMultiQueue *mqueue = GST_MULTI_QUEUE (element);
|
||||||
GstSingleQueue *squeue;
|
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 */
|
/* Create a new single queue, add the sink and source pad and return the sink pad */
|
||||||
squeue = gst_single_queue_new (mqueue);
|
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->sink_segment, GST_FORMAT_TIME);
|
||||||
gst_segment_init (&sq->src_segment, GST_FORMAT_TIME);
|
gst_segment_init (&sq->src_segment, GST_FORMAT_TIME);
|
||||||
/* All pads start off not-linked for a smooth kick-off */
|
/* 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->cur_time = 0;
|
||||||
sq->max_size.visible = mq->max_size.visible;
|
sq->max_size.visible = mq->max_size.visible;
|
||||||
sq->is_eos = FALSE;
|
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
|
* we might need to wake some sleeping pad up, so there's extra work
|
||||||
* there too */
|
* there too */
|
||||||
if (sq->srcresult == GST_FLOW_NOT_LINKED ||
|
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_LOG_OBJECT (mq, "CHECKING sq->srcresult: %s",
|
||||||
gst_flow_get_name (sq->srcresult));
|
gst_flow_get_name (sq->srcresult));
|
||||||
|
|
||||||
|
@ -753,7 +760,7 @@ gst_multi_queue_loop (GstPad * pad)
|
||||||
sq->nextid = newid;
|
sq->nextid = newid;
|
||||||
|
|
||||||
/* Update the oldid (the last ID we output) for highid tracking */
|
/* Update the oldid (the last ID we output) for highid tracking */
|
||||||
if (oldid != -1)
|
if (oldid != G_MAXUINT32)
|
||||||
sq->oldid = oldid;
|
sq->oldid = oldid;
|
||||||
|
|
||||||
if (sq->srcresult == GST_FLOW_NOT_LINKED) {
|
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);
|
sq = (GstSingleQueue *) gst_pad_get_element_private (pad);
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
/* All pads start off not-linked for a smooth kick-off */
|
/* All pads start off linked until they push one buffer */
|
||||||
sq->srcresult = GST_FLOW_NOT_LINKED;
|
sq->srcresult = GST_FLOW_OK;
|
||||||
} else {
|
} else {
|
||||||
sq->srcresult = GST_FLOW_WRONG_STATE;
|
sq->srcresult = GST_FLOW_WRONG_STATE;
|
||||||
gst_data_queue_flush (sq->queue);
|
gst_data_queue_flush (sq->queue);
|
||||||
|
|
|
@ -284,6 +284,7 @@ struct PadData
|
||||||
guint32 *max_linked_id_ptr;
|
guint32 *max_linked_id_ptr;
|
||||||
guint32 *eos_count_ptr;
|
guint32 *eos_count_ptr;
|
||||||
gboolean is_linked;
|
gboolean is_linked;
|
||||||
|
gboolean first_buf;
|
||||||
gint n_linked;
|
gint n_linked;
|
||||||
|
|
||||||
GMutex *mutex;
|
GMutex *mutex;
|
||||||
|
@ -309,10 +310,11 @@ mq_dummypad_chain (GstPad * sinkpad, GstBuffer * buf)
|
||||||
g_mutex_lock (pad_data->mutex);
|
g_mutex_lock (pad_data->mutex);
|
||||||
|
|
||||||
/* For not-linked pads, ensure that we're not running ahead of the 'linked'
|
/* 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 (!pad_data->is_linked) {
|
||||||
/* If there are no linked pads, we can't track a max_id for them :) */
|
/* 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);
|
g_static_mutex_lock (&_check_lock);
|
||||||
fail_unless (cur_id <= *(pad_data->max_linked_id_ptr) + 1,
|
fail_unless (cur_id <= *(pad_data->max_linked_id_ptr) + 1,
|
||||||
"Got buffer %u on pad %u before buffer %u was seen on a "
|
"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))
|
if (cur_id > *(pad_data->max_linked_id_ptr))
|
||||||
*(pad_data->max_linked_id_ptr) = cur_id;
|
*(pad_data->max_linked_id_ptr) = cur_id;
|
||||||
}
|
}
|
||||||
|
pad_data->first_buf = FALSE;
|
||||||
|
|
||||||
g_mutex_unlock (pad_data->mutex);
|
g_mutex_unlock (pad_data->mutex);
|
||||||
|
|
||||||
|
@ -390,6 +393,14 @@ run_output_order_test (gint n_linked)
|
||||||
fail_unless (mq != NULL);
|
fail_unless (mq != NULL);
|
||||||
gst_bin_add (GST_BIN (pipe), mq);
|
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
|
/* 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
|
* return NOT_LINKED. The not-linked ones check the expected ordering of
|
||||||
* output buffers */
|
* output buffers */
|
||||||
|
@ -424,6 +435,7 @@ run_output_order_test (gint n_linked)
|
||||||
pad_data[i].n_linked = n_linked;
|
pad_data[i].n_linked = n_linked;
|
||||||
pad_data[i].cond = cond;
|
pad_data[i].cond = cond;
|
||||||
pad_data[i].mutex = mutex;
|
pad_data[i].mutex = mutex;
|
||||||
|
pad_data[i].first_buf = TRUE;
|
||||||
gst_pad_set_element_private (sinkpads[i], pad_data + i);
|
gst_pad_set_element_private (sinkpads[i], pad_data + i);
|
||||||
|
|
||||||
gst_pad_link (mq_srcpad, sinkpads[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);
|
g_static_mutex_lock (&_check_lock);
|
||||||
fail_if (buf == NULL);
|
fail_if (buf == NULL);
|
||||||
g_static_mutex_unlock (&_check_lock);
|
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);
|
ret = gst_pad_push (inputpads[cur_pad], buf);
|
||||||
g_static_mutex_lock (&_check_lock);
|
g_static_mutex_lock (&_check_lock);
|
||||||
|
|
Loading…
Reference in a new issue