[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