Commit ade73f87 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: adaptive: add buffered chunks stream

provides data backend to prevent breakage
with unwanted seeks (mkv)
parent 173ee01c
......@@ -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;
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment