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:
parent
a31b95c1da
commit
43a205ff43
@ -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);
|
||||
}
|
||||
|
||||
prevSegment = cur;
|
||||
}
|
||||
addSegment(cur);
|
||||
if(!segments.empty())
|
||||
pruneBySegmentNumber(std::numeric_limits<uint64_t>::max());
|
||||
assert(segments.empty());
|
||||
for(auto seg : updated->segments)
|
||||
addSegment(seg);
|
||||
updated->segments.clear();
|
||||
}
|
||||
else
|
||||
delete cur;
|
||||
{
|
||||
const Segment * prevSegment = segments.back();
|
||||
const uint64_t oldest = updated->segments.front()->getSequenceNumber();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user