From 36b533d5b2689cffa916f02f32bed3446112b612 Mon Sep 17 00:00:00 2001 From: Ognyan Tonchev Date: Mon, 11 Oct 2010 10:27:52 +0200 Subject: [PATCH] queue: apply sink segment on the source if queue is empty Apply the sink segment on the source immediatly when it is received and there is nothing in the queue. Solves #482147 --- plugins/elements/gstqueue.c | 23 +++++++++++++---------- plugins/elements/gstqueue.h | 3 +++ tests/check/elements/queue.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 6bf1c48..72c8e0b 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -430,6 +430,8 @@ gst_queue_init (GstQueue * queue, GstQueueClass * g_class) queue->sink_tainted = TRUE; queue->src_tainted = TRUE; + queue->newseg_applied_to_src = FALSE; + GST_DEBUG_OBJECT (queue, "initialized queue's not_empty & not_full conditions"); } @@ -680,15 +682,6 @@ gst_queue_locked_enqueue_buffer (GstQueue * queue, gpointer item) queue->cur_level.bytes += GST_BUFFER_SIZE (buffer); apply_buffer (queue, buffer, &queue->sink_segment, TRUE, TRUE); - /* if this is the first buffer update the end side as well, but without the - * duration. */ - /* FIXME : This will only be useful for current time level if the - * source task is running, which is not the case for ex in - * gstplaybasebin when pre-rolling. - * See #482147 */ - /* if (queue->cur_level.buffers == 1) */ - /* apply_buffer (queue, buffer, &queue->src_segment, FALSE); */ - g_queue_push_tail (queue->queue, item); GST_QUEUE_SIGNAL_ADD (queue); } @@ -709,6 +702,11 @@ gst_queue_locked_enqueue_event (GstQueue * queue, gpointer item) break; case GST_EVENT_NEWSEGMENT: apply_segment (queue, event, &queue->sink_segment, TRUE); + /* if the queue is empty, apply sink segment on the source */ + if (queue->queue->length == 0) { + apply_segment (queue, event, &queue->src_segment, FALSE); + queue->newseg_applied_to_src = TRUE; + } /* a new segment allows us to accept more buffers if we got UNEXPECTED * from downstream */ queue->unexpected = FALSE; @@ -758,7 +756,12 @@ gst_queue_locked_dequeue (GstQueue * queue, gboolean * is_buffer) GST_QUEUE_CLEAR_LEVEL (queue->cur_level); break; case GST_EVENT_NEWSEGMENT: - apply_segment (queue, event, &queue->src_segment, FALSE); + /* apply newsegment if it has not already been applied */ + if (G_LIKELY (!queue->newseg_applied_to_src)) { + apply_segment (queue, event, &queue->src_segment, FALSE); + } else { + queue->newseg_applied_to_src = FALSE; + } break; default: break; diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index 203b508..72ea814 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -115,6 +115,9 @@ struct _GstQueue { gboolean push_newsegment; gboolean silent; /* don't emit signals */ + + /* whether the first new segment has been applied to src */ + gboolean newseg_applied_to_src; }; struct _GstQueueClass { diff --git a/tests/check/elements/queue.c b/tests/check/elements/queue.c index 699382e..3a6e4e4 100644 --- a/tests/check/elements/queue.c +++ b/tests/check/elements/queue.c @@ -537,6 +537,38 @@ GST_START_TEST (test_time_level) GST_END_TEST; +GST_START_TEST (test_time_level_task_not_started) +{ + GstEvent *event; + GstClockTime time; + + GST_DEBUG ("starting"); + + fail_unless (gst_element_set_state (queue, + GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, + "could not set to playing"); + + event = gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, + 1 * GST_SECOND, 5 * GST_SECOND, 0); + gst_pad_push_event (mysrcpad, event); + + g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL); + fail_if (time != 0 * GST_SECOND); + + event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + 1 * GST_SECOND, 5 * GST_SECOND, 0); + gst_pad_push_event (mysrcpad, event); + + g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL); + fail_if (time != 4 * GST_SECOND); + + GST_DEBUG ("stopping"); + fail_unless (gst_element_set_state (queue, + GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); +} + +GST_END_TEST; + static gboolean event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate, GstFormat format, gint64 start, gint64 stop, gint64 position) @@ -674,6 +706,7 @@ queue_suite (void) tcase_add_test (tc_chain, test_leaky_upstream); tcase_add_test (tc_chain, test_leaky_downstream); tcase_add_test (tc_chain, test_time_level); + tcase_add_test (tc_chain, test_time_level_task_not_started); tcase_add_test (tc_chain, test_newsegment); return s; -- 2.7.4