Commit 38664b80 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: dash: fix setting segment duration time/duration

parent bfe02ea6
...@@ -41,7 +41,7 @@ ISegment::ISegment(const ICanonicalUrl *parent): ...@@ -41,7 +41,7 @@ ISegment::ISegment(const ICanonicalUrl *parent):
{ {
debugName = "Segment"; debugName = "Segment";
classId = CLASSID_ISEGMENT; classId = CLASSID_ISEGMENT;
startTime.Set(VLC_TS_INVALID); startTime.Set(0);
duration.Set(0); duration.Set(0);
chunksuse.Set(0); chunksuse.Set(0);
} }
...@@ -114,7 +114,7 @@ bool ISegment::contains(size_t byte) const ...@@ -114,7 +114,7 @@ bool ISegment::contains(size_t byte) const
int ISegment::compare(ISegment *other) const int ISegment::compare(ISegment *other) const
{ {
if(startTime.Get() != VLC_TS_INVALID) if(duration.Get())
{ {
int64_t diff = startTime.Get() - other->startTime.Get(); int64_t diff = startTime.Get() - other->startTime.Get();
if(diff) if(diff)
......
...@@ -64,3 +64,29 @@ Url SegmentInfoCommon::getUrlSegment() const ...@@ -64,3 +64,29 @@ Url SegmentInfoCommon::getUrlSegment() const
ret.append(baseURLs.front()); ret.append(baseURLs.front());
return ret; return ret;
} }
bool SegmentInfoCommon::getSegmentNumberByTime(const std::vector<ISegment *> &segments,
mtime_t time, uint64_t *ret)
{
if(segments.empty() || segments.front()->duration.Get() == 0)
return false;
std::vector<ISegment *>::const_iterator it = segments.begin();
while(it != segments.end())
{
const ISegment *seg = *it;
if(seg->startTime.Get() > time)
{
if(it == segments.begin())
return false;
else
break;
}
(*ret)++;
it++;
}
(*ret)--;
return true;
}
...@@ -51,6 +51,8 @@ namespace adaptative ...@@ -51,6 +51,8 @@ namespace adaptative
void appendBaseURL( const std::string& url ); void appendBaseURL( const std::string& url );
virtual Url getUrlSegment() const; /* impl */ virtual Url getUrlSegment() const; /* impl */
Property<uint64_t> duration; Property<uint64_t> duration;
static bool getSegmentNumberByTime(const std::vector<ISegment *> &,
mtime_t, uint64_t *);
private: private:
int startIndex; int startIndex;
......
...@@ -101,7 +101,7 @@ std::size_t SegmentInformation::getSegments(SegmentInfoType type, vector<ISegmen ...@@ -101,7 +101,7 @@ std::size_t SegmentInformation::getSegments(SegmentInfoType type, vector<ISegmen
} }
else if ( segmentList && !segmentList->getSegments().empty() ) else if ( segmentList && !segmentList->getSegments().empty() )
{ {
std::vector<Segment *>::const_iterator it; std::vector<ISegment *>::const_iterator it;
for(it=segmentList->getSegments().begin(); for(it=segmentList->getSegments().begin();
it!=segmentList->getSegments().end(); ++it) it!=segmentList->getSegments().end(); ++it)
{ {
...@@ -187,35 +187,32 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co ...@@ -187,35 +187,32 @@ ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) co
bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const bool SegmentInformation::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const
{ {
MediaSegmentTemplate *mediaTemplate; if( mediaSegmentTemplate )
if( (mediaTemplate = inheritSegmentTemplate()) )
{ {
uint64_t timescale = mediaTemplate->inheritTimescale(); const uint64_t timescale = mediaSegmentTemplate->inheritTimescale();
mtime_t duration = mediaTemplate->duration.Get(); const mtime_t duration = mediaSegmentTemplate->duration.Get();
if(duration) if(duration)
{ {
*ret = time / (CLOCK_FREQ * duration / timescale); *ret = time / (CLOCK_FREQ * duration / timescale);
return true; return true;
} }
} }
else else if ( segmentList && !segmentList->getSegments().empty() )
{
std::vector<ISegment *> segments;
getSegments(INFOTYPE_MEDIA, segments);
std::vector<ISegment *>::const_iterator it;
*ret = 0;
for(it = segments.begin(); it != segments.end(); ++it)
{
if((*it)->startTime.Get() > VLC_TS_INVALID &&
(*it)->startTime.Get() > time &&
it != segments.begin())
{ {
return true; return segmentList->getSegmentNumberByTime(time, ret);
}
(*ret)++;
} }
else if( segmentBase )
{
const uint64_t timescale = inheritTimescale();
time = time * timescale / CLOCK_FREQ;
*ret = 0;
const std::vector<ISegment *> list = segmentBase->subSegments();
return SegmentInfoCommon::getSegmentNumberByTime(list, time, ret);
} }
if(parent)
return parent->getSegmentNumberByTime(time, ret);
else
return false; return false;
} }
......
...@@ -35,17 +35,17 @@ SegmentList::SegmentList( SegmentInformation *parent ): ...@@ -35,17 +35,17 @@ SegmentList::SegmentList( SegmentInformation *parent ):
} }
SegmentList::~SegmentList() SegmentList::~SegmentList()
{ {
std::vector<Segment *>::iterator it; std::vector<ISegment *>::iterator it;
for(it = segments.begin(); it != segments.end(); ++it) for(it = segments.begin(); it != segments.end(); ++it)
delete(*it); delete(*it);
} }
const std::vector<Segment*>& SegmentList::getSegments() const const std::vector<ISegment*>& SegmentList::getSegments() const
{ {
return segments; return segments;
} }
void SegmentList::addSegment(Segment *seg) void SegmentList::addSegment(ISegment *seg)
{ {
seg->setParent(this); seg->setParent(this);
segments.push_back(seg); segments.push_back(seg);
...@@ -53,9 +53,9 @@ void SegmentList::addSegment(Segment *seg) ...@@ -53,9 +53,9 @@ void SegmentList::addSegment(Segment *seg)
void SegmentList::mergeWith(SegmentList *updated) void SegmentList::mergeWith(SegmentList *updated)
{ {
const Segment * lastSegment = (segments.empty()) ? NULL : segments.back(); const ISegment * lastSegment = (segments.empty()) ? NULL : segments.back();
std::vector<Segment *>::iterator it; std::vector<ISegment *>::iterator it;
for(it = updated->segments.begin(); it != updated->segments.end(); ++it) for(it = updated->segments.begin(); it != updated->segments.end(); ++it)
{ {
if( !lastSegment || lastSegment->compare( *it ) < 0 ) if( !lastSegment || lastSegment->compare( *it ) < 0 )
...@@ -72,10 +72,10 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum) ...@@ -72,10 +72,10 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum)
return; return;
uint64_t current = pruned; uint64_t current = pruned;
std::vector<Segment *>::iterator it = segments.begin(); std::vector<ISegment *>::iterator it = segments.begin();
while(it != segments.end() && current < tobelownum) while(it != segments.end() && current < tobelownum)
{ {
Segment *seg = *it; ISegment *seg = *it;
if(seg->chunksuse.Get()) /* can't prune from here, still in use */ if(seg->chunksuse.Get()) /* can't prune from here, still in use */
break; break;
delete *it; delete *it;
...@@ -86,10 +86,18 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum) ...@@ -86,10 +86,18 @@ void SegmentList::pruneBySegmentNumber(uint64_t tobelownum)
} }
} }
bool SegmentList::getSegmentNumberByTime(mtime_t time, uint64_t *ret) const
{
const uint64_t timescale = inheritTimescale();
time = time * timescale / CLOCK_FREQ;
*ret = pruned;
return SegmentInfoCommon::getSegmentNumberByTime(segments, time, ret);
}
mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number) mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number)
{ {
if(number < pruned || segments.empty()) if(number < pruned || segments.empty())
return 0; return VLC_TS_INVALID;
uint64_t timescale = inheritTimescale(); uint64_t timescale = inheritTimescale();
mtime_t time = segments.at(0)->startTime.Get(); mtime_t time = segments.at(0)->startTime.Get();
...@@ -106,7 +114,7 @@ mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number) ...@@ -106,7 +114,7 @@ mtime_t SegmentList::getPlaybackTimeBySegmentNumber(uint64_t number)
time = number * duration.Get(); time = number * duration.Get();
} }
return CLOCK_FREQ * time / timescale; return VLC_TS_0 + CLOCK_FREQ * time / timescale;
} }
std::size_t SegmentList::getOffset() const std::size_t SegmentList::getOffset() const
......
...@@ -45,15 +45,16 @@ namespace adaptative ...@@ -45,15 +45,16 @@ namespace adaptative
SegmentList ( SegmentInformation * = NULL ); SegmentList ( SegmentInformation * = NULL );
virtual ~SegmentList (); virtual ~SegmentList ();
const std::vector<Segment *>& getSegments() const; const std::vector<ISegment *>& getSegments() const;
void addSegment(Segment *seg); void addSegment(ISegment *seg);
void mergeWith(SegmentList *); void mergeWith(SegmentList *);
void pruneBySegmentNumber(uint64_t); void pruneBySegmentNumber(uint64_t);
bool getSegmentNumberByTime(mtime_t, uint64_t *) const;
mtime_t getPlaybackTimeBySegmentNumber(uint64_t); mtime_t getPlaybackTimeBySegmentNumber(uint64_t);
std::size_t getOffset() const; std::size_t getOffset() const;
private: private:
std::vector<Segment *> segments; std::vector<ISegment *> segments;
std::size_t pruned; std::size_t pruned;
}; };
} }
......
...@@ -248,7 +248,7 @@ static int Control (demux_t *p_demux, int i_query, va_list args) ...@@ -248,7 +248,7 @@ static int Control (demux_t *p_demux, int i_query, va_list args)
!p_sys->p_dashManager->getDuration() || !p_sys->p_dashManager->getDuration() ||
!p_sys->p_dashManager->setPosition(time)) !p_sys->p_dashManager->setPosition(time))
return VLC_EGENERIC; return VLC_EGENERIC;
p_sys->i_nzpcr = time; p_sys->i_nzpcr = VLC_TS_INVALID;
break; break;
} }
...@@ -258,7 +258,7 @@ static int Control (demux_t *p_demux, int i_query, va_list args) ...@@ -258,7 +258,7 @@ static int Control (demux_t *p_demux, int i_query, va_list args)
if(p_sys->p_mpd->isLive() || if(p_sys->p_mpd->isLive() ||
!p_sys->p_dashManager->setPosition(time)) !p_sys->p_dashManager->setPosition(time))
return VLC_EGENERIC; return VLC_EGENERIC;
p_sys->i_nzpcr = time; p_sys->i_nzpcr = VLC_TS_INVALID;
break; break;
} }
......
...@@ -301,7 +301,6 @@ size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformat ...@@ -301,7 +301,6 @@ size_t IsoffMainParser::parseSegmentBase(Node * segmentBaseNode, SegmentInformat
size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation *info) size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation *info)
{ {
size_t total = 0; size_t total = 0;
mtime_t totaltime = 0;
if(segListNode) if(segListNode)
{ {
std::vector<Node *> segments = DOMHelper::getElementByTagName(segListNode, "SegmentURL", false); std::vector<Node *> segments = DOMHelper::getElementByTagName(segListNode, "SegmentURL", false);
...@@ -337,15 +336,13 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation ...@@ -337,15 +336,13 @@ size_t IsoffMainParser::parseSegmentList(Node * segListNode, SegmentInformation
seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str())); seg->setByteRange(atoi(range.substr(0, pos).c_str()), atoi(range.substr(pos + 1, range.size()).c_str()));
} }
if(totaltime || list->duration.Get()) if(list->duration.Get())
{ {
seg->startTime.Set(totaltime); seg->startTime.Set(nzStartTime);
totaltime += list->duration.Get(); seg->duration.Set(list->duration.Get());
nzStartTime += list->duration.Get();
} }
seg->startTime.Set(VLC_TS_0 + nzStartTime);
nzStartTime += CLOCK_FREQ * list->duration.Get();
list->addSegment(seg); list->addSegment(seg);
total++; total++;
} }
......
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