mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 02:45:35 +00:00
queue: Ignore thresholds if a query is queued
The queue gets filled by the tail, so a query will always be the tail object, not the head object. Also add a _peek_tail_struct() method to the GstQueueArray to enable looking at the tail. With unit test to prevent future regression. https://bugzilla.gnome.org/show_bug.cgi?id=762875
This commit is contained in:
parent
9e44738ae7
commit
23b32d5600
4 changed files with 70 additions and 5 deletions
|
@ -338,6 +338,34 @@ gst_queue_array_peek_tail (GstQueueArray * array)
|
|||
return *(gpointer *) (array->array + (sizeof (gpointer) * idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_queue_array_peek_tail_struct: (skip)
|
||||
* @array: a #GstQueueArray object
|
||||
*
|
||||
* Returns the tail of the queue @array, but does not remove it from the queue.
|
||||
*
|
||||
* Returns: The tail of the queue
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
gpointer
|
||||
gst_queue_array_peek_tail_struct (GstQueueArray * array)
|
||||
{
|
||||
guint len, idx;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
len = array->length;
|
||||
|
||||
/* empty array */
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
idx = (array->head + (len - 1)) % array->size;
|
||||
|
||||
return array->array + (array->elt_size * idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_queue_array_pop_tail: (skip)
|
||||
* @array: a #GstQueueArray object
|
||||
|
|
|
@ -83,6 +83,8 @@ GST_EXPORT
|
|||
gboolean gst_queue_array_drop_struct (GstQueueArray * array,
|
||||
guint idx,
|
||||
gpointer p_struct);
|
||||
GST_EXPORT
|
||||
gpointer gst_queue_array_peek_tail_struct (GstQueueArray * array);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -1094,18 +1094,18 @@ out_flushing:
|
|||
static gboolean
|
||||
gst_queue_is_empty (GstQueue * queue)
|
||||
{
|
||||
GstQueueItem *head;
|
||||
GstQueueItem *tail;
|
||||
|
||||
head = gst_queue_array_peek_head_struct (queue->queue);
|
||||
tail = gst_queue_array_peek_tail_struct (queue->queue);
|
||||
|
||||
if (head == NULL)
|
||||
if (tail == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* Only consider the queue empty if the minimum thresholds
|
||||
* are not reached and data is at the queue head. Otherwise
|
||||
* are not reached and data is at the queue tail. Otherwise
|
||||
* we would block forever on serialized queries.
|
||||
*/
|
||||
if (!GST_IS_BUFFER (head->item) && !GST_IS_BUFFER_LIST (head->item))
|
||||
if (!GST_IS_BUFFER (tail->item) && !GST_IS_BUFFER_LIST (tail->item))
|
||||
return FALSE;
|
||||
|
||||
/* It is possible that a max size is reached before all min thresholds are.
|
||||
|
|
|
@ -906,6 +906,40 @@ GST_START_TEST (test_queries_while_flushing)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_serialized_query_with_threshold)
|
||||
{
|
||||
GstQuery *query;
|
||||
GstSegment segment;
|
||||
|
||||
gst_segment_init (&segment, GST_FORMAT_BYTES);
|
||||
|
||||
mysinkpad = gst_check_setup_sink_pad (queue, &sinktemplate);
|
||||
gst_pad_set_event_function (mysinkpad, event_func);
|
||||
gst_pad_set_active (mysinkpad, TRUE);
|
||||
|
||||
g_object_set (queue, "min-threshold-buffers", 10, NULL);
|
||||
|
||||
fail_unless (gst_element_set_state (queue,
|
||||
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
|
||||
"could not set to playing");
|
||||
|
||||
gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
|
||||
gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));
|
||||
|
||||
gst_pad_push (mysrcpad, gst_buffer_new ());
|
||||
|
||||
query = gst_query_new_drain ();
|
||||
gst_pad_peer_query (mysrcpad, query);
|
||||
gst_query_unref (query);
|
||||
|
||||
fail_unless (gst_element_set_state (queue,
|
||||
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
static gpointer
|
||||
push_event_thread_func (gpointer data)
|
||||
{
|
||||
|
@ -1162,6 +1196,7 @@ queue_suite (void)
|
|||
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_queries_while_flushing);
|
||||
tcase_add_test (tc_chain, test_serialized_query_with_threshold);
|
||||
tcase_add_test (tc_chain, test_state_change_when_flushing);
|
||||
#if 0
|
||||
tcase_add_test (tc_chain, test_newsegment);
|
||||
|
|
Loading…
Reference in a new issue