vlc/vlc-3.0 | branch: master | Francois Cartegnie <[email protected]> | 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 _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
