diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am index 0d6e23ce662fb34527c7ce8f0abc2285dfa9c460..d87639d6ad4b451071236c79b7a3a3900603a9f0 100644 --- a/modules/demux/Makefile.am +++ b/modules/demux/Makefile.am @@ -315,10 +315,10 @@ libadaptive_plugin_la_SOURCES = \ demux/adaptive/playlist/Segment.h \ demux/adaptive/playlist/SegmentBase.cpp \ demux/adaptive/playlist/SegmentBase.h \ + demux/adaptive/playlist/SegmentBaseType.cpp \ + demux/adaptive/playlist/SegmentBaseType.hpp \ demux/adaptive/playlist/SegmentChunk.cpp \ demux/adaptive/playlist/SegmentChunk.hpp \ - demux/adaptive/playlist/SegmentInfoCommon.cpp \ - demux/adaptive/playlist/SegmentInfoCommon.h \ demux/adaptive/playlist/SegmentList.cpp \ demux/adaptive/playlist/SegmentList.h \ demux/adaptive/playlist/SegmentTimeline.cpp \ diff --git a/modules/demux/adaptive/logic/BufferingLogic.cpp b/modules/demux/adaptive/logic/BufferingLogic.cpp index d4073dd976901f6bcf48f1f1b02a9aec62f1115c..5829a025b06c03a953e77f47f782bee5afd50350 100644 --- a/modules/demux/adaptive/logic/BufferingLogic.cpp +++ b/modules/demux/adaptive/logic/BufferingLogic.cpp @@ -80,24 +80,8 @@ uint64_t DefaultBufferingLogic::getStartSegmentNumber(BaseRepresentation *rep) c if(rep->getPlaylist()->isLive()) return getLiveStartSegmentNumber(rep); - const MediaSegmentTemplate *segmentTemplate = rep->inheritSegmentTemplate(); - if(segmentTemplate) - { - const SegmentTimeline *timeline = segmentTemplate->inheritSegmentTimeline(); - if(timeline) - return timeline->minElementNumber(); - return segmentTemplate->inheritStartNumber(); - } - - const SegmentList *list = rep->inheritSegmentList(); - if(list) - return list->getStartIndex(); - - const SegmentBase *base = rep->inheritSegmentBase(); - if(base) - return base->getSequenceNumber(); - - return 0; + const AbstractSegmentBaseType *profile = rep->inheritSegmentProfile(); + return profile ? profile->getStartSegmentNumber() : 0; } vlc_tick_t DefaultBufferingLogic::getMinBuffering(const AbstractPlaylist *p) const @@ -154,7 +138,7 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re SegmentList *segmentList = rep->inheritSegmentList(); SegmentBase *segmentBase = rep->inheritSegmentBase(); - MediaSegmentTemplate *mediaSegmentTemplate = rep->inheritSegmentTemplate(); + SegmentTemplate *mediaSegmentTemplate = rep->inheritSegmentTemplate(); if(mediaSegmentTemplate) { uint64_t start = 0; @@ -347,8 +331,8 @@ uint64_t DefaultBufferingLogic::getLiveStartSegmentNumber(BaseRepresentation *re const stime_t bufferingstart = back->startTime.Get() + back->duration.Get() - timescale.ToScaled(i_buffering); - uint64_t start; - if(!SegmentInfoCommon::getSegmentNumberByScaledTime(list, bufferingstart, &start)) + uint64_t start = AbstractSegmentBaseType::findSegmentNumberByScaledTime(list, bufferingstart); + if(start == std::numeric_limits<uint64_t>::max()) return list.front()->getSequenceNumber(); if(segmentBase->getSequenceNumber() + SAFETY_BUFFERING_EDGE_OFFSET <= start) diff --git a/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp b/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp index 01fb3c35923755715f49a151ac611e4add1b74f2..7afa7e9c794a7e33002276778ce008e522c22550 100644 --- a/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp +++ b/modules/demux/adaptive/playlist/BaseAdaptationSet.cpp @@ -137,6 +137,9 @@ void BaseAdaptationSet::debug(vlc_object_t *obj, int indent) const text.append("BaseAdaptationSet "); text.append(id.str()); msg_Dbg(obj, "%s", text.c_str()); + const AbstractSegmentBaseType *profile = getProfile(); + if(profile) + profile->debug(obj, indent + 1); std::vector<BaseRepresentation *>::const_iterator k; for(k = representations.begin(); k != representations.end(); ++k) (*k)->debug(obj, indent + 1); diff --git a/modules/demux/adaptive/playlist/BasePeriod.cpp b/modules/demux/adaptive/playlist/BasePeriod.cpp index 94295ff51da8c1a8390e7b3ea2f9e7ebd97ecf3d..16229771e2ad9cc7d4964e08e72cce3ef10cb670 100644 --- a/modules/demux/adaptive/playlist/BasePeriod.cpp +++ b/modules/demux/adaptive/playlist/BasePeriod.cpp @@ -28,6 +28,7 @@ #include "BasePeriod.h" #include "AbstractPlaylist.hpp" +#include "SegmentBaseType.hpp" #include "../Streams.hpp" #include <vlc_common.h> @@ -90,6 +91,9 @@ void BasePeriod::debug(vlc_object_t *obj, int indent) const std::string text(indent, ' '); text.append("Period"); msg_Dbg(obj, "%s", text.c_str()); + const AbstractSegmentBaseType *profile = getProfile(); + if(profile) + profile->debug(obj, indent + 1); std::vector<BaseAdaptationSet *>::const_iterator k; for(k = adaptationSets.begin(); k != adaptationSets.end(); ++k) (*k)->debug(obj, indent + 1); diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.cpp b/modules/demux/adaptive/playlist/BaseRepresentation.cpp index c0c353b2f6513bdd8fea3156e75aa4ab364cefcc..e0529705e823a4fe748b060fc917cb819d2973e6 100644 --- a/modules/demux/adaptive/playlist/BaseRepresentation.cpp +++ b/modules/demux/adaptive/playlist/BaseRepresentation.cpp @@ -122,34 +122,13 @@ void BaseRepresentation::pruneByPlaybackTime(vlc_tick_t time) vlc_tick_t BaseRepresentation::getMinAheadTime(uint64_t curnum) const { - std::vector<Segment *> seglist; - getMediaSegments(seglist); + AbstractSegmentBaseType *profile = inheritSegmentTemplate(); + if(!profile) + profile = inheritSegmentList(); + if(!profile) + profile = inheritSegmentBase(); - if(seglist.size() == 1 && seglist.front()->isTemplate()) - { - const MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate *>(seglist.front()); - if(templ) - { - const Timescale timescale = templ->inheritTimescale(); - stime_t i_length = templ->getMinAheadScaledTime(curnum); - return timescale.ToTime(i_length); - } - - /* should not happen */ - return VLC_TICK_FROM_SEC(1); - } - - vlc_tick_t minTime = 0; - const Timescale timescale = inheritTimescale(); - std::vector<Segment *>::const_iterator it; - for(it = seglist.begin(); it != seglist.end(); ++it) - { - const Segment *seg = *it; - if(seg->getSequenceNumber() > curnum) - minTime += timescale.ToTime(seg->duration.Get()); - } - - return minTime; + return profile ? profile->getMinAheadTime(curnum) : 0; } void BaseRepresentation::debug(vlc_object_t *obj, int indent) const @@ -166,20 +145,13 @@ void BaseRepresentation::debug(vlc_object_t *obj, int indent) const text.append("]"); } msg_Dbg(obj, "%s", text.c_str()); - const ISegment *seg; - if((seg = getInitSegment())) - seg->debug(obj, indent + 1); - if((seg = getIndexSegment())) - seg->debug(obj, indent + 1); - std::vector<Segment *> list; - getMediaSegments(list); - std::vector<Segment *>::const_iterator l; - for(l = list.begin(); l != list.end(); ++l) - (*l)->debug(obj, indent + 1); + const AbstractSegmentBaseType *profile = getProfile(); + if(profile) + profile->debug(obj, indent + 1); } std::string BaseRepresentation::contextualize(size_t, const std::string &component, - const BaseSegmentTemplate *) const + const SegmentTemplate *) const { return component; } @@ -205,64 +177,8 @@ uint64_t BaseRepresentation::translateSegmentNumber(uint64_t num, const BaseRepr bool BaseRepresentation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const { - MediaSegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate(); - if( mediaSegmentTemplate ) - { - const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline(); - if(timeline) - { - const Timescale timescale = timeline->getTimescale().isValid() - ? timeline->getTimescale() - : mediaSegmentTemplate->inheritTimescale(); - stime_t st = timescale.ToScaled(time); - *ret = timeline->getElementNumberByScaledPlaybackTime(st); - return true; - } - - const stime_t duration = mediaSegmentTemplate->duration.Get(); - if( duration ) - { - if( getPlaylist()->isLive() ) - { - vlc_tick_t now = vlc_tick_from_sec(::time(NULL)); - if(getPlaylist()->availabilityStartTime.Get()) - { - if(time >= getPlaylist()->availabilityStartTime.Get() && time < now) - *ret = mediaSegmentTemplate->getLiveTemplateNumber(time, true); - else if(now - getPlaylist()->availabilityStartTime.Get() > time) - *ret = mediaSegmentTemplate->getLiveTemplateNumber(time, false); - } - else return false; - } - else - { - const Timescale timescale = mediaSegmentTemplate->inheritTimescale(); - *ret = mediaSegmentTemplate->inheritStartNumber(); - *ret += timescale.ToScaled(time) / duration; - } - return true; - } - } - - SegmentList *segmentList = inheritSegmentList(); - if ( segmentList && !segmentList->getSegments().empty() ) - { - const Timescale timescale = segmentList->inheritTimescale(); - stime_t st = timescale.ToScaled(time); - return segmentList->getSegmentNumberByScaledTime(st, ret); - } - - SegmentBase *segmentBase = inheritSegmentBase(); - if( segmentBase ) - { - const Timescale timescale = inheritTimescale(); - stime_t st = timescale.ToScaled(time); - *ret = 0; - const std::vector<Segment *> &list = segmentBase->subSegments(); - return SegmentInfoCommon::getSegmentNumberByScaledTime(list, st, ret); - } - - return false; + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + return profile && profile->getSegmentNumberByTime(time, ret); } bool BaseRepresentation::getPlaybackTimeDurationBySegmentNumber(uint64_t number, @@ -271,56 +187,15 @@ bool BaseRepresentation::getPlaybackTimeDurationBySegmentNumber(uint64_t number, if(number == std::numeric_limits<uint64_t>::max()) return false; - MediaSegmentTemplate *mediaTemplate = inheritSegmentTemplate(); - if( mediaTemplate ) - { - const Timescale timescale = mediaTemplate->inheritTimescale(); - const SegmentTimeline * timeline = mediaTemplate->inheritSegmentTimeline(); - - stime_t stime, sduration; - if(timeline) - { - if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration)) - return false; - } - else - { - uint64_t startNumber = mediaTemplate->inheritStartNumber(); - if(number < startNumber) - return false; - sduration = mediaTemplate->inheritDuration(); - stime = (number - startNumber) * sduration; - } - *time = timescale.ToTime(stime); - *duration = timescale.ToTime(sduration); - return true; - } - - SegmentList *segList = inheritSegmentList(); - if ( segList ) - { - return segList->getPlaybackTimeDurationBySegmentNumber(number, time, duration); - } - else - { - const Timescale timescale = inheritTimescale(); - const ISegment *segment = getMediaSegment(number); - if( segment ) - { - *time = timescale.ToTime(segment->startTime.Get()); - *duration = timescale.ToTime(segment->duration.Get()); - return true; - } - } - - return false; + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + return profile && profile->getPlaybackTimeDurationBySegmentNumber(number, time, duration); } bool BaseRepresentation::getMediaPlaybackRange(vlc_tick_t *rangeBegin, vlc_tick_t *rangeEnd, vlc_tick_t *rangeLength) const { - MediaSegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate(); + SegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate(); if( mediaSegmentTemplate ) { const Timescale timescale = mediaSegmentTemplate->inheritTimescale(); diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.h b/modules/demux/adaptive/playlist/BaseRepresentation.h index 414e10920e308e434bd39cde6b4c2d09739f374f..fe86734e4fcb73e76115ba9e3520f4e6d87df927 100644 --- a/modules/demux/adaptive/playlist/BaseRepresentation.h +++ b/modules/demux/adaptive/playlist/BaseRepresentation.h @@ -40,7 +40,7 @@ namespace adaptive { class BaseAdaptationSet; class AbstractPlaylist; - class BaseSegmentTemplate; + class SegmentTemplateSegment; class BaseRepresentation : public CommonAttributesElements, public SegmentInformation @@ -74,7 +74,7 @@ namespace adaptive /* for segment templates */ virtual std::string contextualize(size_t, const std::string &, - const BaseSegmentTemplate *) const; + const SegmentTemplate *) const; static bool bwCompare(const BaseRepresentation *a, const BaseRepresentation *b); diff --git a/modules/demux/adaptive/playlist/Segment.cpp b/modules/demux/adaptive/playlist/Segment.cpp index 0bbe7c101bcb455d62d479e0d5ebb509ba7f66b5..090fb9ac1bd65d9efee2a1331761fb7fbb929abf 100644 --- a/modules/demux/adaptive/playlist/Segment.cpp +++ b/modules/demux/adaptive/playlist/Segment.cpp @@ -283,14 +283,4 @@ SubSegment::SubSegment(Segment *main, size_t start, size_t end) : classId = CLASSID_SUBSEGMENT; } -SegmentChunk* SubSegment::createChunk(AbstractChunkSource *source, BaseRepresentation *rep) -{ - /* act as factory */ - return new (std::nothrow) SegmentChunk(source, rep); -} - -Url SubSegment::getUrlSegment() const -{ - return getParentUrlSegment(); -} diff --git a/modules/demux/adaptive/playlist/Segment.h b/modules/demux/adaptive/playlist/Segment.h index 11a1e8652c90f8de0acada9410ba451f6c3ec42d..0c6258b919a9c9c55b7e1ddaebf43d68648101cb 100644 --- a/modules/demux/adaptive/playlist/Segment.h +++ b/modules/demux/adaptive/playlist/Segment.h @@ -47,6 +47,7 @@ namespace adaptive { class BaseRepresentation; class SubSegment; + class Segment; class SegmentChunk; using namespace http; @@ -131,8 +132,6 @@ namespace adaptive { public: SubSegment(Segment *, size_t start, size_t end); - virtual SegmentChunk* createChunk(AbstractChunkSource *, BaseRepresentation *); /* impl */ - virtual Url getUrlSegment() const; /* impl */ static const int CLASSID_SUBSEGMENT = 4; }; } diff --git a/modules/demux/adaptive/playlist/SegmentBase.cpp b/modules/demux/adaptive/playlist/SegmentBase.cpp index 62f224daa4f7ffc5aee71142805ebab91d551513..16f3ff1c1faeaabc1cd08e33c3ee3c3a4679f2b1 100644 --- a/modules/demux/adaptive/playlist/SegmentBase.cpp +++ b/modules/demux/adaptive/playlist/SegmentBase.cpp @@ -26,13 +26,107 @@ #endif #include "SegmentBase.h" +#include "SegmentInformation.hpp" + +#include <limits> using namespace adaptive::playlist; -SegmentBase::SegmentBase(ICanonicalUrl *parent) : - Segment(parent) +SegmentBase::SegmentBase(SegmentInformation *parent) : + Segment(parent), AbstractSegmentBaseType(parent) { + this->parent = parent; } SegmentBase::~SegmentBase () { } + +vlc_tick_t SegmentBase::getMinAheadTime(uint64_t curnum) const +{ + const std::vector<Segment *> &segments = subSegments(); + + vlc_tick_t minTime = 0; + const Timescale timescale = inheritTimescale(); + std::vector<Segment *>::const_iterator it; + for(it = segments.begin(); it != segments.end(); ++it) + { + const Segment *seg = *it; + if(seg->getSequenceNumber() > curnum) + minTime += timescale.ToTime(seg->duration.Get()); + } + return minTime; +} + +Segment * SegmentBase::getMediaSegment(uint64_t pos) const +{ + std::vector<Segment *>::const_iterator it; + for(it = subsegments.begin(); it != subsegments.end(); ++it) + { + Segment *seg = *it; + if(seg->getSequenceNumber() >= pos) + { + if(seg->getSequenceNumber() == pos) + return seg; + else + return NULL; + } + } + return NULL; +} + +Segment * SegmentBase::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos, + bool *pb_gap) const +{ + std::vector<Segment *>::const_iterator it; + for(it = subsegments.begin(); it != subsegments.end(); ++it) + { + Segment *seg = *it; + if(seg->getSequenceNumber() >= i_pos) + { + *pi_newpos = seg->getSequenceNumber(); + *pb_gap = (*pi_newpos != i_pos); + return seg; + } + } + *pb_gap = false; + *pi_newpos = i_pos; + return NULL; +} + +uint64_t SegmentBase::getStartSegmentNumber() const +{ + return subsegments.empty() ? 0 : subsegments.front()->getSequenceNumber(); +} + +bool SegmentBase::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const +{ + const Timescale timescale = inheritTimescale(); + if(!timescale.isValid()) + return false; + stime_t st = timescale.ToScaled(time); + *ret = AbstractSegmentBaseType::findSegmentNumberByScaledTime(subsegments, st); + return *ret != std::numeric_limits<uint64_t>::max(); +} + +bool SegmentBase::getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, + vlc_tick_t *dur) const +{ + const Timescale timescale = inheritTimescale(); + const ISegment *segment = getMediaSegment(number); + if( segment ) + { + *time = timescale.ToTime(segment->startTime.Get()); + *dur = timescale.ToTime(segment->duration.Get()); + return true; + } + return false; +} + +void SegmentBase::debug(vlc_object_t *obj, int indent) const +{ + AbstractSegmentBaseType::debug(obj, indent); + std::vector<Segment *>::const_iterator it; + for(it = subsegments.begin(); it != subsegments.end(); ++it) + (*it)->debug(obj, indent); +} diff --git a/modules/demux/adaptive/playlist/SegmentBase.h b/modules/demux/adaptive/playlist/SegmentBase.h index 4297b28be63b133c7df36f04608b3cd3ba548ee6..20e410178dfb20af88e5c294106220ba6143f536 100644 --- a/modules/demux/adaptive/playlist/SegmentBase.h +++ b/modules/demux/adaptive/playlist/SegmentBase.h @@ -26,21 +26,36 @@ #define SEGMENTBASE_H_ #include "Segment.h" -#include "SegmentInfoCommon.h" +#include "SegmentBaseType.hpp" #include "../tools/Properties.hpp" namespace adaptive { namespace playlist { + class SegmentInformation; + /* SegmentBase can contain only one segment */ class SegmentBase : public Segment, - public Initializable<InitSegment>, - public Indexable<IndexSegment> + public AbstractSegmentBaseType { public: - SegmentBase (ICanonicalUrl *); + SegmentBase (SegmentInformation * = NULL); virtual ~SegmentBase (); + + virtual vlc_tick_t getMinAheadTime(uint64_t curnum) const; /* impl */ + virtual Segment *getMediaSegment(uint64_t number) const; /* impl */ + virtual Segment *getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */ + virtual uint64_t getStartSegmentNumber() const; /* impl */ + + virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */ + virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */ + + virtual void debug(vlc_object_t *,int = 0) const; /* reimpl */ + + protected: + SegmentInformation *parent; }; } } diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.cpp b/modules/demux/adaptive/playlist/SegmentBaseType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..defc4910419e64e3ca39d9645ea4e777ed83f3aa --- /dev/null +++ b/modules/demux/adaptive/playlist/SegmentBaseType.cpp @@ -0,0 +1,200 @@ +/* + * SegmentBaseType.cpp + ***************************************************************************** + * Copyright (C) 2020 VideoLabs, VideoLAN and VLC Authors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "SegmentBaseType.hpp" +#include "SegmentInformation.hpp" +#include "SegmentTemplate.h" +#include "SegmentTimeline.h" + +#include <limits> + +using namespace adaptive::playlist; + +Segment * AbstractSegmentBaseType::findSegmentByScaledTime(const std::vector<Segment *> &segments, + stime_t time) +{ + if(segments.empty() || (segments.size() > 1 && segments[1]->startTime.Get() == 0) ) + return NULL; + + Segment *ret = NULL; + std::vector<Segment *>::const_iterator it = segments.begin(); + while(it != segments.end()) + { + Segment *seg = *it; + if(seg->startTime.Get() > time) + { + if(it == segments.begin()) + return NULL; + else + break; + } + + ret = seg; + it++; + } + + return ret; +} + +uint64_t AbstractSegmentBaseType::findSegmentNumberByScaledTime(const std::vector<Segment *> &segments, + stime_t time) +{ + Segment *s = findSegmentByScaledTime(segments, time); + if(!s) + return std::numeric_limits<uint64_t>::max(); + return s->getSequenceNumber(); +} + +AbstractSegmentBaseType::AbstractSegmentBaseType(SegmentInformation *parent) + : TimescaleAble(parent) +{ + this->parent = parent; +} + +AbstractSegmentBaseType::~AbstractSegmentBaseType() +{ +} + +InitSegment *AbstractSegmentBaseType::getInitSegment() const +{ + return initialisationSegment.Get(); +} + +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()) + initialisationSegment.Get()->debug(obj, indent); + if(indexSegment.Get()) + indexSegment.Get()->debug(obj, indent); +} + +AbstractMultipleSegmentBaseType::AbstractMultipleSegmentBaseType(SegmentInformation *parent) + : AbstractSegmentBaseType(parent) +{ + 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); +} diff --git a/modules/demux/adaptive/playlist/SegmentBaseType.hpp b/modules/demux/adaptive/playlist/SegmentBaseType.hpp new file mode 100644 index 0000000000000000000000000000000000000000..89432bcd41984d928e06bc301d82450c06dd3563 --- /dev/null +++ b/modules/demux/adaptive/playlist/SegmentBaseType.hpp @@ -0,0 +1,91 @@ +/* + * SegmentBaseType.hpp + ***************************************************************************** + * Copyright (C) 2020 VideoLabs, VideoLAN and VLC Authors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ +#ifndef SEGMENTBASETYPE_H_ +#define SEGMENTBASETYPE_H_ + +#include "Segment.h" +#include "Inheritables.hpp" +#include "Templates.hpp" +#include "../tools/Properties.hpp" + +namespace adaptive +{ + namespace playlist + { + class SegmentInformation; + class SegmentTimeline; + + class AbstractSegmentBaseType : public Initializable<InitSegment>, + public Indexable<IndexSegment>, + public TimescaleAble + { + public: + AbstractSegmentBaseType( SegmentInformation * ); + virtual ~AbstractSegmentBaseType(); + + virtual vlc_tick_t getMinAheadTime(uint64_t) const = 0; + virtual Segment *getMediaSegment(uint64_t pos) const = 0; + virtual InitSegment *getInitSegment() const; + virtual IndexSegment *getIndexSegment() const; + virtual Segment *getNextMediaSegment(uint64_t, uint64_t *, bool *) const = 0; + virtual uint64_t getStartSegmentNumber() const = 0; + + virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const = 0; + 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; + }; + + class AbstractMultipleSegmentBaseType : public AbstractSegmentBaseType + { + public: + AbstractMultipleSegmentBaseType( SegmentInformation * ); + 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; + + }; + } +} + +#endif /* SEGMENTBASETYPE_H_ */ diff --git a/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp b/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp deleted file mode 100644 index f8c00708032dcffcb22506479cf7489ba8e2a606..0000000000000000000000000000000000000000 --- a/modules/demux/adaptive/playlist/SegmentInfoCommon.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/***************************************************************************** - * SegmentInfoCommon.cpp: Implement the common part for both SegmentInfoDefault - * and SegmentInfo - ***************************************************************************** - * Copyright (C) 1998-2007 VLC authors and VideoLAN - * - * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - *****************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "SegmentInfoCommon.h" - -using namespace adaptive::playlist; - -SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) : - ICanonicalUrl( parent ), - startIndex( 0 ) -{ - duration.Set(0); -} - -SegmentInfoCommon::~SegmentInfoCommon() -{ -} - -int SegmentInfoCommon::getStartIndex() const -{ - return this->startIndex; -} - -void SegmentInfoCommon::setStartIndex(int startIndex) -{ - if ( startIndex >= 0 ) - this->startIndex = startIndex; -} - -void SegmentInfoCommon::appendBaseURL(const std::string &url) -{ - this->baseURLs.push_back( url ); -} - -Url SegmentInfoCommon::getUrlSegment() const -{ - Url ret = getParentUrlSegment(); - if (!baseURLs.empty()) - ret.append(baseURLs.front()); - return ret; -} - -bool SegmentInfoCommon::getSegmentNumberByScaledTime(const std::vector<Segment *> &segments, - stime_t time, uint64_t *ret) -{ - if(segments.empty() || (segments.size() > 1 && segments[1]->startTime.Get() == 0) ) - return false; - - *ret = 0; - - std::vector<Segment *>::const_iterator it = segments.begin(); - while(it != segments.end()) - { - const Segment *seg = *it; - if(seg->startTime.Get() > time) - { - if(it == segments.begin()) - return false; - else - break; - } - - *ret = seg->getSequenceNumber(); - it++; - } - - return true; -} diff --git a/modules/demux/adaptive/playlist/SegmentInfoCommon.h b/modules/demux/adaptive/playlist/SegmentInfoCommon.h deleted file mode 100644 index 0498a4b75f4f17246102486218363269367b633c..0000000000000000000000000000000000000000 --- a/modules/demux/adaptive/playlist/SegmentInfoCommon.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** - * SegmentInfoCommon.h: Implement the common part for both SegmentInfoDefault - * and SegmentInfo - ***************************************************************************** - * Copyright (C) 1998-2007 VLC authors and VideoLAN - * - * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - *****************************************************************************/ - -#ifndef SEGMENTINFOCOMMON_H -#define SEGMENTINFOCOMMON_H - -#include <string> -#include <list> -#include "Inheritables.hpp" -#include "Templates.hpp" -#include "Segment.h" -#include "ICanonicalUrl.hpp" -#include "../tools/Properties.hpp" - -namespace adaptive -{ - namespace playlist - { - class Segment; - - class SegmentInfoCommon : public ICanonicalUrl, - public Initializable<InitSegment>, - public Indexable<IndexSegment> - { - public: - SegmentInfoCommon( ICanonicalUrl *parent = NULL ); - virtual ~SegmentInfoCommon(); - int getStartIndex() const; - void setStartIndex( int startIndex ); - void appendBaseURL( const std::string& url ); - virtual Url getUrlSegment() const; /* impl */ - Property<stime_t> duration; - static bool getSegmentNumberByScaledTime(const std::vector<Segment *> &, - stime_t, uint64_t *); - - private: - int startIndex; - std::list<std::string> baseURLs; - }; - } -} - -#endif // SEGMENTINFOCOMMON_H diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp index 6867529924fb08b20dd8d0e5a4dd728ebe467623..e046d60f5753c1ec73ebefbdb36cfb0fca4f1e89 100644 --- a/modules/demux/adaptive/playlist/SegmentInformation.cpp +++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp @@ -81,7 +81,7 @@ std::size_t SegmentInformation::getMediaSegments(std::vector<Segment *> &retSegm { if( mediaSegmentTemplate ) { - retSegments.push_back( mediaSegmentTemplate ); + retSegments.push_back( mediaSegmentTemplate->getMediaSegment(0) ); } else if ( segmentList && !segmentList->getSegments().empty() ) { @@ -100,144 +100,49 @@ std::size_t SegmentInformation::getMediaSegments(std::vector<Segment *> &retSegm return retSegments.size(); } +const AbstractSegmentBaseType * SegmentInformation::inheritSegmentProfile() const +{ + const AbstractSegmentBaseType *profile = inheritSegmentTemplate(); + if(!profile) + profile = inheritSegmentList(); + if(!profile) + profile = inheritSegmentBase(); + return profile; +} + + /* Returns wanted segment, or next in sequence if not found */ Segment * SegmentInformation::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos, bool *pb_gap) const { - *pb_gap = false; - *pi_newpos = i_pos; - - std::vector<Segment *> retSegments; - const size_t size = getMediaSegments( retSegments ); - if( size ) - { - std::vector<Segment *>::const_iterator it; - for(it = retSegments.begin(); it != retSegments.end(); ++it) - { - Segment *seg = *it; - if(seg->isTemplate()) /* we don't care about seq number */ - { - /* Check if we don't exceed timeline */ - MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]); - const SegmentTimeline *timeline = (templ) ? templ->inheritSegmentTimeline() : NULL; - if(timeline) - { - *pi_newpos = std::max(timeline->minElementNumber(), i_pos); - if(timeline->maxElementNumber() < i_pos) - return NULL; - } - else - { - /* check template upper bound */ - if(!getPlaylist()->isLive()) - { - const Timescale timescale = templ->inheritTimescale(); - const stime_t segmentduration = templ->inheritDuration(); - vlc_tick_t totalduration = getPeriodDuration(); - if(totalduration == 0) - totalduration = getPlaylist()->duration.Get(); - if(totalduration && segmentduration) - { - uint64_t endnum = templ->inheritStartNumber() + - (timescale.ToScaled(totalduration) + segmentduration - 1) / segmentduration; - if(i_pos >= endnum) - { - *pi_newpos = i_pos; - return NULL; - } - } - } - *pi_newpos = i_pos; - /* start number */ - *pi_newpos = std::max(templ->inheritStartNumber(), i_pos); - } - return seg; - } - else if(seg->getSequenceNumber() >= i_pos) - { - *pi_newpos = seg->getSequenceNumber(); - *pb_gap = (*pi_newpos != i_pos); - return seg; - } - } - } - - return NULL; + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + if(!profile) + return NULL; + return profile->getNextMediaSegment(i_pos, pi_newpos, pb_gap); } InitSegment * SegmentInformation::getInitSegment() const { - if( segmentBase && segmentBase->initialisationSegment.Get() ) - { - return segmentBase->initialisationSegment.Get(); - } - else if( segmentList && segmentList->initialisationSegment.Get() ) - { - return segmentList->initialisationSegment.Get(); - } - else if( mediaSegmentTemplate && mediaSegmentTemplate->initialisationSegment.Get() ) - { - return mediaSegmentTemplate->initialisationSegment.Get(); - } - else if( parent ) - { - return parent->getInitSegment(); - } - else return NULL; + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + if(!profile) + return NULL; + return profile->getInitSegment(); } IndexSegment *SegmentInformation::getIndexSegment() const { - if( segmentBase && segmentBase->indexSegment.Get() ) - { - return segmentBase->indexSegment.Get(); - } - else if( segmentList && segmentList->indexSegment.Get() ) - { - return segmentList->indexSegment.Get(); - } - else if( parent ) - { - return parent->getIndexSegment(); - } - else return NULL; + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + if(!profile) + return NULL; + return profile->getIndexSegment(); } Segment * SegmentInformation::getMediaSegment(uint64_t pos) const { - if( mediaSegmentTemplate ) - { - const SegmentTimeline *tl = mediaSegmentTemplate->inheritSegmentTimeline(); - if(tl == NULL || tl->maxElementNumber() > pos) - return mediaSegmentTemplate; - } - else if( segmentList ) - { - return segmentList->getSegmentByNumber( pos ); - } - else if( segmentBase ) - { - /* FIXME add getSegmentByNumber */ - const std::vector<Segment *> &retSegments = segmentBase->subSegments(); - std::vector<Segment *>::const_iterator it; - for(it = retSegments.begin(); it != retSegments.end(); ++it) - { - Segment *seg = *it; - if(seg->getSequenceNumber() >= pos) - { - if(seg->getSequenceNumber() == pos) - return seg; - else - return NULL; - } - } + const AbstractSegmentBaseType *profile = inheritSegmentProfile(); + if(!profile) return NULL; - } - else if( parent ) - { - return parent->getMediaSegment(pos); - } - return NULL; + return profile->getMediaSegment(pos); } SegmentInformation * SegmentInformation::getChildByID(const adaptive::ID &id) @@ -271,17 +176,6 @@ void SegmentInformation::updateWith(SegmentInformation *updated) /* FIXME: handle difference */ } -void SegmentInformation::mergeWithTimeline(SegmentTimeline *updated) -{ - MediaSegmentTemplate *templ = inheritSegmentTemplate(); - if(templ) - { - SegmentTimeline *timeline = templ->inheritSegmentTimeline(); - if(timeline) - timeline->updateWith(*updated); - } -} - void SegmentInformation::pruneByPlaybackTime(vlc_tick_t time) { if(segmentList) @@ -334,6 +228,23 @@ 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; +} + void SegmentInformation::updateSegmentList(SegmentList *list, bool restamp) { if(segmentList && restamp) @@ -355,7 +266,7 @@ void SegmentInformation::setSegmentBase(SegmentBase *base) segmentBase = base; } -void SegmentInformation::setSegmentTemplate(MediaSegmentTemplate *templ) +void SegmentInformation::setSegmentTemplate(SegmentTemplate *templ) { if(mediaSegmentTemplate) { @@ -456,7 +367,7 @@ SegmentList * SegmentInformation::inheritSegmentList() const return NULL; } -MediaSegmentTemplate * SegmentInformation::inheritSegmentTemplate() const +SegmentTemplate * SegmentInformation::inheritSegmentTemplate() const { if(mediaSegmentTemplate) return mediaSegmentTemplate; diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp index 3d3ac27046478d6297184ab40a86fb9b14dbaeec..465999852f19484133a7771c96e85320b873e2f3 100644 --- a/modules/demux/adaptive/playlist/SegmentInformation.hpp +++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp @@ -21,9 +21,10 @@ #define SEGMENTINFORMATION_HPP #include "ICanonicalUrl.hpp" +#include "Inheritables.hpp" +#include "Segment.h" #include "../tools/Properties.hpp" #include "../encryption/CommonEncryption.hpp" -#include "SegmentInfoCommon.h" #include <vlc_common.h> #include <vector> @@ -31,11 +32,12 @@ namespace adaptive { namespace playlist { + class AbstractSegmentBaseType; class SegmentBase; class SegmentList; class SegmentTimeline; class SegmentTemplate; - class MediaSegmentTemplate; + class SegmentTemplate; class AbstractPlaylist; class ISegment; @@ -45,7 +47,8 @@ namespace adaptive public TimescaleAble, public Unique { - friend class MediaSegmentTemplate; + friend class AbstractMultipleSegmentBaseType; + public: SegmentInformation( SegmentInformation * = 0 ); explicit SegmentInformation( AbstractPlaylist * ); @@ -70,7 +73,6 @@ namespace adaptive virtual Segment * getNextMediaSegment(uint64_t, uint64_t *, bool *) const; virtual void updateWith(SegmentInformation *); - virtual void mergeWithTimeline(SegmentTimeline *); /* ! don't use with global merge */ virtual void pruneBySegmentNumber(uint64_t); virtual void pruneByPlaybackTime(vlc_tick_t); void setEncryption(const CommonEncryption &); @@ -83,16 +85,19 @@ namespace adaptive SegmentInformation *parent; public: + SegmentInformation *getParent() const; + AbstractSegmentBaseType *getProfile() const; void updateSegmentList(SegmentList *, bool = false); void setSegmentBase(SegmentBase *); - void setSegmentTemplate(MediaSegmentTemplate *); + 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; - MediaSegmentTemplate * inheritSegmentTemplate() const; + SegmentTemplate * inheritSegmentTemplate() const; vlc_tick_t inheritAvailabilityTimeOffset() const; bool inheritAvailabilityTimeComplete() const; @@ -100,7 +105,7 @@ namespace adaptive void init(); SegmentBase *segmentBase; SegmentList *segmentList; - MediaSegmentTemplate *mediaSegmentTemplate; + 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 16efe98c8e99ccbb2d6c078935fb4be70177a9fc..211b9ef80ce4ae254f1fded6726cd4d3b966105f 100644 --- a/modules/demux/adaptive/playlist/SegmentList.cpp +++ b/modules/demux/adaptive/playlist/SegmentList.cpp @@ -28,11 +28,14 @@ #include "SegmentList.h" #include "Segment.h" #include "SegmentInformation.hpp" +#include "SegmentTimeline.h" + +#include <limits> using namespace adaptive::playlist; SegmentList::SegmentList( SegmentInformation *parent ): - SegmentInfoCommon( parent ), TimescaleAble( parent ) + AbstractMultipleSegmentBaseType( parent ) { totalLength = 0; } @@ -48,8 +51,17 @@ const std::vector<Segment*>& SegmentList::getSegments() const return segments; } -Segment * SegmentList::getSegmentByNumber(uint64_t number) +Segment * SegmentList::getMediaSegment(uint64_t number) const { + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if(timeline) + { + uint64_t listindex = timeline->getElementIndexBySequence(number); + if(listindex >= segments.size()) + return NULL; + return segments.at(listindex); + } + std::vector<Segment *>::const_iterator it = segments.begin(); for(it = segments.begin(); it != segments.end(); ++it) { @@ -68,19 +80,23 @@ Segment * SegmentList::getSegmentByNumber(uint64_t number) void SegmentList::addSegment(Segment *seg) { - seg->setParent(this); + seg->setParent(parent); segments.push_back(seg); totalLength += seg->duration.Get(); } -void SegmentList::updateWith(SegmentList *updated, bool b_restamp) +void SegmentList::updateWith(AbstractMultipleSegmentBaseType *updated_, + bool b_restamp) { - const Segment * lastSegment = (segments.empty()) ? NULL : segments.back(); - const Segment * prevSegment = lastSegment; + AbstractMultipleSegmentBaseType::updateWith(updated_); - if(updated->segments.empty()) + SegmentList *updated = dynamic_cast<SegmentList *>(updated_); + if(!updated || updated->segments.empty()) return; + const Segment * lastSegment = (segments.empty()) ? NULL : segments.back(); + const Segment * prevSegment = lastSegment; + uint64_t firstnumber = updated->segments.front()->getSequenceNumber(); std::vector<Segment *>::iterator it; @@ -111,9 +127,9 @@ void SegmentList::updateWith(SegmentList *updated, bool b_restamp) void SegmentList::pruneByPlaybackTime(vlc_tick_t time) { - uint64_t num; const Timescale timescale = inheritTimescale(); - if(getSegmentNumberByScaledTime(timescale.ToScaled(time), &num)) + uint64_t num = findSegmentNumberByScaledTime(segments, timescale.ToScaled(time)); + if(num != std::numeric_limits<uint64_t>::max()) pruneBySegmentNumber(num); } @@ -133,56 +149,159 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum) } } -bool SegmentList::getSegmentNumberByScaledTime(stime_t time, uint64_t *ret) const +bool SegmentList::getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, vlc_tick_t *dur) const { - return SegmentInfoCommon::getSegmentNumberByScaledTime(segments, time, ret); + if(number == std::numeric_limits<uint64_t>::max()) + return false; + + Timescale timescale; + stime_t stime, sduration; + + const SegmentTimeline * timeline = inheritSegmentTimeline(); + if(timeline) + { + timescale = timeline->inheritTimescale(); + if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration)) + return false; + } + else + { + *time = *dur = VLC_TICK_INVALID; + timescale = inheritTimescale(); + + if(segments.empty()) + return false; + + const ISegment *first = segments.front(); + if(first->getSequenceNumber() > number) + return false; + + bool found = false; + stime_t stime = first->startTime.Get(); + stime_t sduration = 0; + std::vector<Segment *>::const_iterator it = segments.begin(); + for(it = segments.begin(); it != segments.end(); ++it) + { + const Segment *seg = *it; + + if(seg->duration.Get()) + sduration = seg->duration.Get(); + else + sduration = duration.Get(); + + /* Assuming there won't be any discontinuity in sequence */ + if(seg->getSequenceNumber() == number) + { + found = true; + break; + } + + stime += sduration; + } + + if(!found) + return false; + } + + *time = VLC_TICK_0 + timescale.ToTime(stime); + *dur = VLC_TICK_0 + timescale.ToTime(sduration); + return true; } -bool SegmentList::getPlaybackTimeDurationBySegmentNumber(uint64_t number, - vlc_tick_t *time, vlc_tick_t *dur) const +stime_t SegmentList::getTotalLength() const { - *time = *dur = VLC_TICK_INVALID; + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if(timeline) + return timeline->getTotalLength(); + return totalLength; +} - if(segments.empty()) - return false; +vlc_tick_t SegmentList::getMinAheadTime(uint64_t curnum) const +{ + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if( timeline ) + { + const Timescale timescale = timeline->inheritTimescale(); + return timescale.ToTime(timeline->getMinAheadScaledTime(curnum)); + } + vlc_tick_t minTime = 0; const Timescale timescale = inheritTimescale(); - const ISegment *first = segments.front(); - if(first->getSequenceNumber() > number) - return false; - - bool found = false; - stime_t seg_start = first->startTime.Get(); - stime_t seg_dura = 0; - std::vector<Segment *>::const_iterator it = segments.begin(); + std::vector<Segment *>::const_iterator it; for(it = segments.begin(); it != segments.end(); ++it) { const Segment *seg = *it; + if(seg->getSequenceNumber() > curnum) + minTime += timescale.ToTime(seg->duration.Get()); + } + return minTime; +} - if(seg->duration.Get()) - seg_dura = seg->duration.Get(); - else - seg_dura = duration.Get(); +Segment * SegmentList::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos, + bool *pb_gap) const +{ + *pb_gap = false; + *pi_newpos = i_pos; - /* Assuming there won't be any discontinuity in sequence */ - if(seg->getSequenceNumber() == number) + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if(timeline) + { + uint64_t listindex = timeline->getElementIndexBySequence(i_pos); + if(listindex >= segments.size()) + return NULL; + return segments.at(listindex); + } + + std::vector<Segment *>::const_iterator it; + for(it = segments.begin(); it != segments.end(); ++it) + { + Segment *seg = *it; + if(seg->getSequenceNumber() >= i_pos) { - found = true; - break; + *pi_newpos = seg->getSequenceNumber(); + *pb_gap = (*pi_newpos != i_pos); + return seg; } + } + return NULL; +} + +uint64_t SegmentList::getStartSegmentNumber() const +{ + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if( timeline ) + return timeline->minElementNumber(); + return !segments.empty() ? segments.front()->getSequenceNumber() : inheritStartNumber(); +} - seg_start += seg_dura; +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(); + stime_t st = timescale.ToScaled(time); + *ret = timeline->getElementNumberByScaledPlaybackTime(st); + return true; } - if(!found) + const Timescale timescale = inheritTimescale(); + if(!timescale.isValid()) return false; - - *time = VLC_TICK_0 + timescale.ToTime(seg_start); - *dur = VLC_TICK_0 + timescale.ToTime(seg_dura); - return true; + stime_t st = timescale.ToScaled(time); + *ret = AbstractSegmentBaseType::findSegmentNumberByScaledTime(segments, st); + return *ret != std::numeric_limits<uint64_t>::max(); } -stime_t SegmentList::getTotalLength() const +void SegmentList::debug(vlc_object_t *obj, int indent) const { - return totalLength; + AbstractSegmentBaseType::debug(obj, indent); + 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); } diff --git a/modules/demux/adaptive/playlist/SegmentList.h b/modules/demux/adaptive/playlist/SegmentList.h index 6fd1a0083692295623d0ab447bb9db799371ec4b..f67d64ad8a2566a3770172476245673bb48337da 100644 --- a/modules/demux/adaptive/playlist/SegmentList.h +++ b/modules/demux/adaptive/playlist/SegmentList.h @@ -25,7 +25,7 @@ #ifndef SEGMENTLIST_H_ #define SEGMENTLIST_H_ -#include "SegmentInfoCommon.h" +#include "SegmentBaseType.hpp" namespace adaptive { @@ -34,23 +34,30 @@ namespace adaptive class SegmentInformation; class Segment; - class SegmentList : public SegmentInfoCommon, - public TimescaleAble + class SegmentList : public AbstractMultipleSegmentBaseType { public: SegmentList ( SegmentInformation * = NULL ); virtual ~SegmentList (); const std::vector<Segment *>& getSegments() const; - Segment * getSegmentByNumber(uint64_t); void addSegment(Segment *seg); - void updateWith(SegmentList *, bool = false); + virtual void updateWith(AbstractMultipleSegmentBaseType *, + bool = false); /* reimpl */ void pruneBySegmentNumber(uint64_t); void pruneByPlaybackTime(vlc_tick_t); - bool getSegmentNumberByScaledTime(stime_t, uint64_t *) const; - bool getPlaybackTimeDurationBySegmentNumber(uint64_t, vlc_tick_t *, vlc_tick_t *) const; stime_t getTotalLength() const; + virtual vlc_tick_t getMinAheadTime(uint64_t) const; /* impl */ + virtual Segment * getMediaSegment(uint64_t pos) const; /* impl */ + virtual Segment * getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */ + virtual uint64_t getStartSegmentNumber() const; /* impl */ + virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */ + virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */ + + virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */ + private: std::vector<Segment *> segments; stime_t totalLength; diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp index 04b70557c2b0accec0e70d18b0129a67495b1ea0..f66fe7eb024f1e5aaf571d0e6171f0c2074f1997 100644 --- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp +++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp @@ -31,127 +31,58 @@ using namespace adaptive::playlist; -BaseSegmentTemplate::BaseSegmentTemplate( ICanonicalUrl *parent ) : +SegmentTemplateSegment::SegmentTemplateSegment( SegmentTemplate *templ_, + ICanonicalUrl *parent ) : Segment( parent ) { + debugName = "SegmentTemplateSegment"; + classId = Segment::CLASSID_SEGMENT; + templated = true; + templ = templ_; } -BaseSegmentTemplate::~BaseSegmentTemplate() +SegmentTemplateSegment::~SegmentTemplateSegment() { } -void BaseSegmentTemplate::setSourceUrl(const std::string &url) +void SegmentTemplateSegment::setSourceUrl(const std::string &url) { - sourceUrl = Url(Url::Component(url, this)); + sourceUrl = Url(Url::Component(url, templ)); } -MediaSegmentTemplate::MediaSegmentTemplate( SegmentInformation *parent ) : - BaseSegmentTemplate( parent ), - TimescaleAble( NULL ) /* we don't want auto inherit */ +SegmentTemplate::SegmentTemplate( SegmentInformation *parent ) : + AbstractMultipleSegmentBaseType( NULL ) /* we don't want auto inherit */ { - debugName = "SegmentTemplate"; - classId = Segment::CLASSID_SEGMENT; - startNumber = std::numeric_limits<uint64_t>::max(); - segmentTimeline = NULL; initialisationSegment.Set( NULL ); - templated = true; parentSegmentInformation = parent; + segments.push_back( new SegmentTemplateSegment( this, parent ) ); } -MediaSegmentTemplate::~MediaSegmentTemplate() +SegmentTemplate::~SegmentTemplate() { - delete segmentTimeline; + delete *segments.begin(); } -void MediaSegmentTemplate::updateWith(MediaSegmentTemplate *updated) +void SegmentTemplate::setSourceUrl( const std::string &url ) { - SegmentTimeline *timeline = segmentTimeline; - if(timeline && updated->segmentTimeline) - { - timeline->updateWith(*updated->segmentTimeline); - /*if(prunebarrier) - { - const Timescale timescale = timeline->inheritTimescale(); - const uint64_t number = - timeline->getElementNumberByScaledPlaybackTime(timescale.ToScaled(prunebarrier)); - timeline->pruneBySequenceNumber(number); - }*/ - } + (*segments.begin())->setSourceUrl(url); } -void MediaSegmentTemplate::pruneByPlaybackTime(vlc_tick_t time) +void SegmentTemplate::pruneByPlaybackTime(vlc_tick_t time) { if(segmentTimeline) return segmentTimeline->pruneByPlaybackTime(time); } -size_t MediaSegmentTemplate::pruneBySequenceNumber(uint64_t number) +size_t SegmentTemplate::pruneBySequenceNumber(uint64_t number) { if(segmentTimeline) return segmentTimeline->pruneBySequenceNumber(number); return 0; } -uint64_t MediaSegmentTemplate::inheritStartNumber() const -{ - if( startNumber != std::numeric_limits<uint64_t>::max() ) - return startNumber; - - 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->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::getLiveTemplateNumber(vlc_tick_t playbacktime, bool abs) const +uint64_t SegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bool abs) const { uint64_t number = inheritStartNumber(); /* live streams / templated */ @@ -176,53 +107,181 @@ uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bo return number; } -stime_t MediaSegmentTemplate::getMinAheadScaledTime(uint64_t number) const +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); +} + +vlc_tick_t SegmentTemplate::getMinAheadTime(uint64_t number) const { if( segmentTimeline ) - return segmentTimeline->getMinAheadScaledTime(number); + { + const Timescale timescale = segmentTimeline->inheritTimescale(); + return timescale.ToTime(segmentTimeline->getMinAheadScaledTime(number)); + } + else + { + const Timescale timescale = inheritTimescale(); + uint64_t current = getLiveTemplateNumber(vlc_tick_from_sec(time(NULL))); + stime_t i_length = (current - number) * inheritDuration(); + return timescale.ToTime(i_length); + } +} - uint64_t current = getLiveTemplateNumber(vlc_tick_from_sec(time(NULL))); - return (current - number) * inheritDuration(); +Segment * SegmentTemplate::getMediaSegment(uint64_t number) const +{ + const SegmentTimeline *tl = inheritSegmentTimeline(); + if(tl == NULL || tl->maxElementNumber() > number) + return *segments.begin(); + return NULL; } -uint64_t MediaSegmentTemplate::getSequenceNumber() const +InitSegment * SegmentTemplate::getInitSegment() const { - return inheritStartNumber(); + return initialisationSegment.Get(); } -void MediaSegmentTemplate::setStartNumber( uint64_t v ) +Segment * SegmentTemplate::getNextMediaSegment(uint64_t i_pos,uint64_t *pi_newpos, + bool *pb_gap) const { - startNumber = v; + *pb_gap = false; + *pi_newpos = i_pos; + /* Check if we don't exceed timeline */ + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if(timeline) + { + *pi_newpos = std::max(timeline->minElementNumber(), i_pos); + if (timeline->maxElementNumber() < i_pos) + return NULL; + } + else + { + /* check template upper bound */ + const AbstractPlaylist *playlist = parentSegmentInformation->getPlaylist(); + if(!playlist->isLive()) + { + const Timescale timescale = inheritTimescale(); + const stime_t segmentduration = inheritDuration(); + vlc_tick_t totalduration = parentSegmentInformation->getPeriodDuration(); + if(totalduration == 0) + totalduration = playlist->duration.Get(); + if(totalduration && segmentduration) + { + uint64_t endnum = inheritStartNumber() + + (timescale.ToScaled(totalduration) + segmentduration - 1) / segmentduration; + if(i_pos >= endnum) + { + *pi_newpos = i_pos; + return NULL; + } + } + } + *pi_newpos = i_pos; + /* start number */ + *pi_newpos = std::max(inheritStartNumber(), i_pos); + } + return *segments.begin(); } -void MediaSegmentTemplate::setSegmentTimeline( SegmentTimeline *v ) +uint64_t SegmentTemplate::getStartSegmentNumber() const { - delete segmentTimeline; - segmentTimeline = v; + const SegmentTimeline *timeline = inheritSegmentTimeline(); + return timeline ? timeline->minElementNumber() : inheritStartNumber(); } -void MediaSegmentTemplate::debug(vlc_object_t *obj, int indent) const +bool SegmentTemplate::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const { - Segment::debug(obj, indent); - if(segmentTimeline) - segmentTimeline->debug(obj, indent + 1); + const SegmentTimeline *timeline = inheritSegmentTimeline(); + if(timeline) + { + const Timescale timescale = timeline->getTimescale().isValid() + ? timeline->getTimescale() + : inheritTimescale(); + stime_t st = timescale.ToScaled(time); + *ret = timeline->getElementNumberByScaledPlaybackTime(st); + return true; + } + + const stime_t duration = inheritDuration(); + if( duration && parent ) + { + AbstractPlaylist *playlist = parent->getPlaylist(); + if( playlist->isLive() ) + { + vlc_tick_t now = vlc_tick_from_sec(::time(NULL)); + if(playlist->availabilityStartTime.Get()) + { + if(time >= playlist->availabilityStartTime.Get() && time < now) + *ret = getLiveTemplateNumber(time, true); + else if(now - playlist->availabilityStartTime.Get() > time) + *ret = getLiveTemplateNumber(time, false); + } + else return false; + } + else + { + const Timescale timescale = inheritTimescale(); + *ret = inheritStartNumber(); + *ret += timescale.ToScaled(time) / duration; + } + return true; + } + + return false; +} + + +bool SegmentTemplate::getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, + vlc_tick_t *duration) const +{ + if(number == std::numeric_limits<uint64_t>::max()) + return false; + + Timescale timescale; + stime_t stime, sduration; + + const SegmentTimeline * timeline = inheritSegmentTimeline(); + if(timeline) + { + timescale = timeline->inheritTimescale(); + if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(number, &stime, &sduration)) + return false; + } + else + { + timescale = inheritTimescale(); + uint64_t startNumber = inheritStartNumber(); + if(number < startNumber) + return false; + sduration = inheritDuration(); + stime = (number - startNumber) * sduration; + } + + *time = timescale.ToTime(stime); + *duration = timescale.ToTime(sduration); + return true; + } -InitSegmentTemplate::InitSegmentTemplate( ICanonicalUrl *parent, - MediaSegmentTemplate *templ ) : +SegmentTemplateInit::SegmentTemplateInit( SegmentTemplate *templ_, + ICanonicalUrl *parent ) : InitSegment(parent) { debugName = "InitSegmentTemplate"; classId = InitSegment::CLASSID_INITSEGMENT; - maintempl = templ; + templ = templ_; } -InitSegmentTemplate::~InitSegmentTemplate() +SegmentTemplateInit::~SegmentTemplateInit() { } -void InitSegmentTemplate::setSourceUrl(const std::string &url) +void SegmentTemplateInit::setSourceUrl(const std::string &url) { - sourceUrl = Url(Url::Component(url, maintempl)); + sourceUrl = Url(Url::Component(url, templ)); } diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.h b/modules/demux/adaptive/playlist/SegmentTemplate.h index cac4dbf3b353c635476f15f2fa9678e75d6d1276..6c864e0f024b0b5e4112b26b47bf5394b7591a7a 100644 --- a/modules/demux/adaptive/playlist/SegmentTemplate.h +++ b/modules/demux/adaptive/playlist/SegmentTemplate.h @@ -25,61 +25,64 @@ #include "Segment.h" #include "../tools/Properties.hpp" -#include "SegmentInfoCommon.h" +#include "SegmentBaseType.hpp" namespace adaptive { namespace playlist { class ICanonicalUrl; - class InitSegmentTemplate; + class SegmentTemplateInit; class SegmentInformation; - class SegmentTimeline; + class SegmentTemplate; - class BaseSegmentTemplate : public Segment + class SegmentTemplateSegment : public Segment { public: - BaseSegmentTemplate( ICanonicalUrl * = NULL ); - virtual ~BaseSegmentTemplate(); + SegmentTemplateSegment( SegmentTemplate *, ICanonicalUrl * = NULL ); + virtual ~SegmentTemplateSegment(); virtual void setSourceUrl( const std::string &url ); /* reimpl */ + + protected: + const SegmentTemplate *templ; }; - class MediaSegmentTemplate : public BaseSegmentTemplate, - public Initializable<InitSegmentTemplate>, - public TimescaleAble + class SegmentTemplate : public AbstractMultipleSegmentBaseType { public: - MediaSegmentTemplate( SegmentInformation * = NULL ); - virtual ~MediaSegmentTemplate(); - void setStartNumber( uint64_t ); - void setSegmentTimeline( SegmentTimeline * ); - void updateWith( MediaSegmentTemplate * ); - virtual uint64_t getSequenceNumber() const; /* reimpl */ + SegmentTemplate( SegmentInformation * = NULL ); + virtual ~SegmentTemplate(); + void setSourceUrl( const std::string &url ); uint64_t getLiveTemplateNumber(vlc_tick_t, bool = true) 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 vlc_tick_t getMinAheadTime(uint64_t curnum) const; /* impl */ + virtual Segment * getMediaSegment(uint64_t number) const; /* impl */ + virtual Segment * getNextMediaSegment(uint64_t, uint64_t *, bool *) const; /* impl */ + virtual InitSegment *getInitSegment() const;/* reimpl */ + virtual uint64_t getStartSegmentNumber() const; /* impl */ + + virtual bool getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const; /* impl */ + virtual bool getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, vlc_tick_t *duration) const; /* impl */ + virtual void debug(vlc_object_t *, int = 0) const; /* reimpl */ protected: - uint64_t startNumber; - SegmentTimeline *segmentTimeline; SegmentInformation *parentSegmentInformation; + std::vector<SegmentTemplateSegment *> segments; /* should have only 1 */ }; - class InitSegmentTemplate : public InitSegment + class SegmentTemplateInit : public InitSegment { public: - InitSegmentTemplate( ICanonicalUrl * = NULL, MediaSegmentTemplate * = NULL ); - virtual ~InitSegmentTemplate(); + SegmentTemplateInit( SegmentTemplate *, ICanonicalUrl * = NULL ); + virtual ~SegmentTemplateInit(); virtual void setSourceUrl( const std::string &url ); /* reimpl */ protected: - const MediaSegmentTemplate *maintempl; + const SegmentTemplate *templ; }; } } diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.cpp b/modules/demux/adaptive/playlist/SegmentTimeline.cpp index e1c530a7677b3810d6faebff5babbf0aa316cd84..a8e60ccc66be7adcd6437d78d9d8af0596cfb998 100644 --- a/modules/demux/adaptive/playlist/SegmentTimeline.cpp +++ b/modules/demux/adaptive/playlist/SegmentTimeline.cpp @@ -24,15 +24,19 @@ #endif #include "SegmentTimeline.h" +#include "SegmentBaseType.hpp" +#include "SegmentInformation.hpp" #include <algorithm> +#include <sstream> using namespace adaptive::playlist; -SegmentTimeline::SegmentTimeline(TimescaleAble *parent) - :TimescaleAble(parent) +SegmentTimeline::SegmentTimeline(AbstractMultipleSegmentBaseType *parent_) + :TimescaleAble(NULL) { totalLength = 0; + parent = parent_; } SegmentTimeline::SegmentTimeline(uint64_t scale) @@ -40,6 +44,7 @@ SegmentTimeline::SegmentTimeline(uint64_t scale) { setTimescale(scale); totalLength = 0; + parent = NULL; } SegmentTimeline::~SegmentTimeline() @@ -88,6 +93,33 @@ 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; @@ -167,6 +199,21 @@ uint64_t SegmentTimeline::minElementNumber() const return elements.front()->number; } +uint64_t SegmentTimeline::getElementIndexBySequence(uint64_t number) const +{ + std::list<Element *>::const_iterator it; + for(it = elements.begin(); it != elements.end(); ++it) + { + const Element *el = *it; + if(number >= el->number) + { + if(number <= el->number + el->r) + return std::distance(elements.begin(), it); + } + } + return std::numeric_limits<uint64_t>::max(); +} + void SegmentTimeline::pruneByPlaybackTime(vlc_tick_t time) { const Timescale timescale = inheritTimescale(); diff --git a/modules/demux/adaptive/playlist/SegmentTimeline.h b/modules/demux/adaptive/playlist/SegmentTimeline.h index 7489e7a7406691eccc714be24f3b9591ee1d8d19..668f7d53897cfd306c35afb9e5bf61af07dfef09 100644 --- a/modules/demux/adaptive/playlist/SegmentTimeline.h +++ b/modules/demux/adaptive/playlist/SegmentTimeline.h @@ -23,7 +23,8 @@ #ifndef SEGMENTTIMELINE_H #define SEGMENTTIMELINE_H -#include "SegmentInfoCommon.h" +#include "Inheritables.hpp" + #include <vlc_common.h> #include <list> @@ -31,12 +32,14 @@ namespace adaptive { namespace playlist { + class AbstractMultipleSegmentBaseType; + class SegmentTimeline : public TimescaleAble { class Element; public: - SegmentTimeline(TimescaleAble *); + SegmentTimeline(AbstractMultipleSegmentBaseType *); SegmentTimeline(uint64_t); virtual ~SegmentTimeline(); void addElement(uint64_t, stime_t d, uint64_t r = 0, stime_t t = 0); @@ -44,9 +47,11 @@ namespace adaptive 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; + uint64_t getElementIndexBySequence(uint64_t) const; void pruneByPlaybackTime(vlc_tick_t); size_t pruneBySequenceNumber(uint64_t); void updateWith(SegmentTimeline &); @@ -55,6 +60,7 @@ namespace adaptive private: std::list<Element *> elements; stime_t totalLength; + AbstractMultipleSegmentBaseType *parent; class Element { diff --git a/modules/demux/adaptive/playlist/Url.cpp b/modules/demux/adaptive/playlist/Url.cpp index 86385b1afe09026d0baf82ed9b076a90559e160a..0b8fb5c6e21b3730171f3823ef286688ceb73456 100644 --- a/modules/demux/adaptive/playlist/Url.cpp +++ b/modules/demux/adaptive/playlist/Url.cpp @@ -140,7 +140,7 @@ std::string Url::toString(size_t index, const BaseRepresentation *rep) const return ret; } -Url::Component::Component(const std::string & str, const BaseSegmentTemplate *templ_) +Url::Component::Component(const std::string & str, const SegmentTemplate *templ_) : component(str), templ(templ_), b_scheme(false), b_dir(false), b_absolute(false) { if(!component.empty()) diff --git a/modules/demux/adaptive/playlist/Url.hpp b/modules/demux/adaptive/playlist/Url.hpp index 6650eff0e08f884e8dcf9d9f9d1fe59133a97a6e..d91cf47caf1ca8a4d720aca2abb13607727b5049 100644 --- a/modules/demux/adaptive/playlist/Url.hpp +++ b/modules/demux/adaptive/playlist/Url.hpp @@ -28,7 +28,7 @@ namespace adaptive { namespace playlist { - class BaseSegmentTemplate; + class SegmentTemplate; class BaseRepresentation; class Url @@ -38,11 +38,11 @@ namespace adaptive { friend class Url; public: - Component(const std::string &, const BaseSegmentTemplate * = NULL); + Component(const std::string &, const SegmentTemplate * = NULL); protected: std::string component; - const BaseSegmentTemplate *templ; + const SegmentTemplate *templ; private: bool b_scheme; diff --git a/modules/demux/dash/mpd/IsoffMainParser.cpp b/modules/demux/dash/mpd/IsoffMainParser.cpp index 3188fba343d07b37009561a799bee3228b6154bb..6f158a81aa5373f7ebd57a8a3bd0df07b1f3ac5d 100644 --- a/modules/demux/dash/mpd/IsoffMainParser.cpp +++ b/modules/demux/dash/mpd/IsoffMainParser.cpp @@ -182,6 +182,49 @@ void IsoffMainParser::parsePeriods(MPD *mpd, Node *root) } } +void IsoffMainParser::parseSegmentBaseType(MPD *, Node *node, + AbstractSegmentBaseType *base, + SegmentInformation *parent) +{ + parseInitSegment(DOMHelper::getFirstChildElementByName(node, "Initialization"), base, parent); + + if(node->hasAttribute("indexRange")) + { + size_t start = 0, end = 0; + if (std::sscanf(node->getAttributeValue("indexRange").c_str(), "%zu-%zu", &start, &end) == 2) + { + IndexSegment *index = new (std::nothrow) DashIndexSegment(parent); + if(index) + { + index->setByteRange(start, end); + base->indexSegment.Set(index); + /* index must be before data, so data starts at index end */ + if(dynamic_cast<SegmentBase *>(base)) + dynamic_cast<SegmentBase *>(base)->setByteRange(end + 1, 0); + } + } + } + + if(node->hasAttribute("timescale")) + base->setTimescale(Integer<uint64_t>(node->getAttributeValue("timescale"))); + +} + +void IsoffMainParser::parseMultipleSegmentBaseType(MPD *mpd, Node *node, + AbstractMultipleSegmentBaseType *base, + SegmentInformation *parent) +{ + parseSegmentBaseType(mpd, node, base, parent); + + if(node->hasAttribute("duration")) + base->duration.Set(Integer<stime_t>(node->getAttributeValue("duration"))); + + if(node->hasAttribute("startNumber")) + base->setStartNumber(Integer<uint64_t>(node->getAttributeValue("startNumber"))); + + parseTimeline(DOMHelper::getFirstChildElementByName(node, "SegmentTimeline"), base); +} + size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, SegmentInformation *info) { size_t total = 0; @@ -192,33 +235,26 @@ size_t IsoffMainParser::parseSegmentTemplate(MPD *mpd, Node *templateNode, Segme if(templateNode->hasAttribute("media")) mediaurl = templateNode->getAttributeValue("media"); - MediaSegmentTemplate *mediaTemplate = NULL; - if( !(mediaTemplate = new (std::nothrow) MediaSegmentTemplate(info)) ) + SegmentTemplate *mediaTemplate = new (std::nothrow) SegmentTemplate(info); + if(!mediaTemplate) return total; mediaTemplate->setSourceUrl(mediaurl); - if(templateNode->hasAttribute("startNumber")) - mediaTemplate->setStartNumber(Integer<uint64_t>(templateNode->getAttributeValue("startNumber"))); - - if(templateNode->hasAttribute("timescale")) - mediaTemplate->setTimescale(Integer<uint64_t>(templateNode->getAttributeValue("timescale"))); - - if(templateNode->hasAttribute("duration")) - mediaTemplate->duration.Set(Integer<stime_t>(templateNode->getAttributeValue("duration"))); + parseMultipleSegmentBaseType(mpd, templateNode, mediaTemplate, info); parseAvailability<SegmentInformation>(mpd, templateNode, info); - InitSegmentTemplate *initTemplate = NULL; - - if(templateNode->hasAttribute("initialization")) + if(templateNode->hasAttribute("initialization")) /* /!\ != Initialization */ { + SegmentTemplateInit *initTemplate; std::string initurl = templateNode->getAttributeValue("initialization"); - if(!initurl.empty() && (initTemplate = new (std::nothrow) InitSegmentTemplate(info, mediaTemplate))) + if(!initurl.empty() && (initTemplate = new (std::nothrow) SegmentTemplateInit(mediaTemplate, info))) + { initTemplate->setSourceUrl(initurl); + delete mediaTemplate->initialisationSegment.Get(); + mediaTemplate->initialisationSegment.Set(initTemplate); + } } - mediaTemplate->initialisationSegment.Set(initTemplate); - - parseTimeline(DOMHelper::getFirstChildElementByName(templateNode, "SegmentTimeline"), mediaTemplate); info->setSegmentTemplate(mediaTemplate); @@ -371,23 +407,8 @@ size_t IsoffMainParser::parseSegmentBase(MPD *mpd, Node * segmentBaseNode, Segme if(!segmentBaseNode || !(base = new (std::nothrow) SegmentBase(info))) return 0; - if(segmentBaseNode->hasAttribute("indexRange")) - { - size_t start = 0, end = 0; - if (std::sscanf(segmentBaseNode->getAttributeValue("indexRange").c_str(), "%zu-%zu", &start, &end) == 2) - { - IndexSegment *index = new (std::nothrow) DashIndexSegment(info); - if(index) - { - index->setByteRange(start, end); - base->indexSegment.Set(index); - /* index must be before data, so data starts at index end */ - base->setByteRange(end + 1, 0); - } - } - } + parseSegmentBaseType(mpd, segmentBaseNode, base, info); - parseInitSegment(DOMHelper::getFirstChildElementByName(segmentBaseNode, "Initialization"), base, info); parseAvailability<SegmentInformation>(mpd, segmentBaseNode, info); if(!base->initialisationSegment.Get() && base->indexSegment.Get() && base->indexSegment.Get()->getOffset()) @@ -412,13 +433,7 @@ size_t IsoffMainParser::parseSegmentList(MPD *mpd, Node * segListNode, SegmentIn SegmentList *list; if((list = new (std::nothrow) SegmentList(info))) { - parseInitSegment(DOMHelper::getFirstChildElementByName(segListNode, "Initialization"), list, info); - - if(segListNode->hasAttribute("duration")) - list->duration.Set(Integer<stime_t>(segListNode->getAttributeValue("duration"))); - - if(segListNode->hasAttribute("timescale")) - list->setTimescale(Integer<uint64_t>(segListNode->getAttributeValue("timescale"))); + parseMultipleSegmentBaseType(mpd, segListNode, list, info); parseAvailability<SegmentInformation>(mpd, segListNode, info); @@ -480,7 +495,7 @@ void IsoffMainParser::parseInitSegment(Node *initNode, Initializable<InitSegment init->initialisationSegment.Set(seg); } -void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ) +void IsoffMainParser::parseTimeline(Node *node, AbstractMultipleSegmentBaseType *base) { if(!node) return; @@ -488,10 +503,10 @@ 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->inheritStartNumber()) - number = templ->inheritStartNumber(); + else if(base->inheritStartNumber()) + number = base->inheritStartNumber(); - SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(templ); + SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(base); if(timeline) { std::vector<Node *> elements = DOMHelper::getElementByTagName(node, "S", false); @@ -519,7 +534,7 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ) number += (1 + r); } - templ->setSegmentTimeline(timeline); + base->setSegmentTimeline(timeline); } } diff --git a/modules/demux/dash/mpd/IsoffMainParser.h b/modules/demux/dash/mpd/IsoffMainParser.h index 0856bfb132adf856a872213c7426a52e6ce384da..88a6e253f8474d46d5592e670e2448a247154bab 100644 --- a/modules/demux/dash/mpd/IsoffMainParser.h +++ b/modules/demux/dash/mpd/IsoffMainParser.h @@ -29,7 +29,7 @@ # include "config.h" #endif -#include "../../adaptive/playlist/SegmentInfoCommon.h" +#include "../../adaptive/playlist/SegmentBaseType.hpp" #include "Profile.hpp" #include <cstdlib> @@ -41,7 +41,7 @@ namespace adaptive namespace playlist { class SegmentInformation; - class MediaSegmentTemplate; + class SegmentTemplate; } namespace xml { @@ -75,13 +75,19 @@ namespace dash void parseAdaptationSets (MPD *, xml::Node *periodNode, Period *period); void parseRepresentations(MPD *, xml::Node *adaptationSetNode, AdaptationSet *adaptationSet); void parseInitSegment (xml::Node *, Initializable<InitSegment> *, SegmentInformation *); - void parseTimeline (xml::Node *, MediaSegmentTemplate *); + void parseTimeline (xml::Node *, AbstractMultipleSegmentBaseType *); void parsePeriods (MPD *, xml::Node *); size_t parseSegmentInformation(MPD *, xml::Node *, SegmentInformation *, uint64_t *); size_t parseSegmentBase (MPD *, xml::Node *, SegmentInformation *); size_t parseSegmentList (MPD *, xml::Node *, SegmentInformation *); size_t parseSegmentTemplate(MPD *, xml::Node *, SegmentInformation *); void parseProgramInformation(xml::Node *, MPD *); + void parseSegmentBaseType(MPD *mpd, xml::Node *node, + AbstractSegmentBaseType *base, + SegmentInformation *parent); + void parseMultipleSegmentBaseType(MPD *mpd, xml::Node *node, + AbstractMultipleSegmentBaseType *base, + SegmentInformation *parent); xml::Node *root; vlc_object_t *p_object; diff --git a/modules/demux/dash/mpd/Representation.cpp b/modules/demux/dash/mpd/Representation.cpp index a1acf7986c6c95c09007da267443467f8ba28e90..9f936fe4ef31a2da17b9bdc1d50884037c49ad78 100644 --- a/modules/demux/dash/mpd/Representation.cpp +++ b/modules/demux/dash/mpd/Representation.cpp @@ -54,14 +54,12 @@ StreamFormat Representation::getStreamFormat() const } std::string Representation::contextualize(size_t number, const std::string &component, - const BaseSegmentTemplate *basetempl) const + const SegmentTemplate *templ) const { std::string str(component); - if(!basetempl) + if(!templ) return str; - const MediaSegmentTemplate *templ = dynamic_cast<const MediaSegmentTemplate *>(basetempl); - std::string::size_type pos = 0; while(pos < str.length()) { @@ -103,7 +101,7 @@ std::string Representation::contextualize(size_t number, const std::string &comp return str; } -stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const MediaSegmentTemplate *templ) const +stime_t Representation::getScaledTimeBySegmentNumber(uint64_t index, const SegmentTemplate *templ) const { stime_t time = 0; const SegmentTimeline *tl = templ->inheritSegmentTimeline(); diff --git a/modules/demux/dash/mpd/Representation.h b/modules/demux/dash/mpd/Representation.h index ac0c5e1aa25431f9e6d92cdeb668f496a71dbc91..2d66fa5d5dffce5100edc20eac4d159bb3f4e758 100644 --- a/modules/demux/dash/mpd/Representation.h +++ b/modules/demux/dash/mpd/Representation.h @@ -26,7 +26,7 @@ #define DASHREPRESENTATION_H_ #include "DASHCommonAttributesElements.h" -#include "../../adaptive/playlist/SegmentInfoCommon.h" +#include "../../adaptive/playlist/SegmentBaseType.hpp" #include "../../adaptive/playlist/BaseRepresentation.h" namespace dash @@ -50,12 +50,12 @@ namespace dash /* for segment templates */ virtual std::string contextualize(size_t, const std::string &, - const BaseSegmentTemplate *) const; // reimpl + const SegmentTemplate *) const; // reimpl private: /* for contextualize() */ - stime_t getScaledTimeBySegmentNumber(uint64_t, const MediaSegmentTemplate *) const; + stime_t getScaledTimeBySegmentNumber(uint64_t, const SegmentTemplate *) const; }; } } diff --git a/modules/demux/hls/playlist/Parser.hpp b/modules/demux/hls/playlist/Parser.hpp index fc0ac6314f4736219200677a32825669cb2cdc88..6bcc1b6d040c3d993ee4b0e375854794e0b3be40 100644 --- a/modules/demux/hls/playlist/Parser.hpp +++ b/modules/demux/hls/playlist/Parser.hpp @@ -20,10 +20,11 @@ #ifndef PARSER_HPP #define PARSER_HPP -#include "../../adaptive/playlist/SegmentInfoCommon.h" +#include "../../adaptive/playlist/SegmentBaseType.hpp" #include <cstdlib> #include <sstream> +#include <list> #include <vlc_common.h> @@ -34,7 +35,7 @@ namespace adaptive namespace playlist { class SegmentInformation; - class MediaSegmentTemplate; + class SegmentTemplate; class BasePeriod; class BaseAdaptationSet; } diff --git a/modules/demux/hls/playlist/Representation.cpp b/modules/demux/hls/playlist/Representation.cpp index 97ce41883beee8cdfb063040960510cc0d37ea66..08f7b40249444b4b383fb137e53c8eaa40d14b35 100644 --- a/modules/demux/hls/playlist/Representation.cpp +++ b/modules/demux/hls/playlist/Representation.cpp @@ -172,9 +172,8 @@ uint64_t Representation::translateSegmentNumber(uint64_t num, const BaseRepresen const vlc_tick_t utcTime = fromHlsSeg->getUTCTime() + getTimescale().ToTime(fromHlsSeg->duration.Get()) / 2; - std::vector<Segment *> list; + const std::vector<Segment *> &list = inheritSegmentList()->getSegments(); std::vector<Segment *>::const_iterator it; - getMediaSegments(list); for(it=list.begin(); it != list.end(); ++it) { const HLSSegment *hlsSeg = dynamic_cast<HLSSegment *>(*it); diff --git a/modules/demux/smooth/mp4/IndexReader.cpp b/modules/demux/smooth/mp4/IndexReader.cpp index 60ac7c08252a4530a3bd86f6e11165bfb556ad6a..ef3e363030d8d6cde80259bc69c1a85cbe602180 100644 --- a/modules/demux/smooth/mp4/IndexReader.cpp +++ b/modules/demux/smooth/mp4/IndexReader.cpp @@ -71,7 +71,9 @@ bool IndexReader::parseIndex(block_t *p_block, BaseRepresentation *rep) timelineadd->addElement(i+1, dur, 0, stime); } - rep->mergeWithTimeline(timelineadd); + rep->inheritSegmentTemplate()-> + inheritSegmentTimeline()-> + updateWith(*timelineadd); delete timelineadd; #ifndef NDEBUG diff --git a/modules/demux/smooth/playlist/Parser.cpp b/modules/demux/smooth/playlist/Parser.cpp index 9d2286bcfba9d426979ff948dd4041f47ab3f77a..4ca85add22f86049ac7009f9bc7ddb9ae1b1501f 100644 --- a/modules/demux/smooth/playlist/Parser.cpp +++ b/modules/demux/smooth/playlist/Parser.cpp @@ -232,7 +232,7 @@ static void ParseStreamIndex(BasePeriod *period, Node *streamIndexNode, unsigned if(!url.empty()) { /* SmoothSegment is a template holder */ - SmoothSegment *templ = new SmoothSegment(adaptSet); + SmoothSegmentTemplate *templ = new SmoothSegmentTemplate(adaptSet); if(templ) { templ->setSourceUrl(url); diff --git a/modules/demux/smooth/playlist/Parser.hpp b/modules/demux/smooth/playlist/Parser.hpp index 70ee526283f050b283c44c956e8eaf136d07a788..ee93e4b45a8c4129d3b28f799d30317b899f3786 100644 --- a/modules/demux/smooth/playlist/Parser.hpp +++ b/modules/demux/smooth/playlist/Parser.hpp @@ -20,7 +20,7 @@ #ifndef MANIFESTPARSER_HPP #define MANIFESTPARSER_HPP -#include "../../adaptive/playlist/SegmentInfoCommon.h" +#include "../../adaptive/playlist/SegmentBaseType.hpp" #include <cstdlib> #include <sstream> @@ -32,7 +32,7 @@ namespace adaptive namespace playlist { class SegmentInformation; - class MediaSegmentTemplate; + class SegmentTemplate; class BasePeriod; class BaseAdaptationSet; } diff --git a/modules/demux/smooth/playlist/Representation.cpp b/modules/demux/smooth/playlist/Representation.cpp index eae39dded9d139360a16b50e9b4e2103826e239f..91c57182dd7a4a5fee6e6bec4e82c89b0a0dd98f 100644 --- a/modules/demux/smooth/playlist/Representation.cpp +++ b/modules/demux/smooth/playlist/Representation.cpp @@ -52,16 +52,14 @@ InitSegment * Representation::getInitSegment() const } std::string Representation::contextualize(size_t number, const std::string &component, - const BaseSegmentTemplate *basetempl) const + const SegmentTemplate *templ) const { std::string ret(component); size_t pos; - if(!basetempl) + if(!templ) return ret; - const MediaSegmentTemplate *templ = dynamic_cast<const MediaSegmentTemplate *>(basetempl); - if(templ) { pos = ret.find("{start time}"); diff --git a/modules/demux/smooth/playlist/Representation.hpp b/modules/demux/smooth/playlist/Representation.hpp index 09eb6927f879779b227eb3526c55e68d8b8ee693..e708fc14a81a009b5916c8bb9f77203abba2e750 100644 --- a/modules/demux/smooth/playlist/Representation.hpp +++ b/modules/demux/smooth/playlist/Representation.hpp @@ -20,7 +20,7 @@ #ifndef SMOOTHREPRESENTATION_HPP #define SMOOTHREPRESENTATION_HPP -#include "../../adaptive/playlist/SegmentInfoCommon.h" +#include "../../adaptive/playlist/SegmentBaseType.hpp" #include "../../adaptive/playlist/BaseRepresentation.h" namespace adaptive @@ -50,7 +50,7 @@ namespace smooth /* for segment templates */ virtual std::string contextualize(size_t, const std::string &, - const BaseSegmentTemplate *) const; // reimpl + const SegmentTemplate *) const; // reimpl }; } } diff --git a/modules/demux/smooth/playlist/SmoothSegment.cpp b/modules/demux/smooth/playlist/SmoothSegment.cpp index fc4eb7ac565b5e9b04ccca23a880b4d45fcec37b..9371353bfc9da96e4bc6515cbe3c8f17e7aca685 100644 --- a/modules/demux/smooth/playlist/SmoothSegment.cpp +++ b/modules/demux/smooth/playlist/SmoothSegment.cpp @@ -64,18 +64,18 @@ void SmoothSegmentChunk::onDownload(block_t **pp_block) } } -SmoothSegment::SmoothSegment(SegmentInformation *parent) : - MediaSegmentTemplate( parent ) +SmoothSegmentTemplate::SmoothSegmentTemplate(SegmentInformation *parent) : + SegmentTemplate( parent ) { } -SmoothSegment::~SmoothSegment() +SmoothSegmentTemplate::~SmoothSegmentTemplate() { } -SegmentChunk* SmoothSegment::createChunk(AbstractChunkSource *source, BaseRepresentation *rep) +SegmentChunk* SmoothSegmentTemplate::createChunk(AbstractChunkSource *source, BaseRepresentation *rep) { /* act as factory */ return new (std::nothrow) SmoothSegmentChunk(source, rep); diff --git a/modules/demux/smooth/playlist/SmoothSegment.hpp b/modules/demux/smooth/playlist/SmoothSegment.hpp index 3849e38034673ba6125aa00e8bb79da3815a3a0c..44261b147bff0026a842805808a3c57324337bf4 100644 --- a/modules/demux/smooth/playlist/SmoothSegment.hpp +++ b/modules/demux/smooth/playlist/SmoothSegment.hpp @@ -37,11 +37,11 @@ namespace smooth virtual void onDownload(block_t **); /* reimpl */ }; - class SmoothSegment : public MediaSegmentTemplate + class SmoothSegmentTemplate : public SegmentTemplate { public: - SmoothSegment(SegmentInformation * = NULL); - ~SmoothSegment(); + SmoothSegmentTemplate(SegmentInformation * = NULL); + ~SmoothSegmentTemplate(); virtual SegmentChunk* createChunk(AbstractChunkSource *, BaseRepresentation *); /* reimpl */ }; }