[vlc-commits] demux: adaptive: have peek on buffered chunks up to max cache

Francois Cartegnie git at videolan.org
Mon Dec 14 10:41:35 UTC 2020


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Sep  7 15:39:25 2020 +0200| [62859f82a20a83bc91a5f6ef7ebfd7d41cc96aed] | committer: Francois Cartegnie

demux: adaptive: have peek on buffered chunks up to max cache

(cherry picked from commit 467c01b34a7034277fa0cd5e3eac05242a9b5888)

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=62859f82a20a83bc91a5f6ef7ebfd7d41cc96aed
---

 modules/demux/adaptive/plumbing/SourceStream.cpp | 106 +++++++++++++++--------
 modules/demux/adaptive/plumbing/SourceStream.hpp |   5 +-
 2 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/modules/demux/adaptive/plumbing/SourceStream.cpp b/modules/demux/adaptive/plumbing/SourceStream.cpp
index bdd6fc12ad..feecd1de2f 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.cpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.cpp
@@ -204,11 +204,13 @@ BufferedChunksSourceStream::BufferedChunksSourceStream(vlc_object_t *p_obj_, Abs
     i_global_offset = 0;
     i_bytestream_offset = 0;
     block_BytestreamInit( &bs );
+    p_peekdata = NULL;
 }
 
 BufferedChunksSourceStream::~BufferedChunksSourceStream()
 {
     block_BytestreamEmpty( &bs );
+    invalidatePeek();
 }
 
 void BufferedChunksSourceStream::Reset()
@@ -216,42 +218,40 @@ void BufferedChunksSourceStream::Reset()
     block_BytestreamEmpty( &bs );
     i_bytestream_offset = 0;
     i_global_offset = 0;
+    invalidatePeek();
     AbstractChunksSourceStream::Reset();
 }
 
-ssize_t BufferedChunksSourceStream::Read(uint8_t *buf, size_t size)
+ssize_t BufferedChunksSourceStream::doRead(uint8_t *buf, size_t i_toread)
 {
-    size_t i_copied = 0;
-    size_t i_toread = size;
-
-    while(i_toread && !b_eof)
+    size_t i_remain = block_BytestreamRemaining(&bs) - i_bytestream_offset;
+    if(i_remain < i_toread)
     {
-        size_t i_remain = block_BytestreamRemaining(&bs) - i_bytestream_offset;
+        fillByteStream(i_bytestream_offset + i_toread);
+        i_remain = block_BytestreamRemaining(&bs) - i_bytestream_offset;
+        if(i_remain == 0)
+            return 0;
+    }
 
-        if(i_remain < i_toread)
-        {
-            block_t *p_add = source->readNextBlock();
-            if(p_add)
-            {
-                i_remain += p_add->i_buffer;
-                block_BytestreamPush(&bs, p_add);
+    if(i_remain < i_toread)
+        i_toread = i_remain;
 
-            }
-            else b_eof = true;
-        }
+    if(buf)
+        block_PeekOffsetBytes(&bs, i_bytestream_offset, buf, i_toread);
 
-        size_t i_read;
-        if(i_remain >= i_toread)
-            i_read = i_toread;
-        else
-            i_read = i_remain;
+    return i_toread;
+}
 
-        if(buf)
-            block_PeekOffsetBytes(&bs, i_bytestream_offset, &buf[i_copied], i_read);
-        i_bytestream_offset += i_read;
-        i_copied += i_read;
-        i_toread -= i_read;
-    }
+ssize_t BufferedChunksSourceStream::Read(uint8_t *buf, size_t i_toread)
+{
+    invalidatePeek();
+
+    ssize_t i_read = doRead(buf, i_toread);
+    if(i_read <= 0)
+        return i_read;
+
+    i_bytestream_offset += i_read;
+    i_toread -= i_read;
 
     if(i_bytestream_offset > MAX_BACKEND)
     {
@@ -264,37 +264,58 @@ ssize_t BufferedChunksSourceStream::Read(uint8_t *buf, size_t size)
             i_global_offset += i_drop;
         }
     }
