From 0bb0c68566e53849583f6ce447d227ad3e9cd2a8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 4 Apr 2012 13:07:27 +0200 Subject: [PATCH 1/3] queue2: avoid waiting for a filled buffer Use a threshold variable to hold the maximum distance from the current position for with we will wait instead of doing a seek. When using the ringbuffer and the requested offset is not available, avoid waiting until the complete ringbuffer is filled but instead do a seek when the requested data is further than the threshold. Avoid doing the seek twice in the ringbuffer case. Use the same threshold for ringbuffer and download buffering. --- plugins/elements/gstqueue2.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 8c4e4ccad4..347c64a696 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1139,20 +1139,27 @@ gst_queue2_have_data (GstQueue2 * queue, guint64 offset, guint length) (offset + length) - range->writing_pos); } else { - GST_INFO_OBJECT (queue, "not found in any range"); - /* we don't have the range, see how far away we are, FIXME, find a good - * threshold based on the incoming rate. */ + GST_INFO_OBJECT (queue, "not found in any range off %" G_GUINT64_FORMAT + " len %u", offset, length); + /* we don't have the range, see how far away we are */ if (!queue->is_eos && queue->current) { + /* FIXME, find a good threshold based on the incoming rate. */ + guint64 threshold = 1024 * 512; + if (QUEUE_IS_USING_RING_BUFFER (queue)) { - if (offset < queue->current->offset || offset > - queue->current->writing_pos + QUEUE_MAX_BYTES (queue) - - queue->cur_level.bytes) { - perform_seek_to_offset (queue, offset); - } else { + guint64 distance; + + distance = QUEUE_MAX_BYTES (queue) - queue->cur_level.bytes; + /* don't wait for the complete buffer to fill */ + distance = MIN (distance, threshold); + + if (offset >= queue->current->offset && offset <= + queue->current->writing_pos + distance) { GST_INFO_OBJECT (queue, "requested data is within range, wait for data"); + return FALSE; } - } else if (offset < queue->current->writing_pos + 200000) { + } else if (offset < queue->current->writing_pos + threshold) { update_cur_pos (queue, queue->current, offset + length); GST_INFO_OBJECT (queue, "wait for data"); return FALSE; From 9a1185673e7e8a5308886d08f3e5afc18491d466 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 5 Apr 2012 09:56:52 +0200 Subject: [PATCH 2/3] queue2: check for filled buffer correctly When using the ringbuffer mode, the buffer is filled when we reached the max_level.bytes mark or the total size of the ringbuffer, whichever is smaller. --- plugins/elements/gstqueue2.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 347c64a696..b011cd3429 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1244,6 +1244,7 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length, guint block_length, remaining, read_length; gint64 read_return; guint64 rb_size; + guint64 max_size; guint64 rpos; /* allocate the output buffer of the requested size */ @@ -1255,6 +1256,7 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length, rpos = offset; rb_size = queue->ring_buffer_max_size; + max_size = QUEUE_MAX_BYTES (queue); remaining = length; while (remaining > 0) { @@ -1273,16 +1275,16 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length, GST_DEBUG_OBJECT (queue, "reading %" G_GUINT64_FORMAT ", writing %" G_GUINT64_FORMAT - ", level %" G_GUINT64_FORMAT, - rpos, queue->current->writing_pos, level); + ", level %" G_GUINT64_FORMAT ", max %" G_GUINT64_FORMAT, + rpos, queue->current->writing_pos, level, max_size); - if (level >= rb_size) { + if (level >= max_size) { /* we don't have the data but if we have a ring buffer that is full, we * need to read */ GST_DEBUG_OBJECT (queue, - "ring buffer full, reading ring-buffer-max-size %" - G_GUINT64_FORMAT " bytes", rb_size); - read_length = rb_size; + "ring buffer full, reading QUEUE_MAX_BYTES %" + G_GUINT64_FORMAT " bytes", max_size); + read_length = max_size; } else if (queue->is_eos) { /* won't get any more data so read any data we have */ if (level) { From 67ccad0621d1867b8777c2ccafbf186046725de5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 5 Apr 2012 10:03:02 +0200 Subject: [PATCH 3/3] queue2: stop waiting for more data after EOS When we have EOS, read the remaining bytes in the buffer and make sure we don't wait for more data. Also clip the output buffer to the amount of remaining bytes. --- plugins/elements/gstqueue2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index b011cd3429..02fd10a1b4 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1292,6 +1292,8 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length, "EOS hit but read %" G_GUINT64_FORMAT " bytes that we have", level); read_length = level; + remaining = level; + length = level; } else { GST_DEBUG_OBJECT (queue, "EOS hit and we don't have any requested data");