Commit 442030d6 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: dash: add timeline support

parent d44c8a1e
......@@ -45,7 +45,7 @@ Timelineable::~Timelineable()
SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ), Initializable(),
duration( -1 ),
duration( 0 ),
startIndex( 0 )
{
}
......
......@@ -23,6 +23,7 @@
#include "SegmentBase.h"
#include "SegmentList.h"
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
using namespace dash::mpd;
using namespace std;
......@@ -158,18 +159,19 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
{
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)
{
......@@ -182,6 +184,41 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
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)
......
......@@ -72,6 +72,7 @@ namespace dash
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;
......
......@@ -47,6 +47,53 @@ void SegmentTimeline::addElement(mtime_t d, uint64_t r, mtime_t t)
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_;
......
......@@ -39,6 +39,8 @@ namespace dash
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;
......
......@@ -20,6 +20,7 @@
#include "Url.hpp"
#include "Representation.h"
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "MPD.h"
#include <sstream>
......@@ -85,21 +86,42 @@ Url::Component::Component(const std::string & str, const MediaSegmentTemplate *t
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;
}
......@@ -118,7 +140,7 @@ std::string Url::Component::contextualize(size_t index, const Representation *re
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());
}
......
......@@ -22,6 +22,7 @@
#include <string>
#include <vector>
#include <vlc_common.h>
namespace dash
{
......@@ -41,6 +42,7 @@ 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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment