From 43a205ff43b7f9b66bc0312760e3ae8c1fad28ef Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Tue, 26 Oct 2021 22:44:22 +0200 Subject: [PATCH] demux: adaptive: rework segmentlist update --- .../demux/adaptive/playlist/SegmentList.cpp | 70 +++++++++++++------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/modules/demux/adaptive/playlist/SegmentList.cpp b/modules/demux/adaptive/playlist/SegmentList.cpp index 147d611760..0d183946e7 100644 --- a/modules/demux/adaptive/playlist/SegmentList.cpp +++ b/modules/demux/adaptive/playlist/SegmentList.cpp @@ -31,6 +31,8 @@ #include "SegmentTimeline.h" #include +#include +#include using namespace adaptive; using namespace adaptive::playlist; @@ -90,41 +92,65 @@ void SegmentList::addSegment(Segment *seg) void SegmentList::updateWith(AbstractMultipleSegmentBaseType *updated_, bool b_restamp) { + stime_t duration = inheritDuration(); + AbstractMultipleSegmentBaseType::updateWith(updated_); SegmentList *updated = dynamic_cast(updated_); if(!updated || updated->segments.empty()) return; - const Segment * lastSegment = (segments.empty()) ? nullptr : segments.back(); - const Segment * prevSegment = lastSegment; + b_restamp = b_relative_mediatimes; - uint64_t firstnumber = updated->segments.front()->getSequenceNumber(); - - std::vector::iterator it; - for(it = updated->segments.begin(); it != updated->segments.end(); ++it) + if(!b_restamp || segments.empty()) { - Segment *cur = *it; - if(!lastSegment || lastSegment->compare(cur) < 0) - { - if(b_restamp && prevSegment) - { - stime_t starttime = prevSegment->startTime.Get() + prevSegment->duration.Get(); - if(starttime != cur->startTime.Get() && !cur->discontinuity) - { - cur->startTime.Set(starttime); - } + if(!segments.empty()) + pruneBySegmentNumber(std::numeric_limits::max()); + assert(segments.empty()); + for(auto seg : updated->segments) + addSegment(seg); + updated->segments.clear(); + } + else + { + const Segment * prevSegment = segments.back(); + const uint64_t oldest = updated->segments.front()->getSequenceNumber(); - prevSegment = cur; + /* filter out known segments from the update */ + updated->segments.erase( + std::remove_if(updated->segments.begin(), updated->segments.end(), + [updated, prevSegment](Segment *s){ + return s->getSequenceNumber() <= prevSegment->getSequenceNumber(); + }), + updated->segments.end()); + + if(updated->segments.empty()) + return; + + /* merge update with current list */ + for(auto it = updated->segments.begin(); it != updated->segments.end(); ++it) + { + Segment *cur = *it; + cur->startTime.Set(prevSegment->startTime.Get() + prevSegment->duration.Get()); + /* not continuous */ + if(cur->getSequenceNumber() != prevSegment->getSequenceNumber() + 1) + { + assert(prevSegment->getSequenceNumber() < cur->getSequenceNumber()); + assert(duration); + uint64_t gap = cur->getSequenceNumber() - prevSegment->getSequenceNumber() - 1; + cur->startTime.Set(cur->startTime.Get() + duration * gap); } + prevSegment = cur; addSegment(cur); } - else - delete cur; - } - updated->segments.clear(); + updated->segments.clear(); - pruneBySegmentNumber(firstnumber); + /* prune previous list using update window start */ + segments.erase(std::remove_if(segments.begin(), segments.end(), + [this, oldest](Segment *s){return s->getSequenceNumber() < oldest;}), + segments.end()); + + } } void SegmentList::pruneByPlaybackTime(vlc_tick_t time)