Commit 0785e30c authored by François Cartegnie's avatar François Cartegnie 🤞

demux: dash: split templates

parent feb92cce
...@@ -110,13 +110,13 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat ...@@ -110,13 +110,13 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
return total; return total;
std::string mediaurl = templateNode->getAttributeValue("media"); std::string mediaurl = templateNode->getAttributeValue("media");
SegmentTemplate *mediaTemplate = NULL; MediaSegmentTemplate *mediaTemplate = NULL;
if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) SegmentTemplate(info)) ) if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
return total; return total;
mediaTemplate->setSourceUrl(mediaurl); mediaTemplate->setSourceUrl(mediaurl);
if(templateNode->hasAttribute("startNumber")) if(templateNode->hasAttribute("startNumber"))
mediaTemplate->setStartIndex(Integer<uint64_t>(templateNode->getAttributeValue("startNumber"))); mediaTemplate->startIndex.Set(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
if(templateNode->hasAttribute("duration")) if(templateNode->hasAttribute("duration"))
mediaTemplate->duration.Set(Integer<mtime_t>(templateNode->getAttributeValue("duration"))); mediaTemplate->duration.Set(Integer<mtime_t>(templateNode->getAttributeValue("duration")));
...@@ -133,8 +133,8 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat ...@@ -133,8 +133,8 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
initTemplate->setSourceUrl(initurl); initTemplate->setSourceUrl(initurl);
} }
info->setSegmentTemplate(mediaTemplate, SegmentInformation::INFOTYPE_MEDIA); mediaTemplate->initialisationSegment.Set(initTemplate);
info->setSegmentTemplate(initTemplate, SegmentInformation::INFOTYPE_INIT); info->setSegmentTemplate(mediaTemplate);
total += ( mediaTemplate != NULL ); total += ( mediaTemplate != NULL );
...@@ -322,7 +322,7 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation ...@@ -322,7 +322,7 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation
return total; return total;
} }
void IsoffMainParser::parseInitSegment(Node *initNode, Initializable *init) void IsoffMainParser::parseInitSegment(Node *initNode, Initializable<Segment> *init)
{ {
if(!initNode) if(!initNode)
return; return;
......
...@@ -53,7 +53,7 @@ namespace dash ...@@ -53,7 +53,7 @@ namespace dash
void setMPDAttributes (); void setMPDAttributes ();
void setAdaptationSets (dash::xml::Node *periodNode, Period *period); void setAdaptationSets (dash::xml::Node *periodNode, Period *period);
void setRepresentations (dash::xml::Node *adaptationSetNode, AdaptationSet *adaptationSet); void setRepresentations (dash::xml::Node *adaptationSetNode, AdaptationSet *adaptationSet);
void parseInitSegment (dash::xml::Node *, Initializable *); void parseInitSegment (dash::xml::Node *, Initializable<Segment> *);
void parsePeriods (dash::xml::Node *); void parsePeriods (dash::xml::Node *);
size_t parseSegmentInformation(dash::xml::Node *, SegmentInformation *); size_t parseSegmentInformation(dash::xml::Node *, SegmentInformation *);
void parseSegmentBase (dash::xml::Node *, SegmentInformation *); void parseSegmentBase (dash::xml::Node *, SegmentInformation *);
......
...@@ -32,7 +32,7 @@ namespace dash ...@@ -32,7 +32,7 @@ namespace dash
{ {
namespace mpd namespace mpd
{ {
class SegmentBase : public Initializable class SegmentBase : public Initializable<Segment>
{ {
public: public:
SegmentBase (); SegmentBase ();
......
...@@ -33,16 +33,6 @@ ...@@ -33,16 +33,6 @@
using namespace dash::mpd; using namespace dash::mpd;
Initializable::Initializable()
{
initialisationSegment.Set(NULL);
}
Initializable::~Initializable()
{
delete initialisationSegment.Get();
}
SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) : SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ), Initializable(), ICanonicalUrl( parent ), Initializable(),
duration( -1 ), duration( -1 ),
......
...@@ -38,16 +38,22 @@ namespace dash ...@@ -38,16 +38,22 @@ namespace dash
class Segment; class Segment;
class SegmentTimeline; class SegmentTimeline;
class Initializable template<class T> class Initializable
{ {
public: public:
Initializable(); Initializable()
~Initializable(); {
Property<Segment *> initialisationSegment; initialisationSegment.Set(NULL);
}
~Initializable()
{
delete initialisationSegment.Get();
}
Property<T *> initialisationSegment;
}; };
class SegmentInfoCommon : public ICanonicalUrl, class SegmentInfoCommon : public ICanonicalUrl,
public Initializable public Initializable<Segment>
{ {
public: public:
SegmentInfoCommon( ICanonicalUrl *parent = NULL ); SegmentInfoCommon( ICanonicalUrl *parent = NULL );
......
...@@ -33,8 +33,7 @@ SegmentInformation::SegmentInformation(SegmentInformation *parent_) : ...@@ -33,8 +33,7 @@ SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
parent = parent_; parent = parent_;
segmentBase = NULL; segmentBase = NULL;
segmentList = NULL; segmentList = NULL;
for(int i=0; i<InfoTypeCount; i++) mediaSegmentTemplate = NULL;
segmentTemplate[i] = NULL;
bitswitch_policy = BITSWITCH_INHERIT; bitswitch_policy = BITSWITCH_INHERIT;
timescale.Set(0); timescale.Set(0);
} }
...@@ -45,8 +44,7 @@ SegmentInformation::SegmentInformation(ICanonicalUrl * parent_) : ...@@ -45,8 +44,7 @@ SegmentInformation::SegmentInformation(ICanonicalUrl * parent_) :
parent = NULL; parent = NULL;
segmentBase = NULL; segmentBase = NULL;
segmentList = NULL; segmentList = NULL;
for(int i=0; i<InfoTypeCount; i++) mediaSegmentTemplate = NULL;
segmentTemplate[i] = NULL;
bitswitch_policy = BITSWITCH_INHERIT; bitswitch_policy = BITSWITCH_INHERIT;
timescale.Set(0); timescale.Set(0);
} }
...@@ -55,8 +53,7 @@ SegmentInformation::~SegmentInformation() ...@@ -55,8 +53,7 @@ SegmentInformation::~SegmentInformation()
{ {
delete segmentBase; delete segmentBase;
delete segmentList; delete segmentList;
for(int i=0; i<InfoTypeCount; i++) delete mediaSegmentTemplate;
delete segmentTemplate[i];
} }
vector<ISegment *> SegmentInformation::getSegments(SegmentInfoType type) const vector<ISegment *> SegmentInformation::getSegments(SegmentInfoType type) const
...@@ -77,9 +74,9 @@ vector<ISegment *> SegmentInformation::getSegments(SegmentInfoType type) const ...@@ -77,9 +74,9 @@ vector<ISegment *> SegmentInformation::getSegments(SegmentInfoType type) const
case INFOTYPE_MEDIA: case INFOTYPE_MEDIA:
{ {
SegmentList *segList = inheritSegmentList(); SegmentList *segList = inheritSegmentList();
if( inheritSegmentTemplate(INFOTYPE_MEDIA) ) if( inheritSegmentTemplate() )
{ {
retSegments.push_back( inheritSegmentTemplate(INFOTYPE_MEDIA) ); retSegments.push_back( inheritSegmentTemplate() );
} }
else if ( segList && !segList->getSegments().empty() ) else if ( segList && !segList->getSegments().empty() )
{ {
...@@ -129,16 +126,16 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co ...@@ -129,16 +126,16 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co
{ {
segment = segList->initialisationSegment.Get(); segment = segList->initialisationSegment.Get();
} }
else if( inheritSegmentTemplate(INFOTYPE_INIT) ) else if( inheritSegmentTemplate() )
{ {
segment = inheritSegmentTemplate(INFOTYPE_INIT); segment = inheritSegmentTemplate()->initialisationSegment.Get();
} }
break; break;
case INFOTYPE_MEDIA: case INFOTYPE_MEDIA:
if( inheritSegmentTemplate(INFOTYPE_MEDIA) ) if( inheritSegmentTemplate() )
{ {
segment = inheritSegmentTemplate(INFOTYPE_MEDIA); segment = inheritSegmentTemplate();
} }
else if ( segList && !segList->getSegments().empty() ) else if ( segList && !segList->getSegments().empty() )
{ {
...@@ -160,7 +157,7 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co ...@@ -160,7 +157,7 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co
bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const
{ {
SegmentList *segList; SegmentList *segList;
SegmentTemplate *segTemplate; MediaSegmentTemplate *mediaTemplate;
uint64_t timescale; uint64_t timescale;
mtime_t duration = 0; mtime_t duration = 0;
if ( (segList = inheritSegmentList()) ) if ( (segList = inheritSegmentList()) )
...@@ -168,10 +165,10 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con ...@@ -168,10 +165,10 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
timescale = segList->timescale.Get(); timescale = segList->timescale.Get();
duration = segList->getDuration(); duration = segList->getDuration();
} }
else if( (segTemplate = inheritSegmentTemplate(INFOTYPE_MEDIA)) ) else if( (mediaTemplate = inheritSegmentTemplate()) )
{ {
timescale = segTemplate->timescale.Get(); timescale = mediaTemplate->timescale.Get();
duration = segTemplate->duration.Get(); duration = mediaTemplate->duration.Get();
} }
if(duration) if(duration)
...@@ -221,9 +218,9 @@ void SegmentInformation::setSegmentBase(SegmentBase *base) ...@@ -221,9 +218,9 @@ void SegmentInformation::setSegmentBase(SegmentBase *base)
segmentBase = base; segmentBase = base;
} }
void SegmentInformation::setSegmentTemplate(SegmentTemplate *templ, SegmentInfoType type) void SegmentInformation::setSegmentTemplate(MediaSegmentTemplate *templ)
{ {
segmentTemplate[type] = templ; mediaSegmentTemplate = templ;
} }
static void insertIntoSegment(std::vector<Segment *> &seglist, size_t start, static void insertIntoSegment(std::vector<Segment *> &seglist, size_t start,
...@@ -298,12 +295,12 @@ SegmentList * SegmentInformation::inheritSegmentList() const ...@@ -298,12 +295,12 @@ SegmentList * SegmentInformation::inheritSegmentList() const
return NULL; return NULL;
} }
SegmentTemplate * SegmentInformation::inheritSegmentTemplate(SegmentInfoType type) const MediaSegmentTemplate * SegmentInformation::inheritSegmentTemplate() const
{ {
if(segmentTemplate[type]) if(mediaSegmentTemplate)
return segmentTemplate[type]; return mediaSegmentTemplate;
else if (parent) else if (parent)
return parent->inheritSegmentTemplate(type); return parent->inheritSegmentTemplate();
else else
return NULL; return NULL;
} }
...@@ -80,17 +80,17 @@ namespace dash ...@@ -80,17 +80,17 @@ namespace dash
private: private:
void setSegmentList(SegmentList *); void setSegmentList(SegmentList *);
void setSegmentBase(SegmentBase *); void setSegmentBase(SegmentBase *);
void setSegmentTemplate(SegmentTemplate *, SegmentInfoType); void setSegmentTemplate(MediaSegmentTemplate *);
void setBitstreamSwitching(bool); void setBitstreamSwitching(bool);
SegmentBase * inheritSegmentBase() const; SegmentBase * inheritSegmentBase() const;
SegmentList * inheritSegmentList() const; SegmentList * inheritSegmentList() const;
SegmentTemplate * inheritSegmentTemplate(SegmentInfoType) const; MediaSegmentTemplate * inheritSegmentTemplate() const;
SegmentInformation *parent; SegmentInformation *parent;
SegmentBase *segmentBase; SegmentBase *segmentBase;
SegmentList *segmentList; SegmentList *segmentList;
SegmentTemplate *segmentTemplate[InfoTypeCount]; MediaSegmentTemplate *mediaSegmentTemplate;
enum BitswitchPolicy enum BitswitchPolicy
{ {
......
...@@ -31,38 +31,36 @@ ...@@ -31,38 +31,36 @@
using namespace dash::mpd; using namespace dash::mpd;
SegmentTemplate::SegmentTemplate( ICanonicalUrl *parent ) : BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) :
Segment( parent ), Segment( parent )
startIndex( 0 )
{ {
debugName = "SegmentTemplate";
classId = Segment::CLASSID_SEGMENT;
duration.Set(0);
timescale.Set(0);
} }
Url SegmentTemplate::getUrlSegment() const Url BaseSegmentTemplate::getUrlSegment() const
{ {
Url ret = getParentUrlSegment(); Url ret = getParentUrlSegment();
if (!sourceUrl.empty()) if (!sourceUrl.empty())
{ {
ret.append(Url::Component(sourceUrl, this)); ret.append(Url::Component(
sourceUrl,
dynamic_cast<const MediaSegmentTemplate *>(this)) /* casts to NULL if != */
);
} }
return ret; return ret;
} }
size_t SegmentTemplate::getStartIndex() const MediaSegmentTemplate::MediaSegmentTemplate( ICanonicalUrl *parent ) :
BaseSegmentTemplate( parent )
{ {
return startIndex; debugName = "SegmentTemplate";
} classId = Segment::CLASSID_SEGMENT;
timescale.Set( 0 );
void SegmentTemplate::setStartIndex(size_t i) startIndex.Set( 0 );
{ initialisationSegment.Set( NULL );
startIndex = i;
} }
InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent ) : InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent ) :
SegmentTemplate(parent) BaseSegmentTemplate(parent)
{ {
debugName = "InitSegmentTemplate"; debugName = "InitSegmentTemplate";
classId = InitSegment::CLASSID_INITSEGMENT; classId = InitSegment::CLASSID_INITSEGMENT;
......
...@@ -26,28 +26,32 @@ ...@@ -26,28 +26,32 @@
#include "mpd/Segment.h" #include "mpd/Segment.h"
#include "Properties.hpp" #include "Properties.hpp"
#include "SegmentInfoCommon.h"
namespace dash namespace dash
{ {
namespace mpd namespace mpd
{ {
class ICanonicalUrl; class ICanonicalUrl;
class InitSegmentTemplate;
class SegmentTemplate : public Segment class BaseSegmentTemplate : public Segment
{ {
public: public:
SegmentTemplate( ICanonicalUrl * = NULL ); BaseSegmentTemplate( ICanonicalUrl * = NULL );
virtual Url getUrlSegment() const; /* reimpl */ virtual Url getUrlSegment() const; /* reimpl */
size_t getStartIndex() const; };
void setStartIndex(size_t);
Property<mtime_t> duration;
Property<uint64_t> timescale;
private: class MediaSegmentTemplate : public BaseSegmentTemplate,
size_t startIndex; public Initializable<InitSegmentTemplate>
{
public:
MediaSegmentTemplate( ICanonicalUrl * = NULL );
Property<size_t> startIndex;
Property<uint64_t> timescale;
}; };
class InitSegmentTemplate : public SegmentTemplate class InitSegmentTemplate : public BaseSegmentTemplate
{ {
public: public:
InitSegmentTemplate( ICanonicalUrl * = NULL ); InitSegmentTemplate( ICanonicalUrl * = NULL );
......
...@@ -79,7 +79,7 @@ std::string Url::toString(size_t index, const Representation *rep) const ...@@ -79,7 +79,7 @@ std::string Url::toString(size_t index, const Representation *rep) const
return ret; return ret;
} }
Url::Component::Component(const std::string & str, const SegmentTemplate *templ_) Url::Component::Component(const std::string & str, const MediaSegmentTemplate *templ_)
{ {
component = str; component = str;
templ = templ_; templ = templ_;
...@@ -87,7 +87,7 @@ Url::Component::Component(const std::string & str, const SegmentTemplate *templ_ ...@@ -87,7 +87,7 @@ Url::Component::Component(const std::string & str, const SegmentTemplate *templ_
size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const
{ {
index += templ->getStartIndex(); index += templ->startIndex.Get();
/* live streams / templated */ /* live streams / templated */
if(rep->getMPD()->isLive() && templ->duration.Get()) if(rep->getMPD()->isLive() && templ->duration.Get())
{ {
...@@ -107,48 +107,52 @@ size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) ...@@ -107,48 +107,52 @@ size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep)
std::string Url::Component::contextualize(size_t index, const Representation *rep) const std::string Url::Component::contextualize(size_t index, const Representation *rep) const
{ {
std::string ret(component); std::string ret(component);
size_t pos;
if(!rep || !templ) if(!rep)
return ret; return ret;
size_t pos = ret.find("$Time$"); if(templ)
if(pos != std::string::npos)
{ {
std::stringstream ss; pos = ret.find("$Time$");
ss << (templ->duration.Get() * index); if(pos != std::string::npos)
ret.replace(pos, std::string("$Time$").length(), ss.str()); {
} std::stringstream ss;
ss << (templ->duration.Get() * index);
ret.replace(pos, std::string("$Time$").length(), ss.str());
}
pos = ret.find("$Number$"); pos = ret.find("$Number$");
if(pos != std::string::npos) if(pos != std::string::npos)
{ {
std::stringstream ss; std::stringstream ss;
ss << getSegmentNumber(index, rep); ss << getSegmentNumber(index, rep);
ret.replace(pos, std::string("$Number$").length(), ss.str()); ret.replace(pos, std::string("$Number$").length(), ss.str());
} }
else else
{
pos = ret.find("$Number%");
size_t tokenlength = std::string("$Number%").length();
size_t fmtstart = pos + tokenlength;
if(pos != std::string::npos && fmtstart < ret.length())
{ {
size_t fmtend = ret.find('$', fmtstart); pos = ret.find("$Number%");
if(fmtend != std::string::npos) size_t tokenlength = std::string("$Number%").length();
size_t fmtstart = pos + tokenlength;
if(pos != std::string::npos && fmtstart < ret.length())
{ {
std::istringstream iss(ret.substr(fmtstart, fmtend - fmtstart + 1)); size_t fmtend = ret.find('$', fmtstart);
try if(fmtend != std::string::npos)
{ {
size_t width; std::istringstream iss(ret.substr(fmtstart, fmtend - fmtstart + 1));
iss >> width; try
if (iss.peek() != '$') {
throw VLC_EGENERIC; size_t width;
std::stringstream oss; iss >> width;
oss.width(width); /* set format string length */ if (iss.peek() != '$')
oss.fill('0'); throw VLC_EGENERIC;
oss << getSegmentNumber(index, rep); std::stringstream oss;
ret.replace(pos, fmtend - pos + 1, oss.str()); oss.width(width); /* set format string length */
} catch(int) {} oss.fill('0');
oss << getSegmentNumber(index, rep);
ret.replace(pos, fmtend - pos + 1, oss.str());
} catch(int) {}
}
} }
} }
} }
......
...@@ -28,7 +28,7 @@ namespace dash ...@@ -28,7 +28,7 @@ namespace dash
namespace mpd namespace mpd
{ {
class Representation; class Representation;
class SegmentTemplate; class MediaSegmentTemplate;
class Url class Url
{ {
...@@ -37,13 +37,13 @@ namespace dash ...@@ -37,13 +37,13 @@ namespace dash
{ {
friend class Url; friend class Url;
public: public:
Component(const std::string &, const SegmentTemplate * = NULL); Component(const std::string &, const MediaSegmentTemplate * = NULL);
protected: protected:
std::string contextualize(size_t, const Representation *) const; std::string contextualize(size_t, const Representation *) const;
size_t getSegmentNumber(size_t, const Representation *) const; size_t getSegmentNumber(size_t, const Representation *) const;
std::string component; std::string component;
const SegmentTemplate *templ; const MediaSegmentTemplate *templ;
}; };
Url(); Url();
......
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