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

demux: adaptative: move Chunk out of connection and simplify ranges

parent a34ae180
......@@ -332,13 +332,17 @@ block_t * AbstractStream::readNextBlock(size_t)
/* New chunk, do query */
if(chunk->getBytesRead() == 0)
{
if(chunk->getConnection()->query(chunk->getPath()) != VLC_SUCCESS)
BytesRange bytesRange;
if(chunk->usesByteRange())
bytesRange = BytesRange(chunk->getStartByte(), chunk->getEndByte());
if(chunk->getConnection()->query(chunk->getPath(), bytesRange) != VLC_SUCCESS)
{
chunk->getConnection()->releaseChunk();
currentChunk = NULL;
delete chunk;
return NULL;
}
chunk->setLength(chunk->getConnection()->getContentLength());
b_segment_head_chunk = true;
}
......@@ -359,13 +363,13 @@ block_t * AbstractStream::readNextBlock(size_t)
if(ret < 0)
{
block_Release(block);
chunk->getConnection()->releaseChunk();
currentChunk = NULL;
delete chunk;
return NULL;
}
else
{
chunk->setBytesRead(chunk->getBytesRead() + ret);
block->i_buffer = (size_t)ret;
adaptationLogic->updateDownloadRate(block->i_buffer, time);
......@@ -373,7 +377,6 @@ block_t * AbstractStream::readNextBlock(size_t)
if (chunk->getBytesToRead() == 0)
{
chunk->getConnection()->releaseChunk();
currentChunk = NULL;
delete chunk;
}
......@@ -395,10 +398,7 @@ bool AbstractStream::setPosition(mtime_t time, bool tryonly)
if(demuxer->reinitsOnSeek())
{
if(currentChunk)
{
currentChunk->getConnection()->releaseChunk();
delete currentChunk;
}
currentChunk = NULL;
restartDemux();
......
......@@ -38,7 +38,6 @@ Chunk::Chunk (const std::string& url) :
port (0),
length (0),
bytesRead (0),
bytesToRead (0),
connection (NULL)
{
this->url = url;
......@@ -73,6 +72,12 @@ Chunk::Chunk (const std::string& url) :
throw VLC_EGENERIC;
}
Chunk::~Chunk()
{
if(connection)
connection->setUsed(false);
}
size_t Chunk::getEndByte () const
{
return endByte;
......@@ -89,13 +94,13 @@ void Chunk::setEndByte (size_t endByte)
{
this->endByte = endByte;
if (endByte > startByte)
bytesToRead = endByte - startByte;
length = endByte - startByte;
}
void Chunk::setStartByte (size_t startByte)
{
this->startByte = startByte;
if (endByte > startByte)
bytesToRead = endByte - startByte;
length = endByte - startByte;
}
bool Chunk::usesByteRange () const
......@@ -121,25 +126,20 @@ int Chunk::getPort () const
return this->port;
}
void Chunk::setLength (uint64_t length)
void Chunk::setLength (size_t length)
{
this->length = length;
}
uint64_t Chunk::getBytesRead () const
size_t Chunk::getBytesRead () const
{
return this->bytesRead;
}
void Chunk::setBytesRead (uint64_t bytes)
void Chunk::setBytesRead (size_t bytes)
{
this->bytesRead = bytes;
}
void Chunk::setBytesToRead (uint64_t bytes)
{
bytesToRead = bytes;
}
uint64_t Chunk::getBytesToRead () const
size_t Chunk::getBytesToRead () const
{
return length - bytesRead;
}
......
......@@ -41,7 +41,7 @@ namespace adaptative
{
public:
Chunk (const std::string &url);
virtual ~Chunk () {}
virtual ~Chunk ();
size_t getEndByte () const;
size_t getStartByte () const;
......@@ -50,14 +50,13 @@ namespace adaptative
const std::string& getHostname () const;
const std::string& getPath () const;
int getPort () const;
uint64_t getBytesRead () const;
uint64_t getBytesToRead () const;
size_t getBytesRead () const;
size_t getBytesToRead () const;
HTTPConnection* getConnection () const;
void setConnection (HTTPConnection *connection);
void setBytesRead (uint64_t bytes);
void setBytesToRead (uint64_t bytes);
void setLength (uint64_t length);
void setBytesRead (size_t bytes);
void setLength (size_t length);
void setEndByte (size_t endByte);
void setStartByte (size_t startByte);
bool usesByteRange () const;
......@@ -72,9 +71,8 @@ namespace adaptative
size_t startByte;
size_t endByte;
int port;
uint64_t length;
uint64_t bytesRead;
uint64_t bytesToRead;
size_t length;
size_t bytesRead;
HTTPConnection *connection;
};
}
......
......@@ -20,26 +20,24 @@
#include "HTTPConnection.hpp"
#include "Sockets.hpp"
#include "Chunk.h"
#include "../adaptative/tools/Helper.h"
#include <sstream>
using namespace adaptative::http;
HTTPConnection::HTTPConnection(vlc_object_t *stream_, Socket *socket_,
Chunk *chunk_, bool persistent)
HTTPConnection::HTTPConnection(vlc_object_t *stream_, Socket *socket_, bool persistent)
{
socket = socket_;
stream = stream_;
psz_useragent = var_InheritString(stream, "http-user-agent");
toRead = 0;
chunk = NULL;
bytesRead = 0;
contentLength = 0;
queryOk = false;
retries = 0;
connectionClose = !persistent;
port = 80;
bindChunk(chunk_);
available = true;
}
HTTPConnection::~HTTPConnection()
......@@ -74,21 +72,21 @@ bool HTTPConnection::connected() const
void HTTPConnection::disconnect()
{
queryOk = false;
toRead = 0;
bytesRead = 0;
contentLength = 0;
bytesRange = BytesRange();
socket->disconnect();
}
int HTTPConnection::query(const std::string &path)
int HTTPConnection::query(const std::string &path, const BytesRange &range)
{
if(!chunk)
return VLC_EGENERIC;
queryOk = false;
if(!connected() &&
!connect(chunk->getHostname(), chunk->getPort()))
if(!connected() && ( hostname.empty() || !connect(hostname, port) ))
return VLC_EGENERIC;
bytesRange = range;
std::string header = buildRequestHeader(path);
if(connectionClose)
header.append("Connection: close\r\n");
......@@ -101,7 +99,7 @@ int HTTPConnection::query(const std::string &path)
{
/* server closed connection pipeline after last req. need new */
connectionClose = true;
return query(path);
return query(path, range);
}
return VLC_EGENERIC;
}
......@@ -117,7 +115,7 @@ int HTTPConnection::query(const std::string &path)
if(!connectionClose)
{
connectionClose = true;
return query(path);
return query(path, range);
}
}
......@@ -126,8 +124,8 @@ int HTTPConnection::query(const std::string &path)
ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
if(!chunk || !connected() ||
(!queryOk && chunk->getBytesRead() == 0) )
if( !connected() ||
(!queryOk && bytesRead == 0) )
return VLC_EGENERIC;
if(len == 0)
......@@ -135,19 +133,20 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len)
queryOk = false;
if(chunk->getBytesToRead() == 0)
const size_t toRead = contentLength - bytesRead;
if (toRead == 0)
return VLC_SUCCESS;
if(len > chunk->getBytesToRead())
len = chunk->getBytesToRead();
if(len > toRead)
len = toRead;
ssize_t ret = socket->read(stream, p_buffer, len);
if(ret >= 0)
chunk->setBytesRead(chunk->getBytesRead() + ret);
bytesRead += ret;
if(ret < 0 || (size_t)ret < len) /* set EOF */
{
chunk->setBytesToRead(chunk->getBytesRead());
socket->disconnect();
return VLC_EGENERIC;
}
......@@ -203,41 +202,31 @@ std::string HTTPConnection::readLine()
return socket->readline(stream);
}
const std::string& HTTPConnection::getHostname() const
{
return hostname;
}
void HTTPConnection::bindChunk(Chunk *chunk_)
bool HTTPConnection::isAvailable() const
{
if(chunk_ == chunk)
return;
if (chunk_)
chunk_->setConnection(this);
chunk = chunk_;
return available;
}
void HTTPConnection::releaseChunk()
void HTTPConnection::setUsed( bool b )
{
if(!connectionClose &&
(!chunk || chunk->getBytesRead() == toRead) ) /* We can't resend request if we haven't finished reading */
{
queryOk = false;
toRead = 0;
}
else
disconnect();
if(chunk)
available = !b;
if(available)
{
chunk->setConnection(NULL);
chunk = NULL;
if(!connectionClose && contentLength == bytesRead )
{
queryOk = false;
bytesRead = 0;
contentLength = 0;
bytesRange = BytesRange();
}
else /* We can't resend request if we haven't finished reading */
disconnect();
}
}
bool HTTPConnection::isAvailable() const
size_t HTTPConnection::getContentLength() const
{
return chunk == NULL;
return contentLength;
}
void HTTPConnection::onHeader(const std::string &key,
......@@ -248,8 +237,7 @@ void HTTPConnection::onHeader(const std::string &key,
std::istringstream ss(value);
size_t length;
ss >> length;
chunk->setLength(length);
toRead = length;
contentLength = length;
}
else if (key == "Connection" && value =="close")
{
......@@ -271,11 +259,11 @@ std::string HTTPConnection::buildRequestHeader(const std::string &path) const
std::string HTTPConnection::extraRequestHeaders() const
{
std::stringstream ss;
if(chunk->usesByteRange())
if(bytesRange.isValid())
{
ss << "Range: bytes=" << chunk->getStartByte() << "-";
if(chunk->getEndByte())
ss << chunk->getEndByte();
ss << "Range: bytes=" << bytesRange.getStartByte() << "-";
if(bytesRange.getEndByte())
ss << bytesRange.getEndByte();
ss << "\r\n";
}
return ss.str();
......
......@@ -29,6 +29,7 @@
# include "config.h"
#endif
#include "BytesRange.hpp"
#include <vlc_common.h>
#include <string>
......@@ -37,27 +38,25 @@ namespace adaptative
namespace http
{
class Socket;
class Chunk;
class HTTPConnection
{
public:
HTTPConnection(vlc_object_t *stream, Socket *, Chunk * = NULL, bool = false);
HTTPConnection(vlc_object_t *stream, Socket *, bool = false);
virtual ~HTTPConnection();
virtual bool compare (const std::string &, uint16_t, int) const;
virtual bool connect (const std::string& hostname, uint16_t port = 80);
virtual bool connected () const;
virtual int query (const std::string& path);
virtual int query (const std::string& path, const BytesRange & = BytesRange());
virtual bool send (const void *buf, size_t size);
virtual ssize_t read (void *p_buffer, size_t len);
virtual void disconnect ();
virtual bool send (const std::string &data);
const std::string& getHostname () const;
virtual void bindChunk (Chunk *chunk);
virtual bool isAvailable () const;
virtual void releaseChunk();
size_t getContentLength() const;
bool isAvailable () const;
void setUsed( bool );
protected:
......@@ -72,8 +71,10 @@ namespace adaptative
uint16_t port;
char * psz_useragent;
vlc_object_t *stream;
size_t toRead;
Chunk *chunk;
size_t bytesRead;
size_t contentLength;
BytesRange bytesRange;
bool available;
bool connectionClose;
bool queryOk;
......
......@@ -51,7 +51,7 @@ void HTTPConnectionManager::releaseAllConnections()
{
std::vector<HTTPConnection *>::iterator it;
for(it = connectionPool.begin(); it != connectionPool.end(); ++it)
(*it)->releaseChunk();
(*it)->setUsed(false);
}
HTTPConnection * HTTPConnectionManager::getConnection(const std::string &hostname, uint16_t port, int sockettype)
......@@ -85,18 +85,23 @@ bool HTTPConnectionManager::connectChunk(Chunk *chunk)
if(!socket)
return false;
/* disable pipelined tls until we have ticket/resume session support */
conn = new (std::nothrow) HTTPConnection(stream, socket, chunk, sockettype != TLSSocket::TLS);
conn = new (std::nothrow) HTTPConnection(stream, socket, sockettype != TLSSocket::TLS);
if(!conn)
{
delete socket;
return false;
}
connectionPool.push_back(conn);
if (!chunk->getConnection()->connect(chunk->getHostname(), chunk->getPort()))
if (!conn->connect(chunk->getHostname(), chunk->getPort()))
{
return false;
}
}
conn->bindChunk(chunk);
conn->setUsed(true);
chunk->setConnection(conn);
return true;
}
......@@ -37,12 +37,19 @@ uint64_t Retrieve::HTTP(vlc_object_t *obj, const std::string &uri, void **pp_dat
*pp_data = NULL;
return 0;
}
;
if(!connManager.connectChunk(datachunk))
{
delete datachunk;
*pp_data = NULL;
return 0;
}
if( datachunk->getConnection()->query(datachunk->getPath()) == VLC_SUCCESS )
datachunk->setLength(datachunk->getConnection()->getContentLength());
if(!connManager.connectChunk(datachunk) ||
datachunk->getConnection()->query(datachunk->getPath()) != VLC_SUCCESS ||
datachunk->getBytesToRead() == 0 )
if( datachunk->getBytesToRead() == 0 )
{
datachunk->getConnection()->releaseChunk();
delete datachunk;
*pp_data = NULL;
return 0;
......@@ -61,10 +68,10 @@ uint64_t Retrieve::HTTP(vlc_object_t *obj, const std::string &uri, void **pp_dat
}
else
{
datachunk->setBytesRead(datachunk->getBytesRead() + ret);
i_data = ret;
}
}
datachunk->getConnection()->releaseChunk();
delete datachunk;
return i_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