void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ) { if(!node) return; SegmentTimeline *timeline = new (std::nothrow) SegmentTimeline(templ); if(timeline) { std::vector<Node *> elements = DOMHelper::getElementByTagName(node, "S", false); std::vector<Node *>::const_iterator it; for(it = elements.begin(); it != elements.end(); ++it) { const Node *s = *it; if(!s->hasAttribute("d")) /* Mandatory */ continue; mtime_t d = Integer<mtime_t>(s->getAttributeValue("d")); mtime_t r = 0; // never repeats by default if(s->hasAttribute("r")) r = Integer<uint64_t>(s->getAttributeValue("r")); if(s->hasAttribute("t")) { mtime_t t = Integer<mtime_t>(s->getAttributeValue("t")); timeline->addElement(d, r, t); } else timeline->addElement(d, r); templ->segmentTimeline.Set(timeline); } } }
void SegmentInformation::mergeWithTimeline(SegmentTimeline *updated) { MediaSegmentTemplate *templ = inheritSegmentTemplate(); if(templ) { SegmentTimeline *timeline = templ->segmentTimeline.Get(); if(timeline) timeline->mergeWith(*updated); } }
void MediaSegmentTemplate::mergeWith(MediaSegmentTemplate *updated, vlc_tick_t prunebarrier) { SegmentTimeline *timeline = segmentTimeline.Get(); if(timeline && updated->segmentTimeline.Get()) { timeline->mergeWith(*updated->segmentTimeline.Get()); if(prunebarrier) { const Timescale timescale = timeline->inheritTimescale(); const uint64_t number = timeline->getElementNumberByScaledPlaybackTime(timescale.ToScaled(prunebarrier)); timeline->pruneBySequenceNumber(number); } } }
/* Returns wanted segment, or next in sequence if not found */ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_pos, uint64_t *pi_newpos, bool *pb_gap) const { *pb_gap = false; *pi_newpos = i_pos; if( type != INFOTYPE_MEDIA ) return NULL; std::vector<ISegment *> retSegments; const size_t size = getSegments( type, retSegments ); if( size ) { std::vector<ISegment *>::const_iterator it; for(it = retSegments.begin(); it != retSegments.end(); ++it) { ISegment *seg = *it; if(seg->isTemplate()) /* we don't care about seq number */ { /* Check if we don't exceed timeline */ MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]); SegmentTimeline *timeline = (templ) ? templ->segmentTimeline.Get() : NULL; if(timeline) { *pi_newpos = std::max(timeline->minElementNumber(), i_pos); if(timeline->maxElementNumber() < i_pos) return NULL; } else { *pi_newpos = i_pos; /* start number */ *pi_newpos = std::max((uint64_t)templ->startNumber.Get(), i_pos); } return seg; } else if(seg->getSequenceNumber() >= i_pos) { *pi_newpos = seg->getSequenceNumber(); *pb_gap = (*pi_newpos != i_pos); return seg; } } } return NULL; }
bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const { if( mediaSegmentTemplate ) { const Timescale timescale = mediaSegmentTemplate->inheritTimescale(); SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get(); if(timeline) { time = timescale.ToScaled(time); *ret = timeline->getElementNumberByScaledPlaybackTime(time); return true; } const stime_t duration = mediaSegmentTemplate->duration.Get(); *ret = mediaSegmentTemplate->startNumber.Get(); if(duration) { *ret += timescale.ToScaled(time) / duration; return true; } } else if ( segmentList && !segmentList->getSegments().empty() ) { const Timescale timescale = segmentList->inheritTimescale(); time = timescale.ToScaled(time); return segmentList->getSegmentNumberByScaledTime(time, ret); } else if( segmentBase ) { const Timescale timescale = inheritTimescale(); time = timescale.ToScaled(time); *ret = 0; const std::vector<ISegment *> list = segmentBase->subSegments(); return SegmentInfoCommon::getSegmentNumberByScaledTime(list, time, ret); } if(parent) return parent->getSegmentNumberByTime(time, ret); else return false; }
uint64_t SegmentInformation::getLiveStartSegmentNumber(uint64_t def) const { if( mediaSegmentTemplate ) { SegmentTimeline *timeline = mediaSegmentTemplate->segmentTimeline.Get(); if(timeline) { const uint64_t start = timeline->minElementNumber(); const uint64_t end = timeline->maxElementNumber(); if(end > 2 && (end - start >= 2)) return end - 2; else return start; } return mediaSegmentTemplate->startNumber.Get(); } else if ( segmentList && !segmentList->getSegments().empty() ) { const std::vector<ISegment *> list = segmentList->getSegments(); if(list.size() > 3) return list.at(list.size() - 3)->getSequenceNumber(); else if(!list.empty()) return list.front()->getSequenceNumber(); else return segmentList->getStartIndex(); } else if( segmentBase ) { const std::vector<ISegment *> list = segmentBase->subSegments(); if(list.size() > 3) return list.at(list.size() - 3)->getSequenceNumber(); else if(!list.empty()) return list.front()->getSequenceNumber(); else return segmentBase->getSequenceNumber(); } if(parent) return parent->getLiveStartSegmentNumber(def); else return def; }