[vlc-commits] demux: dash: add timeline support
Francois Cartegnie
git at videolan.org
Mon Jan 12 20:22:06 CET 2015
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jan 7 21:07:01 2015 +0100| [442030d608a352417c54611f5217b439502a72ca] | committer: Francois Cartegnie
demux: dash: add timeline support
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=442030d608a352417c54611f5217b439502a72ca
---
modules/demux/dash/mpd/SegmentInfoCommon.cpp | 2 +-
modules/demux/dash/mpd/SegmentInformation.cpp | 51 +++++++++++++++++++++----
modules/demux/dash/mpd/SegmentInformation.hpp | 1 +
modules/demux/dash/mpd/SegmentTimeline.cpp | 47 +++++++++++++++++++++++
modules/demux/dash/mpd/SegmentTimeline.h | 2 +
modules/demux/dash/mpd/Url.cpp | 44 +++++++++++++++------
modules/demux/dash/mpd/Url.hpp | 2 +
7 files changed, 130 insertions(+), 19 deletions(-)
diff --git a/modules/demux/dash/mpd/SegmentInfoCommon.cpp b/modules/demux/dash/mpd/SegmentInfoCommon.cpp
index c0d342d..eebacac 100644
--- a/modules/demux/dash/mpd/SegmentInfoCommon.cpp
+++ b/modules/demux/dash/mpd/SegmentInfoCommon.cpp
@@ -45,7 +45,7 @@ Timelineable::~Timelineable()
SegmentInfoCommon::SegmentInfoCommon( ICanonicalUrl *parent ) :
ICanonicalUrl( parent ), Initializable(),
- duration( -1 ),
+ duration( 0 ),
startIndex( 0 )
{
}
diff --git a/modules/demux/dash/mpd/SegmentInformation.cpp b/modules/demux/dash/mpd/SegmentInformation.cpp
index ac8680e..fc80959 100644
--- a/modules/demux/dash/mpd/SegmentInformation.cpp
+++ b/modules/demux/dash/mpd/SegmentInformation.cpp
@@ -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)
diff --git a/modules/demux/dash/mpd/SegmentInformation.hpp b/modules/demux/dash/mpd/SegmentInformation.hpp
index b940241..f099645 100644
--- a/modules/demux/dash/mpd/SegmentInformation.hpp
+++ b/modules/demux/dash/mpd/SegmentInformation.hpp
@@ -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;
diff --git a/modules/demux/dash/mpd/SegmentTimeline.cpp b/modules/demux/dash/mpd/SegmentTimeline.cpp
index 2f1b240..07c4dbf 100644
--- a/modules/demux/dash/mpd/SegmentTimeline.cpp
+++ b/modules/demux/dash/mpd/SegmentTimeline.cpp
@@ -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_;
diff --git a/modules/demux/dash/mpd/SegmentTimeline.h b/modules/demux/dash/mpd/SegmentTimeline.h
index 9764730..f387372 100644
--- a/modules/demux/dash/mpd/SegmentTimeline.h
+++ b/modules/demux/dash/mpd/SegmentTimeline.h
@@ -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;
diff --git a/modules/demux/dash/mpd/Url.cpp b/modules/demux/dash/mpd/Url.cpp
index 5015185..446690b 100644
--- a/modules/demux/dash/mpd/Url.cpp
+++ b/modules/demux/dash/mpd/Url.cpp
@@ -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());
}
diff --git a/modules/demux/dash/mpd/Url.hpp b/modules/demux/dash/mpd/Url.hpp
index 55d80c2..3fe09ad 100644
--- a/modules/demux/dash/mpd/Url.hpp
+++ b/modules/demux/dash/mpd/Url.hpp
@@ -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;
More information about the vlc-commits
mailing list