Commit bc4b3050 authored by Francois Cartegnie's avatar Francois Cartegnie

stream_filter: dash: ensure chunks have hostname and fully chain build url

Otherwise, connection can never be reused, and late url fix is ugly
parent 3eb5817a
...@@ -29,17 +29,34 @@ ...@@ -29,17 +29,34 @@
using namespace dash::http; using namespace dash::http;
Chunk::Chunk () : Chunk::Chunk (const std::string& url) :
startByte (0), startByte (0),
endByte (0), endByte (0),
bitrate (1), bitrate (1),
port (0), port (0),
isHostname (false),
length (0), length (0),
bytesRead (0), bytesRead (0),
bytesToRead (0), bytesToRead (0),
connection (NULL) connection (NULL)
{ {
this->url = url;
if(url.compare(0, 7, "http://"))
throw VLC_EGENERIC;
vlc_url_t url_components;
vlc_UrlParse(&url_components, url.c_str(), 0);
if(url_components.psz_path)
path = url_components.psz_path;
port = url_components.i_port ? url_components.i_port : 80;
if(url_components.psz_host)
hostname = url_components.psz_host;
vlc_UrlClean(&url_components);
if(path.empty() || hostname.empty())
throw VLC_EGENERIC;
} }
size_t Chunk::getEndByte () const size_t Chunk::getEndByte () const
...@@ -66,26 +83,6 @@ void Chunk::setStartByte (size_t startByte) ...@@ -66,26 +83,6 @@ void Chunk::setStartByte (size_t startByte)
if (endByte > startByte) if (endByte > startByte)
bytesToRead = endByte - startByte; bytesToRead = endByte - startByte;
} }
void Chunk::setUrl (const std::string& url )
{
this->url = url;
if(this->url.compare(0, 4, "http"))
{
this->isHostname = false;
return;
}
vlc_url_t url_components;
vlc_UrlParse(&url_components, url.c_str(), 0);
this->path = url_components.psz_path;
this->port = url_components.i_port ? url_components.i_port : 80;
this->hostname = url_components.psz_host;
this->isHostname = true;
vlc_UrlClean(&url_components);
}
void Chunk::addOptionalUrl (const std::string& url) void Chunk::addOptionalUrl (const std::string& url)
{ {
this->optionalUrls.push_back(url); this->optionalUrls.push_back(url);
...@@ -103,13 +100,9 @@ int Chunk::getBitrate () ...@@ -103,13 +100,9 @@ int Chunk::getBitrate ()
{ {
return this->bitrate; return this->bitrate;
} }
bool Chunk::hasHostname () const
{
return this->isHostname;
}
const std::string& Chunk::getHostname () const const std::string& Chunk::getHostname () const
{ {
return this->hostname; return hostname;
} }
const std::string& Chunk::getPath () const const std::string& Chunk::getPath () const
{ {
......
...@@ -45,13 +45,12 @@ namespace dash ...@@ -45,13 +45,12 @@ namespace dash
class Chunk class Chunk
{ {
public: public:
Chunk (); Chunk (const std::string &url);
virtual ~Chunk () {} virtual ~Chunk () {}
size_t getEndByte () const; size_t getEndByte () const;
size_t getStartByte () const; size_t getStartByte () const;
const std::string& getUrl () const; const std::string& getUrl () const;
bool hasHostname () const;
const std::string& getHostname () const; const std::string& getHostname () const;
const std::string& getPath () const; const std::string& getPath () const;
int getPort () const; int getPort () const;
...@@ -67,7 +66,6 @@ namespace dash ...@@ -67,7 +66,6 @@ namespace dash
void setLength (uint64_t length); void setLength (uint64_t length);
void setEndByte (size_t endByte); void setEndByte (size_t endByte);
void setStartByte (size_t startByte); void setStartByte (size_t startByte);
void setUrl (const std::string& url);
void addOptionalUrl (const std::string& url); void addOptionalUrl (const std::string& url);
bool usesByteRange () const; bool usesByteRange () const;
void setBitrate (uint64_t bitrate); void setBitrate (uint64_t bitrate);
...@@ -84,7 +82,6 @@ namespace dash ...@@ -84,7 +82,6 @@ namespace dash
size_t endByte; size_t endByte;
int bitrate; int bitrate;
int port; int port;
bool isHostname;
uint64_t length; uint64_t length;
uint64_t bytesRead; uint64_t bytesRead;
uint64_t bytesToRead; uint64_t bytesToRead;
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "Chunk.h" #include "Chunk.h"
#include <sstream> #include <sstream>
#include <vlc_stream.h>
using namespace dash::http; using namespace dash::http;
...@@ -52,11 +51,7 @@ void HTTPConnection::bindChunk(Chunk *chunk_) ...@@ -52,11 +51,7 @@ void HTTPConnection::bindChunk(Chunk *chunk_)
if(chunk_ == chunk) if(chunk_ == chunk)
return; return;
if (chunk_) if (chunk_)
{
chunk_->setConnection(this); chunk_->setConnection(this);
if(!chunk->hasHostname())
chunk->setUrl(getUrlRelative(chunk));
}
chunk = chunk_; chunk = chunk_;
} }
...@@ -95,13 +90,6 @@ std::string HTTPConnection::extraRequestHeaders() const ...@@ -95,13 +90,6 @@ std::string HTTPConnection::extraRequestHeaders() const
return ss.str(); return ss.str();
} }
std::string HTTPConnection::getUrlRelative(const Chunk *chunk) const
{
std::stringstream ss;
ss << stream->psz_access << "://" << Helper::combinePaths(Helper::getDirectoryPath(stream->psz_path), chunk->getUrl());
return ss.str();
}
bool HTTPConnection::isAvailable() const bool HTTPConnection::isAvailable() const
{ {
return chunk == NULL; return chunk == NULL;
......
...@@ -51,8 +51,6 @@ namespace dash ...@@ -51,8 +51,6 @@ namespace dash
Chunk *chunk; Chunk *chunk;
virtual std::string extraRequestHeaders() const; virtual std::string extraRequestHeaders() const;
virtual std::string buildRequestHeader(const std::string &path) const; virtual std::string buildRequestHeader(const std::string &path) const;
std::string getUrlRelative(const Chunk *chunk) const;
}; };
} }
} }
......
...@@ -32,10 +32,12 @@ ...@@ -32,10 +32,12 @@
#include <vlc_arrays.h> #include <vlc_arrays.h>
#include "SegmentInfoDefault.h" #include "SegmentInfoDefault.h"
#include "Period.h"
using namespace dash::mpd; using namespace dash::mpd;
AdaptationSet::AdaptationSet() : AdaptationSet::AdaptationSet(Period *period) :
ICanonicalUrl( period ),
subsegmentAlignmentFlag( false ), subsegmentAlignmentFlag( false ),
segmentInfoDefault( NULL ), segmentInfoDefault( NULL ),
isBitstreamSwitching( false ) isBitstreamSwitching( false )
...@@ -110,3 +112,8 @@ bool AdaptationSet::getBitstreamSwitching () const ...@@ -110,3 +112,8 @@ bool AdaptationSet::getBitstreamSwitching () const
{ {
return this->isBitstreamSwitching; return this->isBitstreamSwitching;
} }
std::string AdaptationSet::getUrlSegment() const
{
return getParentUrlSegment();
}
...@@ -31,17 +31,19 @@ ...@@ -31,17 +31,19 @@
#include "mpd/Representation.h" #include "mpd/Representation.h"
#include "mpd/CommonAttributesElements.h" #include "mpd/CommonAttributesElements.h"
#include "mpd/ICanonicalUrl.hpp"
namespace dash namespace dash
{ {
namespace mpd namespace mpd
{ {
class SegmentInfoDefault; class SegmentInfoDefault;
class Period;
class AdaptationSet : public CommonAttributesElements class AdaptationSet : public CommonAttributesElements, public ICanonicalUrl
{ {
public: public:
AdaptationSet(); AdaptationSet(Period *);
virtual ~AdaptationSet(); virtual ~AdaptationSet();
virtual const std::string& getMimeType() const; /*reimpl*/ virtual const std::string& getMimeType() const; /*reimpl*/
...@@ -54,6 +56,7 @@ namespace dash ...@@ -54,6 +56,7 @@ namespace dash
void setBitstreamSwitching(bool value); void setBitstreamSwitching(bool value);
bool getBitstreamSwitching() const; bool getBitstreamSwitching() const;
void addRepresentation( Representation *rep ); void addRepresentation( Representation *rep );
virtual std::string getUrlSegment() const; /* reimpl */
private: private:
bool subsegmentAlignmentFlag; bool subsegmentAlignmentFlag;
......
...@@ -222,7 +222,7 @@ void BasicCMParser::setAdaptationSets(Node *root, Period *period) ...@@ -222,7 +222,7 @@ void BasicCMParser::setAdaptationSets(Node *root, Period *period)
for(size_t i = 0; i < adaptSets.size(); i++) for(size_t i = 0; i < adaptSets.size(); i++)
{ {
const std::map<std::string, std::string> attr = adaptSets.at(i)->getAttributes(); const std::map<std::string, std::string> attr = adaptSets.at(i)->getAttributes();
AdaptationSet *adaptSet = new AdaptationSet; AdaptationSet *adaptSet = new AdaptationSet(period);
if ( this->parseCommonAttributesElements( adaptSets.at( i ), adaptSet, NULL ) == false ) if ( this->parseCommonAttributesElements( adaptSets.at( i ), adaptSet, NULL ) == false )
{ {
delete adaptSet; delete adaptSet;
...@@ -264,7 +264,7 @@ void BasicCMParser::setRepresentations (Node *root, AdaptationSet *group) ...@@ -264,7 +264,7 @@ void BasicCMParser::setRepresentations (Node *root, AdaptationSet *group)
{ {
const std::map<std::string, std::string> attributes = representations.at(i)->getAttributes(); const std::map<std::string, std::string> attributes = representations.at(i)->getAttributes();
Representation *rep = new Representation(getMPD()); Representation *rep = new Representation(group, getMPD());
rep->setParentGroup( group ); rep->setParentGroup( group );
this->currentRepresentation = rep; this->currentRepresentation = rep;
if ( this->parseCommonAttributesElements( representations.at( i ), rep, group ) == false ) if ( this->parseCommonAttributesElements( representations.at( i ), rep, group ) == false )
......
...@@ -48,7 +48,7 @@ void IMPDParser::setPeriods(Node *root_) ...@@ -48,7 +48,7 @@ void IMPDParser::setPeriods(Node *root_)
for(size_t i = 0; i < periods.size(); i++) for(size_t i = 0; i < periods.size(); i++)
{ {
Period *period = new Period(); Period *period = new Period(mpd);
setAdaptationSets(periods.at(i), period); setAdaptationSets(periods.at(i), period);
mpd->addPeriod(period); mpd->addPeriod(period);
} }
......
...@@ -76,7 +76,7 @@ void IsoffMainParser::setAdaptationSets (Node *periodNode, Period *period) ...@@ -76,7 +76,7 @@ void IsoffMainParser::setAdaptationSets (Node *periodNode, Period *period)
for(it = adaptationSets.begin(); it != adaptationSets.end(); it++) for(it = adaptationSets.begin(); it != adaptationSets.end(); it++)
{ {
AdaptationSet *adaptationSet = new AdaptationSet(); AdaptationSet *adaptationSet = new AdaptationSet(period);
if(!adaptationSet) if(!adaptationSet)
continue; continue;
if((*it)->hasAttribute("mimeType")) if((*it)->hasAttribute("mimeType"))
...@@ -91,7 +91,7 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation ...@@ -91,7 +91,7 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation
for(size_t i = 0; i < representations.size(); i++) for(size_t i = 0; i < representations.size(); i++)
{ {
this->currentRepresentation = new Representation(getMPD()); this->currentRepresentation = new Representation(adaptationSet, getMPD());
Node *repNode = representations.at(i); Node *repNode = representations.at(i);
std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(repNode, "BaseURL"); std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(repNode, "BaseURL");
......
...@@ -166,7 +166,11 @@ std::string MPD::getUrlSegment() const ...@@ -166,7 +166,11 @@ std::string MPD::getUrlSegment() const
if (!baseUrls.empty()) if (!baseUrls.empty())
return baseUrls.front()->getUrl(); return baseUrls.front()->getUrl();
else else
return std::string(); {
std::stringstream ss;
ss << stream->psz_access << "://" << Helper::getDirectoryPath(stream->psz_path) << "/";
return ss.str();
}
} }
vlc_object_t * MPD::getVLCObject() const vlc_object_t * MPD::getVLCObject() const
......
...@@ -27,13 +27,15 @@ ...@@ -27,13 +27,15 @@
#endif #endif
#include "Period.h" #include "Period.h"
#include "MPD.h"
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_arrays.h> #include <vlc_arrays.h>
using namespace dash::mpd; using namespace dash::mpd;
Period::Period() Period::Period(MPD *mpd) :
ICanonicalUrl( mpd )
{ {
} }
...@@ -75,3 +77,8 @@ AdaptationSet * Period::getAdaptationSet(Streams::Type type) const ...@@ -75,3 +77,8 @@ AdaptationSet * Period::getAdaptationSet(Streams::Type type) const
} }
return NULL; return NULL;
} }
std::string Period::getUrlSegment() const
{
return getParentUrlSegment();
}
...@@ -28,16 +28,18 @@ ...@@ -28,16 +28,18 @@
#include <string> #include <string>
#include "mpd/AdaptationSet.h" #include "mpd/AdaptationSet.h"
#include "mpd/ICanonicalUrl.hpp"
#include "Streams.hpp" #include "Streams.hpp"
namespace dash namespace dash
{ {
namespace mpd namespace mpd
{ {
class Period class MPD;
class Period : public ICanonicalUrl
{ {
public: public:
Period(); Period(MPD *);
virtual ~Period (); virtual ~Period ();
const std::vector<AdaptationSet *>& getAdaptationSets () const; const std::vector<AdaptationSet *>& getAdaptationSets () const;
...@@ -45,6 +47,8 @@ namespace dash ...@@ -45,6 +47,8 @@ namespace dash
AdaptationSet * getAdaptationSet (Streams::Type) const; AdaptationSet * getAdaptationSet (Streams::Type) const;
void addAdaptationSet (AdaptationSet *AdaptationSet); void addAdaptationSet (AdaptationSet *AdaptationSet);
virtual std::string getUrlSegment() const; /* reimpl */
private: private:
std::vector<AdaptationSet *> adaptationSets; std::vector<AdaptationSet *> adaptationSets;
}; };
......
...@@ -28,12 +28,13 @@ ...@@ -28,12 +28,13 @@
#include <cstdlib> #include <cstdlib>
#include "Representation.h" #include "Representation.h"
#include "mpd/AdaptationSet.h"
#include "mpd/MPD.h" #include "mpd/MPD.h"
using namespace dash::mpd; using namespace dash::mpd;
Representation::Representation ( MPD *mpd_ ) : Representation::Representation ( AdaptationSet *set, MPD *mpd_ ) :
ICanonicalUrl ( mpd_ ), ICanonicalUrl ( set ),
mpd ( mpd_ ), mpd ( mpd_ ),
bandwidth (0), bandwidth (0),
qualityRanking ( -1 ), qualityRanking ( -1 ),
......
...@@ -46,7 +46,7 @@ namespace dash ...@@ -46,7 +46,7 @@ namespace dash
public ICanonicalUrl public ICanonicalUrl
{ {
public: public:
Representation( MPD *mpd ); Representation( AdaptationSet *, MPD *mpd );
virtual ~Representation (); virtual ~Representation ();
const std::string& getId () const; const std::string& getId () const;
......
...@@ -47,16 +47,24 @@ ISegment::ISegment(const ICanonicalUrl *parent): ...@@ -47,16 +47,24 @@ ISegment::ISegment(const ICanonicalUrl *parent):
classId = CLASSID_ISEGMENT; classId = CLASSID_ISEGMENT;
} }
dash::http::Chunk * ISegment::getChunk() dash::http::Chunk * ISegment::getChunk(const std::string &url)
{ {
return new SegmentChunk(this); return new (std::nothrow) SegmentChunk(this, url);
} }
dash::http::Chunk* ISegment::toChunk() dash::http::Chunk* ISegment::toChunk()
{ {
Chunk *chunk = getChunk(); Chunk *chunk;
try
{
chunk = getChunk(getUrlSegment());
if (!chunk) if (!chunk)
return NULL; return NULL;
}
catch (int)
{
return NULL;
}
if(startByte != endByte) if(startByte != endByte)
{ {
...@@ -64,8 +72,6 @@ dash::http::Chunk* ISegment::toChunk() ...@@ -64,8 +72,6 @@ dash::http::Chunk* ISegment::toChunk()
chunk->setEndByte(endByte); chunk->setEndByte(endByte);
} }
chunk->setUrl(getUrlSegment());
return chunk; return chunk;
} }
...@@ -121,8 +127,8 @@ int ISegment::getClassId() const ...@@ -121,8 +127,8 @@ int ISegment::getClassId() const
return classId; return classId;
} }
ISegment::SegmentChunk::SegmentChunk(ISegment *segment_) : ISegment::SegmentChunk::SegmentChunk(ISegment *segment_, const std::string &url) :
dash::http::Chunk() dash::http::Chunk(url)
{ {
segment = segment_; segment = segment_;
} }
...@@ -232,13 +238,13 @@ IndexSegment::IndexSegment(Representation *parent) : ...@@ -232,13 +238,13 @@ IndexSegment::IndexSegment(Representation *parent) :
classId = CLASSID_INDEXSEGMENT; classId = CLASSID_INDEXSEGMENT;
} }
dash::http::Chunk * IndexSegment::getChunk() dash::http::Chunk * IndexSegment::getChunk(const std::string &url)
{ {
return new IndexSegmentChunk(this); return new IndexSegmentChunk(this, url);
} }
IndexSegment::IndexSegmentChunk::IndexSegmentChunk(ISegment *segment) IndexSegment::IndexSegmentChunk::IndexSegmentChunk(ISegment *segment, const std::string &url)
: SegmentChunk(segment) : SegmentChunk(segment, url)
{ {
} }
......
...@@ -74,14 +74,14 @@ namespace dash ...@@ -74,14 +74,14 @@ namespace dash
class SegmentChunk : public dash::http::Chunk class SegmentChunk : public dash::http::Chunk
{ {
public: public:
SegmentChunk(ISegment *segment); SegmentChunk(ISegment *segment, const std::string &url);
virtual void onDownload(void *, size_t); virtual void onDownload(void *, size_t);
protected: protected:
ISegment *segment; ISegment *segment;
}; };
virtual dash::http::Chunk * getChunk(); virtual dash::http::Chunk * getChunk(const std::string &);
}; };
class Segment : public ISegment class Segment : public ISegment
...@@ -122,11 +122,11 @@ namespace dash ...@@ -122,11 +122,11 @@ namespace dash
class IndexSegmentChunk : public SegmentChunk class IndexSegmentChunk : public SegmentChunk
{ {
public: public:
IndexSegmentChunk(ISegment *segment); IndexSegmentChunk(ISegment *segment, const std::string &);
virtual void onDownload(void *, size_t); virtual void onDownload(void *, size_t);
}; };
virtual dash::http::Chunk * getChunk(); virtual dash::http::Chunk * getChunk(const std::string &);
}; };
class SubSegment : public ISegment class SubSegment : public ISegment
......
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