[vlc-commits] demux: adaptive: add buffered chunks stream

Francois Cartegnie git at videolan.org
Tue Jul 23 20:36:13 CEST 2019


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Apr 26 15:20:03 2018 +0200| [9ab27936f1b33a7c909f3f0ac5cf378cf1d19533] | committer: Francois Cartegnie

demux: adaptive: add buffered chunks stream

provides data backend to prevent breakage
with unwanted seeks (mkv)

(cherry picked from commit ade73f871752a8163dcf123492076e77324bf700)

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

 modules/demux/adaptive/plumbing/SourceStream.cpp | 93 +++++++++++++++++++++++-
 modules/demux/adaptive/plumbing/SourceStream.hpp | 28 ++++++-
 2 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/modules/demux/adaptive/plumbing/SourceStream.cpp b/modules/demux/adaptive/plumbing/SourceStream.cpp
index 08cf27c54b..5b49b2ea9b 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.cpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.cpp
@@ -32,10 +32,10 @@
 using namespace adaptive;
 
 ChunksSourceStream::ChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
-    : p_block( NULL )
-    , b_eof( false )
+    : b_eof( false )
     , p_obj( p_obj_ )
     , source( source_ )
+    , p_block( NULL )
 { }
 
 ChunksSourceStream::~ChunksSourceStream()
@@ -111,15 +111,21 @@ ssize_t ChunksSourceStream::Read(uint8_t *buf, size_t size)
     return i_copied;
 }
 
+int ChunksSourceStream::Seek(uint64_t)
+{
+    return VLC_EGENERIC;
+}
+
 ssize_t ChunksSourceStream::read_Callback(stream_t *s, void *buf, size_t size)
 {
     ChunksSourceStream *me = reinterpret_cast<ChunksSourceStream *>(s->p_sys);
     return me->Read(reinterpret_cast<uint8_t *>(buf), size);
 }
 
-int ChunksSourceStream::seek_Callback(stream_t *, uint64_t)
+int ChunksSourceStream::seek_Callback(stream_t *s, uint64_t i_pos)
 {
-    return VLC_EGENERIC;
+    ChunksSourceStream *me = reinterpret_cast<ChunksSourceStream *>(s->p_sys);
+    return me->Seek(i_pos);
 }
 
 int ChunksSourceStream::control_Callback(stream_t *s, int i_query, va_list args)
@@ -162,3 +168,82 @@ int ChunksSourceStream::control_Callback(stream_t *s, int i_query, va_list args)
 void ChunksSourceStream::delete_Callback(stream_t *)
 {
 }
+
+BufferedChunksSourceStream::BufferedChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
+    : ChunksSourceStream( p_obj_, source_ )
+{
+    i_global_offset = 0;
+    i_bytestream_offset = 0;
+    block_BytestreamInit( &bs );
+}
+
+BufferedChunksSourceStream::~BufferedChunksSourceStream()
+{
+    block_BytestreamEmpty( &bs );
+}
+
+void BufferedChunksSourceStream::Reset()
+{
+    block_BytestreamEmpty( &bs );
+    i_bytestream_offset = 0;
+    i_global_offset = 0;
+    b_eof = false;
+}
+
+ssize_t BufferedChunksSourceStream::Read(uint8_t *buf, size_t size)
+{
+    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)
+        {
+            block_t *p_add = source->readNextBlock();
+            if(!p_add)
+            {
+                b_eof = true;
+                break;
+            }
+            i_remain += p_add->i_buffer;
+            block_BytestreamPush(&bs, p_add);
+        }
+
+        size_t i_read;
+        if(i_remain >= i_toread)
+            i_read = i_toread;
+        else
+            i_read = i_remain;
+
+        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;
+    }
+
+    if(i_bytestream_offset > MAX_BACKEND)
+    {
+        const size_t i_drop = i_bytestream_offset - MAX_BACKEND;
+        if(i_drop >= MIN_BACKEND_CLEANUP) /* Dont flush for few bytes */
+        {
+            block_GetBytes(&bs, NULL, i_drop);
+            block_BytestreamFlush(&bs);
+            i_bytestream_offset -= i_drop;
+            i_global_offset += i_drop;
+        }
+    }
+
+    return i_copied;
+}
+
+int BufferedChunksSourceStream::Seek(uint64_t i_seek)
+{
+    if(i_seek < i_global_offset ||
+       i_seek - i_global_offset > block_BytestreamRemaining(&bs))
+        return VLC_EGENERIC;
+    i_bytestream_offset = i_seek - i_global_offset;
+    return VLC_SUCCESS;
+}
diff --git a/modules/demux/adaptive/plumbing/SourceStream.hpp b/modules/demux/adaptive/plumbing/SourceStream.hpp
index af0e4fd555..434a1ac447 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.hpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.hpp
@@ -22,6 +22,7 @@
 
 #include <vlc_common.h>
 #include <vlc_block.h>
+#include <vlc_block_helper.h>
 #include <string>
 
 namespace adaptive
@@ -46,18 +47,37 @@ namespace adaptive
 
         protected:
             std::string getContentType();
-            ssize_t Read(uint8_t *, size_t);
+            virtual ssize_t Read(uint8_t *, size_t);
+            virtual int     Seek(uint64_t);
+            bool b_eof;
+            vlc_object_t *p_obj;
+            ChunksSource *source;
 
         private:
             block_t *p_block;
-            bool b_eof;
             static ssize_t read_Callback(stream_t *, void *, size_t);
             static int seek_Callback(stream_t *, uint64_t);
             static int control_Callback( stream_t *, int i_query, va_list );
             static void delete_Callback( stream_t * );
-            vlc_object_t *p_obj;
-            ChunksSource *source;
     };
 
+    class BufferedChunksSourceStream : public ChunksSourceStream
+    {
+        public:
+            BufferedChunksSourceStream(vlc_object_t *, ChunksSource *);
+            virtual ~BufferedChunksSourceStream();
+            virtual void Reset(); /* reimpl */
+
+        protected:
+            virtual ssize_t Read(uint8_t *, size_t); /* reimpl */
+            virtual int     Seek(uint64_t); /* reimpl */
+
+        private:
+            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;
+    };
 }
 #endif // SOURCESTREAM_HPP



More information about the vlc-commits mailing list