[vlc-commits] demux: adaptive: fix missing first block with sourcestream backend

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


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Apr 29 16:09:21 2019 +0200| [3cb56185abc8bb74c875e3907310c2f5e864eba4] | committer: Francois Cartegnie

demux: adaptive: fix missing first block with sourcestream backend

(cherry picked from commit 3853d029869ec0f2e38b0d967cc87a133226f5fe)

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

 modules/demux/adaptive/plumbing/SourceStream.cpp | 170 ++++++++++++++---------
 modules/demux/adaptive/plumbing/SourceStream.hpp |  40 ++++--
 2 files changed, 135 insertions(+), 75 deletions(-)

diff --git a/modules/demux/adaptive/plumbing/SourceStream.cpp b/modules/demux/adaptive/plumbing/SourceStream.cpp
index 5b49b2ea9b..c60262a8a7 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.cpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.cpp
@@ -31,27 +31,76 @@
 
 using namespace adaptive;
 
-ChunksSourceStream::ChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
+AbstractChunksSourceStream::AbstractChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
     : b_eof( false )
     , p_obj( p_obj_ )
     , source( source_ )
-    , p_block( NULL )
 { }
 
-ChunksSourceStream::~ChunksSourceStream()
+AbstractChunksSourceStream::~AbstractChunksSourceStream()
 {
-    Reset();
+
 }
 
-void ChunksSourceStream::Reset()
+void AbstractChunksSourceStream::Reset()
 {
-    if(p_block)
-        block_Release(p_block);
-    p_block = NULL;
     b_eof = false;
 }
 
-stream_t * ChunksSourceStream::makeStream()
+ssize_t AbstractChunksSourceStream::read_Callback(stream_t *s, void *buf, size_t size)
+{
+    AbstractChunksSourceStream *me = reinterpret_cast<AbstractChunksSourceStream *>(s->p_sys);
+    return me->Read(reinterpret_cast<uint8_t *>(buf), size);
+}
+
+int AbstractChunksSourceStream::seek_Callback(stream_t *s, uint64_t i_pos)
+{
+    AbstractChunksSourceStream *me = reinterpret_cast<AbstractChunksSourceStream *>(s->p_sys);
+    return me->Seek(i_pos);
+}
+
+int AbstractChunksSourceStream::control_Callback(stream_t *s, int i_query, va_list args)
+{
+    AbstractChunksSourceStream *me = reinterpret_cast<AbstractChunksSourceStream *>(s->p_sys);
+    switch( i_query )
+    {
+        case STREAM_GET_SIZE:
+            *(va_arg( args, uint64_t * )) = 0;
+            return VLC_SUCCESS;
+
+        case STREAM_CAN_SEEK:
+        case STREAM_CAN_FASTSEEK:
+        case STREAM_CAN_PAUSE:
+        case STREAM_CAN_CONTROL_PACE:
+            *va_arg( args, bool * ) = false;
+            return VLC_SUCCESS;
+
+        case STREAM_GET_CONTENT_TYPE:
+        {
+            std::string type = me->getContentType();
+            if(!type.empty())
+            {
+                *va_arg( args, char ** ) = strdup(type.c_str());
+                return VLC_SUCCESS;
+            }
+        }
+        break;
+
+        case STREAM_GET_PTS_DELAY:
+            *(va_arg( args, mtime_t * )) = DEFAULT_PTS_DELAY;
+            return VLC_SUCCESS;
+
+        default:
+            break;
+    }
+    return VLC_EGENERIC;
+}
+
+void AbstractChunksSourceStream::delete_Callback(stream_t *)
+{
+}
+
+stream_t * AbstractChunksSourceStream::makeStream()
 {
     stream_t *p_stream = vlc_stream_CommonNew( p_obj, delete_Callback );
     if(p_stream)
@@ -65,6 +114,26 @@ stream_t * ChunksSourceStream::makeStream()
     return p_stream;
 }
 
+ChunksSourceStream::ChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
+    : AbstractChunksSourceStream(p_obj_, source_)
+{
+    p_block = NULL;
+}
+
+ChunksSourceStream::~ChunksSourceStream()
+{
+    if(p_block)
+        block_Release(p_block);
+}
+
+void ChunksSourceStream::Reset()
+{
+    if(p_block)
+        block_Release(p_block);
+    p_block = NULL;
+    AbstractChunksSourceStream::Reset();
+}
+
 std::string ChunksSourceStream::getContentType()
 {
     if(!b_eof && !p_block)
@@ -116,61 +185,8 @@ 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 *s, uint64_t i_pos)
-{
-    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)
-{
-    ChunksSourceStream *me = reinterpret_cast<ChunksSourceStream *>(s->p_sys);
-    switch( i_query )
-    {
-        case STREAM_GET_SIZE:
-            *(va_arg( args, uint64_t * )) = 0;
-            return VLC_SUCCESS;
-
-        case STREAM_CAN_SEEK:
-        case STREAM_CAN_FASTSEEK:
-        case STREAM_CAN_PAUSE:
-        case STREAM_CAN_CONTROL_PACE:
-            *va_arg( args, bool * ) = false;
-            return VLC_SUCCESS;
-
-        case STREAM_GET_CONTENT_TYPE:
-        {
-            std::string type = me->getContentType();
-            if(!type.empty())
-            {
-                *va_arg( args, char ** ) = strdup(type.c_str());
-                return VLC_SUCCESS;
-            }
-        }
-        break;
-
-        case STREAM_GET_PTS_DELAY:
-            *(va_arg( args, uint64_t * )) = DEFAULT_PTS_DELAY;
-            return VLC_SUCCESS;
-
-        default:
-            break;
-    }
-    return VLC_EGENERIC;
-}
-
-void ChunksSourceStream::delete_Callback(stream_t *)
-{
-}
-
 BufferedChunksSourceStream::BufferedChunksSourceStream(vlc_object_t *p_obj_, ChunksSource *source_)
