Commit 7081fb2b authored by François Cartegnie's avatar François Cartegnie 🤞

stream_filter: dash: build URL hierarchically

parent 14f9d9d4
......@@ -44,6 +44,7 @@ libdash_plugin_la_SOURCES = \
stream_filter/dash/mpd/ContentDescription.h \
stream_filter/dash/mpd/MPDManager.hpp \
stream_filter/dash/mpd/MPDManager.cpp \
stream_filter/dash/mpd/ICanonicalUrl.hpp \
stream_filter/dash/mpd/IMPDParser.cpp \
stream_filter/dash/mpd/IMPDParser.h \
stream_filter/dash/mpd/IsoffMainParser.cpp \
......
......@@ -54,7 +54,7 @@ Chunk* AlwaysBestAdaptationLogic::getNextChunk()
if ( this->count < this->schedule.size() )
{
Chunk *chunk = new Chunk();
chunk->setUrl(this->schedule.at( this->count )->getSourceUrl());
chunk->setUrl(this->schedule.at( this->count )->getUrlSegment());
this->count++;
return chunk;
}
......
......@@ -263,7 +263,7 @@ void BasicCMParser::setRepresentations (Node *root, AdaptationSet *group)
{
const std::map<std::string, std::string> attributes = representations.at(i)->getAttributes();
Representation *rep = new Representation;
Representation *rep = new Representation(getMPD());
rep->setParentGroup( group );
this->currentRepresentation = rep;
if ( this->parseCommonAttributesElements( representations.at( i ), rep, group ) == false )
......@@ -326,7 +326,7 @@ bool BasicCMParser::setSegmentInfo (Node *root, Representation *rep)
if ( segmentInfo )
{
SegmentInfo *info = new SegmentInfo;
SegmentInfo *info = new SegmentInfo(rep);
this->parseSegmentInfoCommon( segmentInfo, info );
//If we don't have any segment, there's no point keeping this SegmentInfo.
if ( this->setSegments( segmentInfo, info ) == false )
......@@ -427,8 +427,7 @@ bool BasicCMParser::setSegments (Node *root, SegmentInfo *info)
Segment* seg = parseSegment( segments.at( i ) );
if ( seg == NULL )
continue ;
if ( seg->getSourceUrl().empty() == false )
info->addSegment(seg);
info->addSegment(seg);
}
return true;
}
......
/*
* ICanonicalUrl.hpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN Authors
*
* 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 Lesser 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 CANONICALURL_HPP
#define CANONICALURL_HPP
#include <string>
namespace dash
{
namespace mpd
{
class ICanonicalUrl
{
public:
ICanonicalUrl( const ICanonicalUrl *parent = NULL ) { parentUrlMember = parent; }
virtual std::string getUrlSegment() const = 0;
protected:
std::string getParentUrlSegment() const {
return (parentUrlMember) ? parentUrlMember->getUrlSegment()
: std::string();
}
private:
const ICanonicalUrl *parentUrlMember;
};
}
}
#endif // CANONICALURL_HPP
......@@ -84,7 +84,7 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation
for(size_t i = 0; i < representations.size(); i++)
{
this->currentRepresentation = new Representation;
this->currentRepresentation = new Representation(getMPD());
Node *repNode = representations.at(i);
std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(repNode, "BaseURL");
......@@ -147,9 +147,6 @@ void IsoffMainParser::setInitSegment (dash::xml::Node *segBaseNode, Segme
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++)
seg->addBaseUrl(this->mpd->getBaseUrls().at(i));
base->addInitSegment(seg);
}
}
......@@ -169,9 +166,6 @@ void IsoffMainParser::setSegments (dash::xml::Node *segListNode, Segme
seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
}
for(size_t j = 0; j < this->mpd->getBaseUrls().size(); j++)
seg->addBaseUrl(this->mpd->getBaseUrls().at(j));
list->addSegment(seg);
}
}
......@@ -183,9 +177,7 @@ void IsoffMainParser::print ()
static_cast<std::string>(mpd->getProfile()).c_str(),
mpd->getDuration(),
mpd->getMinBufferTime());
std::vector<BaseUrl *>::const_iterator h;
for(h = mpd->getBaseUrls().begin(); h != mpd->getBaseUrls().end(); h++)
msg_Dbg(p_stream, "BaseUrl=%s", (*h)->getUrl().c_str());
msg_Dbg(p_stream, "BaseUrl=%s", mpd->getUrlSegment().c_str());
std::vector<Period *>::const_iterator i;
for(i = mpd->getPeriods().begin(); i != mpd->getPeriods().end(); i++)
......
......@@ -30,6 +30,7 @@
using namespace dash::mpd;
MPD::MPD () :
ICanonicalUrl(),
profile( dash::mpd::Profile::Unknown ),
live( false ),
availabilityStartTime( -1 ),
......@@ -58,12 +59,6 @@ const std::vector<Period*>& MPD::getPeriods () const
return this->periods;
}
const std::vector<BaseUrl*>& MPD::getBaseUrls () const
{
return this->baseUrls;
}
time_t MPD::getDuration() const
{
return this->duration;
......@@ -167,3 +162,11 @@ void MPD::setProfile(Profile profile)
{
this->profile = profile;
}
std::string MPD::getUrlSegment() const
{
if (!baseUrls.empty())
return baseUrls.front()->getUrl();
else
return std::string();
}
......@@ -31,6 +31,7 @@
#include "mpd/Period.h"
#include "mpd/BaseUrl.h"
#include "mpd/ICanonicalUrl.hpp"
#include "mpd/ProgramInformation.h"
#include "mpd/Profile.hpp"
......@@ -38,7 +39,7 @@ namespace dash
{
namespace mpd
{
class MPD
class MPD : public ICanonicalUrl
{
public:
MPD();
......@@ -60,7 +61,6 @@ namespace dash
void setMinBufferTime( time_t time );
time_t getTimeShiftBufferDepth() const;
void setTimeShiftBufferDepth( time_t depth );
const std::vector<BaseUrl *>& getBaseUrls() const;
const std::vector<Period *>& getPeriods() const;
const ProgramInformation* getProgramInformation() const;
......@@ -68,6 +68,8 @@ namespace dash
void addBaseUrl (BaseUrl *url);
void setProgramInformation (ProgramInformation *progInfo);
virtual std::string getUrlSegment() const; /* impl */
private:
Profile profile;
bool live;
......
......@@ -28,10 +28,12 @@
#include <cstdlib>
#include "Representation.h"
#include "mpd/MPD.h"
using namespace dash::mpd;
Representation::Representation () :
Representation::Representation ( MPD *mpd ) :
ICanonicalUrl ( mpd ),
bandwidth (0),
qualityRanking ( -1 ),
segmentInfo ( NULL ),
......@@ -42,7 +44,6 @@ Representation::Representation () :
baseUrl ( NULL ),
width (0),
height (0)
{
}
......@@ -165,11 +166,6 @@ void Representation::setSegmentBase (SegmentBase *base)
this->segmentBase = base;
}
BaseUrl* Representation::getBaseUrl() const
{
return baseUrl;
}
void Representation::setBaseUrl(BaseUrl *base)
{
baseUrl = base;
......@@ -210,3 +206,11 @@ std::vector<std::string> Representation::toString() const
}
return ret;
}
std::string Representation::getUrlSegment() const
{
std::string ret = getParentUrlSegment();
if (baseUrl)
ret.append(baseUrl->getUrl());
return ret;
}
......@@ -33,17 +33,20 @@
#include "mpd/SegmentBase.h"
#include "mpd/SegmentList.h"
#include "mpd/BaseUrl.h"
#include "mpd/ICanonicalUrl.hpp"
namespace dash
{
namespace mpd
{
class AdaptationSet;
class MPD;
class Representation : public CommonAttributesElements
class Representation : public CommonAttributesElements,
public ICanonicalUrl
{
public:
Representation();
Representation( MPD *mpd );
virtual ~Representation ();
const std::string& getId () const;
......@@ -80,10 +83,10 @@ namespace dash
int getWidth () const;
void setHeight (int height);
int getHeight () const;
BaseUrl* getBaseUrl () const;
void setBaseUrl (BaseUrl *baseUrl);
std::vector<std::string> toString() const;
virtual std::string getUrlSegment () const; /* impl */
private:
uint64_t bandwidth;
......
......@@ -34,6 +34,7 @@ using namespace dash::mpd;
using namespace dash::http;
Segment::Segment(const Representation *parent) :
ICanonicalUrl( parent ),
startByte (-1),
endByte (-1),
parentRepresentation( parent )
......@@ -45,11 +46,6 @@ Segment::Segment(const Representation *parent) :
this->size = -1;
}
std::string Segment::getSourceUrl () const
{
return this->sourceUrl;
}
void Segment::setSourceUrl ( const std::string &url )
{
if ( url.empty() == false )
......@@ -63,10 +59,6 @@ void Segment::done ()
{
//Only used for a SegmentTemplate.
}
void Segment::addBaseUrl (BaseUrl *url)
{
this->baseUrls.push_back(url);
}
void Segment::setByteRange (int start, int end)
{
......@@ -85,24 +77,7 @@ dash::http::Chunk* Segment::toChunk ()
chunk->setEndByte(this->endByte);
}
if(this->baseUrls.size() > 0)
{
std::stringstream ss;
ss << this->baseUrls.at(0)->getUrl() << this->sourceUrl;
chunk->setUrl(ss.str());
ss.clear();
for(size_t i = 1; i < this->baseUrls.size(); i++)
{
ss << this->baseUrls.at(i)->getUrl() << this->sourceUrl;
chunk->addOptionalUrl(ss.str());
ss.clear();
}
}
else
{
chunk->setUrl(this->sourceUrl);
}
chunk->setUrl( getUrlSegment() );
chunk->setBitrate(this->parentRepresentation->getBandwidth());
......@@ -113,3 +88,11 @@ const Representation *Segment::getParentRepresentation() const
{
return this->parentRepresentation;
}
std::string Segment::getUrlSegment() const
{
std::string ret = getParentUrlSegment();
if (!sourceUrl.empty())
ret.append(sourceUrl);
return ret;
}
......@@ -29,6 +29,7 @@
#include <sstream>
#include <vector>
#include "mpd/BaseUrl.h"
#include "mpd/ICanonicalUrl.hpp"
#include "http/Chunk.h"
namespace dash
......@@ -36,12 +37,11 @@ namespace dash
namespace mpd
{
class Representation;
class Segment
class Segment : public ICanonicalUrl
{
public:
Segment( const Representation *parent );
virtual ~Segment(){}
virtual std::string getSourceUrl() const;
virtual void setSourceUrl( const std::string &url );
/**
* @return true if the segment should be dropped after being read.
......@@ -50,14 +50,13 @@ namespace dash
*/
virtual bool isSingleShot () const;
virtual void done ();
virtual void addBaseUrl (BaseUrl *url);
virtual void setByteRange (int start, int end);
virtual dash::http::Chunk* toChunk ();
const Representation* getParentRepresentation() const;
virtual std::string getUrlSegment () const; /* impl */
protected:
std::string sourceUrl;
std::vector<BaseUrl *> baseUrls;
int startByte;
int endByte;
const Representation* parentRepresentation;
......
......@@ -29,7 +29,8 @@
using namespace dash::mpd;
SegmentInfo::SegmentInfo() :
SegmentInfo::SegmentInfo( ICanonicalUrl *parent ) :
SegmentInfoCommon( parent ),
initSeg( NULL )
{
}
......
......@@ -31,6 +31,7 @@
#include "mpd/Segment.h"
#include "mpd/SegmentInfoCommon.h"
#include "ICanonicalUrl.hpp"
namespace dash
{
......@@ -39,7 +40,7 @@ namespace dash
class SegmentInfo : public SegmentInfoCommon
{
public:
SegmentInfo ();
SegmentInfo ( ICanonicalUrl * = NULL );
virtual ~SegmentInfo ();
const std::vector<Segment *>& getSegments() const;
......
......@@ -33,7 +33,8 @@
using namespace dash::mpd;
SegmentInfoCommon::SegmentInfoCommon() :
SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ),
duration( -1 ),
initialisationSegment( NULL ),
segmentTimeline( NULL )
......@@ -79,11 +80,6 @@ void SegmentInfoCommon::setInitialisationSegment(Segment *seg)
this->initialisationSegment = seg;
}
const std::list<std::string>& SegmentInfoCommon::getBaseURL() const
{
return this->baseURLs;
}
void SegmentInfoCommon::appendBaseURL(const std::string &url)
{
this->baseURLs.push_back( url );
......@@ -99,3 +95,11 @@ void SegmentInfoCommon::setSegmentTimeline( const SegmentTimeline *segTl )
if ( segTl != NULL )
this->segmentTimeline = segTl;
}
std::string SegmentInfoCommon::getUrlSegment() const
{
std::string ret = getParentUrlSegment();
if (!baseURLs.empty())
ret.append(baseURLs.front());
return ret;
}
......@@ -28,6 +28,7 @@
#include <string>
#include <list>
#include <ctime>
#include "ICanonicalUrl.hpp"
namespace dash
{
......@@ -36,10 +37,10 @@ namespace dash
class Segment;
class SegmentTimeline;
class SegmentInfoCommon
class SegmentInfoCommon : public ICanonicalUrl
{
public:
SegmentInfoCommon();
SegmentInfoCommon( ICanonicalUrl *parent = NULL );
virtual ~SegmentInfoCommon();
time_t getDuration() const;
void setDuration( time_t duration );
......@@ -47,10 +48,10 @@ namespace dash
void setStartIndex( int startIndex );
Segment* getInitialisationSegment() const;
void setInitialisationSegment( Segment* seg );
const std::list<std::string>& getBaseURL() const;
void appendBaseURL( const std::string& url );
const SegmentTimeline* getSegmentTimeline() const;
void setSegmentTimeline( const SegmentTimeline *segTl );
virtual std::string getUrlSegment() const; /* impl */
private:
time_t duration;
......
......@@ -30,7 +30,8 @@
using namespace dash::mpd;
SegmentList::SegmentList ()
SegmentList::SegmentList ( ICanonicalUrl *parent ):
SegmentInfo( parent )
{
}
......
......@@ -26,6 +26,7 @@
#define SEGMENTLIST_H_
#include "mpd/SegmentInfo.h"
#include "mpd/ICanonicalUrl.hpp"
namespace dash
{
......@@ -34,7 +35,7 @@ namespace dash
class SegmentList : public SegmentInfo
{
public:
SegmentList ();
SegmentList ( ICanonicalUrl * = NULL );
virtual ~SegmentList ();
};
}
......
......@@ -30,60 +30,45 @@
#include "AdaptationSet.h"
#include "SegmentInfoDefault.h"
#include <cassert>
#include <cstring>
#include <iostream>
#include <sstream>
using namespace dash::mpd;
SegmentTemplate::SegmentTemplate( bool containRuntimeIdentifier,
Representation* representation ) :
Segment( representation ),
containRuntimeIdentifier( containRuntimeIdentifier ),
beginTime( std::string::npos ),
beginIndex( std::string::npos ),
currentSegmentIndex( 0 )
{
}
std::string SegmentTemplate::getSourceUrl() const
std::string SegmentTemplate::getUrlSegment() const
{
std::string res = this->sourceUrl;
std::string res = Segment::getUrlSegment();
if ( !containRuntimeIdentifier )
return res;
if ( this->containRuntimeIdentifier == false )
return Segment::getSourceUrl();
size_t beginTime = res.find( "$Time$" );
// size_t beginIndex = res.find( "$Index$" );
// if ( this->beginIndex != std::string::npos )
// std::cerr << "Unhandled identifier \"$Index$\"" << std::endl;
if ( this->beginTime != std::string::npos )
if ( beginTime != std::string::npos )
{
//FIXME: This should use the current representation SegmentInfo
//which "inherits" the SegmentInfoDefault values.
if ( this->parentRepresentation->getParentGroup()->getSegmentInfoDefault() != NULL &&
this->parentRepresentation->getParentGroup()->getSegmentInfoDefault()->getSegmentTimeline() != NULL )
if ( parentRepresentation->getParentGroup()->getSegmentInfoDefault() != NULL &&
parentRepresentation->getParentGroup()->getSegmentInfoDefault()->getSegmentTimeline() != NULL )
{
const SegmentTimeline::Element *el = this->parentRepresentation->getParentGroup()->
getSegmentInfoDefault()->getSegmentTimeline()->getElement( this->currentSegmentIndex );
const SegmentTimeline::Element *el = parentRepresentation->getParentGroup()->
getSegmentInfoDefault()->getSegmentTimeline()->getElement( currentSegmentIndex );
if ( el != NULL )
{
std::ostringstream oss;
oss << el->t;
res.replace( this->beginTime, strlen("$Time$"), oss.str() );
res.replace( beginTime, strlen("$Time$"), oss.str() );
}
}
}
return res;
}
void SegmentTemplate::setSourceUrl( const std::string &url )
{
if ( this->containRuntimeIdentifier == true )
{
this->beginTime = url.find( "$Time$" );
this->beginIndex = url.find( "$Index$" );
}
Segment::setSourceUrl( url );
return res;
}
bool SegmentTemplate::isSingleShot() const
......
......@@ -36,14 +36,11 @@ namespace dash
{
public:
SegmentTemplate( bool containRuntimeIdentifier, Representation *rep );
virtual std::string getSourceUrl() const;
virtual void setSourceUrl( const std::string & url );
virtual std::string getUrlSegment() const; /* reimpl */
virtual bool isSingleShot() const;
virtual void done();
private:
bool containRuntimeIdentifier;
size_t beginTime;
size_t beginIndex;
int currentSegmentIndex;
};
}
......
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