[vlc-commits] demux: dash: use demux increments for pcr updates

Francois Cartegnie git at videolan.org
Thu May 7 23:44:07 CEST 2015


vlc | branch: master | Francois Cartegnie <fcvlcdev at 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;
 };



More information about the vlc-commits mailing list