[vlc-commits] demux: adaptive: inherit template defaults (fix #22047)
Francois Cartegnie
git at videolan.org
Mon Apr 15 18:26:05 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Apr 15 18:20:14 2019 +0200| [7ff23c447d942c4bd4f88bbcd680892d57643b9e] | committer: Francois Cartegnie
demux: adaptive: inherit template defaults (fix #22047)
not the complete and efficient way.
we'll need a better inheritance fix at parsing level.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7ff23c447d942c4bd4f88bbcd680892d57643b9e
---
modules/demux/adaptive/playlist/Inheritables.hpp | 4 +-
.../demux/adaptive/playlist/SegmentInformation.cpp | 26 ++---
.../demux/adaptive/playlist/SegmentInformation.hpp | 1 +
.../demux/adaptive/playlist/SegmentTemplate.cpp | 106 +++++++++++++++++----
modules/demux/adaptive/playlist/SegmentTemplate.h | 10 +-
modules/demux/dash/mpd/IsoffMainParser.cpp | 19 ++--
modules/demux/dash/mpd/Representation.cpp | 5 +-
modules/demux/smooth/playlist/Parser.cpp | 2 +-
modules/demux/smooth/playlist/Representation.cpp | 8 +-
9 files changed, 132 insertions(+), 49 deletions(-)
diff --git a/modules/demux/adaptive/playlist/Inheritables.hpp b/modules/demux/adaptive/playlist/Inheritables.hpp
index a1dc597fdf..833c7478ae 100644
--- a/modules/demux/adaptive/playlist/Inheritables.hpp
+++ b/modules/demux/adaptive/playlist/Inheritables.hpp
@@ -34,9 +34,9 @@ namespace adaptive
{
public:
TimescaleAble( TimescaleAble * = NULL );
- ~TimescaleAble();
+ virtual ~TimescaleAble();
void setParentTimescaleAble( TimescaleAble * );
- Timescale inheritTimescale() const;
+ virtual Timescale inheritTimescale() const;
void setTimescale( const Timescale & );
void setTimescale( uint64_t );
const Timescale & getTimescale() const;
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 8dc6bcf297..09740fd6d8 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -176,7 +176,7 @@ uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const
uint64_t end = 0;
const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
- SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get();
+ const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
if( timeline )
{
start = timeline->minElementNumber();
@@ -206,7 +206,7 @@ uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const
if( i_delay < getPlaylist()->getMinBuffering() )
i_delay = getPlaylist()->getMinBuffering();
- const uint64_t startnumber = mediaSegmentTemplate->startNumber.Get();
+ const uint64_t startnumber = mediaSegmentTemplate->inheritStartNumber();
end = mediaSegmentTemplate->getCurrentLiveTemplateNumber();
const uint64_t count = timescale.ToScaled( i_delay ) / mediaSegmentTemplate->duration.Get();
@@ -283,7 +283,7 @@ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_p
{
/* Check if we don't exceed timeline */
MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]);
- SegmentTimeline *timeline = (templ) ? templ->segmentTimeline.Get() : NULL;
+ const SegmentTimeline *timeline = (templ) ? templ->inheritSegmentTimeline() : NULL;
if(timeline)
{
*pi_newpos = std::max(timeline->minElementNumber(), i_pos);
@@ -294,7 +294,7 @@ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_p
{
*pi_newpos = i_pos;
/* start number */
- *pi_newpos = std::max((uint64_t)templ->startNumber.Get(), i_pos);
+ *pi_newpos = std::max(templ->inheritStartNumber(), i_pos);
}
return seg;
}
@@ -319,8 +319,8 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co
if(size == 1 && retSegments[0]->isTemplate())
{
MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]);
- if(!templ || templ->segmentTimeline.Get() == NULL ||
- templ->segmentTimeline.Get()->maxElementNumber() > pos)
+ const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+ if(!templ || tl == NULL || tl->maxElementNumber() > pos)
return templ;
}
else
@@ -349,7 +349,7 @@ bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret)
{
const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
- SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get();
+ const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
if(timeline)
{
stime_t st = timescale.ToScaled(time);
@@ -362,11 +362,11 @@ bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret)
{
if( getPlaylist()->isLive() )
{
- *ret = getLiveStartSegmentNumber( mediaSegmentTemplate->startNumber.Get() );
+ *ret = getLiveStartSegmentNumber( mediaSegmentTemplate->inheritStartNumber() );
}
else
{
- *ret = mediaSegmentTemplate->startNumber.Get();
+ *ret = mediaSegmentTemplate->inheritStartNumber();
*ret += timescale.ToScaled(time) / duration;
}
return true;
@@ -402,12 +402,12 @@ bool SegmentInformation::getPlaybackTimeDurationBySegmentNumber(uint64_t number,
if( (mediaTemplate = inheritSegmentTemplate()) )
{
const Timescale timescale = mediaTemplate->inheritTimescale();
+ const SegmentTimeline * timeline = mediaTemplate->inheritSegmentTimeline();
stime_t stime, sduration;
- if(mediaTemplate->segmentTimeline.Get())
+ if(timeline)
{
- mediaTemplate->segmentTimeline.Get()->
- getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration);
+ timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration);
}
else
{
@@ -473,7 +473,7 @@ void SegmentInformation::mergeWithTimeline(SegmentTimeline *updated)
MediaSegmentTemplate *templ = inheritSegmentTemplate();
if(templ)
{
- SegmentTimeline *timeline = templ->segmentTimeline.Get();
+ SegmentTimeline *timeline = templ->inheritSegmentTimeline();
if(timeline)
timeline->mergeWith(*updated);
}
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index d74764fde7..74633b033b 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -43,6 +43,7 @@ namespace adaptive
public TimescaleAble,
public Unique
{
+ friend class MediaSegmentTemplate;
public:
SegmentInformation( SegmentInformation * = 0 );
explicit SegmentInformation( AbstractPlaylist * );
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
index f1437bbadd..d0aef9f33d 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
@@ -27,6 +27,7 @@
#include "SegmentTimeline.h"
#include "SegmentInformation.hpp"
#include "AbstractPlaylist.hpp"
+#include <limits>
using namespace adaptive::playlist;
@@ -37,12 +38,13 @@ BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) :
MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
- BaseSegmentTemplate( parent ), TimescaleAble( parent )
+ BaseSegmentTemplate( parent ),
+ TimescaleAble( NULL ) /* we don't want auto inherit */
{
debugName = "SegmentTemplate";
classId = Segment::CLASSID_SEGMENT;
- startNumber.Set( 1 );
- segmentTimeline.Set( NULL );
+ startNumber = std::numeric_limits<uint64_t>::max();
+ segmentTimeline = NULL;
initialisationSegment.Set( NULL );
templated = true;
parentSegmentInformation = parent;
@@ -50,15 +52,15 @@ MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) :
MediaSegmentTemplate::~MediaSegmentTemplate()
{
- delete segmentTimeline.Get();
+ delete segmentTimeline;
}
void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, vlc_tick_t prunebarrier)
{
- SegmentTimeline *timeline = segmentTimeline.Get();
- if(timeline && updated->segmentTimeline.Get())
+ SegmentTimeline *timeline = segmentTimeline;
+ if(timeline && updated->segmentTimeline)
{
- timeline->mergeWith(*updated->segmentTimeline.Get());
+ timeline->mergeWith(*updated->segmentTimeline);
if(prunebarrier)
{
const Timescale timescale = timeline->inheritTimescale();
@@ -71,22 +73,77 @@ void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, vlc_tick_t p
void MediaSegmentTemplate::pruneByPlaybackTime(vlc_tick_t time)
{
- if(segmentTimeline.Get())
- return segmentTimeline.Get()->pruneByPlaybackTime(time);
+ if(segmentTimeline)
+ return segmentTimeline->pruneByPlaybackTime(time);
}
size_t MediaSegmentTemplate::pruneBySequenceNumber(uint64_t number)
{
- if(segmentTimeline.Get())
- return segmentTimeline.Get()->pruneBySequenceNumber(number);
+ if(segmentTimeline)
+ return segmentTimeline->pruneBySequenceNumber(number);
return 0;
}
+uint64_t MediaSegmentTemplate::inheritStartNumber() const
+{
+ const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+ : NULL;
+ for( ; ulevel ; ulevel = ulevel->parent )
+ {
+ if( ulevel->mediaSegmentTemplate &&
+ ulevel->mediaSegmentTemplate->startNumber !=
+ std::numeric_limits<uint64_t>::max() )
+ return ulevel->mediaSegmentTemplate->startNumber;
+ }
+ return 1;
+}
+
+Timescale MediaSegmentTemplate::inheritTimescale() const
+{
+ const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+ : NULL;
+ for( ; ulevel ; ulevel = ulevel->parent )
+ {
+ if( ulevel->mediaSegmentTemplate &&
+ ulevel->mediaSegmentTemplate->getTimescale().isValid() )
+ return ulevel->mediaSegmentTemplate->getTimescale();
+ if( ulevel->getTimescale().isValid() )
+ return ulevel->mediaSegmentTemplate->getTimescale();
+ }
+ return Timescale(1);
+}
+
+stime_t MediaSegmentTemplate::inheritDuration() const
+{
+ const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+ : NULL;
+ for( ; ulevel ; ulevel = ulevel->parent )
+ {
+ if( ulevel->mediaSegmentTemplate &&
+ ulevel->mediaSegmentTemplate->duration.Get() > 0 )
+ return ulevel->mediaSegmentTemplate->duration.Get();
+ }
+ return 0;
+}
+
+SegmentTimeline * MediaSegmentTemplate::inheritSegmentTimeline() const
+{
+ const SegmentInformation *ulevel = parentSegmentInformation ? parentSegmentInformation
+ : NULL;
+ for( ; ulevel ; ulevel = ulevel->parent )
+ {
+ if( ulevel->mediaSegmentTemplate &&
+ ulevel->mediaSegmentTemplate->segmentTimeline )
+ return ulevel->mediaSegmentTemplate->segmentTimeline;
+ }
+ return NULL;
+}
+
uint64_t MediaSegmentTemplate::getCurrentLiveTemplateNumber() const
{
- uint64_t number = startNumber.Get();
+ uint64_t number = inheritStartNumber();
/* live streams / templated */
- const stime_t dur = duration.Get();
+ const stime_t dur = inheritDuration();
if(dur)
{
/* compute, based on current time */
@@ -103,16 +160,16 @@ uint64_t MediaSegmentTemplate::getCurrentLiveTemplateNumber() const
stime_t MediaSegmentTemplate::getMinAheadScaledTime(uint64_t number) const
{
- if( segmentTimeline.Get() )
- return segmentTimeline.Get()->getMinAheadScaledTime(number);
+ if( segmentTimeline )
+ return segmentTimeline->getMinAheadScaledTime(number);
uint64_t current = getCurrentLiveTemplateNumber();
- return (current - number) * duration.Get();
+ return (current - number) * inheritDuration();
}
uint64_t MediaSegmentTemplate::getSequenceNumber() const
{
- return startNumber.Get();
+ return inheritStartNumber();
}
void MediaSegmentTemplate::setSourceUrl(const std::string &url)
@@ -120,11 +177,22 @@ void MediaSegmentTemplate::setSourceUrl(const std::string &url)
sourceUrl = Url(Url::Component(url, this));
}
+void MediaSegmentTemplate::setStartNumber( uint64_t v )
+{
+ startNumber = v;
+}
+
+void MediaSegmentTemplate::setSegmentTimeline( SegmentTimeline *v )
+{
+ delete segmentTimeline;
+ segmentTimeline = v;
+}
+
void MediaSegmentTemplate::debug(vlc_object_t *obj, int indent) const
{
Segment::debug(obj, indent);
- if(segmentTimeline.Get())
- segmentTimeline.Get()->debug(obj, indent + 1);
+ if(segmentTimeline)
+ segmentTimeline->debug(obj, indent + 1);
}
InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent ) :
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.h b/modules/demux/adaptive/playlist/SegmentTemplate.h
index b5608e29c0..974bc41f66 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.h
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.h
@@ -50,17 +50,23 @@ namespace adaptive
MediaSegmentTemplate( SegmentInformation * = NULL );
virtual ~MediaSegmentTemplate();
virtual void setSourceUrl( const std::string &url ); /* reimpl */
+ void setStartNumber( uint64_t );
+ void setSegmentTimeline( SegmentTimeline * );
void mergeWith( MediaSegmentTemplate *, vlc_tick_t );
virtual uint64_t getSequenceNumber() const; /* reimpl */
uint64_t getCurrentLiveTemplateNumber() const;
stime_t getMinAheadScaledTime(uint64_t) const;
void pruneByPlaybackTime(vlc_tick_t);
size_t pruneBySequenceNumber(uint64_t);
+ virtual Timescale inheritTimescale() const; /* reimpl */
+ virtual uint64_t inheritStartNumber() const;
+ stime_t inheritDuration() const;
+ SegmentTimeline * inheritSegmentTimeline() const;
virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */
- Property<size_t> startNumber;
- Property<SegmentTimeline *> segmentTimeline;
protected:
+ uint64_t startNumber;
+ SegmentTimeline *segmentTimeline;
SegmentInformation *parentSegmentInformation;
};
diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp
index 1ec3402496..d378c4e548 100644
--- a/modules/demux/dash/mpd/IsoffMainParser.cpp
+++ b/modules/demux/dash/mpd/IsoffMainParser.cpp
@@ -161,17 +161,20 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root)
size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformation *info)
{
size_t total = 0;
- if (templateNode == NULL || !templateNode->hasAttribute("media"))
+ if (templateNode == NULL)
return total;
- std::string mediaurl = templateNode->getAttributeValue("media");
+ std::string mediaurl;
+ if(templateNode->hasAttribute("media"))
+ mediaurl = templateNode->getAttributeValue("media");
+
MediaSegmentTemplate *mediaTemplate = NULL;
- if(mediaurl.empty() || !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
+ if( !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) )
return total;
mediaTemplate->setSourceUrl(mediaurl);
if(templateNode->hasAttribute("startNumber"))
- mediaTemplate->startNumber.Set(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
+ mediaTemplate->setStartNumber(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
if(templateNode->hasAttribute("timescale"))
mediaTemplate->setTimescale(Integer<uint64_t>(templateNode->getAttributeValue("timescale")));
@@ -193,7 +196,7 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
info->setSegmentTemplate(mediaTemplate);
- return ++total;
+ return mediaurl.empty() ? ++total : 0;
}
size_t IsoffMainParser::parseSegmentInformation(Node *node, SegmentInformation *info, uint64_t *nextid)
@@ -452,8 +455,8 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
uint64_t number = 0;
if(node->hasAttribute("startNumber"))
number = Integer<uint64_t>(node->getAttributeValue("startNumber"));
- else if(templ->startNumber.Get())
- number = templ->startNumber.Get();
+ else if(templ->inheritStartNumber())
+ number = templ->inheritStartNumber();
SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(templ);
if(timeline)
@@ -483,7 +486,7 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
number += (1 + r);
}
- templ->segmentTimeline.Set(timeline);
+ templ->setSegmentTimeline(timeline);
}
}
diff --git a/modules/demux/dash/mpd/Representation.cpp b/modules/demux/dash/mpd/Representation.cpp
index 0080699dbc..a37d911c2c 100644
--- a/modules/demux/dash/mpd/Representation.cpp
+++ b/modules/demux/dash/mpd/Representation.cpp
@@ -104,9 +104,10 @@ std::string Representation::contextualize(size_t number, const std::string &comp
stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const MediaSegmentTemplate *templ) const
{
stime_t time = 0;
- if(templ->segmentTimeline.Get())
+ const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+ if(tl)
{
- time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
+ time = tl->getScaledPlaybackTimeByElementNumber(index);
}
else if(templ->duration.Get())
{
diff --git a/modules/demux/smooth/playlist/Parser.cpp b/modules/demux/smooth/playlist/Parser.cpp
index 3868125823..fd14bcbd20 100644
--- a/modules/demux/smooth/playlist/Parser.cpp
+++ b/modules/demux/smooth/playlist/Parser.cpp
@@ -237,7 +237,7 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned
{
templ->setSourceUrl(url);
SegmentTimeline *timeline = createTimeline(streamIndexNode, period->inheritTimescale());
- templ->segmentTimeline.Set(timeline);
+ templ->setSegmentTimeline(timeline);
adaptSet->setSegmentTemplate(templ);
}
diff --git a/modules/demux/smooth/playlist/Representation.cpp b/modules/demux/smooth/playlist/Representation.cpp
index 58234cb146..98ba66816e 100644
--- a/modules/demux/smooth/playlist/Representation.cpp
+++ b/modules/demux/smooth/playlist/Representation.cpp
@@ -61,8 +61,12 @@ std::string Representation::contextualize(size_t number, const std::string &comp
{
std::stringstream ss;
ss.imbue(std::locale("C"));
- ss << templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(number);
- ret.replace(pos, std::string("{start_time}").length(), ss.str());
+ const SegmentTimeline *tl = templ->inheritSegmentTimeline();
+ if(tl)
+ {
+ ss << tl->getScaledPlaybackTimeByElementNumber(number);
+ ret.replace(pos, std::string("{start_time}").length(), ss.str());
+ }
}
}
More information about the vlc-commits
mailing list