[vlc-commits] [Git][videolan/vlc][3.0.x] demux: ts: check pcr offset with value prior matching sync code

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Mon Dec 13 09:30:54 UTC 2021



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
2090e1ea by Francois Cartegnie at 2021-12-13T09:14:23+00:00
demux: ts: check pcr offset with value prior matching sync code

otherwise the last value is always overwritten with a more recent one
and triggers the dts < pcr case

ref #25034

(cherry picked from commit 225e0bc09b847167433d49a591b25a8da4e7655f)
Signed-off-by: Francois Cartegnie <fcvlcdev at free.fr>

- - - - -


3 changed files:

- modules/demux/mpeg/ts.c
- modules/demux/mpeg/ts_streams.c
- modules/demux/mpeg/ts_streams_private.h


Changes:

=====================================
modules/demux/mpeg/ts.c
=====================================
@@ -1447,7 +1447,8 @@ static void SendDataChain( demux_t *p_demux, ts_es_t *p_es, block_t *p_chain )
 /****************************************************************************
  * gathering stuff
  ****************************************************************************/
-static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
+static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes,
+                               int64_t i_append_pcr )
 {
     uint8_t header[34];
     unsigned i_pes_size = 0;
@@ -1606,19 +1607,20 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
                 }
 
                 /* Compute PCR/DTS offset if any */
+                int64_t i_pcrref = i_append_pcr > VLC_TS_INVALID ? i_append_pcr : p_pmt->pcr.i_first;
                 if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts > VLC_TS_INVALID &&
-                    p_pmt->pcr.i_current > VLC_TS_INVALID &&
+                    i_pcrref > VLC_TS_INVALID &&
                    (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) )
                 {
                     int64_t i_dts27 = TO_SCALE(p_block->i_dts);
-                    i_dts27 = TimeStampWrapAround( p_pmt->pcr.i_first, i_dts27 );
-                    int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
-                    if( i_dts27 < i_pcr )
+                    i_dts27 = TimeStampWrapAround( i_pcrref, i_dts27 );
+                    i_pcrref = TimeStampWrapAround( p_pmt->pcr.i_first, i_pcrref );
+                    if( i_dts27 + (CLOCK_FREQ/90000) < i_pcrref )
                     {
-                        p_pmt->pcr.i_pcroffset = i_pcr - i_dts27 + 80000;
+                        p_pmt->pcr.i_pcroffset = i_pcrref - i_dts27 + TO_SCALE_NZ(80000);
                         msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64
                                            "us later than pcr, applying delay",
-                                  pid->i_pid, FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset) );
+                                  pid->i_pid, FROM_SCALE_NZ(i_pcrref - i_dts27) );
                     }
                     else p_pmt->pcr.i_pcroffset = 0;
                 }
@@ -1670,7 +1672,8 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
     }
 }
 
-static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start )
+static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start,
+                          int64_t i_append_pcr )
 {
     bool b_ret = false;
     ts_stream_t *p_pes = pid->u.p_stream;
@@ -1683,10 +1686,13 @@ static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool
         p_pes->gather.i_data_size = 0;
         p_pes->gather.i_gathered = 0;
         p_pes->gather.pp_last = &p_pes->gather.p_data;
-        ParsePESDataChain( p_demux, pid, p_datachain );
+        ParsePESDataChain( p_demux, pid, p_datachain, p_pes->gather.i_append_pcr );
         b_ret = true;
     }
 
+    if( b_unit_start )
+        p_pes->gather.i_append_pcr = i_append_pcr;
+
     if( p_pkt == NULL )
         return b_ret;
 
@@ -1705,7 +1711,7 @@ static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool
     {
         /* re-enter in Flush above */
         assert(p_pes->gather.p_data);
-        return PushPESBlock( p_demux, pid, NULL, true );
+        return PushPESBlock( p_demux, pid, NULL, true, i_append_pcr );
     }
 
     return b_ret;
@@ -2300,7 +2306,7 @@ static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr)
             {
                 msg_Warn( p_demux, "send queued data for pid %d: TS %"PRId64" <= PCR %"PRId64"\n",
                           p_pid->i_pid, i_dts > VLC_TS_INVALID ? i_dts : i_pts, i_pcr);
-                PushPESBlock( p_demux, p_pid, NULL, true ); /* Flush */
+                PushPESBlock( p_demux, p_pid, NULL, true, VLC_TS_INVALID ); /* Flush */
             }
         }
     }
@@ -2634,6 +2640,8 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
     const bool b_unit_start = p_pkt->p_buffer[1]&0x40;
     bool b_ret = false;
     ts_stream_t *p_pes = pid->u.p_stream;
+    const ts_es_t *p_es = p_pes->p_es;
+    int64_t i_append_pcr = ( p_es && p_es->p_program ) ? p_es->p_program->pcr.i_current : -1;
 
     /* We have to gather it */
     p_pkt->p_buffer += i_skip;
@@ -2655,7 +2663,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
     if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) && p_demux->p_sys->b_valid_scrambling )
     {
         block_Release( p_pkt );
-        return PushPESBlock( p_demux, pid, NULL, true );
+        return PushPESBlock( p_demux, pid, NULL, true, i_append_pcr );
     }
 
     /* Data discontinuity, we need to drop or output currently
@@ -2665,7 +2673,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
     {
         p_pes->gather.i_saved = 0;
         /* Flush/output current */
-        b_ret |= PushPESBlock( p_demux, pid, NULL, true );
+        b_ret |= PushPESBlock( p_demux, pid, NULL, true, i_append_pcr );
         /* Propagate to output block to notify packetizers/decoders */
         if( p_pes->p_es )
             p_pes->p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
@@ -2736,7 +2744,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
                 /* Append whole block */
                 if( likely(p_pkt->i_buffer <= i_remain || b_single_payload) )
                 {
-                    b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
+                    b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL, i_append_pcr );
                     p_pkt = NULL;
                 }
                 else /* p_pkt->i_buffer > i_remain */
@@ -2747,7 +2755,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
                         block_Release( p_pkt );
                         return false;
                     }
-                    b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
+                    b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL, i_append_pcr );
                     p_pkt = p_split;
                     b_first_sync_done = false;
                 }
@@ -2755,7 +2763,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size
             else /* if( p_pes->gather.i_data_size == 0 ) // see next packet */
             {
                 /* Append or finish current/start new PES depending on unit_start */
-                b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start );
+                b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start, i_append_pcr );
                 p_pkt = NULL;
             }
         }


=====================================
modules/demux/mpeg/ts_streams.c
=====================================
@@ -286,6 +286,7 @@ ts_stream_t *ts_stream_New( demux_t *p_demux, ts_pmt_t *p_program )
     pes->gather.p_data = NULL;
     pes->gather.pp_last = &pes->gather.p_data;
     pes->gather.i_saved = 0;
+    pes->gather.i_append_pcr = VLC_TS_INVALID;
     pes->b_broken_PUSI_conformance = false;
     pes->b_always_receive = false;
     pes->p_sections_proc = NULL;


=====================================
modules/demux/mpeg/ts_streams_private.h
=====================================
@@ -125,6 +125,7 @@ struct ts_stream_t
         block_t     **pp_last;
         uint8_t     saved[5];
         size_t      i_saved;
+        int64_t     i_append_pcr;
     } gather;
 
     bool        b_always_receive;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2090e1ea9a6a6f34f614218eeaf667d428f2f9c7

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2090e1ea9a6a6f34f614218eeaf667d428f2f9c7
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list