[vlc-devel] [PATCH 01/13] dash: added byte range requests

Christopher at mailsrv.uni-klu.ac.at Christopher at mailsrv.uni-klu.ac.at
Sat Feb 11 11:59:52 CET 2012


From: Christopher Mueller <christopher.mueller at itec.aau.at>

Signed-off-by: Christopher Mueller <christopher.mueller at itec.aau.at>
---
 modules/stream_filter/dash/http/Chunk.cpp          |   14 +++-
 modules/stream_filter/dash/http/Chunk.h            |    3 +
 modules/stream_filter/dash/http/HTTPConnection.cpp |   71 +++++++++++++++-----
 modules/stream_filter/dash/http/HTTPConnection.h   |   10 ++-
 .../dash/http/HTTPConnectionManager.cpp            |    2 +-
 .../stream_filter/dash/mpd/IsoffMainManager.cpp    |    4 +-
 modules/stream_filter/dash/mpd/IsoffMainParser.cpp |    8 +-
 modules/stream_filter/dash/mpd/Segment.cpp         |    1 +
 8 files changed, 85 insertions(+), 28 deletions(-)

diff --git a/modules/stream_filter/dash/http/Chunk.cpp b/modules/stream_filter/dash/http/Chunk.cpp
index ac63737..5de4e9f 100644
--- a/modules/stream_filter/dash/http/Chunk.cpp
+++ b/modules/stream_filter/dash/http/Chunk.cpp
@@ -29,8 +29,10 @@
 
 using namespace dash::http;
 
-Chunk::Chunk() : startByte( 0 ),
-    endByte( 0 )
+Chunk::Chunk        () :
+       startByte    (0),
+       endByte      (0),
+       hasByteRange (false)
 {
 }
 
@@ -62,3 +64,11 @@ void                Chunk::addOptionalUrl   (const std::string& url)
 {
     this->optionalUrls.push_back(url);
 }
+bool                Chunk::useByteRange     ()
+{
+    return this->hasByteRange;
+}
+void                Chunk::setUseByteRange  (bool value)
+{
+    this->hasByteRange = value;
+}
diff --git a/modules/stream_filter/dash/http/Chunk.h b/modules/stream_filter/dash/http/Chunk.h
index 1ec46f7..c2020f8 100644
--- a/modules/stream_filter/dash/http/Chunk.h
+++ b/modules/stream_filter/dash/http/Chunk.h
@@ -44,12 +44,15 @@ namespace dash
                 void                setStartByte    (int startByte);
                 void                setUrl          (const std::string& url);
                 void                addOptionalUrl  (const std::string& url);
+                bool                useByteRange    ();
+                void                setUseByteRange (bool value);
 
             private:
                 std::string                 url;
                 std::vector<std::string>    optionalUrls;
                 int                         startByte;
                 int                         endByte;
+                bool                        hasByteRange;
 
         };
     }
diff --git a/modules/stream_filter/dash/http/HTTPConnection.cpp b/modules/stream_filter/dash/http/HTTPConnection.cpp
index c4ff286..f98c9c7 100644
--- a/modules/stream_filter/dash/http/HTTPConnection.cpp
+++ b/modules/stream_filter/dash/http/HTTPConnection.cpp
@@ -29,29 +29,48 @@
 
 using namespace dash::http;
 
-HTTPConnection::HTTPConnection  (const std::string& url, stream_t *stream)
+HTTPConnection::HTTPConnection  (Chunk *chunk, stream_t *stream) :
+                stream          (stream),
+                chunk           (chunk),
+                peekBufferLen   (0)
 {
-    this->url       = url;
-    this->stream    = stream;
+    this->url        = chunk->getUrl();
+    this->peekBuffer = new uint8_t[PEEKBUFFER];
 }
-
 HTTPConnection::~HTTPConnection ()
 {
-
+    delete[] this->peekBuffer;
+    this->closeSocket();
 }
 
 int             HTTPConnection::read            (void *p_buffer, size_t len)
 {
-    int size = stream_Read(this->urlStream, p_buffer, len);
+    if(this->peekBufferLen == 0)
+    {
+        int size = net_Read(this->stream, this->httpSocket, NULL, p_buffer, len, false);
 
-    if(size <= 0)
-        return 0;
+        if(size <= 0)
+            return 0;
 
-    return size;
+        return size;
+    }
+
+    memcpy(p_buffer, this->peekBuffer, this->peekBufferLen);
+    int ret = this->peekBufferLen;
+    this->peekBufferLen = 0;
+    return ret;
 }
 int             HTTPConnection::peek            (const uint8_t **pp_peek, size_t i_peek)
 {
-    return stream_Peek(this->urlStream, pp_peek, i_peek);
+    if(this->peekBufferLen == 0)
+        this->peekBufferLen = this->read(this->peekBuffer, PEEKBUFFER);
+
+    int size = i_peek > this->peekBufferLen ? this->peekBufferLen : i_peek;
+
+    uint8_t *peek = new uint8_t [size];
+    memcpy(peek, this->peekBuffer, size);
+    *pp_peek = peek;
+    return size;
 }
 void            HTTPConnection::parseURL        ()
 {
@@ -67,16 +86,36 @@ void            HTTPConnection::parseURL        ()
     this->request = "GET " + this->path + " HTTP/1.1\r\n" +
                     "Host: " + this->hostname + "\r\nConnection: close\r\n\r\n";
 }
+void            HTTPConnection::prepareRequest  ()
+{
+    if(!chunk->useByteRange())
+    {
+        this->request = "GET "          + this->path     + " HTTP/1.1" + "\r\n" +
+                        "Host: "        + this->hostname + "\r\n" +
+                        "Connection: close\r\n\r\n";
+    }
+    else
+    {
+        std::stringstream req;
+        req << "GET " << this->path << " HTTP/1.1\r\n" <<
+               "Host: " << this->hostname << "\r\n" <<
+               "Range: bytes=" << this->chunk->getStartByte() << "-" << this->chunk->getEndByte() << "\r\n" <<
+               "Connection: close\r\n\r\n";
 
-bool            HTTPConnection::init()
+        this->request = req.str();
+    }
+}
+bool            HTTPConnection::init            ()
 {
-    this->urlStream = stream_UrlNew( this->stream, this->url.c_str() );
+    this->parseURL();
+    this->prepareRequest();
 
-    if( this->urlStream == NULL )
-        return false;
+    this->httpSocket = net_ConnectTCP(this->stream, this->hostname.c_str(), 80);
 
-    return true;
+    if(this->sendData(this->request))
+        return this->parseHeader();
 
+    return false;
 }
 bool            HTTPConnection::parseHeader     ()
 {
@@ -125,5 +164,5 @@ bool            HTTPConnection::sendData        (const std::string& data)
 }
 void            HTTPConnection::closeSocket     ()
 {
-    stream_Delete(this->urlStream);
+    net_Close(this->httpSocket);
 }
diff --git a/modules/stream_filter/dash/http/HTTPConnection.h b/modules/stream_filter/dash/http/HTTPConnection.h
index 5a76d65..7cb97a0 100644
--- a/modules/stream_filter/dash/http/HTTPConnection.h
+++ b/modules/stream_filter/dash/http/HTTPConnection.h
@@ -36,6 +36,9 @@
 #include <sstream>
 
 #include "http/IHTTPConnection.h"
+#include "http/Chunk.h"
+
+#define PEEKBUFFER 4096
 
 namespace dash
 {
@@ -44,7 +47,7 @@ namespace dash
         class HTTPConnection : public IHTTPConnection
         {
             public:
-                HTTPConnection          ( const std::string& url, stream_t *stream );
+                HTTPConnection          ( Chunk *chunk, stream_t *stream );
                 virtual ~HTTPConnection ();
 
                 bool        init            ();
@@ -60,12 +63,15 @@ namespace dash
                 std::string             path;
                 std::string             request;
                 stream_t                *stream;
-                stream_t                *urlStream;
+                Chunk                   *chunk;
+                uint8_t                 *peekBuffer;
+                size_t                  peekBufferLen;
 
                 void            parseURL        ();
                 bool            sendData        (const std::string& data);
                 bool            parseHeader     ();
                 std::string     readLine        ();
+                void            prepareRequest  ();
         };
     }
 }
