[vlc-commits] demux: adaptative: restart on seek
Francois Cartegnie
git at videolan.org
Wed Jun 10 18:58:07 CEST 2015
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jun 5 15:44:23 2015 +0200| [ed2fe051dab89da249b97bfe5c68927c872a7595] | committer: Francois Cartegnie
demux: adaptative: restart on seek
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ed2fe051dab89da249b97bfe5c68927c872a7595
---
modules/demux/adaptative/SegmentTracker.cpp | 7 +-
modules/demux/adaptative/SegmentTracker.hpp | 2 +-
modules/demux/adaptative/Streams.cpp | 113 ++++++++++++++++++++++-----
modules/demux/adaptative/Streams.hpp | 8 +-
4 files changed, 106 insertions(+), 24 deletions(-)
diff --git a/modules/demux/adaptative/SegmentTracker.cpp b/modules/demux/adaptative/SegmentTracker.cpp
index a9fc992..7480d89 100644
--- a/modules/demux/adaptative/SegmentTracker.cpp
+++ b/modules/demux/adaptative/SegmentTracker.cpp
@@ -54,7 +54,7 @@ void SegmentTracker::resetCounter()
prevRepresentation = NULL;
}
-Chunk * SegmentTracker::getNextChunk(StreamType type)
+Chunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed)
{
BaseRepresentation *rep;
ISegment *segment;
@@ -62,7 +62,8 @@ Chunk * SegmentTracker::getNextChunk(StreamType type)
if(!currentPeriod)
return NULL;
- if(prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE)
+ if( !switch_allowed ||
+ (prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) )
rep = prevRepresentation;
else
rep = logic->getCurrentRepresentation(type, currentPeriod);
@@ -97,7 +98,7 @@ Chunk * SegmentTracker::getNextChunk(StreamType type)
{
currentPeriod = playlist->getNextPeriod(currentPeriod);
resetCounter();
- return getNextChunk(type);
+ return getNextChunk(type, switch_allowed);
}
Chunk *chunk = segment->toChunk(count, rep);
diff --git a/modules/demux/adaptative/SegmentTracker.hpp b/modules/demux/adaptative/SegmentTracker.hpp
index e1d1510..e293c07 100644
--- a/modules/demux/adaptative/SegmentTracker.hpp
+++ b/modules/demux/adaptative/SegmentTracker.hpp
@@ -58,7 +58,7 @@ namespace adaptative
void setAdaptationLogic(AbstractAdaptationLogic *);
void resetCounter();
- Chunk* getNextChunk(StreamType);
+ Chunk* getNextChunk(StreamType, bool);
bool setPosition(mtime_t, bool, bool);
mtime_t getSegmentStart() const;
void pruneFromCurrent();
diff --git a/modules/demux/adaptative/Streams.cpp b/modules/demux/adaptative/Streams.cpp
index 0637357..2c5a0c2 100644
--- a/modules/demux/adaptative/Streams.cpp
+++ b/modules/demux/adaptative/Streams.cpp
@@ -127,7 +127,7 @@ Chunk * Stream::getChunk()
{
if (currentChunk == NULL)
{
- currentChunk = segmentTracker->getNextChunk(type);
+ currentChunk = segmentTracker->getNextChunk(type, output->switchAllowed());
if (currentChunk == NULL)
eof = true;
}
@@ -280,6 +280,7 @@ BaseStreamOutput::BaseStreamOutput(demux_t *demux, const std::string &name) :
{
this->name = name;
seekable = true;
+ restarting = false;
demuxstream = NULL;
fakeesout = new es_out_t;
@@ -295,7 +296,8 @@ BaseStreamOutput::BaseStreamOutput(demux_t *demux, const std::string &name) :
fakeesout->pf_send = esOutSend;
fakeesout->p_sys = (es_out_sys_t*) this;
- if(!restart())
+ demuxstream = stream_DemuxNew(realdemux, name.c_str(), fakeesout);
+ if(!demuxstream)
throw VLC_EGENERIC;
}
@@ -303,14 +305,14 @@ BaseStreamOutput::~BaseStreamOutput()
{
if (demuxstream)
stream_Delete(demuxstream);
- delete fakeesout;
-
- vlc_mutex_destroy(&lock);
/* shouldn't be any */
std::list<Demuxed *>::const_iterator it;
for(it=queues.begin(); it!=queues.end();++it)
delete *it;
+
+ delete fakeesout;
+ vlc_mutex_destroy(&lock);
}
int BaseStreamOutput::esCount() const
@@ -325,7 +327,8 @@ void BaseStreamOutput::pushBlock(block_t *block)
bool BaseStreamOutput::seekAble() const
{
- return (demuxstream && seekable);
+ bool b_canswitch = switchAllowed();
+ return (demuxstream && seekable && b_canswitch);
}
void BaseStreamOutput::setPosition(mtime_t nztime)
@@ -353,6 +356,7 @@ bool BaseStreamOutput::restart()
return false;
vlc_mutex_lock(&lock);
+ restarting = true;
stream_t *olddemuxstream = demuxstream;
demuxstream = newdemuxstream;
vlc_mutex_unlock(&lock);
@@ -365,7 +369,16 @@ bool BaseStreamOutput::restart()
bool BaseStreamOutput::reinitsOnSeek() const
{
- return false;
+ return true;
+}
+
+bool BaseStreamOutput::switchAllowed() const
+{
+ bool b_allowed;
+ vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
+ b_allowed = !restarting;
+ vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
+ return b_allowed;
}
void BaseStreamOutput::sendToDecoder(mtime_t nzdeadline)
@@ -395,15 +408,18 @@ void BaseStreamOutput::sendToDecoderUnlocked(mtime_t nzdeadline)
}
}
-BaseStreamOutput::Demuxed::Demuxed()
+BaseStreamOutput::Demuxed::Demuxed(es_out_id_t *id, const es_format_t *fmt)
{
p_queue = NULL;
pp_queue_last = &p_queue;
- es_id = NULL;
+ es_id = id;
+ es_format_Init(&fmtcpy, UNKNOWN_ES, 0);
+ es_format_Copy(&fmtcpy, fmt);
}
BaseStreamOutput::Demuxed::~Demuxed()
{
+ es_format_Clean(&fmtcpy);
drop();
}
@@ -418,18 +434,52 @@ void BaseStreamOutput::Demuxed::drop()
es_out_id_t * BaseStreamOutput::esOutAdd(es_out_t *fakees, const es_format_t *p_fmt)
{
BaseStreamOutput *me = (BaseStreamOutput *) fakees->p_sys;
- es_out_id_t *p_es = me->realdemux->out->pf_add(me->realdemux->out, p_fmt);
- if(p_es)
+
+ es_out_id_t *p_es = NULL;
+
+ vlc_mutex_lock(&me->lock);
+
+ std::list<Demuxed *>::iterator it;
+ bool b_hasestorecyle = false;
+ for(it=me->queues.begin(); it!=me->queues.end();++it)
+ {
+ Demuxed *pair = *it;
+ b_hasestorecyle |= pair->recycle;
+
+ if( p_es )
+ continue;
+
+ if( me->restarting )
+ {
+ /* If we're recycling from same format */
+ if( es_format_IsSimilar(p_fmt, &pair->fmtcpy) &&
+ p_fmt->i_extra == pair->fmtcpy.i_extra &&
+ !memcmp(p_fmt->p_extra, pair->fmtcpy.p_extra, p_fmt->i_extra) )
+ {
+ msg_Err(me->realdemux, "using recycled");
+ pair->recycle = false;
+ p_es = pair->es_id;
+ }
+ }
+ }
+
+ if(!b_hasestorecyle)
+ {
+ me->restarting = false;
+ }
+
+ if(!p_es)
{
- vlc_mutex_lock(&me->lock);
- Demuxed *pair = new (std::nothrow) Demuxed();
- if(pair)
+ p_es = me->realdemux->out->pf_add(me->realdemux->out, p_fmt);
+ if(p_es)
{
- pair->es_id = p_es;
- me->queues.push_back(pair);
+ Demuxed *pair = new (std::nothrow) Demuxed(p_es, p_fmt);
+ if(pair)
+ me->queues.push_back(pair);
}
- vlc_mutex_unlock(&me->lock);
}
+ vlc_mutex_unlock(&me->lock);
+
return p_es;
}
@@ -461,13 +511,27 @@ void BaseStreamOutput::esOutDel(es_out_t *fakees, es_out_id_t *p_es)
if((*it)->es_id == p_es)
{
me->sendToDecoderUnlocked(INT64_MAX - VLC_TS_0);
+ break;
+ }
+ }
+
+ if(it != me->queues.end())
+ {
+ if(me->restarting)
+ {
+ (*it)->recycle = true;
+ }
+ else
+ {
delete *it;
me->queues.erase(it);
- break;
}
}
+
+ if(!me->restarting)
+ me->realdemux->out->pf_del(me->realdemux->out, p_es);
+
vlc_mutex_unlock(&me->lock);
- me->realdemux->out->pf_del(me->realdemux->out, p_es);
}
int BaseStreamOutput::esOutControl(es_out_t *fakees, int i_query, va_list args)
@@ -484,6 +548,17 @@ int BaseStreamOutput::esOutControl(es_out_t *fakees, int i_query, va_list args)
me->pcr = (int64_t)va_arg( args, int64_t );
return VLC_SUCCESS;
}
+ else if( i_query == ES_OUT_GET_ES_STATE )
+ {
+ va_arg( args, es_out_id_t * );
+ bool *pb = va_arg( args, bool * );
+ *pb = true;
+ return VLC_SUCCESS;
+ }
+ else if( me->restarting )
+ {
+ return VLC_EGENERIC;
+ }
return me->realdemux->out->pf_control(me->realdemux->out, i_query, args);
}
diff --git a/modules/demux/adaptative/Streams.hpp b/modules/demux/adaptative/Streams.hpp
index 6cfd66b..132da24 100644
--- a/modules/demux/adaptative/Streams.hpp
+++ b/modules/demux/adaptative/Streams.hpp
@@ -27,6 +27,7 @@
#include <string>
#include <list>
#include <vlc_common.h>
+#include <vlc_es.h>
#include "StreamsType.hpp"
namespace adaptative
@@ -100,6 +101,7 @@ namespace adaptative
virtual void setPosition(mtime_t) = 0;
virtual void sendToDecoder(mtime_t) = 0;
virtual bool reinitsOnSeek() const = 0;
+ virtual bool switchAllowed() const = 0;
protected:
demux_t *realdemux;
@@ -130,12 +132,14 @@ namespace adaptative
virtual void setPosition(mtime_t); /* reimpl */
virtual void sendToDecoder(mtime_t); /* reimpl */
virtual bool reinitsOnSeek() const; /* reimpl */
+ virtual bool switchAllowed() const; /* reimpl */
protected:
es_out_t *fakeesout; /* to intercept/proxy what is sent from demuxstream */
stream_t *demuxstream;
bool seekable;
std::string name;
+ bool restarting;
private:
static es_out_id_t *esOutAdd(es_out_t *, const es_format_t *);
@@ -147,12 +151,14 @@ namespace adaptative
class Demuxed
{
friend class BaseStreamOutput;
- Demuxed();
+ Demuxed(es_out_id_t *, const es_format_t *);
~Demuxed();
void drop();
es_out_id_t *es_id;
block_t *p_queue;
block_t **pp_queue_last;
+ bool recycle;
+ es_format_t fmtcpy;
};
std::list<Demuxed *> queues;
vlc_mutex_t lock;
More information about the vlc-commits
mailing list