SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ), Initializable(),
- duration( -1 ),
+ duration( 0 ),
startIndex( 0 )
{
}
#include "SegmentBase.h"
#include "SegmentList.h"
#include "SegmentTemplate.h"
+#include "SegmentTimeline.h"
using namespace dash::mpd;
using namespace std;
{
SegmentList *segList;
MediaSegmentTemplate *mediaTemplate;
- uint64_t timescale;
+ uint64_t timescale = 0;
mtime_t duration = 0;
- if ( (segList = inheritSegmentList()) )
- {
- timescale = segList->timescale.Get();
- duration = segList->getDuration();
- }
- else if( (mediaTemplate = inheritSegmentTemplate()) )
+
+ if( (mediaTemplate = inheritSegmentTemplate()) )
{
timescale = mediaTemplate->timescale.Get();
duration = mediaTemplate->duration.Get();
}
+ else if ( (segList = inheritSegmentList()) )
+ {
+ timescale = segList->timescale.Get();
+ duration = segList->getDuration();
+ }
if(duration)
{
return false;
}
+mtime_t SegmentInformation::getPlaybackTimeBySegmentNumber(uint64_t number) const
+{
+ SegmentList *segList;
+ MediaSegmentTemplate *mediaTemplate;
+ uint64_t timescale = 0;
+ mtime_t time = 0;
+ if( (mediaTemplate = inheritSegmentTemplate()) )
+ {
+ timescale = mediaTemplate->timescale.Get();
+ if(mediaTemplate->segmentTimeline.Get())
+ {
+ time = mediaTemplate->segmentTimeline.Get()->
+ getScaledPlaybackTimeByElementNumber(number);
+ }
+ else
+ {
+ time = number * mediaTemplate->duration.Get();
+ }
+ }
+ else if ( (segList = inheritSegmentList()) )
+ {
+ timescale = segList->timescale.Get();
+ time = number * segList->getDuration();
+ }
+
+ if(time)
+ {
+ if(!timescale)
+ timescale = getTimescale(); /* inherit */
+ time = CLOCK_FREQ * time / timescale;
+ }
+
+ return time;
+}
+
bool SegmentInformation::canBitswitch() const
{
if(bitswitch_policy == BITSWITCH_INHERIT)
ISegment * getSegment(SegmentInfoType, uint64_t = 0) const;
bool getSegmentNumberByTime(mtime_t, uint64_t *) const;
+ mtime_t getPlaybackTimeBySegmentNumber(uint64_t) const;
protected:
std::vector<ISegment *> getSegments() const;
elements.push_back(element);
}
+uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(time_t scaled) const
+{
+ uint64_t count = 0;
+ std::list<Element *>::const_iterator it;
+ for(it = elements.begin(); it != elements.end(); it++)
+ {
+ const Element *el = *it;
+ for(uint64_t repeat = 1 + el->r; repeat; repeat--)
+ {
+ if(el->d >= scaled)
+ return count;
+
+ scaled -= el->d;
+ count++;
+ }
+ }
+ return count;
+}
+
+mtime_t SegmentTimeline::getScaledPlaybackTimeByElementNumber(uint64_t number) const
+{
+ mtime_t totalscaledtime = 0;
+
+ std::list<Element *>::const_iterator it;
+ for(it = elements.begin(); it != elements.end(); it++)
+ {
+ const Element *el = *it;
+
+ if(number == 0)
+ {
+ totalscaledtime = el->t;
+ break;
+ }
+ else if(number <= el->r)
+ {
+ totalscaledtime = el->t + (number * el->d);
+ break;
+ }
+ else
+ {
+ number -= el->r + 1;
+ }
+ }
+
+ return totalscaledtime;
+}
+
SegmentTimeline::Element::Element(mtime_t d_, uint64_t r_, mtime_t t_)
{
d = d_;
SegmentTimeline();
virtual ~SegmentTimeline();
void addElement(mtime_t d, uint64_t r = 0, mtime_t t = 0);
+ uint64_t getElementNumberByScaledPlaybackTime(time_t) const;
+ mtime_t getScaledPlaybackTimeByElementNumber(uint64_t) const;
private:
std::list<Element *> elements;
#include "Url.hpp"
#include "Representation.h"
#include "SegmentTemplate.h"
+#include "SegmentTimeline.h"
#include "MPD.h"
#include <sstream>
templ = templ_;
}
+mtime_t Url::Component::getScaledTimeBySegmentNumber(size_t index, const Representation *) const
+{
+ mtime_t time = 0;
+ if(templ->segmentTimeline.Get())
+ {
+ time = templ->segmentTimeline.Get()->getScaledPlaybackTimeByElementNumber(index);
+ }
+ else if(templ->duration.Get())
+ {
+ time = templ->duration.Get() * index;
+ }
+ return time;
+}
+
size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const
{
index += templ->startNumber.Get();
/* live streams / templated */
- if(rep->getMPD()->isLive() && templ->duration.Get())
+ if(rep->getMPD()->isLive())
{
- mtime_t playbackstart = rep->getMPD()->playbackStart.Get();
- mtime_t streamstart = rep->getMPD()->getAvailabilityStartTime();
- streamstart += rep->getPeriodStart();
- mtime_t duration = templ->duration.Get();
- uint64_t timescale = templ->timescale.Get() ?
- templ->timescale.Get() :
- rep->getTimescale();
- if(duration && timescale)
- index += (playbackstart - streamstart) * timescale / duration;
+ if(templ->segmentTimeline.Get())
+ {
+ // do nothing ?
+ }
+ else if(templ->duration.Get())
+ {
+ mtime_t playbackstart = rep->getMPD()->playbackStart.Get();
+ mtime_t streamstart = rep->getMPD()->getAvailabilityStartTime();
+ streamstart += rep->getPeriodStart();
+ mtime_t duration = templ->duration.Get();
+ uint64_t timescale = templ->timescale.Get() ?
+ templ->timescale.Get() :
+ rep->getTimescale();
+ if(duration && timescale)
+ index += (playbackstart - streamstart) * timescale / duration;
+ }
}
return index;
}
if(pos != std::string::npos)
{
std::stringstream ss;
- ss << (templ->duration.Get() * index);
+ ss << getScaledTimeBySegmentNumber(index, rep);
ret.replace(pos, std::string("$Time$").length(), ss.str());
}
#include <string>
#include <vector>
+#include <vlc_common.h>
namespace dash
{
protected:
std::string contextualize(size_t, const Representation *) const;
+ mtime_t getScaledTimeBySegmentNumber(size_t, const Representation *) const;
size_t getSegmentNumber(size_t, const Representation *) const;
std::string component;
const MediaSegmentTemplate *templ;