1
mirror of https://code.videolan.org/videolan/vlc synced 2024-09-04 09:11:33 +02:00

demux: adaptive: rework segmentlist update

This commit is contained in:
Francois Cartegnie 2021-10-26 22:44:22 +02:00 committed by Jean-Baptiste Kempf
parent a31b95c1da
commit 43a205ff43

View File

@ -31,6 +31,8 @@
#include "SegmentTimeline.h" #include "SegmentTimeline.h"
#include <limits> #include <limits>
#include <cassert>
#include <algorithm>
using namespace adaptive; using namespace adaptive;
using namespace adaptive::playlist; using namespace adaptive::playlist;
@ -90,41 +92,65 @@ void SegmentList::addSegment(Segment *seg)
void SegmentList::updateWith(AbstractMultipleSegmentBaseType *updated_, void SegmentList::updateWith(AbstractMultipleSegmentBaseType *updated_,
bool b_restamp) bool b_restamp)
{ {
stime_t duration = inheritDuration();
AbstractMultipleSegmentBaseType::updateWith(updated_); AbstractMultipleSegmentBaseType::updateWith(updated_);
SegmentList *updated = dynamic_cast<SegmentList *>(updated_); SegmentList *updated = dynamic_cast<SegmentList *>(updated_);
if(!updated || updated->segments.empty()) if(!updated || updated->segments.empty())
return; return;
const Segment * lastSegment = (segments.empty()) ? nullptr : segments.back(); b_restamp = b_relative_mediatimes;
const Segment * prevSegment = lastSegment;
uint64_t firstnumber = updated->segments.front()->getSequenceNumber(); if(!b_restamp || segments.empty())
std::vector<Segment *>::iterator it;
for(it = updated->segments.begin(); it != updated->segments.end(); ++it)
{ {
Segment *cur = *it; if(!segments.empty())
if(!lastSegment || lastSegment->compare(cur) < 0) pruneBySegmentNumber(std::numeric_limits<uint64_t>::max());
{ assert(segments.empty());
if(b_restamp && prevSegment) for(auto seg : updated->segments)
{ addSegment(seg);
stime_t starttime = prevSegment->startTime.Get() + prevSegment->duration.Get(); updated->segments.clear();
if(starttime != cur->startTime.Get() && !cur->discontinuity) }
{ else
cur->startTime.Set(starttime); {
} 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); addSegment(cur);
} }
else updated->segments.clear();
delete cur;
}
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) void SegmentList::pruneByPlaybackTime(vlc_tick_t time)