-    : ChunksSourceStream( p_obj_, source_ )
+    : AbstractChunksSourceStream( p_obj_, source_ )
 {
     i_global_offset = 0;
     i_bytestream_offset = 0;
@@ -187,7 +203,7 @@ void BufferedChunksSourceStream::Reset()
     block_BytestreamEmpty( &bs );
     i_bytestream_offset = 0;
     i_global_offset = 0;
-    b_eof = false;
+    AbstractChunksSourceStream::Reset();
 }
 
 ssize_t BufferedChunksSourceStream::Read(uint8_t *buf, size_t size)
@@ -247,3 +263,29 @@ int BufferedChunksSourceStream::Seek(uint64_t i_seek)
     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)
+        return 0;
+    *pp = bs.p_block->p_buffer;
+    return std::min(bs.p_block->i_buffer, sz);
+}
+
+std::string BufferedChunksSourceStream::getContentType()
+{
+    fillByteStream();
+    return source->getContentType();
+}
+
+void BufferedChunksSourceStream::fillByteStream()
+{
+    if(!b_eof && block_BytestreamRemaining(&bs) == 0)
+    {
+        block_t *p_block = source->readNextBlock();
+        b_eof = !p_block;
+        if(p_block)
+            block_BytestreamPush(&bs, p_block);
+    }
+}
diff --git a/modules/demux/adaptive/plumbing/SourceStream.hpp b/modules/demux/adaptive/plumbing/SourceStream.hpp
index 434a1ac447..27317e17ff 100644
--- a/modules/demux/adaptive/plumbing/SourceStream.hpp
+++ b/modules/demux/adaptive/plumbing/SourceStream.hpp
@@ -37,31 +37,46 @@ namespace adaptive
             virtual void Reset() = 0;
     };
 
-    class ChunksSourceStream : public AbstractSourceStream
+    class AbstractChunksSourceStream : public AbstractSourceStream
     {
         public:
-            ChunksSourceStream(vlc_object_t *, ChunksSource *);
-            virtual ~ChunksSourceStream();
-            virtual stream_t *makeStream(); /* impl */
+            AbstractChunksSourceStream(vlc_object_t *, ChunksSource *);
+            virtual ~AbstractChunksSourceStream();
             virtual void Reset(); /* impl */
+            virtual stream_t *makeStream(); /* impl */
 
         protected:
-            std::string getContentType();
-            virtual ssize_t Read(uint8_t *, size_t);
-            virtual int     Seek(uint64_t);
+            virtual ssize_t Read(uint8_t *, size_t) = 0;
+            virtual int     Seek(uint64_t) = 0;
+            virtual std::string getContentType() = 0;
             bool b_eof;
             vlc_object_t *p_obj;
             ChunksSource *source;
 
         private:
-            block_t *p_block;
             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 * );
     };
 
-    class BufferedChunksSourceStream : public ChunksSourceStream
+    class ChunksSourceStream : public AbstractChunksSourceStream
+    {
+        public:
+            ChunksSourceStream(vlc_object_t *, ChunksSource *);
+            virtual ~ChunksSourceStream();
+            virtual void Reset(); /* reimpl */
+
+        protected:
+            virtual ssize_t Read(uint8_t *, size_t); /* impl */
+            virtual int     Seek(uint64_t); /* impl */
+            virtual std::string getContentType(); /* impl */
+
+        private:
+            block_t *p_block;
+    };
+
+    class BufferedChunksSourceStream : public AbstractChunksSourceStream
     {
         public:
             BufferedChunksSourceStream(vlc_object_t *, ChunksSource *);
@@ -69,10 +84,13 @@ namespace adaptive
             virtual void Reset(); /* reimpl */
 
         protected:
-            virtual ssize_t Read(uint8_t *, size_t); /* reimpl */
-            virtual int     Seek(uint64_t); /* reimpl */
+            virtual ssize_t Read(uint8_t *, size_t); /* impl */
+            virtual int     Seek(uint64_t); /* impl */
+            virtual size_t  Peek(const uint8_t **, size_t); /* impl */
+            virtual std::string getContentType(); /* impl */
 
         private:
+            void fillByteStream();
             static const int MAX_BACKEND = 5 * 1024 * 1024;
             static const int MIN_BACKEND_CLEANUP = 50 * 1024;
             uint64_t i_global_offset;



More information about the vlc-commits mailing list