vlc | branch: master | Francois Cartegnie <fcvlc...@free.fr> | Thu May 7 21:37:44 2015 +0200| [76ece833e1fb6c70394434aba153c5f490986e5b] | committer: Francois Cartegnie
demux: dash: use demux increments for pcr updates should appear smoother > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=76ece833e1fb6c70394434aba153c5f490986e5b --- modules/demux/adaptative/PlaylistManager.cpp | 17 +++++++-- modules/demux/adaptative/PlaylistManager.h | 5 ++- modules/demux/adaptative/Streams.cpp | 20 +++++++++- modules/demux/adaptative/Streams.hpp | 4 +- modules/demux/dash/dash.cpp | 52 ++++++++++++++++---------- modules/demux/dash/dash.hpp | 1 + 6 files changed, 70 insertions(+), 29 deletions(-) diff --git a/modules/demux/adaptative/PlaylistManager.cpp b/modules/demux/adaptative/PlaylistManager.cpp index 2d8e0d6..5c59e61 100644 --- a/modules/demux/adaptative/PlaylistManager.cpp +++ b/modules/demux/adaptative/PlaylistManager.cpp @@ -112,16 +112,25 @@ bool PlaylistManager::start(demux_t *demux) return true; } -size_t PlaylistManager::read() +Streams::Stream::status PlaylistManager::demux(mtime_t nzdeadline) { - size_t i_ret = 0; + Streams::Stream::status i_return = Streams::Stream::status_demuxed; + for(int type=0; type<Streams::count; type++) { if(!streams[type]) continue; - i_ret += streams[type]->read(conManager); + + Streams::Stream::status i_ret = + streams[type]->demux(conManager, nzdeadline); + + if(i_ret < Streams::Stream::status_eof) + return i_ret; + else if (i_ret == Streams::Stream::status_buffering) + i_return = Streams::Stream::status_buffering; } - return i_ret; + + return i_return; } mtime_t PlaylistManager::getPCR() const diff --git a/modules/demux/adaptative/PlaylistManager.h b/modules/demux/adaptative/PlaylistManager.h index 51c218e..d38bcb5 100644 --- a/modules/demux/adaptative/PlaylistManager.h +++ b/modules/demux/adaptative/PlaylistManager.h @@ -48,8 +48,9 @@ namespace adaptative AbstractAdaptationLogic::LogicType type, stream_t *stream); virtual ~PlaylistManager (); - bool start (demux_t *); - size_t read(); + bool start(demux_t *); + + Streams::Stream::status demux(mtime_t); mtime_t getDuration() const; mtime_t getPCR() const; int getGroup() const; diff --git a/modules/demux/adaptative/Streams.cpp b/modules/demux/adaptative/Streams.cpp index 848eee6..5ef9a69 100644 --- a/modules/demux/adaptative/Streams.cpp +++ b/modules/demux/adaptative/Streams.cpp @@ -151,6 +151,22 @@ bool Stream::seekAble() const return (output && output->seekAble()); } +Stream::status Stream::demux(HTTPConnectionManager *connManager, mtime_t nz_deadline) +{ + if(nz_deadline + VLC_TS_0 > output->getPCR()) /* not already demuxed */ + { + /* need to read, demuxer still buffering, ... */ + if(read(connManager) <= 0) + return Stream::status_eof; + + if(nz_deadline + VLC_TS_0 > output->getPCR()) /* need to read more */ + return Stream::status_buffering; + } + + output->sendToDecoder(nz_deadline); + return Stream::status_demuxed; +} + size_t Stream::read(HTTPConnectionManager *connManager) { Chunk *chunk = getChunk(); @@ -216,7 +232,6 @@ size_t Stream::read(HTTPConnectionManager *connManager) readsize = block->i_buffer; output->pushBlock(block); - output->sendToDecoder(INT64_MAX - VLC_TS_0); return readsize; } @@ -239,7 +254,7 @@ AbstractStreamOutput::AbstractStreamOutput(demux_t *demux) realdemux = demux; demuxstream = NULL; pcr = VLC_TS_0; - group = -1; + group = 0; seekable = true; fakeesout = new es_out_t; @@ -387,6 +402,7 @@ void AbstractStreamOutput::esOutDel(es_out_t *fakees, es_out_id_t *p_es) { if((*it)->es_id == p_es) { + me->sendToDecoder(INT64_MAX - VLC_TS_0); delete *it; me->queues.erase(it); break; diff --git a/modules/demux/adaptative/Streams.hpp b/modules/demux/adaptative/Streams.hpp index fc4d876..8a9d508 100644 --- a/modules/demux/adaptative/Streams.hpp +++ b/modules/demux/adaptative/Streams.hpp @@ -66,13 +66,15 @@ namespace adaptative int getGroup() const; int esCount() const; bool seekAble() const; - size_t read(HTTPConnectionManager *); + typedef enum {status_eof, status_buffering, status_demuxed} status; + status demux(HTTPConnectionManager *, mtime_t); bool setPosition(mtime_t, bool); mtime_t getPosition() const; private: Chunk *getChunk(); void init(const Type, const Format); + size_t read(HTTPConnectionManager *); Type type; Format format; AbstractStreamOutput *output; diff --git a/modules/demux/dash/dash.cpp b/modules/demux/dash/dash.cpp index a065480..0fe9640 100644 --- a/modules/demux/dash/dash.cpp +++ b/modules/demux/dash/dash.cpp @@ -157,6 +157,8 @@ static int Open(vlc_object_t *p_obj) p_demux->pf_demux = Demux; p_demux->pf_control = Control; + p_sys->i_nzpcr = 0; + msg_Dbg(p_obj,"opening mpd file (%s)", p_demux->s->psz_path); return VLC_SUCCESS; @@ -176,28 +178,30 @@ static void Close(vlc_object_t *p_obj) /***************************************************************************** * Callbacks: *****************************************************************************/ +#define DEMUX_INCREMENT (CLOCK_FREQ / 20) static int Demux(demux_t *p_demux) { demux_sys_t *p_sys = p_demux->p_sys; - if ( p_sys->p_dashManager->read() > 0 ) - { - if ( p_sys->p_dashManager->esCount() ) - { - mtime_t pcr = p_sys->p_dashManager->getPCR(); - int group = p_sys->p_dashManager->getGroup(); - if(group > 0) - es_out_Control(p_demux->out, ES_OUT_SET_GROUP_PCR, group, pcr); - else - es_out_Control(p_demux->out, ES_OUT_SET_PCR, pcr); - } - if( !p_sys->p_dashManager->updatePlaylist() ) - return VLC_DEMUXER_EOF; - - return VLC_DEMUXER_SUCCESS; + Streams::Stream::status status = + p_sys->p_dashManager->demux(p_sys->i_nzpcr + DEMUX_INCREMENT); + switch(status) + { + case Streams::Stream::status_eof: + return VLC_DEMUXER_EOF; + case Streams::Stream::status_buffering: + break; + case Streams::Stream::status_demuxed: + p_sys->i_nzpcr += DEMUX_INCREMENT; + int group = p_sys->p_dashManager->getGroup(); + es_out_Control(p_demux->out, ES_OUT_SET_GROUP_PCR, group, VLC_TS_0 + p_sys->i_nzpcr); + break; } - else + + if( !p_sys->p_dashManager->updatePlaylist() ) return VLC_DEMUXER_EOF; + + return VLC_DEMUXER_SUCCESS; } static int Control (demux_t *p_demux, int i_query, va_list args) @@ -219,7 +223,7 @@ static int Control (demux_t *p_demux, int i_query, va_list args) break; case DEMUX_GET_TIME: - *(va_arg (args, int64_t *)) = p_sys->p_dashManager->getPCR(); + *(va_arg (args, int64_t *)) = p_sys->i_nzpcr; break; case DEMUX_GET_LENGTH: @@ -230,22 +234,30 @@ static int Control (demux_t *p_demux, int i_query, va_list args) if(!p_sys->p_dashManager->getDuration()) return VLC_EGENERIC; - *(va_arg (args, double *)) = (double) p_sys->p_dashManager->getPCR() + *(va_arg (args, double *)) = (double) p_sys->i_nzpcr / p_sys->p_dashManager->getDuration(); break; case DEMUX_SET_POSITION: + { + int64_t time = p_sys->p_dashManager->getDuration() * va_arg(args, double); if(p_sys->p_mpd->isLive() || !p_sys->p_dashManager->getDuration() || - !p_sys->p_dashManager->setPosition( p_sys->p_dashManager->getDuration() * va_arg(args, double))) + !p_sys->p_dashManager->setPosition(time)) return VLC_EGENERIC; + p_sys->i_nzpcr = time; break; + } case DEMUX_SET_TIME: + { + int64_t time = va_arg(args, int64_t); if(p_sys->p_mpd->isLive() || - !p_sys->p_dashManager->setPosition(va_arg(args, int64_t))) + !p_sys->p_dashManager->setPosition(time)) return VLC_EGENERIC; + p_sys->i_nzpcr = time; break; + } case DEMUX_GET_PTS_DELAY: *va_arg (args, int64_t *) = INT64_C(1000) * diff --git a/modules/demux/dash/dash.hpp b/modules/demux/dash/dash.hpp index 3aaf3cd..6fa32a3 100644 --- a/modules/demux/dash/dash.hpp +++ b/modules/demux/dash/dash.hpp @@ -23,4 +23,5 @@ struct demux_sys_t { dash::DASHManager *p_dashManager; dash::mpd::MPD *p_mpd; + mtime_t i_nzpcr; }; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits