[vlc-devel] [PATCH 1/8] dash: added byte range requests
Hugo Beauzée-Luyssen
beauze.h at gmail.com
Sun Feb 5 22:25:32 CET 2012
On Sun, Feb 5, 2012 at 10:34 AM, Christopher Mueller
<christopher.mueller at itec.aau.at> wrote:
> 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
>
Hello,
Looks good to me, however you should include config.h in every cpp
file in order to prevent build breakage on windows.
Regards,
--
Hugo Beauzée-Luyssen
More information about the vlc-devel
mailing list