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 "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)
|
||||||
|
Loading…
Reference in New Issue
Block a user