[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