[vlc-commits] demux: ts: only interpolate PCR on missing PCR

Francois Cartegnie git at videolan.org
Mon Mar 23 16:59:31 CET 2015


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Mar 23 15:57:48 2015 +0100| [224bc2719216162565d06f0db92c5b3925bc7752] | committer: Francois Cartegnie

demux: ts: only interpolate PCR on missing PCR

Because if the PCR exists and has an offset,
the first PCR update will be interpolated
and no following pcr/dts offset fixup will
work without delaying playback by the
real - interpolated pcr.

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

 modules/demux/ts.c |   34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/modules/demux/ts.c b/modules/demux/ts.c
index ca3a4af..d420f3a 100644
--- a/modules/demux/ts.c
+++ b/modules/demux/ts.c
@@ -263,6 +263,7 @@ typedef struct
         mtime_t i_first_dts;
         mtime_t i_pcroffset;
         bool    b_disable; /* ignore PCR field, use dts */
+        bool    b_fix_done;
     } pcr;
 
     mtime_t i_last_dts;
@@ -2345,7 +2346,7 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
             block_t *p_next = p_block->p_next;
             p_block->p_next = NULL;
 
-            if( p_pmt->pcr.i_first == -1 ) /* Not seen yet */
+            if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
                 PCRFixHandle( p_demux, p_pmt, p_block );
 
             if( pid->u.p_pes->es.id && (p_pmt->pcr.i_current > -1 || p_pmt->pcr.b_disable) )
@@ -2399,7 +2400,7 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
             }
             else
             {
-                if( p_pmt->pcr.i_first == -1 ) /* Not seen yet */
+                if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
                     PCRFixHandle( p_demux, p_pmt, p_block );
 
                 block_ChainAppend( &pid->u.p_pes->p_prepcr_outqueue, p_block );
@@ -2935,7 +2936,7 @@ static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr )
 
     /* Check if we have enqueued blocks waiting the/before the
        PCR barrier, and then adapt pcr so they have valid PCR when dequeuing */
-    if( p_pmt->pcr.i_current == -1 )
+    if( p_pmt->pcr.i_current == -1 && p_pmt->pcr.b_fix_done )
     {
         mtime_t i_mindts = -1;
 
@@ -3059,24 +3060,29 @@ static int FindPCRCandidate( ts_pmt_t *p_pmt )
         return 0x1FFF;
 }
 
+/* Tries to reselect a new PCR when none has been received */
 static void PCRFixHandle( demux_t *p_demux, ts_pmt_t *p_pmt, block_t *p_block )
 {
-    if( p_pmt->pcr.i_first > -1 || p_pmt->pcr.b_disable )
+    if ( p_pmt->pcr.b_disable || p_pmt->pcr.b_fix_done )
+    {
         return;
-
+    }
     /* Record the first data packet timestamp in case there wont be any PCR */
-    if( !p_pmt->pcr.i_first_dts )
+    else if( !p_pmt->pcr.i_first_dts )
     {
         p_pmt->pcr.i_first_dts = p_block->i_dts;
     }
-    else if( p_block->i_dts - p_pmt->pcr.i_first_dts > CLOCK_FREQ / 2 ) /* "shall not exceed 100ms" */
+    else if( p_block->i_dts - p_pmt->pcr.i_first_dts > CLOCK_FREQ / 2 ) /* "PCR repeat rate shall not exceed 100ms" */
     {
-        int i_cand = FindPCRCandidate( p_pmt );
-        p_pmt->i_pid_pcr = i_cand;
-        p_pmt->pcr.b_disable = true; /* So we do not wait packet PCR flag as there might be none on the pid */
-        msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
-                  p_pmt->i_number, i_cand );
-        UpdatePESFilters( p_demux, p_demux->p_sys->b_es_all );
+        if( p_pmt->pcr.i_current < 0 )
+        {
+            int i_cand = FindPCRCandidate( p_pmt );
+            p_pmt->i_pid_pcr = i_cand;
+            msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
+                      p_pmt->i_number, i_cand );
+            UpdatePESFilters( p_demux, p_demux->p_sys->b_es_all );
+            p_pmt->pcr.b_fix_done = true;
+        }
     }
 }
 
@@ -5718,6 +5724,8 @@ static ts_pmt_t *ts_pmt_New( demux_t *p_demux )
     pmt->pcr.i_first_dts = VLC_TS_INVALID;
     pmt->pcr.i_pcroffset = -1;
 
+    pmt->pcr.b_fix_done = false;
+
     return pmt;
 }
 



More information about the vlc-commits mailing list