Commit 673cd4db authored by François Cartegnie's avatar François Cartegnie 🤞

demux: adaptative: fix time units and update times

Since we're dealing with 3 different units (time, mtime and scaled time)
things have gone wrong when merging hls and dash code.

Should fix the crazy manifest/playlist updates
parent 5073078a
......@@ -307,6 +307,7 @@ libadaptative_plugin_la_SOURCES = \
demux/adaptative/Streams.cpp \
demux/adaptative/Streams.hpp \
demux/adaptative/StreamsType.hpp \
demux/adaptative/Time.hpp \
demux/adaptative/tools/Helper.cpp \
demux/adaptative/tools/Helper.h \
demux/adaptative/tools/Properties.hpp \
......
......@@ -85,7 +85,7 @@ namespace adaptative
AbstractStreamOutputFactory *streamOutputFactory;
demux_t *p_demux;
std::vector<Stream *> streams;
mtime_t nextPlaylistupdate;
time_t nextPlaylistupdate;
mtime_t i_nzpcr;
BasePeriod *currentPeriod;
};
......
/*****************************************************************************
* Time.hpp: Adaptative streaming time definitions
*****************************************************************************
* Copyright © 2015 - VideoLAN and VLC Authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef TIME_HPP
#define TIME_HPP
/* Scaled time */
typedef int64_t stime_t;
#endif // TIME_HPP
......@@ -39,7 +39,7 @@ AbstractPlaylist::AbstractPlaylist (stream_t *stream_) :
availabilityStartTime.Set( 0 );
availabilityEndTime.Set( 0 );
duration.Set( 0 );
minUpdatePeriod.Set( 2 );
minUpdatePeriod.Set( 2 * CLOCK_FREQ );
maxSegmentDuration.Set( 0 );
minBufferTime.Set( 0 );
timeShiftBufferDepth.Set( 0 );
......
......@@ -62,10 +62,10 @@ namespace adaptative
Property<time_t> playbackStart;
Property<time_t> availabilityEndTime;
Property<time_t> availabilityStartTime;
Property<time_t> minUpdatePeriod;
Property<mtime_t> minUpdatePeriod;
Property<mtime_t> maxSegmentDuration;
Property<time_t> minBufferTime;
Property<time_t> timeShiftBufferDepth;
Property<mtime_t> minBufferTime;
Property<mtime_t> timeShiftBufferDepth;
protected:
stream_t *stream;
......
......@@ -118,7 +118,7 @@ int ISegment::compare(ISegment *other) const
{
if(duration.Get())
{
int64_t diff = startTime.Get() - other->startTime.Get();
stime_t diff = startTime.Get() - other->startTime.Get();
if(diff)
return diff / diff;
}
......
......@@ -31,6 +31,7 @@
#include "ICanonicalUrl.hpp"
#include "../http/Chunk.h"
#include "../tools/Properties.hpp"
#include "Time.hpp"
namespace adaptative
{
......@@ -61,8 +62,8 @@ namespace adaptative
virtual bool contains (size_t byte) const;
virtual int compare (ISegment *) const;
int getClassId () const;
Property<mtime_t> startTime;
Property<mtime_t> duration;
Property<stime_t> startTime;
Property<stime_t> duration;
Property<unsigned> chunksuse;
static const int CLASSID_ISEGMENT = 0;
......
......@@ -65,8 +65,8 @@ Url SegmentInfoCommon::getUrlSegment() const
return ret;
}
bool SegmentInfoCommon::getSegmentNumberByTime(const std::vector<ISegment *> &segments,
mtime_t time, uint64_t *ret)
bool SegmentInfoCommon::getSegmentNumberByScaledTime(const std::vector<ISegment *> &segments,
stime_t time, uint64_t *ret)
{
if(segments.empty() || (segments.size() > 1 && segments[1]->startTime.Get() == 0) )
return false;
......
......@@ -50,9 +50,9 @@ namespace adaptative
void setStartIndex( int startIndex );
void appendBaseURL( const std::string& url );
virtual Url getUrlSegment() const; /* impl */
Property<uint64_t> duration;
static bool getSegmentNumberByTime(const std::vector<ISegment *> &,
mtime_t, uint64_t *);
Property<stime_t> duration;
static bool getSegmentNumberByScaledTime(const std::vector<ISegment *> &,
stime_t, uint64_t *);
private:
int startIndex;
......
......@@ -198,7 +198,9 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
}
else if ( segmentList && !segmentList->getSegments().empty() )
{
return segmentList->getSegmentNumberByTime(time, ret);
const uint64_t timescale = segmentList->inheritTimescale();
time = time * timescale / CLOCK_FREQ;
return segmentList->getSegmentNumberByScaledTime(time, ret);
}
else if( segmentBase )
{
......@@ -206,7 +208,7 @@ bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) con
time = time * timescale / CLOCK_FREQ;
*ret = 0;
const std::vector<ISegment *> list = segmentBase->subSegments();
return SegmentInfoCommon::getSegmentNumberByTime(list, time, ret);
return SegmentInfoCommon::getSegmentNumberByScaledTime(list, time, ret);
}
if(parent)
......@@ -261,7 +263,7 @@ void SegmentInformation::getDurationsRange(mtime_t *min, mtime_t *max) const
mtime_t total = 0;
for(it = seglist.begin(); it != seglist.end(); ++it)
{
const mtime_t duration = (*it)->duration.Get();
const mtime_t duration = (*it)->duration.Get() * CLOCK_FREQ / inheritTimescale();
if(duration)
{
total += duration;
......@@ -334,7 +336,7 @@ void SegmentInformation::setSegmentTemplate(MediaSegmentTemplate *templ)
}
static void insertIntoSegment(std::vector<ISegment *> &seglist, size_t start,
size_t end, mtime_t time)
size_t end, stime_t time)
{
std::vector<ISegment *>::iterator segIt;
for(segIt = seglist.begin(); segIt < seglist.end(); ++segIt)
......@@ -360,6 +362,7 @@ void SegmentInformation::SplitUsingIndex(std::vector<SplitPoint> &splitlist)
std::vector<SplitPoint>::const_iterator splitIt;
size_t start = 0, end = 0;
mtime_t time = 0;
const uint64_t i_timescale = inheritTimescale();
for(splitIt = splitlist.begin(); splitIt < splitlist.end(); ++splitIt)
{
......@@ -369,7 +372,7 @@ void SegmentInformation::SplitUsingIndex(std::vector<SplitPoint> &splitlist)
if(splitIt == splitlist.begin() && split.offset == 0)
continue;
time = split.time;
insertIntoSegment(seglist, start, end, time);
insertIntoSegment(seglist, start, end, time * i_timescale / CLOCK_FREQ);
end++;
}
......@@ -377,7 +380,7 @@ void SegmentInformation::SplitUsingIndex(std::vector<SplitPoint> &splitlist)
{
start = end;
end = 0;
insertIntoSegment(seglist, start, end, time);
insertIntoSegment(seglist, start, end, time * i_timescale / CLOCK_FREQ);
}
}
......
......@@ -86,12 +86,10 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum)
}
}
bool SegmentList::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const
bool SegmentList::getSegmentNumberByScaledTime(stime_t time, uint64_t *ret) const
{
const uint64_t timescale = inheritTimescale();
time = time * timescale / CLOCK_FREQ;
*ret = pruned;
return SegmentInfoCommon::getSegmentNumberByTime(segments, time, ret);
return SegmentInfoCommon::getSegmentNumberByScaledTime(segments, time, ret);
}
mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number)
......@@ -99,8 +97,8 @@ mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number)
if(number < pruned || segments.empty())
return VLC_TS_INVALID;
uint64_t timescale = inheritTimescale();
mtime_t time = segments.at(0)->startTime.Get();
const uint64_t timescale = inheritTimescale();
stime_t time = segments.at(0)->startTime.Get();
if(segments.at(0)->duration.Get())
{
......
......@@ -49,7 +49,7 @@ namespace adaptative
void addSegment(ISegment *seg);
void mergeWith(SegmentList *);
void pruneBySegmentNumber(uint64_t);
bool getSegmentNumberByTime(mtime_t, uint64_t *) const;
bool getSegmentNumberByScaledTime(stime_t, uint64_t *) const;
mtime_t getPlaybackTimeBySegmentNumber(uint64_t);
std::size_t getOffset() const;
......
......@@ -40,7 +40,7 @@ SegmentTimeline::~SegmentTimeline()
delete *it;
}
void SegmentTimeline::addElement(mtime_t d, uint64_t r, mtime_t t)
void SegmentTimeline::addElement(stime_t d, uint64_t r, stime_t t)
{
Element *element = new (std::nothrow) Element(d, r, t);
if(element)
......@@ -54,7 +54,7 @@ void SegmentTimeline::addElement(mtime_t d, uint64_t r, mtime_t t)
}
}
uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(time_t scaled) const
uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(stime_t scaled) const
{
uint64_t count = 0;
std::list<Element *>::const_iterator it;
......@@ -74,9 +74,9 @@ uint64_t SegmentTimeline::getElementNumberByScaledPlaybackTime(time_t scaled) co
return count;
}
mtime_t SegmentTimeline::getScaledPlaybackTimeByElementNumber(uint64_t number) const
stime_t SegmentTimeline::getScaledPlaybackTimeByElementNumber(uint64_t number) const
{
mtime_t totalscaledtime = 0;
stime_t totalscaledtime = 0;
if(number < pruned)
return 0;
......@@ -120,12 +120,12 @@ size_t SegmentTimeline::maxElementNumber() const
size_t SegmentTimeline::prune(mtime_t time)
{
mtime_t scaled = time * inheritTimescale() / CLOCK_FREQ;
stime_t scaled = time * inheritTimescale() / CLOCK_FREQ;
size_t prunednow = 0;
while(elements.size())
{
Element *el = elements.front();
if(el->t + (el->d * (mtime_t)(el->r + 1)) < scaled)
if(el->t + (el->d * (stime_t)(el->r + 1)) < scaled)
{
prunednow += el->r + 1;
delete el;
......@@ -163,7 +163,7 @@ void SegmentTimeline::mergeWith(SegmentTimeline &other)
}
else if(el->t > last->t) /* Did not exist in previous list */
{
if( el->t - last->t >= last->d * (mtime_t)(last->r + 1) )
if( el->t - last->t >= last->d * (stime_t)(last->r + 1) )
{
elements.push_back(el);
last = el;
......@@ -191,7 +191,7 @@ mtime_t SegmentTimeline::start() const
{
if(elements.empty())
return 0;
return CLOCK_FREQ * elements.front()->t / inheritTimescale();
return elements.front()->t * CLOCK_FREQ / inheritTimescale();
}
mtime_t SegmentTimeline::end() const
......@@ -199,11 +199,11 @@ mtime_t SegmentTimeline::end() const
if(elements.empty())
return 0;
const Element *last = elements.back();
mtime_t scaled = last->t + last->d * (last->r + 1);
return CLOCK_FREQ * scaled / inheritTimescale();
stime_t scaled = last->t + last->d * (last->r + 1);
return scaled * CLOCK_FREQ / inheritTimescale();
}
SegmentTimeline::Element::Element(mtime_t d_, uint64_t r_, mtime_t t_)
SegmentTimeline::Element::Element(stime_t d_, uint64_t r_, stime_t t_)
{
d = d_;
t = t_;
......
......@@ -43,9 +43,9 @@ namespace adaptative
public:
SegmentTimeline(TimescaleAble * = NULL);
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;
void addElement(stime_t d, uint64_t r = 0, stime_t t = 0);
uint64_t getElementNumberByScaledPlaybackTime(stime_t) const;
stime_t getScaledPlaybackTimeByElementNumber(uint64_t) const;
size_t maxElementNumber() const;
size_t prune(mtime_t);
void mergeWith(SegmentTimeline &);
......@@ -59,9 +59,9 @@ namespace adaptative
class Element
{
public:
Element(mtime_t, uint64_t, mtime_t);
mtime_t t;
mtime_t d;
Element(stime_t, uint64_t, stime_t);
stime_t t;
stime_t d;
uint64_t r;
};
};
......
......@@ -78,7 +78,7 @@ bool DASHManager::updatePlaylist()
if(!playlist->isLive() || !playlist->minUpdatePeriod.Get())
return true;
mtime_t now = time(NULL);
time_t now = time(NULL);
if(nextPlaylistupdate && now < nextPlaylistupdate)
return true;
......@@ -98,7 +98,7 @@ bool DASHManager::updatePlaylist()
if(!mpdstream)
{
free(p_data);
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get();
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get() / CLOCK_FREQ;
return false;
}
......@@ -106,7 +106,7 @@ bool DASHManager::updatePlaylist()
if(!parser.parse())
{
stream_Delete(mpdstream);
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get();
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get() / CLOCK_FREQ;
return false;
}
......@@ -134,19 +134,20 @@ bool DASHManager::updatePlaylist()
mtime_t mininterval = 0;
mtime_t maxinterval = 0;
playlist->getTimeLinesBoundaries(&mininterval, &maxinterval);
if(maxinterval > mininterval)
maxinterval = (maxinterval - mininterval);
else
maxinterval = 60 * CLOCK_FREQ;
maxinterval = std::max(maxinterval, (mtime_t)60 * CLOCK_FREQ);
mininterval = std::max(playlist->minUpdatePeriod.Get() * CLOCK_FREQ,
playlist->maxSegmentDuration.Get());
if(playlist->minUpdatePeriod.Get() > mininterval)
mininterval = playlist->minUpdatePeriod.Get();
nextPlaylistupdate = now + (maxinterval - mininterval) / (2 * CLOCK_FREQ);
if(mininterval < 5 * CLOCK_FREQ)
mininterval = 5 * CLOCK_FREQ;
if(maxinterval < mininterval)
maxinterval = mininterval;
nextPlaylistupdate = now + (mininterval + (maxinterval - mininterval) / 2) / CLOCK_FREQ;
msg_Dbg(p_demux, "Updated MPD, next update in %" PRId64 "s (%" PRId64 "..%" PRId64 ")",
nextPlaylistupdate - now, mininterval, maxinterval );
nextPlaylistupdate - now, mininterval/ CLOCK_FREQ, maxinterval/ CLOCK_FREQ );
return true;
}
......
......@@ -101,12 +101,12 @@ void IsoffMainParser::setMPDAttributes ()
it = attr.find("minBufferTime");
if(it != attr.end())
this->mpd->minBufferTime.Set(IsoTime(it->second));
this->mpd->minBufferTime.Set(IsoTime(it->second) * CLOCK_FREQ);
it = attr.find("minimumUpdatePeriod");
if(it != attr.end())
{
mtime_t minupdate = IsoTime(it->second);
mtime_t minupdate = IsoTime(it->second) * CLOCK_FREQ;
if(minupdate > 0)
mpd->minUpdatePeriod.Set(minupdate);
}
......@@ -125,7 +125,7 @@ void IsoffMainParser::setMPDAttributes ()
it = attr.find("timeShiftBufferDepth");
if(it != attr.end())
mpd->timeShiftBufferDepth.Set(IsoTime(it->second));
mpd->timeShiftBufferDepth.Set(IsoTime(it->second) * CLOCK_FREQ);
}
void IsoffMainParser::parsePeriods(Node *root)
......@@ -140,9 +140,9 @@ void IsoffMainParser::parsePeriods(Node *root)
continue;
parseSegmentInformation(*it, period);
if((*it)->hasAttribute("start"))
period->startTime.Set(IsoTime((*it)->getAttributeValue("start")));
period->startTime.Set(IsoTime((*it)->getAttributeValue("start")) * CLOCK_FREQ);
if((*it)->hasAttribute("duration"))
period->duration.Set(IsoTime((*it)->getAttributeValue("duration")));
period->duration.Set(IsoTime((*it)->getAttributeValue("duration")) * CLOCK_FREQ);
if((*it)->hasAttribute("id"))
period->setId((*it)->getAttributeValue("id"));
std::vector<Node *> baseUrls = DOMHelper::getChildElementByTagName(*it, "BaseURL");
......@@ -169,12 +169,12 @@ size_t IsoffMainParser::parseSegmentTemplate(Node *templateNode, SegmentInformat
if(templateNode->hasAttribute("startNumber"))
mediaTemplate->startNumber.Set(Integer<uint64_t>(templateNode->getAttributeValue("startNumber")));
if(templateNode->hasAttribute("duration"))
mediaTemplate->duration.Set(Integer<mtime_t>(templateNode->getAttributeValue("duration")));
if(templateNode->hasAttribute("timescale"))
mediaTemplate->timescale.Set(Integer<uint64_t>(templateNode->getAttributeValue("timescale")));
if(templateNode->hasAttribute("duration"))
mediaTemplate->duration.Set(Integer<stime_t>(templateNode->getAttributeValue("duration")));
InitSegmentTemplate *initTemplate = NULL;
if(templateNode->hasAttribute("initialization"))
......@@ -346,7 +346,7 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation
parseInitSegment(DOMHelper::getFirstChildElementByName(segListNode, "Initialization"), list, info);
if(segListNode->hasAttribute("duration"))
list->duration.Set(Integer<uint64_t>(segListNode->getAttributeValue("duration")));
list->duration.Set(Integer<stime_t>(segListNode->getAttributeValue("duration")));
if(segListNode->hasAttribute("timescale"))
list->timescale.Set(Integer<uint64_t>(segListNode->getAttributeValue("timescale")));
......@@ -422,13 +422,13 @@ void IsoffMainParser::parseTimeline(Node *node, MediaSegmentTemplate *templ)
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
stime_t d = Integer<stime_t>(s->getAttributeValue("d"));
uint64_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"));
stime_t t = Integer<stime_t>(s->getAttributeValue("t"));
timeline->addElement(d, r, t);
}
else timeline->addElement(d, r);
......@@ -470,7 +470,7 @@ IsoTime::IsoTime(const std::string &str)
time = str_duration(str.c_str());
}
IsoTime::operator mtime_t () const
IsoTime::operator time_t () const
{
return time;
}
......@@ -543,7 +543,7 @@ UTCTime::UTCTime(const std::string &str)
}
}
UTCTime::operator mtime_t () const
UTCTime::operator time_t () const
{
return time;
}
......@@ -94,20 +94,20 @@ namespace dash
{
public:
IsoTime(const std::string&);
operator mtime_t() const;
operator time_t() const;
private:
mtime_t time;
time_t time;
};
class UTCTime
{
public:
UTCTime(const std::string&);
operator mtime_t() const;
operator time_t() const;
private:
mtime_t time;
time_t time;
};
template<typename T> class Integer
......
......@@ -103,7 +103,7 @@ std::string Representation::contextualize(size_t index, const std::string &compo
if(pos != std::string::npos)
{
std::stringstream ss;
ss << getScaledTimeBySegmentNumber(index, templ);
ss << (getScaledTimeBySegmentNumber(index, templ) * CLOCK_FREQ / templ->inheritTimescale());
ret.replace(pos, std::string("$Time$").length(), ss.str());
}
......@@ -187,13 +187,13 @@ size_t Representation::getSegmentNumber(size_t index, const MediaSegmentTemplate
}
else if(templ->duration.Get())
{
mtime_t playbackstart = getPlaylist()->playbackStart.Get();
mtime_t streamstart = getPlaylist()->availabilityStartTime.Get();
const mtime_t playbackstart = getPlaylist()->playbackStart.Get() * CLOCK_FREQ;
mtime_t streamstart = getPlaylist()->availabilityStartTime.Get() * CLOCK_FREQ;
streamstart += getPeriodStart();
mtime_t duration = templ->duration.Get();
uint64_t timescale = templ->inheritTimescale();
const stime_t duration = templ->duration.Get();
const uint64_t timescale = templ->inheritTimescale();
if(duration && timescale)
index += (playbackstart - streamstart) * timescale / duration;
index += (playbackstart - streamstart) * timescale * duration / CLOCK_FREQ;
}
}
return index;
......
......@@ -128,7 +128,7 @@ bool HLSManager::updatePlaylist()
if(!playlist->isLive() || !playlist->minUpdatePeriod.Get())
return true;
mtime_t now = time(NULL);
time_t now = time(NULL);
if(nextPlaylistupdate && now < nextPlaylistupdate)
return true;
......@@ -150,7 +150,7 @@ bool HLSManager::updatePlaylist()
if(!updatestream)
{
free(p_data);
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get();
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get() / CLOCK_FREQ;
return false;
}
......@@ -159,7 +159,7 @@ bool HLSManager::updatePlaylist()
if(!updatedplaylist)
{
stream_Delete(updatestream);
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get();
nextPlaylistupdate = now + playlist->minUpdatePeriod.Get() / CLOCK_FREQ;
return false;
}
......@@ -189,17 +189,19 @@ bool HLSManager::updatePlaylist()
playlist->getPlaylistDurationsRange(&mininterval, &maxinterval);
}
if(playlist->minUpdatePeriod.Get() * CLOCK_FREQ > mininterval)
mininterval = playlist->minUpdatePeriod.Get() * CLOCK_FREQ;
if(playlist->minUpdatePeriod.Get() > mininterval)
mininterval = playlist->minUpdatePeriod.Get();
if(mininterval < 5 * CLOCK_FREQ)
mininterval = 5 * CLOCK_FREQ;
if(maxinterval < mininterval)
maxinterval = mininterval;
nextPlaylistupdate = now + (mininterval + maxinterval) / (2 * CLOCK_FREQ);
nextPlaylistupdate = now + (mininterval + (maxinterval - mininterval) / 2) / CLOCK_FREQ;
msg_Dbg(p_demux, "Updated playlist, next update in %" PRId64 "s "
"%" PRId64 " %" PRId64, nextPlaylistupdate - now, mininterval,
maxinterval);
msg_Dbg(p_demux, "Updated playlist, next update in %" PRId64 "s (""%" PRId64 "..%" PRId64 ")",
nextPlaylistupdate - now, mininterval/ CLOCK_FREQ, maxinterval/ CLOCK_FREQ);
return true;
}
......@@ -34,7 +34,7 @@ using namespace hls::playlist;
M3U8::M3U8 (stream_t *stream_) :
AbstractPlaylist(stream_)
{
minUpdatePeriod.Set( 5 );
minUpdatePeriod.Set( 5 * CLOCK_FREQ );
}
M3U8::~M3U8()
......
......@@ -186,8 +186,8 @@ void Parser::parseSegments(Representation *rep, const std::list<Tag *> &tagslist
rep->timescale.Set(100);
int64_t totalduration = 0;
int64_t nzStartTime = 0;
stime_t totalduration = 0;
stime_t nzStartTime = 0;
uint64_t sequenceNumber = 0;
std::size_t prevbyterangeoffset = 0;
const SingleValueTag *ctx_byterange = NULL;
......@@ -298,9 +298,9 @@ void Parser::parseSegments(Representation *rep, const std::list<Tag *> &tagslist
{
rep->getPlaylist()->duration.Set(0);
}
else if(totalduration > rep->getPlaylist()->duration.Get())
else if(totalduration * CLOCK_FREQ / rep->timescale.Get() > rep->getPlaylist()->duration.Get())
{
rep->getPlaylist()->duration.Set(CLOCK_FREQ * totalduration / rep->timescale.Get());
rep->getPlaylist()->duration.Set(totalduration * CLOCK_FREQ / rep->timescale.Get());
}
}
......
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