[vlc-commits] demux: hls: sched update from prev one
Francois Cartegnie
git at videolan.org
Thu Jul 23 19:27:50 CEST 2020
vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jul 10 15:43:17 2020 +0200| [860b5656150fbec1d92dbdff9c20a2add247ed36] | committer: Francois Cartegnie
demux: hls: sched update from prev one
should avoid the issues with targetduration rounding
and inaccurate segment durations
(cherry picked from commit d443bd922c331070a211f075e2291ec96c5c2fb1)
> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=860b5656150fbec1d92dbdff9c20a2add247ed36
---
modules/demux/adaptive/SegmentTracker.cpp | 10 ++--
.../demux/adaptive/playlist/BaseRepresentation.cpp | 2 +-
.../demux/adaptive/playlist/BaseRepresentation.h | 2 +-
modules/demux/hls/playlist/Representation.cpp | 66 ++++++++++++----------
modules/demux/hls/playlist/Representation.hpp | 4 +-
5 files changed, 44 insertions(+), 40 deletions(-)
diff --git a/modules/demux/adaptive/SegmentTracker.cpp b/modules/demux/adaptive/SegmentTracker.cpp
index a8beef4526..9646662dfa 100644
--- a/modules/demux/adaptive/SegmentTracker.cpp
+++ b/modules/demux/adaptive/SegmentTracker.cpp
@@ -117,7 +117,7 @@ StreamFormat SegmentTracker::getCurrentFormat() const
if(rep)
{
/* Ensure ephemere content is updated/loaded */
- if(rep->needsUpdate())
+ if(rep->needsUpdate(next))
(void) rep->runLocalUpdates(resources);
return rep->getStreamFormat();
}
@@ -199,7 +199,7 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed,
bool b_updated = false;
/* Ensure ephemere content is updated/loaded */
- if(rep->needsUpdate())
+ if(rep->needsUpdate(next))
b_updated = rep->runLocalUpdates(resources);
if(curNumber == std::numeric_limits<uint64_t>::max())
@@ -313,7 +313,7 @@ bool SegmentTracker::setPositionByTime(mtime_t time, bool restarted, bool tryonl
rep = logic->getNextRepresentation(adaptationSet, NULL);
/* Stream might not have been loaded at all (HLS) or expired */
- if(rep && rep->needsUpdate() && !rep->runLocalUpdates(resources))
+ if(rep && rep->needsUpdate(next) && !rep->runLocalUpdates(resources))
{
msg_Err(rep->getAdaptationSet()->getPlaylist()->getVLCObject(),
"Failed to update Representation %s", rep->getID().str().c_str());
@@ -373,7 +373,7 @@ mtime_t SegmentTracker::getMinAheadTime() const
if(rep)
{
/* Ensure ephemere content is updated/loaded */
- if(rep->needsUpdate())
+ if(rep->needsUpdate(next))
(void) rep->runLocalUpdates(resources);
uint64_t startnumber = curNumber;
@@ -409,7 +409,7 @@ bool SegmentTracker::bufferingAvailable() const
void SegmentTracker::updateSelected()
{
- if(curRepresentation && curRepresentation->needsUpdate())
+ if(curRepresentation && curRepresentation->needsUpdate(next))
{
bool b_updated = curRepresentation->runLocalUpdates(resources);
curRepresentation->scheduleNextUpdate(curNumber, b_updated);
diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.cpp b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
index ade8a93710..b3f9451039 100644
--- a/modules/demux/adaptive/playlist/BaseRepresentation.cpp
+++ b/modules/demux/adaptive/playlist/BaseRepresentation.cpp
@@ -88,7 +88,7 @@ void BaseRepresentation::addCodecs(const std::string &s)
}
}
-bool BaseRepresentation::needsUpdate() const
+bool BaseRepresentation::needsUpdate(uint64_t) const
{
return false;
}
diff --git a/modules/demux/adaptive/playlist/BaseRepresentation.h b/modules/demux/adaptive/playlist/BaseRepresentation.h
index 0946a40357..de0aa28ead 100644
--- a/modules/demux/adaptive/playlist/BaseRepresentation.h
+++ b/modules/demux/adaptive/playlist/BaseRepresentation.h
@@ -65,7 +65,7 @@ namespace adaptive
virtual void pruneByPlaybackTime (mtime_t);
virtual mtime_t getMinAheadTime (uint64_t) const;
- virtual bool needsUpdate () const;
+ virtual bool needsUpdate (uint64_t) const;
virtual bool runLocalUpdates (SharedResources *);
virtual void scheduleNextUpdate (uint64_t, bool);
diff --git a/modules/demux/hls/playlist/Representation.cpp b/modules/demux/hls/playlist/Representation.cpp
index 1944e28e40..a665cebd16 100644
--- a/modules/demux/hls/playlist/Representation.cpp
+++ b/modules/demux/hls/playlist/Representation.cpp
@@ -33,6 +33,7 @@
#include "../../adaptive/playlist/SegmentList.h"
#include <ctime>
+#include <limits>
#include <cassert>
using namespace hls;
@@ -44,7 +45,7 @@ Representation::Representation ( BaseAdaptationSet *set ) :
b_live = true;
b_loaded = false;
b_failed = false;
- nextUpdateTime = 0;
+ lastUpdateTime = 0;
targetDuration = 0;
streamFormat = StreamFormat::UNKNOWN;
}
@@ -100,55 +101,58 @@ void Representation::debug(vlc_object_t *obj, int indent) const
}
}
-void Representation::scheduleNextUpdate(uint64_t number, bool b_updated)
+void Representation::scheduleNextUpdate(uint64_t, bool b_updated)
{
if(!isLive())
return;
- if(!b_updated && nextUpdateTime > 0)
+ if(!b_updated)
+ {
+ /* Ensure we don't update-loop if it failed */
+ //lastUpdateTime = vlc_tick_now();
return;
+ }
- /* Compute new update time */
- mtime_t minbuffer = getMinAheadTime(number);
- const AbstractPlaylist *playlist = getPlaylist();
const mtime_t now = mdate();
+ const AbstractPlaylist *playlist = getPlaylist();
- /* Update frequency must always be at least targetDuration (if any)
- * but we need to update before reaching that last segment, thus -1 */
- if(targetDuration)
- {
- if(minbuffer > CLOCK_FREQ * ( 2 * targetDuration + 1 ))
- minbuffer -= CLOCK_FREQ * ( targetDuration + 1 );
- else
- minbuffer = CLOCK_FREQ * ( targetDuration - 1 );
- }
- else
- {
- if(minbuffer < 10 * CLOCK_FREQ)
- minbuffer = 4 * CLOCK_FREQ;
- else
- minbuffer /= 2;
- }
-
- nextUpdateTime = now + minbuffer;
+ msg_Dbg(playlist->getVLCObject(), "Updated playlist ID %s, after %" PRId64 "s",
+ getID().str().c_str(),
+ lastUpdateTime ? (now - lastUpdateTime)/CLOCK_FREQ : 0);
- msg_Dbg(playlist->getVLCObject(), "Updated playlist ID %s, next update in %" PRId64 "s",
- getID().str().c_str(), (nextUpdateTime - now)/CLOCK_FREQ);
+ lastUpdateTime = now;
debug(playlist->getVLCObject(), 0);
}
-bool Representation::needsUpdate() const
+bool Representation::needsUpdate(uint64_t number) const
{
- return !b_failed && (!b_loaded || (isLive() &&
- nextUpdateTime != 0 &&
- nextUpdateTime < mdate()));
+ if(b_failed)
+ return false;
+ if(!b_loaded)
+ return true;
+ if(isLive())
+ {
+ const mtime_t now = mdate();
+ const mtime_t elapsed = now - lastUpdateTime;
+ const mtime_t duration = targetDuration
+ ? CLOCK_FREQ * targetDuration
+ : CLOCK_FREQ * 2;
+ if(elapsed < duration)
+ return false;
+
+ if(number != std::numeric_limits<uint64_t>::max())
+ {
+ mtime_t minbuffer = getMinAheadTime(number);
+ return ( minbuffer < duration );
+ }
+ }
+ return false;
}
bool Representation::runLocalUpdates(SharedResources *res)
{
AbstractPlaylist *playlist = getPlaylist();
- assert(needsUpdate());
M3U8Parser parser(res);
if(!parser.appendSegmentsFromPlaylistURI(playlist->getVLCObject(), this))
b_failed = true;
diff --git a/modules/demux/hls/playlist/Representation.hpp b/modules/demux/hls/playlist/Representation.hpp
index b3460bd2f8..459cd5cd31 100644
--- a/modules/demux/hls/playlist/Representation.hpp
+++ b/modules/demux/hls/playlist/Representation.hpp
@@ -48,7 +48,7 @@ namespace hls
bool isLive() const;
bool initialized() const;
virtual void scheduleNextUpdate(uint64_t, bool); /* reimpl */
- virtual bool needsUpdate() const; /* reimpl */
+ 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 */
@@ -58,7 +58,7 @@ namespace hls
bool b_live;
bool b_loaded;
bool b_failed;
- mtime_t nextUpdateTime;
+ mtime_t lastUpdateTime;
time_t targetDuration;
Url playlistUrl;
};
More information about the vlc-commits
mailing list