diff --git a/modules/stream_filter/dash/http/HTTPConnectionManager.cpp b/modules/stream_filter/dash/http/HTTPConnectionManager.cpp
index b79947f..1a5e7d0 100644
--- a/modules/stream_filter/dash/http/HTTPConnectionManager.cpp
+++ b/modules/stream_filter/dash/http/HTTPConnectionManager.cpp
@@ -137,7 +137,7 @@ int                 HTTPConnectionManager::peek                     (Chunk *chun
 
 IHTTPConnection*     HTTPConnectionManager::initConnection(Chunk *chunk)
 {
-    HTTPConnection *con = new HTTPConnection(chunk->getUrl(), this->stream);
+    HTTPConnection *con = new HTTPConnection(chunk, this->stream);
     if ( con->init() == false )
         return NULL;
     this->chunkMap[chunk] = con;
diff --git a/modules/stream_filter/dash/mpd/IsoffMainManager.cpp b/modules/stream_filter/dash/mpd/IsoffMainManager.cpp
index e8bfea8..c55c684 100644
--- a/modules/stream_filter/dash/mpd/IsoffMainManager.cpp
+++ b/modules/stream_filter/dash/mpd/IsoffMainManager.cpp
@@ -101,9 +101,7 @@ Representation*             IsoffMainManager::getRepresentation     (Period *per
         {
             int currentBitrate = reps.at(j)->getBandwidth();
 
-            if(best == NULL || bitrate == -1 ||
-                 ( currentBitrate > best->getBandwidth() &&
-                   currentBitrate < bitrate ) )
+            if(best == NULL || (currentBitrate > best->getBandwidth() && currentBitrate < bitrate))
             {
                 std::cout << "Found a better Representation bandwidth=" << reps.at(j)->getBandwidth() << " in adaptationSet #" << i << std::endl;
                 best = reps.at( j );
diff --git a/modules/stream_filter/dash/mpd/IsoffMainParser.cpp b/modules/stream_filter/dash/mpd/IsoffMainParser.cpp
index c965e4c..6d8058c 100644
--- a/modules/stream_filter/dash/mpd/IsoffMainParser.cpp
+++ b/modules/stream_filter/dash/mpd/IsoffMainParser.cpp
@@ -157,7 +157,7 @@ void    IsoffMainParser::setInitSegment     (dash::xml::Node *segBaseNode, Segme
         {
             std::string range = initSeg.at(0)->getAttributeValue("range");
             size_t pos = range.find("-");
-            seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos, range.size()).c_str()));
+            seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
         }
 
         for(size_t i = 0; i < this->mpd->getBaseUrls().size(); i++)
@@ -175,11 +175,11 @@ void    IsoffMainParser::setSegments        (dash::xml::Node *segListNode, Segme
         Segment *seg = new Segment( this->currentRepresentation );
         seg->setSourceUrl(segments.at(i)->getAttributeValue("media"));
 
-        if(segments.at(0)->hasAttribute("mediaRange"))
+        if(segments.at(i)->hasAttribute("mediaRange"))
         {
-            std::string range = segments.at(0)->getAttributeValue("mediaRange");
+            std::string range = segments.at(i)->getAttributeValue("mediaRange");
             size_t pos = range.find("-");
-            seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos, range.size()).c_str()));
+            seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
         }
 
         for(size_t i = 0; i < this->mpd->getBaseUrls().size(); i++)
diff --git a/modules/stream_filter/dash/mpd/Segment.cpp b/modules/stream_filter/dash/mpd/Segment.cpp
index bc77d67..aa0f834 100644
--- a/modules/stream_filter/dash/mpd/Segment.cpp
+++ b/modules/stream_filter/dash/mpd/Segment.cpp
@@ -90,6 +90,7 @@ dash::http::Chunk*      Segment::toChunk        ()
 
     if(this->startByte != -1 && this->endByte != -1)
     {
+        chunk->setUseByteRange(true);
         chunk->setStartByte(this->startByte);
         chunk->setEndByte(this->endByte);
     }
-- 
1.7.0.4




More information about the vlc-devel mailing list