From fc6790c950f274d4eae8fbc2d331627a9aaa5b0b Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Wed, 24 Mar 2021 20:01:39 +0100 Subject: [PATCH] demux: adaptive: handle startsegment number offset ref #25518 --- .../demux/adaptive/logic/BufferingLogic.cpp | 14 ++++++- .../demux/adaptive/playlist/BasePlaylist.cpp | 1 + .../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 maxSegmentDuration; Property timeShiftBufferDepth; Property suggestedPresentationDelay; + Property 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); } }