[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