[vlc-devel] [PATCH 05/12] dash: added Persistent Connection

Christopher at mailsrv.uni-klu.ac.at Christopher at mailsrv.uni-klu.ac.at
Tue Mar 13 15:18:18 CET 2012


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




More information about the vlc-devel mailing list