1
mirror of https://code.videolan.org/videolan/vlc synced 2024-07-21 07:24:15 +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 <limits>
#include <cassert>
#include <algorithm>
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<SegmentList *>(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<Segment *>::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<uint64_t>::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)