[vlc-devel] [PATCH 05/12] dash: added Persistent Connection
Hugo Beauzée-Luyssen
beauze.h at gmail.com
Tue Mar 13 16:18:01 CET 2012
On Tue, Mar 13, 2012 at 3:18 PM, <Christopher at mailsrv.uni-klu.ac.at> wrote:
> From: Christopher Mueller <christopher.mueller at itec.aau.at>
>
> ---
> modules/stream_filter/dash/Modules.am | 2 +
> .../dash/http/PersistentConnection.cpp | 206 ++++++++++++++++++++
> .../stream_filter/dash/http/PersistentConnection.h | 63 ++++++
> 3 files changed, 271 insertions(+), 0 deletions(-)
> create mode 100644 modules/stream_filter/dash/http/PersistentConnection.cpp
> create mode 100644 modules/stream_filter/dash/http/PersistentConnection.h
>
> diff --git a/modules/stream_filter/dash/Modules.am b/modules/stream_filter/dash/Modules.am
> index 9f9b2e0..fe6d7d4 100644
> --- a/modules/stream_filter/dash/Modules.am
> +++ b/modules/stream_filter/dash/Modules.am
> @@ -20,6 +20,8 @@ SOURCES_stream_filter_dash = \
> http/HTTPConnectionManager.cpp \
> http/HTTPConnectionManager.h \
> http/IHTTPConnection.h \
> + http/PersistentConnection.cpp \
> + http/PersistentConnection.h \
> mpd/AdaptationSet.cpp \
> mpd/AdaptationSet.h \
> mpd/BaseUrl.h \
> diff --git a/modules/stream_filter/dash/http/PersistentConnection.cpp b/modules/stream_filter/dash/http/PersistentConnection.cpp
> new file mode 100644
> index 0000000..c2ad258
> --- /dev/null
> +++ b/modules/stream_filter/dash/http/PersistentConnection.cpp
> @@ -0,0 +1,206 @@
> +/*
> + * PersistentConnection.cpp
> + *****************************************************************************
> + * Copyright (C) 2010 - 2012 Klagenfurt University
> + *
> + * Created on: Aug 10, 2010
> + * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
> + * Christian Timmerer <christian.timmerer at itec.uni-klu.ac.at>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include "PersistentConnection.h"
> +
> +using namespace dash::http;
> +
> +const int PersistentConnection::RETRY = 5;
> +
> +PersistentConnection::PersistentConnection (stream_t *stream) :
> + HTTPConnection (stream),
> + isInit (false)
> +{
> +}
> +PersistentConnection::~PersistentConnection ()
> +{
> +}
> +
> +int PersistentConnection::read (void *p_buffer, size_t len)
> +{
> + if(this->chunkQueue.size() == 0)
> + return -1;
> +
> + Chunk *readChunk = this->chunkQueue.front();
> +
> + if(readChunk->getBytesRead() == 0)
> + {
> + if(!this->initChunk(readChunk))
> + {
> + this->chunkQueue.pop_front();
> + return -1;
> + }
> + }
> +
> + if(readChunk->getBytesToRead() == 0)
> + {
> + this->chunkQueue.pop_front();
> + return 0;
> + }
> +
> + int ret = 0;
> + if(len > readChunk->getBytesToRead())
> + ret = HTTPConnection::read(p_buffer, readChunk->getBytesToRead());
> + else
> + ret = HTTPConnection::read(p_buffer, len);
> +
> + if(ret <= 0)
> + {
> + readChunk->setStartByte(readChunk->getStartByte() + readChunk->getBytesRead());
> + readChunk->setBytesRead(0);
> + if(!this->reconnect(readChunk))
> + {
> + this->chunkQueue.pop_front();
> + return -1;
> + }
> +
> + return this->read(p_buffer, len);
> + }
> +
> + readChunk->setBytesRead(readChunk->getBytesRead() + ret);
> +
> + return ret;
> +}
> +std::string PersistentConnection::prepareRequest (Chunk *chunk)
> +{
> + std::string request;
> + if(!chunk->useByteRange())
> + {
> + request = "GET " + chunk->getPath() + " HTTP/1.1" + "\r\n" +
> + "Host: " + chunk->getHostname() + "\r\n\r\n";
> + }
> + else
> + {
> + std::stringstream req;
> + req << "GET " << chunk->getPath() << " HTTP/1.1\r\n" <<
> + "Host: " << chunk->getHostname() << "\r\n" <<
> + "Range: bytes=" << chunk->getStartByte() << "-" << chunk->getEndByte() << "\r\n\r\n";
> +
> + request = req.str();
> + }
> + return request;
> +}
> +bool PersistentConnection::init (Chunk *chunk)
> +{
> + if(this->isInit)
> + return true;
> +
> + if(chunk == NULL)
> + return false;
> +
> + if(!chunk->hasHostname())
> + if(!this->setUrlRelative(chunk))
> + return false;
> +
> + this->httpSocket = net_ConnectTCP(this->stream, chunk->getHostname().c_str(), chunk->getPort());
> +
> + if(this->httpSocket == -1)
> + return false;
> +
> + if(this->sendData(this->prepareRequest(chunk)))
> + this->isInit = true;
> +
> + this->chunkQueue.push_back(chunk);
> + this->hostname = chunk->getHostname();
> +
> + return this->isInit;
> +}
> +bool PersistentConnection::addChunk (Chunk *chunk)
> +{
> + if(chunk == NULL)
> + return false;
> +
> + if(!this->isInit)
> + return this->init(chunk);
> +
> + if(!chunk->hasHostname())
> + if(!this->setUrlRelative(chunk))
> + return false;
> +
> + if(chunk->getHostname().compare(this->hostname))
> + return false;
> +
> + if(this->sendData(this->prepareRequest(chunk)))
> + {
> + this->chunkQueue.push_back(chunk);
> + return true;
> + }
> +
> + return false;
> +}
> +bool PersistentConnection::initChunk (Chunk *chunk)
> +{
> + if(this->parseHeader())
> + {
> + chunk->setLength(this->contentLength);
> + return true;
> + }
> +
> + if(!this->reconnect(chunk))
> + return false;
> +
> + if(this->parseHeader())
> + {
> + chunk->setLength(this->contentLength);
> + return true;
> + }
> +
> + return false;
> +}
> +bool PersistentConnection::reconnect (Chunk *chunk)
> +{
> + int count = 0;
> + std::string request = this->prepareRequest(chunk);
> +
> + while(count < this->RETRY)
> + {
> + this->httpSocket = net_ConnectTCP(this->stream, chunk->getHostname().c_str(), chunk->getPort());
> + if(this->httpSocket != -1)
> + if(this->resendAllRequests())
> + return true;
> +
> + count++;
> + }
> +
> + return false;
> +}
> +const std::string& PersistentConnection::getHostname () const
> +{
> + return this->hostname;
> +}
> +bool PersistentConnection::isConnected () const
> +{
> + return this->isInit;
> +}
> +bool PersistentConnection::resendAllRequests ()
> +{
> + for(size_t i = 0; i < this->chunkQueue.size(); i++)
> + if(!this->sendData((this->prepareRequest(this->chunkQueue.at(i)))))
> + return false;
> +
> + return true;
> +}
> diff --git a/modules/stream_filter/dash/http/PersistentConnection.h b/modules/stream_filter/dash/http/PersistentConnection.h
> new file mode 100644
> index 0000000..e671f79
> --- /dev/null
> +++ b/modules/stream_filter/dash/http/PersistentConnection.h
> @@ -0,0 +1,63 @@
> +/*
> + * PersistentConnection.h
> + *****************************************************************************
> + * Copyright (C) 2010 - 2012 Klagenfurt University
> + *
> + * Created on: Aug 10, 2010
> + * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
> + * Christian Timmerer <christian.timmerer at itec.uni-klu.ac.at>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifndef PERSISTENTCONNECTION_H_
> +#define PERSISTENTCONNECTION_H_
> +
> +#include "HTTPConnection.h"
> +#include <deque>
> +
> +namespace dash
> +{
> + namespace http
> + {
> + class PersistentConnection : public HTTPConnection
> + {
> + public:
> + PersistentConnection (stream_t *stream);
> + virtual ~PersistentConnection ();
> +
> + virtual int read (void *p_buffer, size_t len);
> + virtual bool init (Chunk *chunk);
> + bool addChunk (Chunk *chunk);
> + const std::string& getHostname () const;
> + bool isConnected () const;
> +
> + private:
> + std::deque<Chunk *> chunkQueue;
> + bool isInit;
> + std::string hostname;
> +
> + static const int RETRY;
> +
> + protected:
> + virtual std::string prepareRequest (Chunk *chunk);
> + bool initChunk (Chunk *chunk);
> + bool reconnect (Chunk *chunk);
> + bool resendAllRequests ();
> + };
> + }
> +}
> +
> +#endif /* PERSISTENTCONNECTION_H_ */
> --
> 1.7.0.4
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel
It may be a good thing to add some assert about chunk != NULL in
private/protected methods.
It still looks like the chunk aren't getting deleted (unless I missed
something in an upcomming patch)
Regards,
--
Hugo Beauzée-Luyssen
More information about the vlc-devel
mailing list