[vlc-commits] demux: adaptive: rework attributes inheritance to match siblings first
Francois Cartegnie
git at videolan.org
Fri Nov 27 11:23:28 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Oct 27 11:24:56 2020 +0100| [573752cfad0e024806e29ccef23986aaff0166db] | committer: Francois Cartegnie
demux: adaptive: rework attributes inheritance to match siblings first
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=573752cfad0e024806e29ccef23986aaff0166db
---
modules/demux/adaptive/logic/BufferingLogic.cpp | 7 +-
.../demux/adaptive/playlist/AbstractPlaylist.cpp | 23 +--
.../demux/adaptive/playlist/AbstractPlaylist.hpp | 12 +-
.../demux/adaptive/playlist/BaseRepresentation.cpp | 3 +-
modules/demux/adaptive/playlist/Inheritables.cpp | 228 ++++++++++++++++++++-
modules/demux/adaptive/playlist/Inheritables.hpp | 104 +++++++++-
modules/demux/adaptive/playlist/SegmentBase.cpp | 3 +-
.../demux/adaptive/playlist/SegmentBaseType.cpp | 105 +---------
.../demux/adaptive/playlist/SegmentBaseType.hpp | 21 +-
.../demux/adaptive/playlist/SegmentInformation.cpp | 138 ++++---------
.../demux/adaptive/playlist/SegmentInformation.hpp | 18 +-
modules/demux/adaptive/playlist/SegmentList.cpp | 17 +-
modules/demux/adaptive/playlist/SegmentList.h | 1 +
.../demux/adaptive/playlist/SegmentTemplate.cpp | 28 +--
.../demux/adaptive/playlist/SegmentTimeline.cpp | 37 +---
modules/demux/adaptive/playlist/SegmentTimeline.h | 4 +-
modules/demux/dash/mp4/IndexReader.cpp | 2 +-
modules/demux/dash/mpd/IsoffMainParser.cpp | 30 +--
modules/demux/dash/mpd/Representation.cpp | 4 +-
modules/demux/hls/playlist/Parser.cpp | 7 +-
modules/demux/hls/playlist/Representation.cpp | 4 +-
modules/demux/smooth/mp4/IndexReader.cpp | 2 +-
modules/demux/smooth/playlist/Manifest.cpp | 4 +-
modules/demux/smooth/playlist/Manifest.hpp | 5 +-
modules/demux/smooth/playlist/Parser.cpp | 33 +--
25 files changed, 471 insertions(+), 369 deletions(-)
diff --git a/modules/demux/adaptive/logic/BufferingLogic.cpp b/modules/demux/adaptive/logic/BufferingLogic.cpp
index a3db24368a..0fd79232cc 100644
--- a/modules/demux/adaptive/logic/BufferingLogic.cpp
+++ b/modules/demux/adaptive/logic/BufferingLogic.cpp
@@ -214,7 +214,8 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re
{
/* Else compute, current time and timeshiftdepth based */
uint64_t start = 0;
- if(mediaSegmentTemplate->duration.Get())
+ stime_t scaledduration = mediaSegmentTemplate->inheritDuration();
+ if(scaledduration)
{
/* Compute playback offset and effective finished segment from wall time */
vlc_tick_t now = vlc_tick_from_sec(time(NULL));
@@ -224,7 +225,7 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re
const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
if(!timescale)
return startnumber;
- const vlc_tick_t duration = timescale.ToTime(mediaSegmentTemplate->inheritDuration());
+ const vlc_tick_t duration = timescale.ToTime(scaledduration);
if(!duration)
return startnumber;
@@ -336,6 +337,8 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re
return segmentBase->getSequenceNumber();
const Timescale timescale = rep->inheritTimescale();
+ if(!timeline->isValid())
+ return std::numeric_limits<uint64_t>::max();
const Segment *back = list.back();
const stime_t bufferingstart = back->startTime.Get() + back->duration.Get() -
timescale.ToScaled(i_buffering);
diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
index cf1f930140..a1255431c7 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.cpp
@@ -34,7 +34,7 @@
using namespace adaptive::playlist;
AbstractPlaylist::AbstractPlaylist (vlc_object_t *p_object_) :
- ICanonicalUrl(),
+ ICanonicalUrl(), AttrsNode(Type::PLAYLIST),
p_object(p_object_)
{
playbackStart.Set(0);
@@ -71,28 +71,9 @@ void AbstractPlaylist::setPlaylistUrl(const std::string &url)
playlistUrl = url;
}
-void AbstractPlaylist::setAvailabilityTimeOffset(vlc_tick_t t)
-{
- availabilityTimeOffset = t;
-}
-
-void AbstractPlaylist::setAvailabilityTimeComplete(bool b)
-{
- availabilityTimeComplete = b;
-}
-
-vlc_tick_t AbstractPlaylist::getAvailabilityTimeOffset() const
-{
- return availabilityTimeOffset.isSet() ? availabilityTimeOffset.value() : 0;
-}
-
-bool AbstractPlaylist::getAvailabilityTimeComplete() const
-{
- return !availabilityTimeComplete.isSet() || availabilityTimeComplete.value();
-}
-
void AbstractPlaylist::addPeriod(BasePeriod *period)
{
+ period->setParentNode(this);
periods.push_back(period);
}
diff --git a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
index 3d0e3cf66d..f8c665941d 100644
--- a/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
+++ b/modules/demux/adaptive/playlist/AbstractPlaylist.hpp
@@ -25,6 +25,7 @@
#include <string>
#include "ICanonicalUrl.hpp"
+#include "Inheritables.hpp"
#include "../tools/Properties.hpp"
namespace adaptive
@@ -34,7 +35,8 @@ namespace adaptive
{
class BasePeriod;
- class AbstractPlaylist : public ICanonicalUrl
+ class AbstractPlaylist : public ICanonicalUrl,
+ public AttrsNode
{
public:
AbstractPlaylist(vlc_object_t *);
@@ -52,10 +54,6 @@ namespace adaptive
void addPeriod (BasePeriod *period);
void addBaseUrl (const std::string &);
void setPlaylistUrl (const std::string &);
- void setAvailabilityTimeOffset(vlc_tick_t);
- void setAvailabilityTimeComplete(bool);
- vlc_tick_t getAvailabilityTimeOffset() const;
- bool getAvailabilityTimeComplete() const;
virtual Url getUrlSegment() const; /* impl */
vlc_object_t * getVLCObject() const;
@@ -85,10 +83,6 @@ namespace adaptive
vlc_tick_t minBufferTime;
vlc_tick_t maxBufferTime;
bool b_needsUpdates;
-
- private:
- Undef<bool> availabilityTimeComplete;
- Undef<vlc_tick_t> availabilityTimeOffset;
};
}
}
diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.cpp b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
index e0529705e8..787be04cdd 100644
--- a/modules/demux/adaptive/playlist/BaseRepresentation.cpp
+++ b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
@@ -215,7 +215,7 @@ bool BaseRepresentation::getMediaPlaybackRange(vlc_tick_t *rangeBegin,
return true;
}
/* Else compute, current time and timeshiftdepth based */
- else if( mediaSegmentTemplate->duration.Get() )
+ else if( mediaSegmentTemplate->inheritDuration() )
{
*rangeEnd = 0;
*rangeBegin = -1 * getPlaylist()->timeShiftBufferDepth.Get();
@@ -229,7 +229,6 @@ bool BaseRepresentation::getMediaPlaybackRange(vlc_tick_t *rangeBegin,
{
const Timescale timescale = segmentList->inheritTimescale();
const std::vector<Segment *> &list = segmentList->getSegments();
-
const ISegment *back = list.back();
const stime_t startTime = list.front()->startTime.Get();
const stime_t endTime = back->startTime.Get() + back->duration.Get();
diff --git a/modules/demux/adaptive/playlist/Inheritables.cpp b/modules/demux/adaptive/playlist/Inheritables.cpp
index 4e938cbfe5..dfdf56c4c1 100644
--- a/modules/demux/adaptive/playlist/Inheritables.cpp
+++ b/modules/demux/adaptive/playlist/Inheritables.cpp
@@ -1,7 +1,7 @@
/*****************************************************************************
* Inheritables.cpp
*****************************************************************************
- * Copyright (C) 1998-2015 VLC authors and VideoLAN
+ * Copyright (C) 2016-2020 VideoLabs, VLC authors and VideoLAN
*
* 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
@@ -23,10 +23,236 @@
#endif
#include "Inheritables.hpp"
+#include "SegmentBase.h"
+#include "SegmentList.h"
+#include "SegmentTemplate.h"
+#include "SegmentTimeline.h"
+
+#include <algorithm>
using namespace adaptive::playlist;
using namespace adaptive;
+AbstractAttr::AbstractAttr(Type t)
+{
+ type = t;
+ parentNode = NULL;
+}
+
+AbstractAttr::~AbstractAttr()
+{
+
+}
+
+AbstractAttr::Type AbstractAttr::getType() const
+{
+ return type;
+}
+
+AttrsNode::AttrsNode(Type t, AttrsNode *parent_)
+ : AbstractAttr( t )
+{
+ setParentNode(parent_);
+ is_canonical_root = (t == SEGMENTINFORMATION);
+}
+
+AttrsNode::~AttrsNode()
+{
+ while(props.front())
+ {
+ delete props.front();
+ props.pop_front();
+ }
+}
+
+void AttrsNode::addAttribute(AbstractAttr *p)
+{
+ props.push_front(p);
+ p->setParentNode(this);
+}
+
+void AttrsNode::replaceAttribute(AbstractAttr *p)
+{
+ AbstractAttr *old = getAttribute(p->getType());
+ if(old)
+ {
+ props.remove(old);
+ delete old;
+ }
+ props.push_front(p);
+ p->setParentNode(this);
+}
+
+AbstractAttr * AttrsNode::inheritAttribute(AbstractAttr::Type type)
+{
+ AbstractAttr *p = getAttribute(type);
+ if(p && p->isValid())
+ return p;
+
+ /* List our path elements up to pseudo root node */
+ AttrsNode *rootNode;
+ std::list<AbstractAttr::Type> matchingpath;
+ for(rootNode = this; rootNode; rootNode = rootNode->parentNode)
+ {
+ if(rootNode->is_canonical_root)
+ break;
+ matchingpath.push_front(rootNode->getType());
+ }
+
+ if(rootNode && !matchingpath.empty())
+ {
+ /* Try matching at each sibling level */
+ for(;;)
+ {
+ /* Try same path on each sibling first */
+ for(AttrsNode *node = rootNode->parentNode; node; node = node->parentNode)
+ {
+ p = node->getAttribute(type, matchingpath);
+ if(p && p->isValid())
+ return p;
+ }
+
+ matchingpath.pop_back();
+ if(matchingpath.empty())
+ break;
+ }
+ }
+
+ {
+ /* Just try anything below */
+ for(AttrsNode *node = this->parentNode; node ; node = node->parentNode)
+ {
+ p = node->getAttribute(type);
+ if(p && p->isValid())
+ return p;
+ }
+ }
+
+ return p;
+}
+
+AbstractAttr * AttrsNode::inheritAttribute(AbstractAttr::Type type) const
+{
+ return const_cast<AttrsNode *>(this)->inheritAttribute(type);
+}
+
+stime_t AttrsNode::inheritDuration() const
+{
+ const AbstractAttr *p = inheritAttribute(Type::DURATION);
+ if(p && p->isValid())
+ return (const stime_t &) *(static_cast<const DurationAttr *>(p));
+ return 0;
+}
+
+uint64_t AttrsNode::inheritStartNumber() const
+{
+ const AbstractAttr *p = inheritAttribute(Type::STARTNUMBER);
+ if(p && p->isValid())
+ return (const uint64_t &) *(static_cast<const StartnumberAttr *>(p));
+ return std::numeric_limits<uint64_t>::max();
+}
+
+Timescale AttrsNode::inheritTimescale() const
+{
+ const AbstractAttr *p = inheritAttribute(Type::TIMESCALE);
+ if(p && p->isValid())
+ return (Timescale) *(static_cast<const TimescaleAttr *>(p));
+ else
+ return Timescale(1);
+}
+
+vlc_tick_t AttrsNode::inheritAvailabilityTimeOffset() const
+{
+ const AbstractAttr *p = inheritAttribute(Type::AVAILABILITYTTIMEOFFSET);
+ if(p && p->isValid())
+ return (const vlc_tick_t &) *(static_cast<const AvailabilityTimeOffsetAttr *>(p));
+ return 0;
+}
+
+bool AttrsNode::inheritAvailabilityTimeComplete() const
+{
+ const AbstractAttr *p = inheritAttribute(Type::AVAILABILITYTTIMECOMPLETE);
+ if(p && p->isValid())
+ return (const bool &) *(static_cast<const AvailabilityTimeCompleteAttr *>(p));
+ return true;
+}
+
+SegmentBase * AttrsNode::inheritSegmentBase() const
+{
+ AbstractAttr *p = inheritAttribute(Type::SEGMENTBASE);
+ if(p && p->isValid())
+ return static_cast<SegmentBase *>(p);
+ return NULL;
+}
+
+SegmentList * AttrsNode::inheritSegmentList() const
+{
+ AbstractAttr *p = inheritAttribute(Type::SEGMENTLIST);
+ if(p && p->isValid())
+ return static_cast<SegmentList *> (p);
+ return NULL;
+}
+
+SegmentTemplate * AttrsNode::inheritSegmentTemplate() const
+{
+ AbstractAttr *p = inheritAttribute(Type::SEGMENTTEMPLATE);
+ if(p && p->isValid())
+ return static_cast<SegmentTemplate *> (p);
+ return NULL;
+}
+
+SegmentTimeline * AttrsNode::inheritSegmentTimeline() const
+{
+ AbstractAttr *p = inheritAttribute(Type::TIMELINE);
+ if(p && p->isValid())
+ return static_cast<SegmentTimeline *> (p);
+ return NULL;
+}
+
+AttrsNode * AttrsNode::matchPath(std::list<AbstractAttr::Type>&path)
+{
+ AttrsNode *pn = this;
+ std::list<AbstractAttr::Type>::const_iterator it;
+ for(it = path.begin(); it != path.end(); it++)
+ {
+ AbstractAttr *p = pn->getAttribute(*it);
+ if(!p || !p->isValid())
+ return NULL;
+ pn = dynamic_cast<AttrsNode *>(p);
+ if(pn == NULL)
+ return NULL;
+ }
+ return pn;
+}
+
+AbstractAttr * AttrsNode::getAttribute(AbstractAttr::Type type)
+{
+ for(auto it = props.begin(); it != props.end(); ++it)
+ {
+ if((*it)->getType() == type)
+ return *it;
+ }
+ return NULL;
+}
+
+AbstractAttr * AttrsNode::getAttribute(AbstractAttr::Type type) const
+{
+ return const_cast<AttrsNode *>(this)->getAttribute(type);
+}
+
+AbstractAttr * AttrsNode::getAttribute(AbstractAttr::Type type,
+ std::list<AbstractAttr::Type>&path)
+{
+ AttrsNode *matched = matchPath(path);
+ if(matched)
+ {
+ AbstractAttr *p = matched->getAttribute(type);
+ if(p && p->isValid())
+ return p;
+ }
+ return NULL;
+}
+
TimescaleAble::TimescaleAble(TimescaleAble *parent)
{
parentTimescaleAble = parent;
diff --git a/modules/demux/adaptive/playlist/Inheritables.hpp b/modules/demux/adaptive/playlist/Inheritables.hpp
index 593391e056..8fa04f5ad8 100644
--- a/modules/demux/adaptive/playlist/Inheritables.hpp
+++ b/modules/demux/adaptive/playlist/Inheritables.hpp
@@ -1,7 +1,7 @@
/*****************************************************************************
* Inheritables.hpp Nodes inheritables properties
*****************************************************************************
- * Copyright (C) 1998-2015 VLC authors and VideoLAN
+ * Copyright (C) 2016-2020 VideoLabs, VLC authors and VideoLAN
*
* 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
@@ -20,7 +20,6 @@
#ifndef INHERITABLES_H
#define INHERITABLES_H
-#include "../tools/Properties.hpp"
#include <list>
#include <limits>
#include <stdint.h>
@@ -30,6 +29,107 @@ namespace adaptive
{
namespace playlist
{
+ class AttrsNode;
+ class SegmentTimeline;
+ class SegmentTemplate;
+ class SegmentList;
+ class SegmentBase;
+
+ class AbstractAttr
+ {
+ public:
+ enum Type
+ {
+ NONE,
+ PLAYLIST,
+ SEGMENTINFORMATION,
+ SEGMENTLIST,
+ SEGMENTBASE,
+ SEGMENTTEMPLATE,
+ TIMESCALE,
+ TIMELINE,
+ DURATION,
+ STARTNUMBER,
+ AVAILABILITYTTIMEOFFSET,
+ AVAILABILITYTTIMECOMPLETE,
+ };
+ AbstractAttr(enum Type);
+ virtual ~AbstractAttr();
+ Type getType() const;
+ bool operator ==(const AbstractAttr &t) const { return type == t.getType(); }
+ bool operator !=(const AbstractAttr &t) const { return type != t.getType(); }
+ virtual bool isValid() const { return true; }
+ void setParentNode(AttrsNode *n) { parentNode = n; }
+
+ protected:
+ Type type;
+ AttrsNode *parentNode;
+ };
+
+ class AttrsNode : public AbstractAttr
+ {
+ public:
+ AttrsNode( enum Type, AttrsNode * = NULL );
+ ~AttrsNode();
+ void addAttribute( AbstractAttr * );
+ void replaceAttribute( AbstractAttr * );
+ AbstractAttr * inheritAttribute(AbstractAttr::Type);
+ AbstractAttr * inheritAttribute(AbstractAttr::Type) const;
+ /* helpers */
+ uint64_t inheritStartNumber() const;
+ stime_t inheritDuration() const;
+ Timescale inheritTimescale() const;
+ vlc_tick_t inheritAvailabilityTimeOffset() const;
+ bool inheritAvailabilityTimeComplete() const;
+ SegmentTimeline * inheritSegmentTimeline() const;
+ SegmentTemplate * inheritSegmentTemplate() const;
+ SegmentList * inheritSegmentList() const;
+ SegmentBase * inheritSegmentBase() const;
+
+ protected:
+ AttrsNode * matchPath(std::list<AbstractAttr::Type>&);
+ AbstractAttr * getAttribute(AbstractAttr::Type,
+ std::list<AbstractAttr::Type>&);
+ AbstractAttr * getAttribute(AbstractAttr::Type);
+ AbstractAttr * getAttribute(AbstractAttr::Type) const;
+ std::list<AbstractAttr *> props;
+ bool is_canonical_root;
+ };
+
+ template<enum AbstractAttr::Type e, typename T>
+ class AttrWrapper : public AbstractAttr
+ {
+ public:
+ AttrWrapper(T v) : AbstractAttr(e) { value = v; }
+ virtual ~AttrWrapper() {}
+ operator const T&() const { return value; }
+
+ protected:
+ T value;
+ };
+
+ typedef AttrWrapper<AbstractAttr::Type::AVAILABILITYTTIMEOFFSET, vlc_tick_t> AvailabilityTimeOffsetAttr;
+ typedef AttrWrapper<AbstractAttr::Type::AVAILABILITYTTIMECOMPLETE, bool> AvailabilityTimeCompleteAttr;
+ typedef AttrWrapper<AbstractAttr::Type::STARTNUMBER, uint64_t> StartnumberAttr;
+
+ class TimescaleAttr:
+ public AttrWrapper<AbstractAttr::Type::TIMESCALE, Timescale>
+ {
+ public:
+ TimescaleAttr(Timescale v) :
+ AttrWrapper<AbstractAttr::Type::TIMESCALE, Timescale>( v ) {}
+ virtual bool isValid() const { return value.isValid(); }
+ };
+
+ class DurationAttr:
+ public AttrWrapper<AbstractAttr::Type::DURATION, stime_t>
+ {
+ public:
+ DurationAttr(stime_t v) :
+ AttrWrapper<AbstractAttr::Type::DURATION, stime_t>( v ) {}
+ virtual bool isValid() const { return value > 0; }
+ };
+
class TimescaleAble
{
public:
diff --git a/modules/demux/adaptive/playlist/SegmentBase.cpp b/modules/demux/adaptive/playlist/SegmentBase.cpp
index 16f3ff1c1f..b28dc72834 100644
--- a/modules/demux/adaptive/playlist/SegmentBase.cpp
+++ b/modules/demux/adaptive/playlist/SegmentBase.cpp
@@ -33,7 +33,8 @@
using namespace adaptive::playlist;
SegmentBase::SegmentBase(SegmentInformation *parent) :
- Segment(parent), AbstractSegmentBaseType(parent)
+ Segment(parent),
+ AbstractSegmentBaseType(parent, AttrsNode::Type::SEGMENTBASE)
{
this->parent = parent;
}
diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.cpp b/modules/demux/adaptive/playlist/SegmentBaseType.cpp
index defc491041..1cc85fb474 100644
--- a/modules/demux/adaptive/playlist/SegmentBaseType.cpp
+++ b/modules/demux/adaptive/playlist/SegmentBaseType.cpp
@@ -65,8 +65,8 @@ uint64_t AbstractSegmentBaseType::findSegmentNumberByScaledTime(const std::vecto
return s->getSequenceNumber();
}
-AbstractSegmentBaseType::AbstractSegmentBaseType(SegmentInformation *parent)
- : TimescaleAble(parent)
+AbstractSegmentBaseType::AbstractSegmentBaseType(SegmentInformation *parent, AttrsNode::Type t)
+ : AttrsNode(t, parent)
{
this->parent = parent;
}
@@ -85,30 +85,6 @@ IndexSegment *AbstractSegmentBaseType::getIndexSegment() const
return indexSegment.Get();
}
-Timescale AbstractSegmentBaseType::inheritTimescale() const
-{
- if(getTimescale().isValid())
- return getTimescale();
- if(parent)
- {
- if(parent->getTimescale().isValid())
- return parent->getTimescale();
- if(parent->getParent())
- {
- AbstractSegmentBaseType *bt =
- dynamic_cast<AbstractSegmentBaseType *>(parent->getParent()->getProfile());
- if(bt)
- return bt->inheritTimescale();
- }
- }
- return Timescale(1);
-}
-
-SegmentInformation *AbstractSegmentBaseType::getParent() const
-{
- return parent;
-}
-
void AbstractSegmentBaseType::debug(vlc_object_t *obj, int indent) const
{
if(initialisationSegment.Get())
@@ -117,84 +93,21 @@ void AbstractSegmentBaseType::debug(vlc_object_t *obj, int indent) const
indexSegment.Get()->debug(obj, indent);
}
-AbstractMultipleSegmentBaseType::AbstractMultipleSegmentBaseType(SegmentInformation *parent)
- : AbstractSegmentBaseType(parent)
+AbstractMultipleSegmentBaseType::AbstractMultipleSegmentBaseType(SegmentInformation *parent,
+ AttrsNode::Type type)
+ : AbstractSegmentBaseType(parent, type)
{
- startNumber = std::numeric_limits<uint64_t>::max();
- segmentTimeline = NULL;
- duration.Set(0);
}
AbstractMultipleSegmentBaseType::~AbstractMultipleSegmentBaseType()
{
- delete segmentTimeline;
-}
-
-void AbstractMultipleSegmentBaseType::setSegmentTimeline( SegmentTimeline *v )
-{
- delete segmentTimeline;
- segmentTimeline = v;
-}
-
-SegmentTimeline * AbstractMultipleSegmentBaseType::inheritSegmentTimeline() const
-{
- if( segmentTimeline )
- return segmentTimeline;
- const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
- for( ; ulevel ; ulevel = ulevel->getParent() )
- {
- AbstractMultipleSegmentBaseType *bt =
- dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
- if( bt && bt->segmentTimeline )
- return bt->segmentTimeline;
- }
- return NULL;
-}
-
-SegmentTimeline * AbstractMultipleSegmentBaseType::getSegmentTimeline() const
-{
- return segmentTimeline;
-}
-
-void AbstractMultipleSegmentBaseType::setStartNumber( uint64_t v )
-{
- startNumber = v;
-}
-
-uint64_t AbstractMultipleSegmentBaseType::inheritStartNumber() const
-{
- if( startNumber != std::numeric_limits<uint64_t>::max() )
- return startNumber;
-
- const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
- for( ; ulevel ; ulevel = ulevel->parent )
- {
- AbstractMultipleSegmentBaseType *bt =
- dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
- if( bt && bt->startNumber != std::numeric_limits<uint64_t>::max() )
- return bt->startNumber;
- }
- return std::numeric_limits<uint64_t>::max();
-}
-
-stime_t AbstractMultipleSegmentBaseType::inheritDuration() const
-{
- if(duration.Get() > 0)
- return duration.Get();
- const SegmentInformation *ulevel = parent ? parent->getParent() : NULL;
- for( ; ulevel ; ulevel = ulevel->parent )
- {
- AbstractMultipleSegmentBaseType *bt =
- dynamic_cast<AbstractMultipleSegmentBaseType *>(ulevel->getProfile());
- if( bt && bt->duration.Get() > 0 )
- return bt->duration.Get();
- }
- return 0;
}
void AbstractMultipleSegmentBaseType::updateWith(AbstractMultipleSegmentBaseType *updated,
bool)
{
- if(segmentTimeline && updated->segmentTimeline)
- segmentTimeline->updateWith(*updated->segmentTimeline);
+ SegmentTimeline *local = static_cast<SegmentTimeline *>(getAttribute(Type::TIMELINE));
+ SegmentTimeline *other = static_cast<SegmentTimeline *>(updated->getAttribute(Type::TIMELINE));
+ if(local && other)
+ local->updateWith(*other);
}
diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.hpp b/modules/demux/adaptive/playlist/SegmentBaseType.hpp
index 89432bcd41..16c094b69d 100644
--- a/modules/demux/adaptive/playlist/SegmentBaseType.hpp
+++ b/modules/demux/adaptive/playlist/SegmentBaseType.hpp
@@ -34,10 +34,10 @@ namespace adaptive
class AbstractSegmentBaseType : public Initializable<InitSegment>,
public Indexable<IndexSegment>,
- public TimescaleAble
+ public AttrsNode
{
public:
- AbstractSegmentBaseType( SegmentInformation * );
+ AbstractSegmentBaseType( SegmentInformation *, AttrsNode::Type );
virtual ~AbstractSegmentBaseType();
virtual vlc_tick_t getMinAheadTime(uint64_t) const = 0;
@@ -51,15 +51,12 @@ namespace adaptive
virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number,
vlc_tick_t *time, vlc_tick_t *duration) const = 0;
- Timescale inheritTimescale() const; /* reimpl */
-
virtual void debug(vlc_object_t *, int = 0) const;
static Segment * findSegmentByScaledTime(const std::vector<Segment *> &,
stime_t);
static uint64_t findSegmentNumberByScaledTime(const std::vector<Segment *> &,
stime_t);
- SegmentInformation * getParent() const;
protected:
SegmentInformation *parent;
@@ -68,22 +65,10 @@ namespace adaptive
class AbstractMultipleSegmentBaseType : public AbstractSegmentBaseType
{
public:
- AbstractMultipleSegmentBaseType( SegmentInformation * );
+ AbstractMultipleSegmentBaseType( SegmentInformation *, AttrsNode::Type );
virtual ~AbstractMultipleSegmentBaseType();
- void setSegmentTimeline( SegmentTimeline * );
- SegmentTimeline * inheritSegmentTimeline() const;
- SegmentTimeline * getSegmentTimeline() const;
- void setStartNumber( uint64_t );
- uint64_t inheritStartNumber() const;
- stime_t inheritDuration() const;
virtual void updateWith(AbstractMultipleSegmentBaseType *, bool = false);
- Property<stime_t> duration;
-
- protected:
- uint64_t startNumber;
- SegmentTimeline *segmentTimeline;
-
};
}
}
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index faae1a7639..c4fe204783 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -39,7 +39,7 @@ using namespace adaptive::playlist;
SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
ICanonicalUrl( parent_ ),
- TimescaleAble( parent_ )
+ AttrsNode( AbstractAttr::SEGMENTINFORMATION, parent_ )
{
parent = parent_;
init();
@@ -47,7 +47,7 @@ SegmentInformation::SegmentInformation(SegmentInformation *parent_) :
SegmentInformation::SegmentInformation(AbstractPlaylist * parent_) :
ICanonicalUrl(parent_),
- TimescaleAble()
+ AttrsNode( AbstractAttr::SEGMENTINFORMATION, NULL )
{
parent = NULL;
init();
@@ -56,16 +56,10 @@ SegmentInformation::SegmentInformation(AbstractPlaylist * parent_) :
void SegmentInformation::init()
{
baseUrl.Set(NULL);
- segmentBase = NULL;
- segmentList = NULL;
- mediaSegmentTemplate = NULL;
}
SegmentInformation::~SegmentInformation()
{
- delete segmentBase;
- delete segmentList;
- delete mediaSegmentTemplate;
delete baseUrl.Get();
}
@@ -136,11 +130,17 @@ SegmentInformation * SegmentInformation::getChildByID(const adaptive::ID &id)
void SegmentInformation::updateWith(SegmentInformation *updated)
{
/* Support Segment List for now */
- if(segmentList && updated->segmentList)
- segmentList->updateWith(updated->segmentList);
+ AbstractAttr *p = getAttribute(Type::SEGMENTLIST);
+ if(p && p->isValid() && updated->getAttribute(Type::SEGMENTLIST))
+ {
+ inheritSegmentList()->updateWith(updated->inheritSegmentList());
+ }
- if(mediaSegmentTemplate && updated->mediaSegmentTemplate)
- mediaSegmentTemplate->updateWith(updated->mediaSegmentTemplate);
+ p = getAttribute(Type::SEGMENTTEMPLATE);
+ if(p && p->isValid() && updated->getAttribute(Type::SEGMENTTEMPLATE))
+ {
+ inheritSegmentTemplate()->updateWith(updated->inheritSegmentTemplate());
+ }
std::vector<SegmentInformation *>::const_iterator it;
for(it=childs.begin(); it!=childs.end(); ++it)
@@ -155,11 +155,13 @@ void SegmentInformation::updateWith(SegmentInformation *updated)
void SegmentInformation::pruneByPlaybackTime(vlc_tick_t time)
{
+ SegmentList *segmentList = static_cast<SegmentList *>(getAttribute(Type::SEGMENTLIST));
if(segmentList)
segmentList->pruneByPlaybackTime(time);
- if(mediaSegmentTemplate)
- mediaSegmentTemplate->pruneByPlaybackTime(time);
+ SegmentTemplate *templ = static_cast<SegmentTemplate *>(getAttribute(Type::SEGMENTTEMPLATE));
+ if(templ)
+ templ->pruneByPlaybackTime(time);
std::vector<SegmentInformation *>::const_iterator it;
for(it=childs.begin(); it!=childs.end(); ++it)
@@ -170,11 +172,13 @@ void SegmentInformation::pruneBySegmentNumber(uint64_t num)
{
assert(dynamic_cast<BaseRepresentation *>(this));
+ SegmentList *segmentList = static_cast<SegmentList *>(getAttribute(Type::SEGMENTLIST));
if(segmentList)
segmentList->pruneBySegmentNumber(num);
- if(mediaSegmentTemplate)
- mediaSegmentTemplate->pruneBySequenceNumber(num);
+ SegmentTemplate *templ = static_cast<SegmentTemplate *>(getAttribute(Type::SEGMENTTEMPLATE));
+ if(templ)
+ templ->pruneBySequenceNumber(num);
}
const CommonEncryption & SegmentInformation::intheritEncryption() const
@@ -205,25 +209,22 @@ vlc_tick_t SegmentInformation::getPeriodDuration() const
return 0;
}
-SegmentInformation * SegmentInformation::getParent() const
-{
- return parent;
-}
-
AbstractSegmentBaseType * SegmentInformation::getProfile() const
{
- if(mediaSegmentTemplate)
- return mediaSegmentTemplate;
- else if(segmentList)
- return segmentList;
- else if(segmentBase)
- return segmentBase;
- else
- return NULL;
+ AbstractAttr *p;
+ if((p = getAttribute(Type::SEGMENTTEMPLATE)))
+ return (SegmentTemplate *) p;
+ else if((p = getAttribute(Type::SEGMENTLIST)))
+ return (SegmentList *) p;
+ else if((p = getAttribute(Type::SEGMENTBASE)))
+ return (SegmentBase *) p;
+
+ return NULL;
}
void SegmentInformation::updateSegmentList(SegmentList *list, bool restamp)
{
+ SegmentList *segmentList = static_cast<SegmentList *>(getAttribute(Type::SEGMENTLIST));
if(segmentList && restamp)
{
segmentList->updateWith(list, restamp);
@@ -231,27 +232,22 @@ void SegmentInformation::updateSegmentList(SegmentList *list, bool restamp)
}
else
{
- delete segmentList;
- segmentList = list;
+ replaceAttribute(list);
}
}
-void SegmentInformation::setSegmentBase(SegmentBase *base)
-{
- if(segmentBase)
- delete segmentBase;
- segmentBase = base;
-}
-
void SegmentInformation::setSegmentTemplate(SegmentTemplate *templ)
{
- if(mediaSegmentTemplate)
+ SegmentTemplate *local = static_cast<SegmentTemplate *>(getAttribute(Type::SEGMENTTEMPLATE));
+ if(local)
{
- mediaSegmentTemplate->updateWith(templ);
+ local->updateWith(templ);
delete templ;
}
else
- mediaSegmentTemplate = templ;
+ {
+ addAttribute(templ);
+ }
}
static void insertIntoSegment(std::vector<Segment *> &seglist, size_t start,
@@ -323,63 +319,3 @@ Url SegmentInformation::getUrlSegment() const
return ret;
}
}
-
-SegmentBase * SegmentInformation::inheritSegmentBase() const
-{
- if(segmentBase)
- return segmentBase;
- else if (parent)
- return parent->inheritSegmentBase();
- else
- return NULL;
-}
-
-SegmentList * SegmentInformation::inheritSegmentList() const
-{
- if(segmentList)
- return segmentList;
- else if (parent)
- return parent->inheritSegmentList();
- else
- return NULL;
-}
-
-SegmentTemplate * SegmentInformation::inheritSegmentTemplate() const
-{
- if(mediaSegmentTemplate)
- return mediaSegmentTemplate;
- else if (parent)
- return parent->inheritSegmentTemplate();
- else
- return NULL;
-}
-
-void SegmentInformation::setAvailabilityTimeOffset(vlc_tick_t t)
-{
- availabilityTimeOffset = t;
-}
-
-void SegmentInformation::setAvailabilityTimeComplete(bool b)
-{
- availabilityTimeComplete = b;
-}
-
-vlc_tick_t SegmentInformation::inheritAvailabilityTimeOffset() const
-{
- for(const SegmentInformation *p = this; p; p = p->parent)
- {
- if(availabilityTimeOffset.isSet())
- return availabilityTimeOffset.value();
- }
- return getPlaylist()->getAvailabilityTimeOffset();
-}
-
-bool SegmentInformation::inheritAvailabilityTimeComplete() const
-{
- for(const SegmentInformation *p = this; p; p = p->parent)
- {
- if(availabilityTimeComplete.isSet())
- return availabilityTimeComplete.value();
- }
- return getPlaylist()->getAvailabilityTimeComplete();
-}
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index 6704c3cca6..66e36d5c6f 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -44,8 +44,8 @@ namespace adaptive
/* common segment elements for period/adaptset/rep 5.3.9.1,
* with properties inheritance */
class SegmentInformation : public ICanonicalUrl,
- public TimescaleAble,
- public Unique
+ public Unique,
+ public AttrsNode
{
friend class AbstractMultipleSegmentBaseType;
@@ -84,30 +84,16 @@ namespace adaptive
SegmentInformation *parent;
public:
- SegmentInformation *getParent() const;
AbstractSegmentBaseType *getProfile() const;
void updateSegmentList(SegmentList *, bool = false);
- void setSegmentBase(SegmentBase *);
void setSegmentTemplate(SegmentTemplate *);
virtual Url getUrlSegment() const; /* impl */
Property<Url *> baseUrl;
- void setAvailabilityTimeOffset(vlc_tick_t);
- void setAvailabilityTimeComplete(bool);
const AbstractSegmentBaseType * inheritSegmentProfile() const;
- SegmentBase * inheritSegmentBase() const;
- SegmentList * inheritSegmentList() const;
- SegmentTemplate * inheritSegmentTemplate() const;
- vlc_tick_t inheritAvailabilityTimeOffset() const;
- bool inheritAvailabilityTimeComplete() const;
private:
void init();
- SegmentBase *segmentBase;
- SegmentList *segmentList;
- SegmentTemplate *mediaSegmentTemplate;
CommonEncryption commonEncryption;
- Undef<bool> availabilityTimeComplete;
- Undef<vlc_tick_t>availabilityTimeOffset;
};
}
}
diff --git a/modules/demux/adaptive/playlist/SegmentList.cpp b/modules/demux/adaptive/playlist/SegmentList.cpp
index 211b9ef80c..92d12b56f7 100644
--- a/modules/demux/adaptive/playlist/SegmentList.cpp
+++ b/modules/demux/adaptive/playlist/SegmentList.cpp
@@ -34,8 +34,8 @@
using namespace adaptive::playlist;
-SegmentList::SegmentList( SegmentInformation *parent ):
- AbstractMultipleSegmentBaseType( parent )
+SegmentList::SegmentList( SegmentInformation *parent_ ):
+ AbstractMultipleSegmentBaseType( parent_, AttrsNode::Type::SEGMENTLIST )
{
totalLength = 0;
}
@@ -80,7 +80,7 @@ Segment * SegmentList::getMediaSegment(uint64_t number) const
void SegmentList::addSegment(Segment *seg)
{
- seg->setParent(parent);
+ seg->setParent(AbstractSegmentBaseType::parent);
segments.push_back(seg);
totalLength += seg->duration.Get();
}
@@ -188,7 +188,7 @@ bool SegmentList::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
if(seg->duration.Get())
sduration = seg->duration.Get();
else
- sduration = duration.Get();
+ sduration = inheritDuration();
/* Assuming there won't be any discontinuity in sequence */
if(seg->getSequenceNumber() == number)
@@ -280,9 +280,7 @@ bool SegmentList::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const
const SegmentTimeline *timeline = inheritSegmentTimeline();
if(timeline)
{
- const Timescale timescale = timeline->getTimescale().isValid()
- ? timeline->getTimescale()
- : inheritTimescale();
+ const Timescale timescale = timeline->inheritTimescale();
stime_t st = timescale.ToScaled(time);
*ret = timeline->getElementNumberByScaledPlaybackTime(st);
return true;
@@ -302,6 +300,7 @@ void SegmentList::debug(vlc_object_t *obj, int indent) const
std::vector<Segment *>::const_iterator it;
for(it = segments.begin(); it != segments.end(); ++it)
(*it)->debug(obj, indent);
- if(segmentTimeline)
- segmentTimeline->debug(obj, indent + 1);
+ const AbstractAttr *p = getAttribute(Type::TIMELINE);
+ if(p)
+ ((SegmentTimeline *) p)->debug(obj, indent + 1);
}
diff --git a/modules/demux/adaptive/playlist/SegmentList.h b/modules/demux/adaptive/playlist/SegmentList.h
index f67d64ad8a..28f63e2439 100644
--- a/modules/demux/adaptive/playlist/SegmentList.h
+++ b/modules/demux/adaptive/playlist/SegmentList.h
@@ -26,6 +26,7 @@
#define SEGMENTLIST_H_
#include "SegmentBaseType.hpp"
+#include "Inheritables.hpp"
namespace adaptive
{
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
index f66fe7eb02..d3b7928f31 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
@@ -52,7 +52,7 @@ void SegmentTemplateSegment::setSourceUrl(const std::string &url)
}
SegmentTemplate::SegmentTemplate( SegmentInformation *parent ) :
- AbstractMultipleSegmentBaseType( NULL ) /* we don't want auto inherit */
+ AbstractMultipleSegmentBaseType( parent, AbstractAttr::Type::SEGMENTTEMPLATE )
{
initialisationSegment.Set( NULL );
parentSegmentInformation = parent;
@@ -71,14 +71,16 @@ void SegmentTemplate::setSourceUrl( const std::string &url )
void SegmentTemplate::pruneByPlaybackTime(vlc_tick_t time)
{
- if(segmentTimeline)
- return segmentTimeline->pruneByPlaybackTime(time);
+ const AbstractAttr *p = getAttribute(Type::TIMELINE);
+ if(p)
+ return ((SegmentTimeline *) p)->pruneByPlaybackTime(time);
}
size_t SegmentTemplate::pruneBySequenceNumber(uint64_t number)
{
- if(segmentTimeline)
- return segmentTimeline->pruneBySequenceNumber(number);
+ const AbstractAttr *p = getAttribute(Type::TIMELINE);
+ if(p)
+ return ((SegmentTimeline *) p)->pruneBySequenceNumber(number);
return 0;
}
@@ -111,16 +113,18 @@ void SegmentTemplate::debug(vlc_object_t *obj, int indent) const
{
AbstractSegmentBaseType::debug(obj, indent);
(*segments.begin())->debug(obj, indent);
- if(segmentTimeline)
- segmentTimeline->debug(obj, indent + 1);
+ const AbstractAttr *p = getAttribute(Type::TIMELINE);
+ if(p)
+ ((SegmentTimeline *) p)->debug(obj, indent + 1);
}
vlc_tick_t SegmentTemplate::getMinAheadTime(uint64_t number) const
{
- if( segmentTimeline )
+ SegmentTimeline *timeline = inheritSegmentTimeline();
+ if( timeline )
{
- const Timescale timescale = segmentTimeline->inheritTimescale();
- return timescale.ToTime(segmentTimeline->getMinAheadScaledTime(number));
+ const Timescale timescale = timeline->inheritTimescale();
+ return timescale.ToTime(timeline->getMinAheadScaledTime(number));
}
else
{
@@ -197,9 +201,7 @@ bool SegmentTemplate::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) con
const SegmentTimeline *timeline = inheritSegmentTimeline();
if(timeline)
{
- const Timescale timescale = timeline->getTimescale().isValid()
- ? timeline->getTimescale()
- : inheritTimescale();
+ const Timescale timescale = timeline->inheritTimescale();
stime_t st = timescale.ToScaled(time);
*ret = timeline->getElementNumberByScaledPlaybackTime(st);
return true;
diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.cpp b/modules/demux/adaptive/playlist/SegmentTimeline.cpp
index a8e60ccc66..51e2873c13 100644
--- a/modules/demux/adaptive/playlist/SegmentTimeline.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTimeline.cpp
@@ -33,20 +33,12 @@
using namespace adaptive::playlist;
SegmentTimeline::SegmentTimeline(AbstractMultipleSegmentBaseType *parent_)
- :TimescaleAble(NULL)
+ : AttrsNode(Type::TIMELINE, parent_)
{
totalLength = 0;
parent = parent_;
}
-SegmentTimeline::SegmentTimeline(uint64_t scale)
- :TimescaleAble(NULL)
-{
- setTimescale(scale);
- totalLength = 0;
- parent = NULL;
-}
-
SegmentTimeline::~SegmentTimeline()
{
std::list<Element *>::iterator it;
@@ -93,33 +85,6 @@ stime_t SegmentTimeline::getMinAheadScaledTime(uint64_t number) const
return totalscaledtime;
}
-Timescale SegmentTimeline::inheritTimescale() const
-{
- if(getTimescale().isValid())
- return getTimescale();
-
- if(parent && parent->getTimescale().isValid())
- return parent->getTimescale();
-
- SegmentInformation *info = NULL;
- if(parent && parent->getParent() && parent->getParent()->getParent())
- info = parent->getParent()->getParent();
- else
- info = NULL;
-
- AbstractMultipleSegmentBaseType *bt;
- for(; info; info = info->getParent())
- {
- bt = dynamic_cast<AbstractMultipleSegmentBaseType *>(info->getProfile());
- if(bt && bt->getSegmentTimeline() && bt->getSegmentTimeline()->getTimescale().isValid())
- return bt->getSegmentTimeline()->getTimescale();
- if(info->getTimescale().isValid())
- return info->getTimescale();
- }
-
- return Timescale(1);
-}
-
uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(stime_t scaled) const
{
const Element *prevel = NULL;
diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.h b/modules/demux/adaptive/playlist/SegmentTimeline.h
index 668f7d5389..e56f16437f 100644
--- a/modules/demux/adaptive/playlist/SegmentTimeline.h
+++ b/modules/demux/adaptive/playlist/SegmentTimeline.h
@@ -34,20 +34,18 @@ namespace adaptive
{
class AbstractMultipleSegmentBaseType;
- class SegmentTimeline : public TimescaleAble
+ class SegmentTimeline : public AttrsNode
{
class Element;
public:
SegmentTimeline(AbstractMultipleSegmentBaseType *);
- SegmentTimeline(uint64_t);
virtual ~SegmentTimeline();
void addElement(uint64_t, stime_t d, uint64_t r = 0, stime_t t = 0);
uint64_t getElementNumberByScaledPlaybackTime(stime_t) const;
bool getScaledPlaybackTimeDurationBySegmentNumber(uint64_t, stime_t *, stime_t *) const;
stime_t getScaledPlaybackTimeByElementNumber(uint64_t) const;
stime_t getMinAheadScaledTime(uint64_t) const;
- Timescale inheritTimescale() const; /* reimpl */
stime_t getTotalLength() const;
uint64_t maxElementNumber() const;
uint64_t minElementNumber() const;
diff --git a/modules/demux/dash/mp4/IndexReader.cpp b/modules/demux/dash/mp4/IndexReader.cpp
index 5dc8089a6d..4e4312a72d 100644
--- a/modules/demux/dash/mp4/IndexReader.cpp
+++ b/modules/demux/dash/mp4/IndexReader.cpp
@@ -57,7 +57,7 @@ bool IndexReader::parseIndex(block_t *p_block, BaseRepresentation *rep, uint64_t
point.duration = sidx->p_items[i].i_subsegment_duration;
point.time += point.duration;
}
- rep->setTimescale(Timescale(sidx->i_timescale));
+ rep->replaceAttribute(new TimescaleAttr(Timescale(sidx->i_timescale)));
rep->SplitUsingIndex(splitlist);
rep->getPlaylist()->debug();
}
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 6f158a81aa..408c61b567 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -70,12 +70,12 @@ static void parseAvailability(MPD *mpd, Node *node, T *s)
if(node->hasAttribute("availabilityTimeOffset"))
{
double val = Integer<double>(node->getAttributeValue("availabilityTimeOffset"));
- s->setAvailabilityTimeOffset(val * CLOCK_FREQ);
+ s->addAttribute(new AvailabilityTimeOffsetAttr(val * CLOCK_FREQ));
}
if(node->hasAttribute("availabilityTimeComplete"))
{
bool b = (node->getAttributeValue("availabilityTimeComplete") == "false");
- s->setAvailabilityTimeComplete(!b);
+ s->addAttribute(new AvailabilityTimeCompleteAttr(!b));
if(b)
mpd->setLowLatency(b);
}
@@ -206,8 +206,10 @@ void IsoffMainParser::parseSegmentBaseType(MPD *, Node *node,
}
if(node->hasAttribute("timescale"))
- base->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale")));
-
+ {
+ TimescaleAttr *prop = new TimescaleAttr(Timescale(Integer<uint64_t>(node->getAttributeValue("timescale"))));
+ base->addAttribute(prop);
+ }
}
void IsoffMainParser::parseMultipleSegmentBaseType(MPD *mpd, Node *node,
@@ -217,10 +219,10 @@ void IsoffMainParser::parseMultipleSegmentBaseType(MPD *mpd, Node *node,
parseSegmentBaseType(mpd, node, base, parent);
if(node->hasAttribute("duration"))
- base->duration.Set(Integer<stime_t>(node->getAttributeValue("duration")));
+ base->addAttribute(new DurationAttr(Integer<stime_t>(node->getAttributeValue("duration"))));
if(node->hasAttribute("startNumber"))
- base->setStartNumber(Integer<uint64_t>(node->getAttributeValue("startNumber")));
+ base->addAttribute(new StartnumberAttr(Integer<uint64_t>(node->getAttributeValue("startNumber"))));
parseTimeline(DOMHelper::getFirstChildElementByName(node, "SegmentTimeline"), base);
}
@@ -269,7 +271,7 @@ size_t IsoffMainParser::parseSegmentInformation(MPD *mpd, Node *node,
total += parseSegmentList(mpd, DOMHelper::getFirstChildElementByName(node, "SegmentList"), info);
total += parseSegmentTemplate(mpd, DOMHelper::getFirstChildElementByName(node, "SegmentTemplate" ), info);
if(node->hasAttribute("timescale"))
- info->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale")));
+ info->addAttribute(new TimescaleAttr(Timescale(Integer<uint64_t>(node->getAttributeValue("timescale")))));
parseAvailability<SegmentInformation>(mpd, node, info);
@@ -394,7 +396,7 @@ void IsoffMainParser::parseRepresentations (MPD *mpd, Node *adaptationSetNode
{
SegmentBase *base = new (std::nothrow) SegmentBase(currentRepresentation);
if(base)
- currentRepresentation->setSegmentBase(base);
+ currentRepresentation->addAttribute(base);
}
adaptationSet->addRepresentation(currentRepresentation);
@@ -419,7 +421,7 @@ size_t IsoffMainParser::parseSegmentBase(MPD *mpd, Node * segmentBaseNode, Segme
base->initialisationSegment.Set(initSeg);
}
- info->setSegmentBase(base);
+ info->addAttribute(base);
return 1;
}
@@ -458,11 +460,12 @@ size_t IsoffMainParser::parseSegmentList(MPD *mpd, Node * segListNode, SegmentIn
seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
}
- if(list->duration.Get())
+ stime_t duration = list->inheritDuration();
+ if(duration)
{
seg->startTime.Set(nzStartTime);
- seg->duration.Set(list->duration.Get());
- nzStartTime += list->duration.Get();
+ seg->duration.Set(duration);
+ nzStartTime += duration;
}
seg->setSequenceNumber(total);
@@ -534,7 +537,8 @@ void IsoffMainParser::parseTimeline(Node *node, AbstractMultipleSegmentBaseType
number += (1 + r);
}
- base->setSegmentTimeline(timeline);
+ //base->setSegmentTimeline(timeline);
+ base->addAttribute(timeline);
}
}
diff --git a/modules/demux/dash/mpd/Representation.cpp b/modules/demux/dash/mpd/Representation.cpp
index 9f936fe4ef..e0026e3902 100644
--- a/modules/demux/dash/mpd/Representation.cpp
+++ b/modules/demux/dash/mpd/Representation.cpp
@@ -109,9 +109,9 @@ stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const Segme
{
time = tl->getScaledPlaybackTimeByElementNumber(index);
}
- else if(templ->duration.Get())
+ else if(templ->inheritDuration())
{
- time = templ->duration.Get() * index;
+ time = templ->inheritDuration() * index;
}
return time;
}
diff --git a/modules/demux/hls/playlist/Parser.cpp b/modules/demux/hls/playlist/Parser.cpp
index 5a6de6049d..e2e1aaefe4 100644
--- a/modules/demux/hls/playlist/Parser.cpp
+++ b/modules/demux/hls/playlist/Parser.cpp
@@ -209,7 +209,8 @@ void M3U8Parser::parseSegments(vlc_object_t *, Representation *rep, const std::l
{
SegmentList *segmentList = new (std::nothrow) SegmentList(rep);
- rep->setTimescale(100);
+ Timescale timescale(100);
+ rep->addAttribute(new TimescaleAttr(timescale));
rep->b_loaded = true;
vlc_tick_t totalduration = 0;
@@ -266,8 +267,8 @@ void M3U8Parser::parseSegments(vlc_object_t *, Representation *rep, const std::l
nzDuration = vlc_tick_from_sec(durAttribute->floatingPoint());
ctx_extinf = NULL;
}
- segment->duration.Set(rep->getTimescale().ToScaled(nzDuration));
- segment->startTime.Set(rep->getTimescale().ToScaled(nzStartTime));
+ segment->duration.Set(timescale.ToScaled(nzDuration));
+ segment->startTime.Set(timescale.ToScaled(nzStartTime));
nzStartTime += nzDuration;
totalduration += nzDuration;
if(absReferenceTime != VLC_TICK_INVALID)
diff --git a/modules/demux/hls/playlist/Representation.cpp b/modules/demux/hls/playlist/Representation.cpp
index 08f7b40249..4103478f46 100644
--- a/modules/demux/hls/playlist/Representation.cpp
+++ b/modules/demux/hls/playlist/Representation.cpp
@@ -169,8 +169,10 @@ uint64_t Representation::translateSegmentNumber(uint64_t num, const BaseRepresen
HLSSegment *fromHlsSeg = dynamic_cast<HLSSegment *>(fromSeg);
if(!fromHlsSeg)
return 1;
+
+ const Timescale timescale = inheritTimescale();
const vlc_tick_t utcTime = fromHlsSeg->getUTCTime() +
- getTimescale().ToTime(fromHlsSeg->duration.Get()) / 2;
+ timescale.ToTime(fromHlsSeg->duration.Get()) / 2;
const std::vector<Segment *> &list = inheritSegmentList()->getSegments();
std::vector<Segment *>::const_iterator it;
diff --git a/modules/demux/smooth/mp4/IndexReader.cpp b/modules/demux/smooth/mp4/IndexReader.cpp
index ef3e363030..597918a9e5 100644
--- a/modules/demux/smooth/mp4/IndexReader.cpp
+++ b/modules/demux/smooth/mp4/IndexReader.cpp
@@ -60,7 +60,7 @@ bool IndexReader::parseIndex(block_t *p_block, BaseRepresentation *rep)
if(!uuid_box)
return false;
- SegmentTimeline *timelineadd = new (std::nothrow) SegmentTimeline(rep->inheritTimescale());
+ SegmentTimeline *timelineadd = new (std::nothrow) SegmentTimeline(NULL);
if (timelineadd)
{
const MP4_Box_data_tfrf_t *p_tfrfdata = uuid_box->data.p_tfrf;
diff --git a/modules/demux/smooth/playlist/Manifest.cpp b/modules/demux/smooth/playlist/Manifest.cpp
index 5538bc644f..c967feb29f 100644
--- a/modules/demux/smooth/playlist/Manifest.cpp
+++ b/modules/demux/smooth/playlist/Manifest.cpp
@@ -29,10 +29,10 @@
using namespace smooth::playlist;
Manifest::Manifest (vlc_object_t *p_object) :
- AbstractPlaylist(p_object), TimescaleAble()
+ AbstractPlaylist(p_object)
{
minUpdatePeriod.Set( VLC_TICK_FROM_SEC(5) );
- setTimescale( 10000000 ); // 100ns
+ addAttribute(new TimescaleAttr(Timescale(10000000))); // 100ns
b_live = false;
}
diff --git a/modules/demux/smooth/playlist/Manifest.hpp b/modules/demux/smooth/playlist/Manifest.hpp
index 94facfd503..b0e0e6a3f7 100644
--- a/modules/demux/smooth/playlist/Manifest.hpp
+++ b/modules/demux/smooth/playlist/Manifest.hpp
@@ -21,8 +21,6 @@
#define MANIFEST_HPP
#include "../../adaptive/playlist/AbstractPlaylist.hpp"
-#include "../../adaptive/playlist/Inheritables.hpp"
-#include "../../adaptive/Time.hpp"
namespace smooth
{
@@ -30,8 +28,7 @@ namespace smooth
{
using namespace adaptive::playlist;
- class Manifest : public AbstractPlaylist,
- public TimescaleAble
+ class Manifest : public AbstractPlaylist
{
friend class ManifestParser;
diff --git a/modules/demux/smooth/playlist/Parser.cpp b/modules/demux/smooth/playlist/Parser.cpp
index 4ca85add22..08b68188be 100644
--- a/modules/demux/smooth/playlist/Parser.cpp
+++ b/modules/demux/smooth/playlist/Parser.cpp
@@ -52,9 +52,9 @@ ManifestParser::~ManifestParser()
{
}
-static SegmentTimeline *createTimeline(Node *streamIndexNode, uint64_t timescale)
+static SegmentTimeline *createTimeline(Node *streamIndexNode)
{
- SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(timescale);
+ SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(NULL);
if(timeline)
{
std::vector<Node *> chunks = DOMHelper::getElementByTagName(streamIndexNode, "c", true);
@@ -143,7 +143,8 @@ static SegmentTimeline *createTimeline(Node *streamIndexNode, uint64_t timescale
return timeline;
}
-static void ParseQualityLevel(BaseAdaptationSet *adaptSet, Node *qualNode, const std::string &type, unsigned id, unsigned trackid)
+static void ParseQualityLevel(BaseAdaptationSet *adaptSet, Node *qualNode, const std::string &type,
+ unsigned id, unsigned trackid, const Timescale ×cale)
{
Representation *rep = new (std::nothrow) Representation(adaptSet);
if(rep)
@@ -168,7 +169,7 @@ static void ParseQualityLevel(BaseAdaptationSet *adaptSet, Node *qualNode, const
ForgedInitSegment *initSegment = new (std::nothrow)
ForgedInitSegment(rep, type,
- adaptSet->inheritTimescale(),
+ timescale,
adaptSet->getPlaylist()->duration.Get());
if(initSegment)
{
@@ -225,8 +226,12 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
if(streamIndexNode->hasAttribute("Name"))
adaptSet->description.Set(streamIndexNode->getAttributeValue("Name"));
+ Timescale timescale(10000000);
if(streamIndexNode->hasAttribute("TimeScale"))
- adaptSet->setTimescale(Integer<uint64_t>(streamIndexNode->getAttributeValue("TimeScale")));
+ {
+ timescale = Timescale(Integer<uint64_t>(streamIndexNode->getAttributeValue("TimeScale")));
+ adaptSet->addAttribute(new TimescaleAttr(timescale));
+ }
const std::string url = streamIndexNode->getAttributeValue("Url");
if(!url.empty())
@@ -236,8 +241,8 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
if(templ)
{
templ->setSourceUrl(url);
- SegmentTimeline *timeline = createTimeline(streamIndexNode, adaptSet->inheritTimescale());
- templ->setSegmentTimeline(timeline);
+ SegmentTimeline *timeline = createTimeline(streamIndexNode);
+ templ->addAttribute(timeline);
adaptSet->setSegmentTemplate(templ);
}
@@ -246,7 +251,7 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
std::vector<Node *> qualLevels = DOMHelper::getElementByTagName(streamIndexNode, "QualityLevel", true);
std::vector<Node *>::const_iterator it;
for(it = qualLevels.begin(); it != qualLevels.end(); ++it)
- ParseQualityLevel(adaptSet, *it, type, nextid++, id);
+ ParseQualityLevel(adaptSet, *it, type, nextid++, id, timescale);
}
if(!adaptSet->getRepresentations().empty())
period->addAdaptationSet(adaptSet);
@@ -263,19 +268,24 @@ Manifest * ManifestParser::parse()
manifest->setPlaylistUrl(Helper::getDirectoryPath(playlisturl).append("/"));
+ Timescale timescale(10000000);
+
if(root->hasAttribute("TimeScale"))
- manifest->setTimescale(Integer<uint64_t>(root->getAttributeValue("TimeScale")));
+ {
+ timescale = Timescale(Integer<uint64_t>(root->getAttributeValue("TimeScale")));
+ manifest->addAttribute(new TimescaleAttr(timescale));
+ }
if(root->hasAttribute("Duration"))
{
stime_t time = Integer<stime_t>(root->getAttributeValue("Duration"));
- manifest->duration.Set(manifest->getTimescale().ToTime(time));
+ manifest->duration.Set(timescale.ToTime(time));
}
if(root->hasAttribute("DVRWindowLength"))
{
stime_t time = Integer<stime_t>(root->getAttributeValue("DVRWindowLength"));
- manifest->timeShiftBufferDepth.Set(manifest->getTimescale().ToTime(time));
+ manifest->timeShiftBufferDepth.Set(timescale.ToTime(time));
}
if(root->hasAttribute("IsLive") && root->getAttributeValue("IsLive") == "TRUE")
@@ -285,7 +295,6 @@ Manifest * ManifestParser::parse()
BasePeriod *period = new (std::nothrow) BasePeriod(manifest);
if(period)
{
- period->setTimescale(manifest->getTimescale());
period->duration.Set(manifest->duration.Get());
unsigned nextid = 1;
std::vector<Node *> streamIndexes = DOMHelper::getElementByTagName(root, "StreamIndex", true);
More information about the vlc-commits
mailing list