mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
gio: make better use of the cached buffer
When playing mp3 files from a smb server, we get 64k read requests that mostly overlap. Without using the cache to partially satisfy these, we send these requests straight to the server, resulting in a lot more network traffic than necessary. https://bugzilla.gnome.org/show_bug.cgi?id=705415
This commit is contained in:
parent
ca2a515373
commit
cc1de5ae94
1 changed files with 46 additions and 23 deletions
|
@ -320,50 +320,75 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
|
|||
} else {
|
||||
guint cachesize = MAX (4096, size);
|
||||
GstMapInfo map;
|
||||
gssize read, res;
|
||||
gssize read, streamread, res;
|
||||
guint64 readoffset;
|
||||
gboolean success, eos;
|
||||
GError *err = NULL;
|
||||
GstBuffer *newbuffer;
|
||||
GstMemory *mem;
|
||||
|
||||
if (src->cache) {
|
||||
gst_buffer_unref (src->cache);
|
||||
src->cache = NULL;
|
||||
newbuffer = gst_buffer_new ();
|
||||
|
||||
/* copy any overlapping data from the cached buffer */
|
||||
if (src->cache && offset >= GST_BUFFER_OFFSET (src->cache) &&
|
||||
offset <= GST_BUFFER_OFFSET_END (src->cache)) {
|
||||
read = GST_BUFFER_OFFSET_END (src->cache) - offset;
|
||||
GST_LOG_OBJECT (src,
|
||||
"Copying %" G_GUINT64_FORMAT " bytes from cached buffer at %"
|
||||
G_GUINT64_FORMAT, read, offset - GST_BUFFER_OFFSET (src->cache));
|
||||
gst_buffer_copy_into (newbuffer, src->cache, GST_BUFFER_COPY_MEMORY,
|
||||
offset - GST_BUFFER_OFFSET (src->cache), read);
|
||||
} else {
|
||||
read = 0;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (offset != src->position)) {
|
||||
if (src->cache)
|
||||
gst_buffer_unref (src->cache);
|
||||
src->cache = newbuffer;
|
||||
|
||||
readoffset = offset + read;
|
||||
GST_LOG_OBJECT (src,
|
||||
"Reading %u bytes from offset %" G_GUINT64_FORMAT, cachesize,
|
||||
readoffset);
|
||||
|
||||
if (G_UNLIKELY (readoffset != src->position)) {
|
||||
if (!GST_GIO_STREAM_IS_SEEKABLE (src->stream))
|
||||
return GST_FLOW_NOT_SUPPORTED;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "Seeking to position %" G_GUINT64_FORMAT, offset);
|
||||
ret = gst_gio_seek (src, G_SEEKABLE (src->stream), offset, src->cancel);
|
||||
GST_DEBUG_OBJECT (src, "Seeking to position %" G_GUINT64_FORMAT,
|
||||
readoffset);
|
||||
ret =
|
||||
gst_gio_seek (src, G_SEEKABLE (src->stream), readoffset, src->cancel);
|
||||
|
||||
if (ret == GST_FLOW_OK)
|
||||
src->position = offset;
|
||||
src->position = readoffset;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
src->cache = gst_buffer_new_and_alloc (cachesize);
|
||||
if (G_UNLIKELY (src->cache == NULL)) {
|
||||
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", cachesize);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (src, "Reading %u bytes from offset %" G_GUINT64_FORMAT,
|
||||
cachesize, offset);
|
||||
|
||||
/* GIO sometimes gives less bytes than requested although
|
||||
* it's not at the end of file. SMB for example only
|
||||
* supports reads up to 64k. So we loop here until we get at
|
||||
* at least the requested amount of bytes or a read returns
|
||||
* nothing. */
|
||||
gst_buffer_map (src->cache, &map, GST_MAP_WRITE);
|
||||
read = 0;
|
||||
mem = gst_allocator_alloc (NULL, cachesize, NULL);
|
||||
if (mem == NULL) {
|
||||
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", cachesize);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
gst_memory_map (mem, &map, GST_MAP_WRITE);
|
||||
streamread = 0;
|
||||
while (size - read > 0 && (res =
|
||||
g_input_stream_read (G_INPUT_STREAM (src->stream),
|
||||
map.data + read, cachesize - read, src->cancel, &err)) > 0) {
|
||||
map.data + streamread, cachesize - streamread, src->cancel,
|
||||
&err)) > 0) {
|
||||
read += res;
|
||||
streamread += res;
|
||||
src->position += res;
|
||||
}
|
||||
gst_buffer_unmap (src->cache, &map);
|
||||
gst_memory_unmap (mem, &map);
|
||||
gst_buffer_append_memory (src->cache, mem);
|
||||
|
||||
success = (read >= 0);
|
||||
eos = (cachesize > 0 && read == 0);
|
||||
|
@ -375,8 +400,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
|
|||
}
|
||||
|
||||
if (success && !eos) {
|
||||
src->position += read;
|
||||
|
||||
GST_BUFFER_OFFSET (src->cache) = offset;
|
||||
GST_BUFFER_OFFSET_END (src->cache) = offset + read;
|
||||
|
||||
|
|
Loading…
Reference in a new issue