[vlc-commits] demux: adaptive: handle startsegment number offset

Francois Cartegnie git at videolan.org
Wed Mar 24 22:02:37 UTC 2021


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Mar 24 20:01:39 2021 +0100| [fc6790c950f274d4eae8fbc2d331627a9aaa5b0b] | committer: Francois Cartegnie

demux: adaptive: handle startsegment number offset

ref #25518

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fc6790c950f274d4eae8fbc2d331627a9aaa5b0b
---

 modules/demux/adaptive/logic/BufferingLogic.cpp  | 14 ++++++++-
 modules/demux/adaptive/playlist/BasePlaylist.cpp |  1 +
 modules/demux/adaptive/playlist/BasePlaylist.hpp |  1 +
 modules/demux/adaptive/test/playlist/M3U8.cpp    | 37 ++++++++++++++++++++++++
 modules/demux/hls/playlist/Parser.cpp            |  7 +++--
 5 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/modules/demux/adaptive/logic/BufferingLogic.cpp b/modules/demux/adaptive/logic/BufferingLogic.cpp
index f4b713d80e..7d12dfad97 100644
--- a/modules/demux/adaptive/logic/BufferingLogic.cpp
+++ b/modules/demux/adaptive/logic/BufferingLogic.cpp
@@ -87,7 +87,17 @@ uint64_t DefaultBufferingLogic::getStartSegmentNumber(BaseRepresentation *rep) c
         return getLiveStartSegmentNumber(rep);
 
     const AbstractSegmentBaseType *profile = rep->inheritSegmentProfile();
-    return profile ? profile->getStartSegmentNumber() : 0;
+    if(!profile)
+        return 0;
+    uint64_t num = profile->getStartSegmentNumber();
+    vlc_tick_t offset = rep->getPlaylist()->presentationStartOffset.Get();
+    if(offset > 0)
+    {
+        vlc_tick_t startTime, duration;
+        if(profile->getPlaybackTimeDurationBySegmentNumber(num, &startTime, &duration))
+            profile->getSegmentNumberByTime(startTime + offset, &num);
+    }
+    return num;
 }
 
 vlc_tick_t DefaultBufferingLogic::getMinBuffering(const BasePlaylist *p) const
@@ -124,6 +134,8 @@ vlc_tick_t DefaultBufferingLogic::getLiveDelay(const BasePlaylist *p) const
                                      : DEFAULT_LIVE_BUFFERING;
     if(p->suggestedPresentationDelay.Get())
         delay = p->suggestedPresentationDelay.Get();
+    else if(p->presentationStartOffset.Get())
+        delay = p->presentationStartOffset.Get();
     if(p->timeShiftBufferDepth.Get())
         delay = std::min(delay, p->timeShiftBufferDepth.Get());
     return std::max(delay, getMinBuffering(p));
diff --git a/modules/demux/adaptive/playlist/BasePlaylist.cpp b/modules/demux/adaptive/playlist/BasePlaylist.cpp
index 2e3edab52b..14ce175bb4 100644
--- a/modules/demux/adaptive/playlist/BasePlaylist.cpp
+++ b/modules/demux/adaptive/playlist/BasePlaylist.cpp
@@ -47,6 +47,7 @@ BasePlaylist::BasePlaylist (vlc_object_t *p_object_) :
     maxBufferTime = 0;
     timeShiftBufferDepth.Set( 0 );
     suggestedPresentationDelay.Set( 0 );
+    presentationStartOffset.Set( 0 );
     b_needsUpdates = true;
 }
 
diff --git a/modules/demux/adaptive/playlist/BasePlaylist.hpp b/modules/demux/adaptive/playlist/BasePlaylist.hpp
index 6d4f430dc6..7052915d92 100644
--- a/modules/demux/adaptive/playlist/BasePlaylist.hpp
+++ b/modules/demux/adaptive/playlist/BasePlaylist.hpp
@@ -73,6 +73,7 @@ namespace adaptive
                 Property<vlc_tick_t>                   maxSegmentDuration;
                 Property<vlc_tick_t>                   timeShiftBufferDepth;
                 Property<vlc_tick_t>                   suggestedPresentationDelay;
+                Property<vlc_tick_t>                   presentationStartOffset;
 
             protected:
                 vlc_object_t                       *p_object;
diff --git a/modules/demux/adaptive/test/playlist/M3U8.cpp b/modules/demux/adaptive/test/playlist/M3U8.cpp
index fc96faa4a4..1e5b99cc65 100644
--- a/modules/demux/adaptive/test/playlist/M3U8.cpp
+++ b/modules/demux/adaptive/test/playlist/M3U8.cpp
@@ -345,6 +345,43 @@ int M3U8Playlist_test()
         return 1;
     }
 
+    /* Manifest 4 */
+    const char manifest4[] =
+    "#EXTM3U\n"
+    "#EXT-X-MEDIA-SEQUENCE:10\n"
+    "#EXT-X-START:TIME-OFFSET=-11.5,PRECISE=NO\n"
+    "#EXTINF:10\n"
+    "foobar.ts\n"
+    "#EXTINF:10\n"
+    "foobar.ts\n"
+    "#EXTINF:10\n"
+    "foobar.ts\n"
+    "#EXTINF:10\n"
+    "foobar.ts\n"
+    "#EXTINF:10\n"
+    "foobar.ts\n"
+    "#EXT-X-ENDLIST\n";
+
+    m3u = ParseM3U8(obj, manifest4, sizeof(manifest4));
+    try
+    {
+        Expect(m3u);
+        Expect(m3u->isLive() == false);
+        Expect(m3u->presentationStartOffset.Get() == ((50 - 11.5) * CLOCK_FREQ));
+        BaseRepresentation *rep = m3u->getFirstPeriod()->getAdaptationSets().front()->
+                                  getRepresentations().front();
+        Expect(bufferingLogic.getStartSegmentNumber(rep) == 13);
+        m3u->presentationStartOffset.Set(11.5 * CLOCK_FREQ);
+        Expect(bufferingLogic.getStartSegmentNumber(rep) == 11);
+
+        delete m3u;
+    }
+    catch (...)
+    {
+        delete m3u;
+        return 1;
+    }
+
 
     return 0;
 }
diff --git a/modules/demux/hls/playlist/Parser.cpp b/modules/demux/hls/playlist/Parser.cpp
index 07e329ced6..aa2869dad7 100644
--- a/modules/demux/hls/playlist/Parser.cpp
+++ b/modules/demux/hls/playlist/Parser.cpp
@@ -584,8 +584,11 @@ M3U8 * M3U8Parser::parse(vlc_object_t *p_object, stream_t *p_stream, const std::
         if(xstartTag->getAttributeByName("TIME-OFFSET"))
         {
             float offset = xstartTag->getAttributeByName("TIME-OFFSET")->floatingPoint();
-            if(offset > 0)
-                playlist->suggestedPresentationDelay.Set(CLOCK_FREQ * offset);
+            if(offset > 0 && (offset * CLOCK_FREQ) <= playlist->duration.Get())
+                playlist->presentationStartOffset.Set(CLOCK_FREQ * offset);
+            else if(offset < 0 && (-offset * CLOCK_FREQ) <= playlist->duration.Get())
+                playlist->presentationStartOffset.Set(playlist->duration.Get() +
+                                                      CLOCK_FREQ * offset);
         }
     }
 



More information about the vlc-commits mailing list