-
-    return i_copied;
+    return i_read;
 }
 
 int BufferedChunksSourceStream::Seek(uint64_t i_seek)
 {
-    if(i_seek < i_global_offset ||
-       i_seek - i_global_offset > block_BytestreamRemaining(&bs))
+    if(i_seek < i_global_offset) /* can't seek into discarded data */
+    {
+        msg_Err(p_obj, "tried to seek back in cache %" PRIu64 " < %" PRIu64,
+                i_seek, i_global_offset);
+        return VLC_EGENERIC;
+    }
+    size_t i_bsseekoffset = i_seek - i_global_offset;
+    fillByteStream(i_bsseekoffset);
+    if(block_BytestreamRemaining(&bs) < i_bsseekoffset)
+    {
+        msg_Err(p_obj, "tried to seek too far in cache %" PRIu64 " < %" PRIu64 " < %" PRIu64,
+                i_global_offset, i_seek, i_global_offset + block_BytestreamRemaining(&bs));
         return VLC_EGENERIC;
+    }
+    invalidatePeek();
     i_bytestream_offset = i_seek - i_global_offset;
     return VLC_SUCCESS;
 }
 
 size_t BufferedChunksSourceStream::Peek(const uint8_t **pp, size_t sz)
 {
-    fillByteStream();
-    if(block_BytestreamRemaining(&bs) == 0)
+    sz = std::min(sz, (size_t)MAX_BACKEND);
+    invalidatePeek();
+    p_peekdata = block_Alloc(sz);
+    if(!p_peekdata)
+        return 0;
+    ssize_t i_read = doRead(p_peekdata->p_buffer, sz);
+    if(i_read <= 0)
+    {
+        invalidatePeek();
         return 0;
-    *pp = bs.p_block->p_buffer;
-    return std::min(bs.p_block->i_buffer, sz);
+    }
+    *pp = p_peekdata->p_buffer;
+    return i_read;
 }
 
 std::string BufferedChunksSourceStream::getContentType()
 {
-    fillByteStream();
+    if(block_BytestreamRemaining(&bs) == 0)
+        fillByteStream(1);
     return source->getContentType();
 }
 
-void BufferedChunksSourceStream::fillByteStream()
+void BufferedChunksSourceStream::fillByteStream(size_t sz)
 {
-    if(!b_eof && block_BytestreamRemaining(&bs) == 0)
+    sz = std::min(sz, (size_t)MAX_BACKEND);
+    while(!b_eof && sz > block_BytestreamRemaining(&bs))
     {
         block_t *p_block = source->readNextBlock();
         b_eof = !p_block;
@@ -302,3 +323,12 @@ void BufferedChunksSourceStream::fillByteStream()
             block_BytestreamPush(&bs, p_block);
     }
 }
+
+void BufferedChunksSourceStream::invalidatePeek()
+{
+    if(p_peekdata)
+    {
+        block_Release(p_peekdata);
+        p_peekdata = NULL;
+    }
+}
diff --git a/modules/demux/adaptive/plumbing/SourceStream.hpp b/modules/demux/adaptive/plumbing/SourceStream.hpp
index b9ef1ab09f..a2b18a00ca 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.hpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.hpp
@@ -92,12 +92,15 @@ namespace adaptive
             virtual std::string getContentType(); /* impl */
 
         private:
-            void fillByteStream();
+            ssize_t doRead(uint8_t *, size_t);
+            void fillByteStream(size_t);
+            void invalidatePeek();
             static const int MAX_BACKEND = 5 * 1024 * 1024;
             static const int MIN_BACKEND_CLEANUP = 50 * 1024;
             uint64_t i_global_offset;
             size_t i_bytestream_offset;
             block_bytestream_t bs;
+            block_t *p_peekdata;
     };
 }
 #endif // SOURCESTREAM_HPP



More information about the vlc-commits mailing list