[vlc-commits] demux: adaptive: rework commands dequeuing (fix #18499)

Francois Cartegnie git at videolan.org
Wed Jul 19 17:59:35 CEST 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jul 19 17:53:05 2017 +0200| [482db5806e4afe2eb7b6003f3125a28c47d4ae67] | committer: Francois Cartegnie

demux: adaptive: rework commands dequeuing (fix #18499)

could not cope with badly muxed late audio
(high dts<->pcr delay)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=482db5806e4afe2eb7b6003f3125a28c47d4ae67
---

 modules/demux/adaptive/plumbing/CommandsQueue.cpp | 59 +++++++++++++++++------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/modules/demux/adaptive/plumbing/CommandsQueue.cpp b/modules/demux/adaptive/plumbing/CommandsQueue.cpp
index 6a262a67c6..f2a48b6cec 100644
--- a/modules/demux/adaptive/plumbing/CommandsQueue.cpp
+++ b/modules/demux/adaptive/plumbing/CommandsQueue.cpp
@@ -276,33 +276,62 @@ mtime_t CommandsQueue::Process( es_out_t *out, mtime_t barrier )
     mtime_t lastdts = barrier;
     bool b_datasent = false;
 
+    /* We need to filter the current commands list
+       We need to return on discontinuity or reset events if data was sent
+       We must lookup every packet until end or PCR matching barrier,
+       because packets of multiple stream can arrive delayed (with intermidiate pcr)
+       ex: for a target time of 2, you must dequeue <= 2 until >= PCR2
+       A0,A1,A2,B0,PCR0,B1,B2,PCR2,B3,A3,PCR3
+    */
+    std::list<AbstractCommand *> output;
+    std::list<AbstractCommand *> in;
+
     vlc_mutex_lock(&lock);
-    while( !commands.empty() && commands.front()->getTime() <= barrier )
+
+    in.splice( in.end(), commands );
+
+    while( !in.empty() )
     {
-        AbstractCommand *command = commands.front();
-        /* We need to have PCR set for stream before Deleting ES,
-         * or it will get stuck if any waiting decoder buffer */
-        if(command->getType() == ES_OUT_PRIVATE_COMMAND_DEL && b_datasent)
+        AbstractCommand *command = in.front();
+
+        if( command->getType() == ES_OUT_PRIVATE_COMMAND_DEL && b_datasent )
             break;
 
-        if(command->getType() == ES_OUT_PRIVATE_COMMAND_DISCONTINUITY && b_datasent)
+        if( command->getType() == ES_OUT_PRIVATE_COMMAND_DISCONTINUITY && b_datasent )
             break;
 
-        if(command->getType() == ES_OUT_PRIVATE_COMMAND_SEND)
-        {
-            lastdts = command->getTime();
-            b_datasent = true;
-        }
+        if(command->getType() == ES_OUT_SET_GROUP_PCR && command->getTime() > barrier )
+            break;
 
-        commands.pop_front();
-        command->Execute( out );
-        delete command;
+        in.pop_front();
+        b_datasent = true;
+
+        if( command->getType() == ES_OUT_PRIVATE_COMMAND_SEND && command->getTime() > barrier )
+            commands.push_back( command );
+        else
+            output.push_back( command );
     }
-    pcr = lastdts;
+
+    /* push remaining ones if broke above */
+    commands.splice( commands.end(), in );
 
     if(commands.empty() && b_draining)
         b_draining = false;
 
+    /* Now execute our selected commands */
+    while( !output.empty() )
+    {
+        AbstractCommand *command = output.front();
+        output.pop_front();
+
+        if( command->getType() == ES_OUT_PRIVATE_COMMAND_SEND )
+            lastdts = command->getTime();
+
+        command->Execute( out );
+        delete command;
+    }
+    pcr = lastdts; /* Warn! no PCR update/lock release until execution */
+
     vlc_mutex_unlock(&lock);
 
     return lastdts;



More information about the vlc-commits mailing list