Commit 442030d6 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: dash: add timeline support

parent d44c8a1e
...@@ -45,7 +45,7 @@ Timelineable::~Timelineable() ...@@ -45,7 +45,7 @@ Timelineable::~Timelineable()
SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) : SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ), Initializable(), ICanonicalUrl( parent ), Initializable(),
duration( -1 ), duration( 0 ),
startIndex( 0 ) startIndex( 0 )
{ {
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "SegmentBase.h" #include "SegmentBase.h"
#include "SegmentList.h" #include "SegmentList.h"
#include "SegmentTemplate.h" #include "SegmentTemplate.h"
#include "SegmentTimeline.h"
using namespace dash::mpd; using namespace dash::mpd;
using namespace std; using namespace std;
...@@ -158,18 +159,19 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con ...@@ -158,18 +159,19 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
{ {
SegmentList *segList; SegmentList *segList;
MediaSegmentTemplate *mediaTemplate; MediaSegmentTemplate *mediaTemplate;
uint64_t timescale; uint64_t timescale = 0;
mtime_t duration = 0; mtime_t duration = 0;
if ( (segList = inheritSegmentList()) )
{ if( (mediaTemplate = inheritSegmentTemplate()) )
timescale = segList->timescale.Get();
duration = segList->getDuration();
}
else if( (mediaTemplate = inheritSegmentTemplate()) )
{ {
timescale = mediaTemplate->timescale.Get(); timescale = mediaTemplate->timescale.Get();
duration = mediaTemplate->duration.Get(); duration = mediaTemplate->duration.Get();
} }
else if ( (segList = inheritSegmentList()) )
{
timescale = segList->timescale.Get();
duration = segList->getDuration();
}
if(duration) if(duration)
{ {
...@@ -182,6 +184,41 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con ...@@ -182,6 +184,41 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
return false; 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 bool SegmentInformation::canBitswitch() const
{ {
if(bitswitch_policy == BITSWITCH_INHERIT) if(bitswitch_policy == BITSWITCH_INHERIT)
......
...@@ -72,6 +72,7 @@ namespace dash ...@@ -72,6 +72,7 @@ namespace dash
ISegment * getSegment(SegmentInfoType, uint64_t = 0) const; ISegment * getSegment(SegmentInfoType, uint64_t = 0) const;
bool getSegmentNumberByTime(mtime_t, uint64_t *) const; bool getSegmentNumberByTime(mtime_t, uint64_t *) const;
mtime_t getPlaybackTimeBySegmentNumber(uint64_t) const;
protected: protected:
std::vector<ISegment *> getSegments() const; std::vector<ISegment *> getSegments() const;
......
...@@ -47,6 +47,53 @@ void SegmentTimeline::addElement(mtime_t d, uint64_t r, mtime_t t) ...@@ -47,6 +47,53 @@ void SegmentTimeline::addElement(mtime_t d, uint64_t r, mtime_t t)
elements.push_back(element); 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_) SegmentTimeline::Element::Element(mtime_t d_, uint64_t r_, mtime_t t_)
{ {
d = d_; d = d_;
......
...@@ -39,6 +39,8 @@ namespace dash ...@@ -39,6 +39,8 @@ namespace dash
SegmentTimeline(); SegmentTimeline();
virtual ~SegmentTimeline(); virtual ~SegmentTimeline();
void addElement(mtime_t d, uint64_t r = 0, mtime_t t = 0); 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: private:
std::list<Element *> elements; std::list<Element *> elements;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "Url.hpp" #include "Url.hpp"
#include "Representation.h" #include "Representation.h"
#include "SegmentTemplate.h" #include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "MPD.h" #include "MPD.h"
#include <sstream> #include <sstream>
...@@ -85,11 +86,31 @@ Url::Component::Component(const std::string & str, const MediaSegmentTemplate *t ...@@ -85,11 +86,31 @@ Url::Component::Component(const std::string & str, const MediaSegmentTemplate *t
templ = templ_; 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 size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) const
{ {
index += templ->startNumber.Get(); index += templ->startNumber.Get();
/* live streams / templated */ /* live streams / templated */
if(rep->getMPD()->isLive() && templ->duration.Get()) if(rep->getMPD()->isLive())
{
if(templ->segmentTimeline.Get())
{
// do nothing ?
}
else if(templ->duration.Get())
{ {
mtime_t playbackstart = rep->getMPD()->playbackStart.Get(); mtime_t playbackstart = rep->getMPD()->playbackStart.Get();
mtime_t streamstart = rep->getMPD()->getAvailabilityStartTime(); mtime_t streamstart = rep->getMPD()->getAvailabilityStartTime();
...@@ -101,6 +122,7 @@ size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep) ...@@ -101,6 +122,7 @@ size_t Url::Component::getSegmentNumber(size_t index, const Representation *rep)
if(duration && timescale) if(duration && timescale)
index += (playbackstart - streamstart) * timescale / duration; index += (playbackstart - streamstart) * timescale / duration;
} }
}
return index; return index;
} }
...@@ -118,7 +140,7 @@ std::string Url::Component::contextualize(size_t index, const Representation *re ...@@ -118,7 +140,7 @@ std::string Url::Component::contextualize(size_t index, const Representation *re
if(pos != std::string::npos) if(pos != std::string::npos)
{ {
std::stringstream ss; std::stringstream ss;
ss << (templ->duration.Get() * index); ss << getScaledTimeBySegmentNumber(index, rep);
ret.replace(pos, std::string("$Time$").length(), ss.str()); ret.replace(pos, std::string("$Time$").length(), ss.str());
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <vlc_common.h>
namespace dash namespace dash
{ {
...@@ -41,6 +42,7 @@ namespace dash ...@@ -41,6 +42,7 @@ namespace dash
protected: protected:
std::string contextualize(size_t, const Representation *) const; std::string contextualize(size_t, const Representation *) const;
mtime_t getScaledTimeBySegmentNumber(size_t, const Representation *) const;
size_t getSegmentNumber(size_t, const Representation *) const; size_t getSegmentNumber(size_t, const Representation *) const;
std::string component; std::string component;
const MediaSegmentTemplate *templ; 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