vlc | branch: master | Francois Cartegnie <[email protected]> | 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()); + } } } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
