vlc | branch: master | Francois Cartegnie <[email protected]> | 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; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
