vlc | branch: master | Francois Cartegnie <[email protected]> | Thu Oct 1 20:49:41 2020 +0200| [7d4c094510c2269c1689f78abd008f93f67b74cf] | committer: Francois Cartegnie
demux: adaptive: move computation to representation > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7d4c094510c2269c1689f78abd008f93f67b74cf --- .../demux/adaptive/playlist/BaseRepresentation.cpp | 194 +++++++++++++++++++++ .../demux/adaptive/playlist/BaseRepresentation.h | 7 + .../demux/adaptive/playlist/SegmentInformation.cpp | 188 -------------------- .../demux/adaptive/playlist/SegmentInformation.hpp | 4 - modules/demux/hls/playlist/Representation.cpp | 2 +- modules/demux/hls/playlist/Representation.hpp | 3 +- 6 files changed, 204 insertions(+), 194 deletions(-) diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.cpp b/modules/demux/adaptive/playlist/BaseRepresentation.cpp index eeda1de3c6..b55808d620 100644 --- a/modules/demux/adaptive/playlist/BaseRepresentation.cpp +++ b/modules/demux/adaptive/playlist/BaseRepresentation.cpp @@ -29,11 +29,16 @@ #include "BaseRepresentation.h" #include "BaseAdaptationSet.h" +#include "AbstractPlaylist.hpp" #include "SegmentTemplate.h" #include "SegmentTimeline.h" +#include "SegmentList.h" +#include "SegmentBase.h" #include "../ID.hpp" #include "../tools/Helper.h" +#include <limits> + using namespace adaptive; using namespace adaptive::playlist; @@ -178,3 +183,192 @@ bool BaseRepresentation::validateCodec(const std::string &) const { return true; } + +uint64_t BaseRepresentation::translateSegmentNumber(uint64_t num, const BaseRepresentation *from) const +{ + vlc_tick_t time, duration; + if( from->getPlaybackTimeDurationBySegmentNumber(num, &time, &duration) ) + getSegmentNumberByTime(time, &num); + return num; +} + +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<ISegment *> list = segmentBase->subSegments(); + return SegmentInfoCommon::getSegmentNumberByScaledTime(list, st, ret); + } + + return false; +} + +bool BaseRepresentation::getPlaybackTimeDurationBySegmentNumber(uint64_t number, + vlc_tick_t *time, vlc_tick_t *duration) const +{ + 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 = getSegment(INFOTYPE_MEDIA, number); + if( segment ) + { + *time = timescale.ToTime(segment->startTime.Get()); + *duration = timescale.ToTime(segment->duration.Get()); + return true; + } + } + + return false; +} + +bool BaseRepresentation::getMediaPlaybackRange(vlc_tick_t *rangeBegin, + vlc_tick_t *rangeEnd, + vlc_tick_t *rangeLength) const +{ + MediaSegmentTemplate *mediaSegmentTemplate = inheritSegmentTemplate(); + if( mediaSegmentTemplate ) + { + const Timescale timescale = mediaSegmentTemplate->inheritTimescale(); + const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline(); + if( timeline ) + { + stime_t startTime, endTime, duration; + if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(timeline->minElementNumber(), + &startTime, &duration) || + !timeline->getScaledPlaybackTimeDurationBySegmentNumber(timeline->maxElementNumber(), + &endTime, &duration)) + return false; + + *rangeBegin = timescale.ToTime(startTime); + *rangeEnd = timescale.ToTime(endTime+duration); + *rangeLength = timescale.ToTime(timeline->getTotalLength()); + return true; + } + /* Else compute, current time and timeshiftdepth based */ + else if( mediaSegmentTemplate->duration.Get() ) + { + *rangeEnd = 0; + *rangeBegin = -1 * getPlaylist()->timeShiftBufferDepth.Get(); + *rangeLength = getPlaylist()->timeShiftBufferDepth.Get(); + return true; + } + } + + SegmentList *segmentList = inheritSegmentList(); + if ( segmentList && !segmentList->getSegments().empty() ) + { + const Timescale timescale = segmentList->inheritTimescale(); + const std::vector<ISegment *> list = segmentList->getSegments(); + + const ISegment *back = list.back(); + const stime_t startTime = list.front()->startTime.Get(); + const stime_t endTime = back->startTime.Get() + back->duration.Get(); + *rangeBegin = timescale.ToTime(startTime); + *rangeEnd = timescale.ToTime(endTime); + *rangeLength = timescale.ToTime(segmentList->getTotalLength()); + return true; + } + + SegmentBase *segmentBase = inheritSegmentBase(); + if( segmentBase ) + { + const std::vector<ISegment *> list = segmentBase->subSegments(); + if(list.empty()) + return false; + + const Timescale timescale = inheritTimescale(); + const ISegment *back = list.back(); + const stime_t startTime = list.front()->startTime.Get(); + const stime_t endTime = back->startTime.Get() + back->duration.Get(); + *rangeBegin = timescale.ToTime(startTime); + *rangeEnd = timescale.ToTime(endTime); + *rangeLength = 0; + return true; + } + + return false; +} diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.h b/modules/demux/adaptive/playlist/BaseRepresentation.h index f8d86999a0..b770b78ffc 100644 --- a/modules/demux/adaptive/playlist/BaseRepresentation.h +++ b/modules/demux/adaptive/playlist/BaseRepresentation.h @@ -77,6 +77,13 @@ namespace adaptive static bool bwCompare(const BaseRepresentation *a, const BaseRepresentation *b); + + virtual uint64_t translateSegmentNumber(uint64_t, const BaseRepresentation *) const; + bool getSegmentNumberByTime(vlc_tick_t, uint64_t *) const; + bool getPlaybackTimeDurationBySegmentNumber(uint64_t, vlc_tick_t *, vlc_tick_t *) const; + bool getMediaPlaybackRange(vlc_tick_t *rangeBegin, + vlc_tick_t *rangeEnd, + vlc_tick_t *rangeLength) const; protected: virtual bool validateCodec(const std::string &) const; BaseAdaptationSet *adaptationSet; diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp index d76025da8a..0f70969e8e 100644 --- a/modules/demux/adaptive/playlist/SegmentInformation.cpp +++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp @@ -162,72 +162,6 @@ std::size_t SegmentInformation::getAllSegments(std::vector<ISegment *> &retSegme return retSegments.size(); } -bool SegmentInformation::getMediaPlaybackRange(vlc_tick_t *rangeBegin, - vlc_tick_t *rangeEnd, - vlc_tick_t *rangeLength) const -{ - if( mediaSegmentTemplate ) - { - const Timescale timescale = mediaSegmentTemplate->inheritTimescale(); - const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline(); - if( timeline ) - { - stime_t startTime, endTime, duration; - if(!timeline->getScaledPlaybackTimeDurationBySegmentNumber(timeline->minElementNumber(), - &startTime, &duration) || - !timeline->getScaledPlaybackTimeDurationBySegmentNumber(timeline->maxElementNumber(), - &endTime, &duration)) - return false; - - *rangeBegin = timescale.ToTime(startTime); - *rangeEnd = timescale.ToTime(endTime+duration); - *rangeLength = timescale.ToTime(timeline->getTotalLength()); - return true; - } - /* Else compute, current time and timeshiftdepth based */ - else if( mediaSegmentTemplate->duration.Get() ) - { - *rangeEnd = 0; - *rangeBegin = -1 * getPlaylist()->timeShiftBufferDepth.Get(); - *rangeLength = getPlaylist()->timeShiftBufferDepth.Get(); - return true; - } - } - else if ( segmentList && !segmentList->getSegments().empty() ) - { - const Timescale timescale = segmentList->inheritTimescale(); - const std::vector<ISegment *> list = segmentList->getSegments(); - - const ISegment *back = list.back(); - const stime_t startTime = list.front()->startTime.Get(); - const stime_t endTime = back->startTime.Get() + back->duration.Get(); - *rangeBegin = timescale.ToTime(startTime); - *rangeEnd = timescale.ToTime(endTime); - *rangeLength = timescale.ToTime(segmentList->getTotalLength()); - return true; - } - else if( segmentBase ) - { - const std::vector<ISegment *> list = segmentBase->subSegments(); - if(list.empty()) - return false; - - const Timescale timescale = inheritTimescale(); - const ISegment *back = list.back(); - const stime_t startTime = list.front()->startTime.Get(); - const stime_t endTime = back->startTime.Get() + back->duration.Get(); - *rangeBegin = timescale.ToTime(startTime); - *rangeEnd = timescale.ToTime(endTime); - *rangeLength = 0; - return true; - } - - if(parent) - return parent->getMediaPlaybackRange(rangeBegin, rangeEnd, rangeLength); - else - return false; -} - /* Returns wanted segment, or next in sequence if not found */ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_pos, uint64_t *pi_newpos, bool *pb_gap) const @@ -328,120 +262,6 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co return NULL; } -bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret) const -{ - 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; - } - } - else if ( segmentList && !segmentList->getSegments().empty() ) - { - const Timescale timescale = segmentList->inheritTimescale(); - stime_t st = timescale.ToScaled(time); - return segmentList->getSegmentNumberByScaledTime(st, ret); - } - else if( segmentBase ) - { - const Timescale timescale = inheritTimescale(); - stime_t st = timescale.ToScaled(time); - *ret = 0; - const std::vector<ISegment *> list = segmentBase->subSegments(); - return SegmentInfoCommon::getSegmentNumberByScaledTime(list, st, ret); - } - - if(parent) - return parent->getSegmentNumberByTime(time, ret); - else - return false; -} - -bool SegmentInformation::getPlaybackTimeDurationBySegmentNumber(uint64_t number, - vlc_tick_t *time, vlc_tick_t *duration) const -{ - SegmentList *segList; - MediaSegmentTemplate *mediaTemplate; - - if(number == std::numeric_limits<uint64_t>::max()) - return false; - - if( (mediaTemplate = inheritSegmentTemplate()) ) - { - 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; - } - else if ( (segList = inheritSegmentList()) ) - { - return segList->getPlaybackTimeDurationBySegmentNumber(number, time, duration); - } - else - { - const Timescale timescale = inheritTimescale(); - const ISegment *segment = getSegment(INFOTYPE_MEDIA, number); - if( segment ) - { - *time = timescale.ToTime(segment->startTime.Get()); - *duration = timescale.ToTime(segment->duration.Get()); - return true; - } - } - - if(parent) - return parent->getPlaybackTimeDurationBySegmentNumber(number, time, duration); - - return false; -} - SegmentInformation * SegmentInformation::getChildByID(const adaptive::ID &id) { std::vector<SegmentInformation *>::const_iterator it; @@ -508,14 +328,6 @@ void SegmentInformation::pruneBySegmentNumber(uint64_t num) mediaSegmentTemplate->pruneBySequenceNumber(num); } -uint64_t SegmentInformation::translateSegmentNumber(uint64_t num, const SegmentInformation *from) const -{ - vlc_tick_t time, duration; - if( from->getPlaybackTimeDurationBySegmentNumber(num, &time, &duration) ) - getSegmentNumberByTime(time, &num); - return num; -} - const CommonEncryption & SegmentInformation::intheritEncryption() const { if(parent && commonEncryption.method == CommonEncryption::Method::NONE) diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp index a32f1f360d..396239c7c4 100644 --- a/modules/demux/adaptive/playlist/SegmentInformation.hpp +++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp @@ -74,14 +74,10 @@ namespace adaptive ISegment * getSegment(SegmentInfoType, uint64_t = 0) const; ISegment * getNextSegment(SegmentInfoType, uint64_t, uint64_t *, bool *) const; - bool getSegmentNumberByTime(vlc_tick_t, uint64_t *) const; - bool getPlaybackTimeDurationBySegmentNumber(uint64_t, vlc_tick_t *, vlc_tick_t *) const; - bool getMediaPlaybackRange(vlc_tick_t *, vlc_tick_t *, vlc_tick_t *) 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); - virtual uint64_t translateSegmentNumber(uint64_t, const SegmentInformation *) const; void setEncryption(const CommonEncryption &); const CommonEncryption & intheritEncryption() const; diff --git a/modules/demux/hls/playlist/Representation.cpp b/modules/demux/hls/playlist/Representation.cpp index 8f6e7e9fa2..4bcdd7beae 100644 --- a/modules/demux/hls/playlist/Representation.cpp +++ b/modules/demux/hls/playlist/Representation.cpp @@ -161,7 +161,7 @@ bool Representation::runLocalUpdates(SharedResources *res) return true; } -uint64_t Representation::translateSegmentNumber(uint64_t num, const SegmentInformation *from) const +uint64_t Representation::translateSegmentNumber(uint64_t num, const BaseRepresentation *from) const { if(consistentSegmentNumber()) return num; diff --git a/modules/demux/hls/playlist/Representation.hpp b/modules/demux/hls/playlist/Representation.hpp index 76420f322d..0d685a3add 100644 --- a/modules/demux/hls/playlist/Representation.hpp +++ b/modules/demux/hls/playlist/Representation.hpp @@ -51,7 +51,8 @@ namespace hls virtual bool needsUpdate(uint64_t) const; /* reimpl */ virtual void debug(vlc_object_t *, int) const; /* reimpl */ virtual bool runLocalUpdates(SharedResources *); /* reimpl */ - virtual uint64_t translateSegmentNumber(uint64_t, const SegmentInformation *) const; /* reimpl */ + + virtual uint64_t translateSegmentNumber(uint64_t, const BaseRepresentation *) const; /* reimpl */ private: StreamFormat streamFormat; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
