Commit b8a1ad1d authored by Francois Cartegnie's avatar Francois Cartegnie

demux: adaptative: fix content-length less chunks reads

parent 19375695
...@@ -311,7 +311,7 @@ block_t * AbstractStream::readNextBlock() ...@@ -311,7 +311,7 @@ block_t * AbstractStream::readNextBlock()
return NULL; return NULL;
} }
if (currentChunk->getBytesToRead() == 0) if (currentChunk->isEmpty())
{ {
delete currentChunk; delete currentChunk;
currentChunk = NULL; currentChunk = NULL;
......
...@@ -52,11 +52,6 @@ void AbstractChunkSource::setParentChunk(AbstractChunk *parent) ...@@ -52,11 +52,6 @@ void AbstractChunkSource::setParentChunk(AbstractChunk *parent)
parentChunk = parent; parentChunk = parent;
} }
size_t AbstractChunkSource::getContentLength() const
{
return contentLength;
}
void AbstractChunkSource::setBytesRange(const BytesRange &range) void AbstractChunkSource::setBytesRange(const BytesRange &range)
{ {
bytesRange = range; bytesRange = range;
...@@ -86,11 +81,6 @@ size_t AbstractChunk::getBytesRead() const ...@@ -86,11 +81,6 @@ size_t AbstractChunk::getBytesRead() const
return this->bytesRead; return this->bytesRead;
} }
size_t AbstractChunk::getBytesToRead() const
{
return source->getContentLength() - bytesRead;
}
block_t * AbstractChunk::doRead(size_t size, bool b_block) block_t * AbstractChunk::doRead(size_t size, bool b_block)
{ {
if(!source) if(!source)
...@@ -109,6 +99,11 @@ block_t * AbstractChunk::doRead(size_t size, bool b_block) ...@@ -109,6 +99,11 @@ block_t * AbstractChunk::doRead(size_t size, bool b_block)
return block; return block;
} }
bool AbstractChunk::isEmpty() const
{
return !source->hasMoreData();
}
block_t * AbstractChunk::readBlock() block_t * AbstractChunk::readBlock()
{ {
return doRead(0, true); return doRead(0, true);
...@@ -127,6 +122,7 @@ HTTPChunkSource::HTTPChunkSource(const std::string& url, HTTPConnectionManager * ...@@ -127,6 +122,7 @@ HTTPChunkSource::HTTPChunkSource(const std::string& url, HTTPConnectionManager *
port (0) port (0)
{ {
prepared = false; prepared = false;
eof = false;
if(!init(url)) if(!init(url))
throw VLC_EGENERIC; throw VLC_EGENERIC;
} }
...@@ -173,20 +169,38 @@ bool HTTPChunkSource::init(const std::string &url) ...@@ -173,20 +169,38 @@ bool HTTPChunkSource::init(const std::string &url)
return true; return true;
} }
bool HTTPChunkSource::hasMoreData() const
{
if(eof)
return false;
else if(contentLength)
return consumed < contentLength;
else return true;
}
block_t * HTTPChunkSource::read(size_t readsize) block_t * HTTPChunkSource::read(size_t readsize)
{ {
if(!prepare()) if(!prepare())
{
eof = true;
return NULL; return NULL;
}
if(consumed == contentLength && consumed > 0) if(consumed == contentLength && consumed > 0)
{
eof = true;
return NULL; return NULL;
}
if(contentLength && readsize > contentLength - consumed) if(contentLength && readsize > contentLength - consumed)
readsize = contentLength - consumed; readsize = contentLength - consumed;
block_t *p_block = block_Alloc(readsize); block_t *p_block = block_Alloc(readsize);
if(!p_block) if(!p_block)
{
eof = true;
return NULL; return NULL;
}
mtime_t time = mdate(); mtime_t time = mdate();
ssize_t ret = connection->read(p_block->p_buffer, readsize); ssize_t ret = connection->read(p_block->p_buffer, readsize);
...@@ -195,11 +209,14 @@ block_t * HTTPChunkSource::read(size_t readsize) ...@@ -195,11 +209,14 @@ block_t * HTTPChunkSource::read(size_t readsize)
{ {
block_Release(p_block); block_Release(p_block);
p_block = NULL; p_block = NULL;
eof = true;
} }
else else
{ {
p_block->i_buffer = (size_t) ret; p_block->i_buffer = (size_t) ret;
consumed += p_block->i_buffer; consumed += p_block->i_buffer;
if((size_t)ret < readsize)
eof = true;
connManager->updateDownloadRate(p_block->i_buffer, time); connManager->updateDownloadRate(p_block->i_buffer, time);
} }
...@@ -245,6 +262,7 @@ HTTPChunkBufferedSource::HTTPChunkBufferedSource(const std::string& url, HTTPCon ...@@ -245,6 +262,7 @@ HTTPChunkBufferedSource::HTTPChunkBufferedSource(const std::string& url, HTTPCon
vlc_mutex_init(&lock); vlc_mutex_init(&lock);
vlc_cond_init(&avail); vlc_cond_init(&avail);
done = false; done = false;
eof = false;
downloadstart = 0; downloadstart = 0;
} }
...@@ -350,6 +368,15 @@ bool HTTPChunkBufferedSource::prepare() ...@@ -350,6 +368,15 @@ bool HTTPChunkBufferedSource::prepare()
return true; return true;
} }
bool HTTPChunkBufferedSource::hasMoreData() const
{
bool b_hasdata;
vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
b_hasdata = !eof;
vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
return b_hasdata;
}
block_t * HTTPChunkBufferedSource::readBlock() block_t * HTTPChunkBufferedSource::readBlock()
{ {
block_t *p_block = NULL; block_t *p_block = NULL;
...@@ -361,15 +388,22 @@ block_t * HTTPChunkBufferedSource::readBlock() ...@@ -361,15 +388,22 @@ block_t * HTTPChunkBufferedSource::readBlock()
if(!p_head && done) if(!p_head && done)
{ {
if(!eof)
p_block = block_Alloc(0);
eof = true;
vlc_mutex_unlock(&lock); vlc_mutex_unlock(&lock);
return NULL; return p_block;
} }
/* dequeue */ /* dequeue */
p_block = p_head; p_block = p_head;
p_head = p_head->p_next; p_head = p_head->p_next;
if(p_head == NULL) if(p_head == NULL)
{
pp_tail = &p_head; pp_tail = &p_head;
if(done)
eof = true;
}
p_block->p_next = NULL; p_block->p_next = NULL;
consumed += p_block->i_buffer; consumed += p_block->i_buffer;
...@@ -390,6 +424,7 @@ block_t * HTTPChunkBufferedSource::read(size_t readsize) ...@@ -390,6 +424,7 @@ block_t * HTTPChunkBufferedSource::read(size_t readsize)
block_t *p_block = NULL; block_t *p_block = NULL;
if(!readsize || !buffered || !(p_block = block_Alloc(readsize)) ) if(!readsize || !buffered || !(p_block = block_Alloc(readsize)) )
{ {
eof = true;
vlc_mutex_unlock(&lock); vlc_mutex_unlock(&lock);
return NULL; return NULL;
} }
...@@ -418,6 +453,9 @@ block_t * HTTPChunkBufferedSource::read(size_t readsize) ...@@ -418,6 +453,9 @@ block_t * HTTPChunkBufferedSource::read(size_t readsize)
consumed += copied; consumed += copied;
p_block->i_buffer = copied; p_block->i_buffer = copied;
if(copied < readsize)
eof = true;
vlc_mutex_unlock(&lock); vlc_mutex_unlock(&lock);
return p_block; return p_block;
......
...@@ -47,10 +47,10 @@ namespace adaptative ...@@ -47,10 +47,10 @@ namespace adaptative
virtual ~AbstractChunkSource(); virtual ~AbstractChunkSource();
virtual block_t * readBlock () = 0; virtual block_t * readBlock () = 0;
virtual block_t * read (size_t) = 0; virtual block_t * read (size_t) = 0;
virtual bool hasMoreData () const = 0;
void setParentChunk (AbstractChunk *); void setParentChunk (AbstractChunk *);
void setBytesRange (const BytesRange &); void setBytesRange (const BytesRange &);
const BytesRange & getBytesRange () const; const BytesRange & getBytesRange () const;
size_t getContentLength() const;
protected: protected:
AbstractChunk *parentChunk; AbstractChunk *parentChunk;
...@@ -64,7 +64,7 @@ namespace adaptative ...@@ -64,7 +64,7 @@ namespace adaptative
virtual ~AbstractChunk(); virtual ~AbstractChunk();
size_t getBytesRead () const; size_t getBytesRead () const;
size_t getBytesToRead () const; bool isEmpty () const;
virtual block_t * readBlock (); virtual block_t * readBlock ();
virtual block_t * read (size_t); virtual block_t * read (size_t);
...@@ -87,6 +87,7 @@ namespace adaptative ...@@ -87,6 +87,7 @@ namespace adaptative
virtual block_t * readBlock (); /* impl */ virtual block_t * readBlock (); /* impl */
virtual block_t * read (size_t); /* impl */ virtual block_t * read (size_t); /* impl */
virtual bool hasMoreData () const; /* impl */
static const size_t CHUNK_SIZE = 32768; static const size_t CHUNK_SIZE = 32768;
...@@ -96,6 +97,7 @@ namespace adaptative ...@@ -96,6 +97,7 @@ namespace adaptative
HTTPConnectionManager *connManager; HTTPConnectionManager *connManager;
size_t consumed; /* read pointer */ size_t consumed; /* read pointer */
bool prepared; bool prepared;
bool eof;
private: private:
bool init(const std::string &); bool init(const std::string &);
...@@ -115,6 +117,7 @@ namespace adaptative ...@@ -115,6 +117,7 @@ namespace adaptative
virtual ~HTTPChunkBufferedSource(); virtual ~HTTPChunkBufferedSource();
virtual block_t * readBlock (); /* reimpl */ virtual block_t * readBlock (); /* reimpl */
virtual block_t * read (size_t); /* reimpl */ virtual block_t * read (size_t); /* reimpl */
virtual bool hasMoreData () const; /* impl */
protected: protected:
virtual bool prepare(); /* reimpl */ virtual bool prepare(); /* reimpl */
...@@ -126,6 +129,7 @@ namespace adaptative ...@@ -126,6 +129,7 @@ namespace adaptative
block_t **pp_tail; block_t **pp_tail;
size_t buffered; /* read cache size */ size_t buffered; /* read cache size */
bool done; bool done;
bool eof;
mtime_t downloadstart; mtime_t downloadstart;
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_cond_t avail; vlc_cond_t avail;
......
...@@ -138,8 +138,7 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len) ...@@ -138,8 +138,7 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len)
queryOk = false; queryOk = false;
const size_t toRead = contentLength - bytesRead; const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
if (toRead == 0) if (toRead == 0)
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -153,7 +152,7 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len) ...@@ -153,7 +152,7 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len)
if(ret < 0 || (size_t)ret < len) /* set EOF */ if(ret < 0 || (size_t)ret < len) /* set EOF */
{ {
socket->disconnect(); socket->disconnect();
return VLC_EGENERIC; return ret;
} }
return ret; return ret;
......
...@@ -72,12 +72,7 @@ void Socket::disconnect() ...@@ -72,12 +72,7 @@ void Socket::disconnect()
ssize_t Socket::read(vlc_object_t *stream, void *p_buffer, size_t len) ssize_t Socket::read(vlc_object_t *stream, void *p_buffer, size_t len)
{ {
ssize_t size; return net_Read(stream, netfd, p_buffer, len);
do
{
size = net_Read(stream, netfd, p_buffer, len);
} while (size < 0 && errno==EAGAIN );
return size;
} }
std::string Socket::readline(vlc_object_t *stream) std::string Socket::readline(vlc_object_t *stream)
......
...@@ -96,7 +96,7 @@ void HLSSegment::onChunkDownload(block_t **pp_block, SegmentChunk *chunk, BaseRe ...@@ -96,7 +96,7 @@ void HLSSegment::onChunkDownload(block_t **pp_block, SegmentChunk *chunk, BaseRe
else else
{ {
/* last bytes */ /* last bytes */
if(chunk->getBytesToRead() == 0) if(chunk->isEmpty())
{ {
/* remove the PKCS#7 padding from the buffer */ /* remove the PKCS#7 padding from the buffer */
const uint8_t pad = p_block->p_buffer[p_block->i_buffer - 1]; const uint8_t pad = p_block->p_buffer[p_block->i_buffer - 1];
......
...@@ -36,6 +36,11 @@ MemoryChunkSource::~MemoryChunkSource() ...@@ -36,6 +36,11 @@ MemoryChunkSource::~MemoryChunkSource()
block_Release(data); block_Release(data);
} }
bool MemoryChunkSource::hasMoreData() const
{
return i_read > contentLength;
}
block_t * MemoryChunkSource::readBlock() block_t * MemoryChunkSource::readBlock()
{ {
block_t *p_block = NULL; block_t *p_block = NULL;
......
...@@ -36,6 +36,7 @@ namespace smooth ...@@ -36,6 +36,7 @@ namespace smooth
virtual block_t * readBlock(); /* impl */ virtual block_t * readBlock(); /* impl */
virtual block_t * read(size_t); /* impl */ virtual block_t * read(size_t); /* impl */
virtual bool hasMoreData() const; /* impl */
private: private:
block_t *data; block_t *data;
......
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