[vlc-commits] demux: adaptive: use new buffering logic
Francois Cartegnie
git at videolan.org
Tue Mar 24 23:35:19 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Mar 23 19:37:17 2020 +0100| [f8f3f11fae3f4c95e595a3f0cc3ad5ce8ab8994a] | committer: Francois Cartegnie
demux: adaptive: use new buffering logic
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f8f3f11fae3f4c95e595a3f0cc3ad5ce8ab8994a
---
modules/demux/adaptive/PlaylistManager.cpp | 18 ++-
modules/demux/adaptive/PlaylistManager.h | 2 +
modules/demux/adaptive/SegmentTracker.cpp | 25 +++-
modules/demux/adaptive/SegmentTracker.hpp | 7 +-
modules/demux/adaptive/Streams.cpp | 7 ++
.../demux/adaptive/playlist/SegmentInformation.cpp | 127 +--------------------
.../demux/adaptive/playlist/SegmentInformation.hpp | 2 -
.../demux/adaptive/playlist/SegmentTemplate.cpp | 18 ++-
modules/demux/adaptive/playlist/SegmentTemplate.h | 2 +-
modules/demux/hls/playlist/Parser.cpp | 4 +-
10 files changed, 69 insertions(+), 143 deletions(-)
diff --git a/modules/demux/adaptive/PlaylistManager.cpp b/modules/demux/adaptive/PlaylistManager.cpp
index ce6da8e5dd..fea803ef27 100644
--- a/modules/demux/adaptive/PlaylistManager.cpp
+++ b/modules/demux/adaptive/PlaylistManager.cpp
@@ -36,6 +36,7 @@
#include "logic/AlwaysLowestAdaptationLogic.hpp"
#include "logic/PredictiveAdaptationLogic.hpp"
#include "logic/NearOptimalAdaptationLogic.hpp"
+#include "logic/BufferingLogic.hpp"
#include "tools/Debug.hpp"
#include <vlc_stream.h>
#include <vlc_demux.h>
@@ -61,6 +62,7 @@ PlaylistManager::PlaylistManager( demux_t *p_demux_,
{
currentPeriod = playlist->getFirstPeriod();
resources = res;
+ bufferingLogic = NULL;
failedupdates = 0;
b_thread = false;
b_buffering = false;
@@ -89,6 +91,7 @@ PlaylistManager::~PlaylistManager ()
delete playlist;
delete logic;
delete resources;
+ delete bufferingLogic;
}
void PlaylistManager::unsetPeriod()
@@ -107,6 +110,9 @@ bool PlaylistManager::setupPeriod()
if(!logic && !(logic = createLogic(logicType, resources->getConnManager())))
return false;
+ if(!bufferingLogic && !(bufferingLogic = createBufferingLogic()))
+ return false;
+
std::vector<BaseAdaptationSet*> sets = currentPeriod->getAdaptationSets();
std::vector<BaseAdaptationSet*>::iterator it;
for(it=sets.begin();it!=sets.end();++it)
@@ -114,7 +120,8 @@ bool PlaylistManager::setupPeriod()
BaseAdaptationSet *set = *it;
if(set && streamFactory)
{
- SegmentTracker *tracker = new SegmentTracker(resources, logic, set);
+ SegmentTracker *tracker = new SegmentTracker(resources, logic,
+ bufferingLogic, set);
if(!tracker)
continue;
@@ -610,8 +617,8 @@ void PlaylistManager::setBufferingRunState(bool b)
void PlaylistManager::Run()
{
vlc_mutex_lock(&lock);
- const vlc_tick_t i_min_buffering = playlist->getMinBuffering();
- const vlc_tick_t i_extra_buffering = playlist->getMaxBuffering() - i_min_buffering;
+ const vlc_tick_t i_min_buffering = bufferingLogic->getMinBuffering(playlist);
+ const vlc_tick_t i_extra_buffering = bufferingLogic->getMaxBuffering(playlist) - i_min_buffering;
while(1)
{
while(!b_buffering && !b_canceled)
@@ -823,3 +830,8 @@ AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::L
return logic;
}
+
+AbstractBufferingLogic *PlaylistManager::createBufferingLogic() const
+{
+ return new DefaultBufferingLogic();
+}
diff --git a/modules/demux/adaptive/PlaylistManager.h b/modules/demux/adaptive/PlaylistManager.h
index 55ceacde7c..6d0f6e15c5 100644
--- a/modules/demux/adaptive/PlaylistManager.h
+++ b/modules/demux/adaptive/PlaylistManager.h
@@ -90,10 +90,12 @@ namespace adaptive
/* local factories */
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType,
AbstractConnectionManager *);
+ virtual AbstractBufferingLogic *createBufferingLogic() const;
SharedResources *resources;
AbstractAdaptationLogic::LogicType logicType;
AbstractAdaptationLogic *logic;
+ AbstractBufferingLogic *bufferingLogic;
AbstractPlaylist *playlist;
AbstractStreamFactory *streamFactory;
demux_t *p_demux;
diff --git a/modules/demux/adaptive/SegmentTracker.cpp b/modules/demux/adaptive/SegmentTracker.cpp
index ff853558d7..7655d1621c 100644
--- a/modules/demux/adaptive/SegmentTracker.cpp
+++ b/modules/demux/adaptive/SegmentTracker.cpp
@@ -29,6 +29,7 @@
#include "playlist/Segment.h"
#include "playlist/SegmentChunk.hpp"
#include "logic/AbstractAdaptationLogic.h"
+#include "logic/BufferingLogic.hpp"
#include <cassert>
#include <limits>
@@ -80,7 +81,9 @@ SegmentTrackerEvent::SegmentTrackerEvent(const ID &id, vlc_tick_t duration)
}
SegmentTracker::SegmentTracker(SharedResources *res,
- AbstractAdaptationLogic *logic_, BaseAdaptationSet *adaptSet)
+ AbstractAdaptationLogic *logic_,
+ const AbstractBufferingLogic *bl,
+ BaseAdaptationSet *adaptSet)
{
resources = res;
first = true;
@@ -89,6 +92,7 @@ SegmentTracker::SegmentTracker(SharedResources *res,
index_sent = false;
init_sent = false;
curRepresentation = NULL;
+ bufferingLogic = bl;
setAdaptationLogic(logic_);
adaptationSet = adaptSet;
format = StreamFormat::UNKNOWN;
@@ -213,7 +217,7 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed,
if(curNumber == std::numeric_limits<uint64_t>::max())
{
- next = rep->getLiveStartSegmentNumber(next);
+ next = bufferingLogic->getStartSegmentNumber(rep);
if(next == std::numeric_limits<uint64_t>::max())
return NULL;
}
@@ -381,7 +385,15 @@ vlc_tick_t SegmentTracker::getMinAheadTime() const
if(!rep)
rep = logic->getNextRepresentation(adaptationSet, NULL);
if(rep)
- return rep->getMinAheadTime(curNumber);
+ {
+ /* Ensure ephemere content is updated/loaded */
+ if(rep->needsUpdate())
+ (void) rep->runLocalUpdates(resources);
+
+ uint64_t startnumber = bufferingLogic->getStartSegmentNumber(rep);
+ assert(startnumber != std::numeric_limits<uint64_t>::max());
+ return rep->getMinAheadTime(startnumber);
+ }
return 0;
}
@@ -400,6 +412,13 @@ void SegmentTracker::registerListener(SegmentTrackerListenerInterface *listener)
listeners.push_back(listener);
}
+bool SegmentTracker::bufferingAvailable() const
+{
+ if(adaptationSet->getPlaylist()->isLive())
+ return bufferingLogic->getMinBuffering(adaptationSet->getPlaylist()) <= getMinAheadTime();
+ return true;
+}
+
void SegmentTracker::updateSelected()
{
if(curRepresentation && curRepresentation->needsUpdate())
diff --git a/modules/demux/adaptive/SegmentTracker.hpp b/modules/demux/adaptive/SegmentTracker.hpp
index 4f6e132caf..91dd84c792 100644
--- a/modules/demux/adaptive/SegmentTracker.hpp
+++ b/modules/demux/adaptive/SegmentTracker.hpp
@@ -39,6 +39,7 @@ namespace adaptive
namespace logic
{
class AbstractAdaptationLogic;
+ class AbstractBufferingLogic;
}
namespace playlist
@@ -116,7 +117,9 @@ namespace adaptive
{
public:
SegmentTracker(SharedResources *,
- AbstractAdaptationLogic *, BaseAdaptationSet *);
+ AbstractAdaptationLogic *,
+ const AbstractBufferingLogic *,
+ BaseAdaptationSet *);
~SegmentTracker();
StreamFormat getCurrentFormat() const;
@@ -136,6 +139,7 @@ namespace adaptive
void notifyBufferingLevel(vlc_tick_t, vlc_tick_t, vlc_tick_t) const;
void registerListener(SegmentTrackerListenerInterface *);
void updateSelected();
+ bool bufferingAvailable() const;
private:
void setAdaptationLogic(AbstractAdaptationLogic *);
@@ -149,6 +153,7 @@ namespace adaptive
StreamFormat format;
SharedResources *resources;
AbstractAdaptationLogic *logic;
+ const AbstractBufferingLogic *bufferingLogic;
BaseAdaptationSet *adaptationSet;
BaseRepresentation *curRepresentation;
std::list<SegmentTrackerListenerInterface *> listeners;
diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp
index f78aaf1a70..668aaec412 100644
--- a/modules/demux/adaptive/Streams.cpp
+++ b/modules/demux/adaptive/Streams.cpp
@@ -338,6 +338,13 @@ AbstractStream::buffering_status AbstractStream::doBufferize(vlc_tick_t nz_deadl
return AbstractStream::buffering_suspended;
}
+ /* Reached end of live playlist */
+ if(!segmentTracker->bufferingAvailable())
+ {
+ vlc_mutex_unlock(&lock);
+ return AbstractStream::buffering_suspended;
+ }
+
if(!demuxer)
{
format = segmentTracker->getCurrentFormat();
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.cpp b/modules/demux/adaptive/playlist/SegmentInformation.cpp
index 3e3a24baf8..adbead58f1 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.cpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.cpp
@@ -162,131 +162,6 @@ std::size_t SegmentInformation::getAllSegments(std::vector<ISegment *> &retSegme
return retSegments.size();
}
-uint64_t SegmentInformation::getLiveSegmentNumberByTime(uint64_t def, vlc_tick_t t) const
-{
- if( mediaSegmentTemplate )
- {
- if( mediaSegmentTemplate->duration.Get() )
- {
- return mediaSegmentTemplate->getLiveTemplateNumber(t);
- }
- }
-
- if(parent)
- return parent->getLiveStartSegmentNumber(def);
- else
- return def;
-}
-
-uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const
-{
- const vlc_tick_t i_max_buffering = getPlaylist()->getMaxBuffering() +
- /* FIXME: add dynamic pts-delay */ VLC_TICK_FROM_SEC(1);
-
- /* Try to never buffer up to really end */
- const uint64_t OFFSET_FROM_END = 3;
-
- if( mediaSegmentTemplate )
- {
- uint64_t start = 0;
- uint64_t end = 0;
- const Timescale timescale = mediaSegmentTemplate->inheritTimescale();
-
- const SegmentTimeline *timeline = mediaSegmentTemplate->inheritSegmentTimeline();
- if( timeline )
- {
- start = timeline->minElementNumber();
- end = timeline->maxElementNumber();
- /* Try to never buffer up to really end */
- end = end - std::min(end - start, OFFSET_FROM_END);
- stime_t endtime, duration;
-
- bool b_ret = timeline->getScaledPlaybackTimeDurationBySegmentNumber( end, &endtime, &duration );
- if(unlikely(!b_ret)) /* should never happen */
- {
- assert(b_ret);
- return 0;
- }
-
- vlc_tick_t fromend = std::max( i_max_buffering, getPlaylist()->suggestedPresentationDelay.Get() );
- if( endtime + duration <= timescale.ToScaled( fromend ) )
- return start;
-
- uint64_t number = timeline->getElementNumberByScaledPlaybackTime(endtime - timescale.ToScaled( fromend ));
- if( number < start )
- number = start;
- return number;
- }
- /* Else compute, current time and timeshiftdepth based */
- else if( mediaSegmentTemplate->duration.Get() )
- {
- vlc_tick_t i_delay = getPlaylist()->suggestedPresentationDelay.Get();
-
- if( i_delay == 0 || i_delay > getPlaylist()->timeShiftBufferDepth.Get() )
- i_delay = getPlaylist()->timeShiftBufferDepth.Get();
-
- if( i_delay < getPlaylist()->getMinBuffering() )
- i_delay = getPlaylist()->getMinBuffering();
-
- const uint64_t startnumber = mediaSegmentTemplate->inheritStartNumber();
- end = mediaSegmentTemplate->getLiveTemplateNumber(vlc_tick_from_sec(time(NULL)));
-
- const uint64_t count = timescale.ToScaled( i_delay ) / mediaSegmentTemplate->duration.Get();
- if( startnumber + count >= end )
- start = startnumber;
- else
- start = end - count;
-
- uint64_t bufcount = ( OFFSET_FROM_END + timescale.ToScaled(i_max_buffering) /
- mediaSegmentTemplate->duration.Get() );
- /* Ensure we always pick > start # of availability window as this segment might no longer be avail */
- if( end - start <= bufcount )
- bufcount = end - start - 1;
-
- return ( end - start > bufcount ) ? end - bufcount : start;
- }
- }
- else if ( segmentList && !segmentList->getSegments().empty() )
- {
- const Timescale timescale = segmentList->inheritTimescale();
- const std::vector<ISegment *> list = segmentList->getSegments();
-
- const ISegment *back = list.back();
- vlc_tick_t fromend = std::max( i_max_buffering, getPlaylist()->suggestedPresentationDelay.Get() );
- stime_t bufferingstart = back->startTime.Get() + back->duration.Get() - timescale.ToScaled( fromend );
-
- uint64_t number;
- if( !segmentList->getSegmentNumberByScaledTime( bufferingstart, &number ) )
- return list.front()->getSequenceNumber();
- if( number > list.front()->getSequenceNumber() + OFFSET_FROM_END )
- number -= OFFSET_FROM_END;
- else
- number = list.front()->getSequenceNumber();
- return number;
- }
- else if( segmentBase )
- {
- const std::vector<ISegment *> list = segmentBase->subSegments();
- if(!list.empty())
- return segmentBase->getSequenceNumber();
-
- const Timescale timescale = inheritTimescale();
- const ISegment *back = list.back();
- vlc_tick_t fromend = std::max( i_max_buffering, getPlaylist()->suggestedPresentationDelay.Get() );
- const stime_t bufferingstart = back->startTime.Get() -
- (OFFSET_FROM_END * back->duration.Get())- timescale.ToScaled( fromend );
- uint64_t number;
- if( !SegmentInfoCommon::getSegmentNumberByScaledTime( list, bufferingstart, &number ) )
- return list.front()->getSequenceNumber();
- return number;
- }
-
- if(parent)
- return parent->getLiveStartSegmentNumber(def);
- else
- return def;
-}
-
bool SegmentInformation::getMediaPlaybackRange(vlc_tick_t *rangeBegin,
vlc_tick_t *rangeEnd,
vlc_tick_t *rangeLength) const
@@ -454,7 +329,7 @@ bool SegmentInformation::getSegmentNumberByTime(vlc_tick_t time, uint64_t *ret)
{
if( getPlaylist()->isLive() )
{
- *ret = getLiveSegmentNumberByTime( mediaSegmentTemplate->inheritStartNumber(), time );
+ *ret = mediaSegmentTemplate->getLiveTemplateNumber(time, false);
}
else
{
diff --git a/modules/demux/adaptive/playlist/SegmentInformation.hpp b/modules/demux/adaptive/playlist/SegmentInformation.hpp
index ffbdf9dcb6..48d6e9c227 100644
--- a/modules/demux/adaptive/playlist/SegmentInformation.hpp
+++ b/modules/demux/adaptive/playlist/SegmentInformation.hpp
@@ -75,8 +75,6 @@ namespace adaptive
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;
- uint64_t getLiveSegmentNumberByTime(uint64_t, vlc_tick_t) const;
- uint64_t getLiveStartSegmentNumber(uint64_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 */
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.cpp b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
index 458c9668de..b024936763 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.cpp
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.cpp
@@ -148,7 +148,7 @@ SegmentTimeline * MediaSegmentTemplate::inheritSegmentTimeline() const
return NULL;
}
-uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime) const
+uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime, bool abs) const
{
uint64_t number = inheritStartNumber();
/* live streams / templated */
@@ -156,12 +156,18 @@ uint64_t MediaSegmentTemplate::getLiveTemplateNumber(vlc_tick_t playbacktime) co
if(dur)
{
/* compute, based on current time */
+ /* N = (T - AST - PS - D)/D + sSN */
const Timescale timescale = inheritTimescale();
- vlc_tick_t streamstart =
- vlc_tick_from_sec(parentSegmentInformation->getPlaylist()->availabilityStartTime.Get());
- streamstart += parentSegmentInformation->getPeriodStart();
- stime_t elapsed = timescale.ToScaled(playbacktime - streamstart);
- number += elapsed / dur;
+ if(abs)
+ {
+ vlc_tick_t streamstart =
+ vlc_tick_from_sec(parentSegmentInformation->getPlaylist()->availabilityStartTime.Get());
+ streamstart += parentSegmentInformation->getPeriodStart();
+ playbacktime -= streamstart;
+ }
+ stime_t elapsed = timescale.ToScaled(playbacktime) - dur;
+ if(elapsed > 0)
+ number += elapsed / dur;
}
return number;
diff --git a/modules/demux/adaptive/playlist/SegmentTemplate.h b/modules/demux/adaptive/playlist/SegmentTemplate.h
index 9d100439f1..12d3e1f7c7 100644
--- a/modules/demux/adaptive/playlist/SegmentTemplate.h
+++ b/modules/demux/adaptive/playlist/SegmentTemplate.h
@@ -55,7 +55,7 @@ namespace adaptive
void setSegmentTimeline( SegmentTimeline * );
void updateWith( MediaSegmentTemplate * );
virtual uint64_t getSequenceNumber() const; /* reimpl */
- uint64_t getLiveTemplateNumber(vlc_tick_t) const;
+ 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);
diff --git a/modules/demux/hls/playlist/Parser.cpp b/modules/demux/hls/playlist/Parser.cpp
index 2c4d645007..5dcb370c7f 100644
--- a/modules/demux/hls/playlist/Parser.cpp
+++ b/modules/demux/hls/playlist/Parser.cpp
@@ -32,6 +32,7 @@
#include "../../adaptive/tools/Retrieve.hpp"
#include "../../adaptive/tools/Helper.h"
#include "../../adaptive/tools/Conversions.hpp"
+#include "../../adaptive/logic/BufferingLogic.hpp"
#include "M3U8.hpp"
#include "Tags.hpp"
@@ -148,7 +149,8 @@ void M3U8Parser::createAndFillRepresentation(vlc_object_t *p_obj, BaseAdaptation
if(rep->isLive())
{
/* avoid update playlist immediately */
- uint64_t startseq = rep->getLiveStartSegmentNumber(0);
+ logic::DefaultBufferingLogic buflogic;
+ uint64_t startseq = buflogic.getStartSegmentNumber(rep);
rep->scheduleNextUpdate(startseq);
}
adaptSet->addRepresentation(rep);
More information about the vlc-commits
mailing list