[vlc-commits] [Git][videolan/vlc][master] 11 commits: demux: ps: refactor dts as condition branch

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sat Jul 5 12:24:50 UTC 2025



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
fd7157d0 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ps: refactor dts as condition branch

- - - - -
1125e0a1 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: simplify signature and code for ParsePESHeader

- - - - -
92469e17 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: move getters and defines to ts_packet.h

- - - - -
581d8653 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: refactor skipping AF header

- - - - -
630578f9 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: refactor PES using helpers

- - - - -
461968f9 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: add define for stream_id

- - - - -
bd77a06e by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ps: use stream id defines

- - - - -
ab0b0969 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: move PES check into header parsing

- - - - -
93b69419 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ts: simplify ProbePES using ts_packet.h

- - - - -
dd60043f by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ps: update comments

- - - - -
fe2328a4 by François Cartegnie at 2025-07-05T12:09:25+00:00
demux: ps: use single scale conversion

- - - - -


8 changed files:

- modules/demux/Makefile.am
- modules/demux/mpeg/pes.h
- modules/demux/mpeg/ps.c
- modules/demux/mpeg/ps.h
- modules/demux/mpeg/ts.c
- modules/demux/mpeg/ts_hotfixes.c
- modules/demux/mpeg/ts_hotfixes.h
- + modules/demux/mpeg/ts_packet.h


Changes:

=====================================
modules/demux/Makefile.am
=====================================
@@ -280,6 +280,7 @@ libts_plugin_la_SOURCES = demux/mpeg/ts.c demux/mpeg/ts.h \
         demux/mpeg/ts_metadata.c demux/mpeg/ts_metadata.h \
         demux/mpeg/ts_hotfixes.c demux/mpeg/ts_hotfixes.h \
         demux/mpeg/ts_strings.h demux/mpeg/ts_streams_private.h \
+        demux/mpeg/ts_packet.h \
         demux/mpeg/ts_pes.c demux/mpeg/ts_pes.h \
         demux/mpeg/ts_streamwrapper.h \
         demux/mpeg/pes.h \


=====================================
modules/demux/mpeg/pes.h
=====================================
@@ -22,8 +22,24 @@
 
 #include "timestamps.h"
 
+#define STREAM_ID_PROGRAM_STREAM_MAP         0xBC
+#define STREAM_ID_PRIVATE_STREAM_1           0xBD
+#define STREAM_ID_PADDING                    0xBE
+#define STREAM_ID_PRIVATE_STREAM_2           0xBF
+#define STREAM_ID_AUDIO_STREAM_0             0xC0
+#define STREAM_ID_VIDEO_STREAM_0             0xE0
+#define STREAM_ID_ECM                        0xF0
+#define STREAM_ID_EMM                        0xF1
+#define STREAM_ID_DSM_CC                     0xF2
+#define STREAM_ID_H222_1_TYPE_E              0xF8
+#define STREAM_ID_METADATA_STREAM            0xFC
+#define STREAM_ID_EXTENDED_STREAM_ID         0xFD
+#define STREAM_ID_PROGRAM_STREAM_DIRECTORY   0xFF
+
+/* MPEG-2 PTS/DTS */
 static inline ts_90khz_t GetPESTimestamp( const uint8_t *p_data )
 {
+    /* prefixed by 4 bits 0010 or 0011 */
     return  ((ts_90khz_t)(p_data[ 0]&0x0e ) << 29)|
              (ts_90khz_t)(p_data[1] << 22)|
             ((ts_90khz_t)(p_data[2]&0xfe) << 14)|
@@ -50,6 +66,7 @@ static inline bool ExtractPESTimestamp( const uint8_t *p_data, uint8_t i_flags,
 /* PS SCR timestamp as defined in H222 2.5.3.2 */
 static inline ts_90khz_t ExtractPackHeaderTimestamp( const uint8_t *p_data )
 {
+    /* prefixed by 2 bits 01 */
     return  ((ts_90khz_t)(p_data[0]&0x38 ) << 27)|
             ((ts_90khz_t)(p_data[0]&0x03 ) << 28)|
              (ts_90khz_t)(p_data[1] << 20)|
@@ -59,31 +76,50 @@ static inline ts_90khz_t ExtractPackHeaderTimestamp( const uint8_t *p_data )
              (ts_90khz_t)(p_data[4] >> 3);
 }
 
+typedef struct
+{
+    ts_90khz_t i_dts;
+    ts_90khz_t i_pts;
+    uint8_t i_stream_id;
+    bool b_scrambling;
+    unsigned i_size;
+} ts_pes_header_t;
+
+static inline void ts_pes_header_init(ts_pes_header_t *h)
+{
+    h->i_dts = TS_90KHZ_INVALID;
+    h->i_pts = TS_90KHZ_INVALID;
+    h->i_stream_id = 0;
+    h->b_scrambling = false;
+    h->i_size = 0;
+}
+
 inline
-static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size_t i_header,
-                           unsigned *pi_skip, ts_90khz_t *pi_dts, ts_90khz_t *pi_pts,
-                           uint8_t *pi_stream_id, bool *pb_pes_scambling )
+static int ParsePESHeader( struct vlc_logger *p_logger, const uint8_t *p_header, size_t i_header,
+                           ts_pes_header_t *h )
 {
     unsigned i_skip;
 
     if ( i_header < 9 )
         return VLC_EGENERIC;
 
-    *pi_stream_id = p_header[3];
+    if( p_header[0] != 0 || p_header[1] != 0 || p_header[2] != 1 )
+        return VLC_EGENERIC;
+
+    h->i_stream_id = p_header[3];
 
     switch( p_header[3] )
     {
-    case 0xBC:  /* Program stream map */
-    case 0xBE:  /* Padding */
-    case 0xBF:  /* Private stream 2 */
-    case 0xF0:  /* ECM */
-    case 0xF1:  /* EMM */
-    case 0xFF:  /* Program stream directory */
-    case 0xF2:  /* DSMCC stream */
-    case 0xF8:  /* ITU-T H.222.1 type E stream */
+    case STREAM_ID_PROGRAM_STREAM_MAP:
+    case STREAM_ID_PADDING:
+    case STREAM_ID_PRIVATE_STREAM_2:
+    case STREAM_ID_ECM:
+    case STREAM_ID_EMM:
+    case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
+    case STREAM_ID_DSM_CC:
+    case STREAM_ID_H222_1_TYPE_E:
         i_skip = 6;
-        if( pb_pes_scambling )
-            *pb_pes_scambling = false;
+        h->b_scrambling = false;
         break;
     default:
         if( ( p_header[6]&0xC0 ) == 0x80 )
@@ -91,17 +127,16 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
             /* mpeg2 PES */
             i_skip = p_header[8] + 9;
 
-            if( pb_pes_scambling )
-                *pb_pes_scambling = p_header[6]&0x30;
+            h->b_scrambling = p_header[6]&0x30;
 
             if( p_header[7]&0x80 )    /* has pts */
             {
                 if( i_header >= 9 + 5 )
-                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, pi_pts );
+                   (void) ExtractPESTimestamp( &p_header[9], p_header[7] >> 6, &h->i_pts );
 
                 if( ( p_header[7]&0x40 ) &&    /* has dts */
                     i_header >= 14 + 5 )
-                   (void) ExtractPESTimestamp( &p_header[14], 0x01, pi_dts );
+                   (void) ExtractPESTimestamp( &p_header[14], 0x01, &h->i_dts );
             }
         }
         else
@@ -112,8 +147,7 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
                Non spec reference for packet format on http://andrewduncan.net/mpeg/mpeg-1.html */
             i_skip = 6;
 
-            if( pb_pes_scambling )
-                *pb_pes_scambling = false;
+            h->b_scrambling = false;
 
             while( i_skip < 23 && p_header[i_skip] == 0xff )
             {
@@ -123,7 +157,7 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
             }
             if( i_skip == 23 )
             {
-                msg_Err( p_object, "too much MPEG-1 stuffing" );
+                vlc_error( p_logger, "too much MPEG-1 stuffing" );
                 return VLC_EGENERIC;
             }
             /* Skip STD buffer size */
@@ -138,12 +172,12 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
             if(  p_header[i_skip]&0x20 )
             {
                 if( i_header >= i_skip + 5 )
-                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, pi_pts );
+                    (void) ExtractPESTimestamp( &p_header[i_skip], p_header[i_skip] >> 4, &h->i_pts );
 
                 if( ( p_header[i_skip]&0x10 ) &&     /* has dts */
                     i_header >= i_skip + 10 )
                 {
-                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, pi_dts );
+                    (void) ExtractPESTimestamp( &p_header[i_skip+5], 0x01, &h->i_dts );
                     i_skip += 10;
                 }
                 else
@@ -161,7 +195,7 @@ static int ParsePESHeader( vlc_object_t *p_object, const uint8_t *p_header, size
         break;
     }
 
-    *pi_skip = i_skip;
+    h->i_size = i_skip;
     return VLC_SUCCESS;
 }
 


=====================================
modules/demux/mpeg/ps.c
=====================================
@@ -210,8 +210,8 @@ static int OpenCommon( vlc_object_t *p_this, bool b_force )
         if( memcmp( p_header, startcode, 3 ) ||
            ( (p_header[3] & 0xB0) != 0xB0 &&
             !(p_header[3] >= 0xC0 && p_header[3] <= 0xEF) &&
-              p_header[3] != PS_STREAM_ID_EXTENDED &&
-              p_header[3] != PS_STREAM_ID_DIRECTORY ) )
+              p_header[3] != STREAM_ID_EXTENDED_STREAM_ID &&
+              p_header[3] != STREAM_ID_PROGRAM_STREAM_DIRECTORY ) )
             return VLC_EGENERIC;
 
         ssize_t i_pessize = ps_pkt_size( p_header, 16 );
@@ -480,7 +480,7 @@ static int Demux( demux_t *p_demux )
     switch( i_stream_id )
     {
     case PS_STREAM_ID_END_STREAM:
-    case PS_STREAM_ID_PADDING:
+    case STREAM_ID_PADDING:
         block_Release( p_pkt );
         break;
 
@@ -507,7 +507,7 @@ static int Demux( demux_t *p_demux )
         block_Release( p_pkt );
         break;
 
-    case PS_STREAM_ID_MAP:
+    case STREAM_ID_PROGRAM_STREAM_MAP:
         if( p_sys->psm.i_version == 0xFF )
             msg_Dbg( p_demux, "contains a PSM");
 
@@ -525,8 +525,8 @@ static int Demux( demux_t *p_demux )
             break;
         }
         /* fallthrough */
-    case PS_STREAM_ID_PRIVATE_STREAM1:
-    case PS_STREAM_ID_EXTENDED:
+    case STREAM_ID_PRIVATE_STREAM_1:
+    case STREAM_ID_EXTENDED_STREAM_ID:
         {
             int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
             /* Small heuristic to improve MLP detection from AOB */


=====================================
modules/demux/mpeg/ps.h
=====================================
@@ -27,11 +27,6 @@
 #define PS_STREAM_ID_END_STREAM       0xB9
 #define PS_STREAM_ID_PACK_HEADER      0xBA
 #define PS_STREAM_ID_SYSTEM_HEADER    0xBB
-#define PS_STREAM_ID_MAP              0xBC
-#define PS_STREAM_ID_PRIVATE_STREAM1  0xBD
-#define PS_STREAM_ID_PADDING          0xBE
-#define PS_STREAM_ID_EXTENDED         0xFD
-#define PS_STREAM_ID_DIRECTORY        0xFF
 
 /* 256-0xC0 for normal stream, 256 for 0xbd stream, 256 for 0xfd stream, 8 for 0xa0 AOB stream */
 #define PS_TK_COUNT (256+256+256+8 - 0xc0)
@@ -435,8 +430,8 @@ static inline int ps_pkt_size( const uint8_t *p, int i_peek )
             break;
 
         case PS_STREAM_ID_SYSTEM_HEADER:
-        case PS_STREAM_ID_MAP:
-        case PS_STREAM_ID_DIRECTORY:
+        case STREAM_ID_PROGRAM_STREAM_MAP:
+        case STREAM_ID_PROGRAM_STREAM_DIRECTORY:
         default:
             if( i_peek >= 6 )
                 return 6 + ((p[4]<<8) | p[5] );
@@ -449,23 +444,23 @@ static inline int ps_pkt_parse_pack( const uint8_t *p_pkt, size_t i_pkt,
                                      vlc_tick_t *pi_scr, int *pi_mux_rate )
 {
     const uint8_t *p = p_pkt;
-    if( i_pkt >= 14 && (p[4] >> 6) == 0x01 )
+    ts_90khz_t i_scr;
+    if( i_pkt >= 14 && (p[4] >> 6) == 0x01 ) /* 0b01 H.222 MPEG-2 Pack Header */
     {
-        *pi_scr = FROM_SCALE( ExtractPackHeaderTimestamp( &p[4] ) );
+        i_scr = ExtractPackHeaderTimestamp( &p[4] );
         *pi_mux_rate = ( p[10] << 14 )|( p[11] << 6 )|( p[12] >> 2);
     }
-    else if( i_pkt >= 12 && (p[4] >> 4) == 0x02 ) /* MPEG-1 Pack SCR, same bits as PES/PTS */
+    else if( i_pkt >= 12 && (p[4] >> 4) == 0x02 ) /* 0b0010 ISO 11172-1 MPEG-1 Pack Header */
     {
-        ts_90khz_t i_scr;
-        if(!ExtractPESTimestamp( &p[4], 0x02, &i_scr ))
+        if(!ExtractPESTimestamp( &p[4], 0x02, &i_scr )) /* same bits as PES/PTS */
             return VLC_EGENERIC;
-        *pi_scr = FROM_SCALE( i_scr );
         *pi_mux_rate = ( ( p[9]&0x7f )<< 15 )|( p[10] << 7 )|( p[11] >> 1);
     }
     else
     {
         return VLC_EGENERIC;
     }
+    *pi_scr = FROM_SCALE( i_scr );
     return VLC_SUCCESS;
 }
 
@@ -487,7 +482,7 @@ static inline int ps_pkt_parse_system( const uint8_t *p_pkt, size_t i_pkt,
             case 0xB7:
                 if( p_pktend - p < 6 )
                     return VLC_EGENERIC;
-                i_id = ((int)PS_STREAM_ID_EXTENDED << 8) | (p[2] & 0x7F);
+                i_id = ((int)STREAM_ID_EXTENDED_STREAM_ID << 8) | (p[2] & 0x7F);
                 p += 6;
                 break;
             default:
@@ -510,17 +505,16 @@ static inline int ps_pkt_parse_system( const uint8_t *p_pkt, size_t i_pkt,
 /* Parse a PES (and skip i_skip_extra in the payload) */
 static inline int ps_pkt_parse_pes( vlc_object_t *p_object, block_t *p_pes, int i_skip_extra )
 {
-    unsigned int i_skip  = 0;
-    ts_90khz_t i_pts = TS_90KHZ_INVALID;
-    ts_90khz_t i_dts = TS_90KHZ_INVALID;
-    uint8_t i_stream_id = 0;
-    bool b_pes_scrambling = false;
-
-    if( ParsePESHeader( p_object, p_pes->p_buffer, p_pes->i_buffer,
-                        &i_skip, &i_dts, &i_pts, &i_stream_id, &b_pes_scrambling ) != VLC_SUCCESS )
+    unsigned int i_skip;
+    ts_pes_header_t pesh;
+    ts_pes_header_init( &pesh );
+
+    if( ParsePESHeader( p_object->logger, p_pes->p_buffer, p_pes->i_buffer, &pesh ) != VLC_SUCCESS )
         return VLC_EGENERIC;
 
-    if( b_pes_scrambling )
+    i_skip = pesh.i_size;
+
+    if( pesh.b_scrambling )
         p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
 
     if( i_skip_extra >= 0 )
@@ -538,14 +532,14 @@ static inline int ps_pkt_parse_pes( vlc_object_t *p_object, block_t *p_pes, int
     p_pes->p_buffer += i_skip;
     p_pes->i_buffer -= i_skip;
 
-    /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
-    if( i_pts != TS_90KHZ_INVALID && i_dts == TS_90KHZ_INVALID )
-        i_dts = i_pts;
-
-    if( i_dts != TS_90KHZ_INVALID )
-        p_pes->i_dts = FROM_SCALE( i_dts );
-    if( i_pts != TS_90KHZ_INVALID )
-        p_pes->i_pts = FROM_SCALE( i_pts );
+    if( pesh.i_pts != TS_90KHZ_INVALID )
+    {
+        p_pes->i_pts = FROM_SCALE( pesh.i_pts );
+        if( pesh.i_dts != TS_90KHZ_INVALID )
+            p_pes->i_dts = FROM_SCALE( pesh.i_dts );
+        else /* ISO/IEC 13818-1 2.7.5: if pts and no dts, then dts == pts */
+            p_pes->i_dts = p_pes->i_pts;
+    }
 
     return VLC_SUCCESS;
 }
@@ -644,7 +638,7 @@ static inline int ps_psm_fill( ps_psm_t *p_psm,
     // Demux() checks that we have at least 4 bytes, but we need
     // at least 10 to read up to the info_length field
     assert(i_pkt >= 4);
-    if( !p_psm || i_pkt < 10 || p_buffer[3] != PS_STREAM_ID_MAP)
+    if( !p_psm || i_pkt < 10 || p_buffer[3] != STREAM_ID_PROGRAM_STREAM_MAP)
         return VLC_EGENERIC;
 
     i_length = GetWBE(&p_buffer[4]) + 6;
@@ -690,7 +684,7 @@ static inline int ps_psm_fill( ps_psm_t *p_psm,
          *      descriptor 0x5 with format_identifier == 0x56432D31 (VC-1)
          *      (I need a sample that use PSM with VC-1) */
 
-        if( p_es->i_id == PS_STREAM_ID_EXTENDED && b_single_extension == 0 )
+        if( p_es->i_id == STREAM_ID_EXTENDED_STREAM_ID && b_single_extension == 0 )
         {
             if( i_info_length < 3 )
                 break;


=====================================
modules/demux/mpeg/ts.c
=====================================
@@ -38,6 +38,7 @@
 #include "ts_pid.h"
 #include "ts_streams.h"
 #include "ts_streams_private.h"
+#include "ts_packet.h"
 #include "ts_pes.h"
 #include "ts_psi.h"
 #include "ts_si.h"
@@ -182,11 +183,6 @@ static bool PIDReferencedByProgram( const ts_pmt_t *, uint16_t );
 void UpdatePESFilters( demux_t *p_demux, bool b_all );
 static inline void FlushESBuffer( ts_stream_t *p_pes );
 static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool );
-static inline int PIDGet( block_t *p )
-{
-    return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
-}
-static ts_90khz_t GetPCR( const block_t * );
 
 static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int * );
 static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *, block_t *, size_t );
@@ -199,12 +195,6 @@ static void ReadyQueuesPostSeek( demux_t *p_demux );
 static void PCRHandle( demux_t *p_demux, ts_pid_t *, ts_90khz_t );
 static void PCRFixHandle( demux_t *, ts_pmt_t *, block_t * );
 
-#define TS_PACKET_SIZE_188 188
-#define TS_PACKET_SIZE_192 192
-#define TS_PACKET_SIZE_204 204
-#define TS_PACKET_SIZE_MAX 204
-#define TS_HEADER_SIZE 4
-
 #define PROBE_CHUNK_COUNT 500
 #define PROBE_MAX         (PROBE_CHUNK_COUNT * 10)
 
@@ -707,8 +697,7 @@ static int Demux( demux_t *p_demux )
             (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
             (p_pkt->p_buffer[3] & 0xD0) == 0x10 )  /* Has payload but is not encrypted */
         {
-            ProbePES( p_demux, p_pid, p_pkt->p_buffer + TS_HEADER_SIZE,
-                      p_pkt->i_buffer - TS_HEADER_SIZE, p_pkt->p_buffer[3] & 0x20 /* Adaptation field */);
+            ProbePES( p_demux, p_pid, p_pkt );
         }
 
         switch( p_pid->type )
@@ -1551,13 +1540,9 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes,
     uint8_t header[34];
     unsigned i_pes_size = 0;
     unsigned i_skip = 0;
-    ts_90khz_t i_pktdts = TS_90KHZ_INVALID;
-    ts_90khz_t i_pktpts = TS_90KHZ_INVALID;
     ts_90khz_t i_length = 0;
     vlc_tick_t i_dts = VLC_TICK_INVALID;
     vlc_tick_t i_pts = VLC_TICK_INVALID;
-    uint8_t i_stream_id;
-    bool b_pes_scrambling = false;
     const es_mpeg4_descriptor_t *p_mpeg4desc = NULL;
     demux_sys_t *p_sys = p_demux->p_sys;
 
@@ -1586,20 +1571,23 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes,
 
     ts_es_t *p_es = pid->u.p_stream->p_es;
 
-    if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
-                        &i_pktdts, &i_pktpts, &i_stream_id, &b_pes_scrambling ) == VLC_EGENERIC )
+    ts_pes_header_t pesh;
+    ts_pes_header_init( &pesh );
+
+    if( ParsePESHeader( p_demux->obj.logger, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
     {
         block_ChainRelease( p_pes );
         return;
     }
     else
     {
-        if( i_pktpts != TS_90KHZ_INVALID && p_es->p_program )
-            i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(i_pktpts) );
-        if( i_pktdts != TS_90KHZ_INVALID && p_es->p_program )
-            i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(i_pktdts) );
-        if( b_pes_scrambling )
+        if( pesh.i_pts != TS_90KHZ_INVALID && p_es->p_program )
+            i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_pts) );
+        if( pesh.i_dts != TS_90KHZ_INVALID && p_es->p_program )
+            i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_dts) );
+        if( pesh.b_scrambling )
             p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
+        i_skip = pesh.i_size;
     }
 
     if( p_es->i_sl_es_id )
@@ -1749,12 +1737,12 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes,
                 {
                     if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
                         ts_stream_processor_Reset( pid->u.p_stream->p_proc );
-                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, i_stream_id, p_block );
+                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
                 }
                 else
                 /* Some codecs might need xform or AU splitting */
                 {
-                    p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, i_stream_id, p_block );
+                    p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, pesh.i_stream_id, p_block );
                 }
 
                 SendDataChain( p_demux, p_es, p_block );
@@ -1768,7 +1756,7 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes,
                 {
                     if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
                         ts_stream_processor_Reset( pid->u.p_stream->p_proc );
-                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, i_stream_id, p_block );
+                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
                 }
 
                 if( p_block )
@@ -1874,32 +1862,6 @@ static block_t* ReadTSPacket( demux_t *p_demux )
     return p_pkt;
 }
 
-static ts_90khz_t GetPCR( const block_t *p_pkt )
-{
-    const uint8_t *p = p_pkt->p_buffer;
-
-    ts_90khz_t i_pcr = TS_90KHZ_INVALID;
-
-    if(unlikely(p_pkt->i_buffer < 12))
-        return i_pcr;
-
-    const uint8_t i_adaption = p[3] & 0x30;
-
-    if( ( ( i_adaption == 0x30 && p[4] <= 182 ) ||   /* adaptation 0b11 */
-          ( i_adaption == 0x20 && p[4] == 183 ) ) && /* adaptation 0b10 */
-        ( p[4] >= 7 )  &&
-        ( p[5] & 0x10 ) ) /* PCR carry flag */
-    {
-        /* PCR is 33 bits */
-        i_pcr = ( (ts_90khz_t)p[6] << 25 ) |
-                ( (ts_90khz_t)p[7] << 17 ) |
-                ( (ts_90khz_t)p[8] << 9 ) |
-                ( (ts_90khz_t)p[9] << 1 ) |
-                ( (ts_90khz_t)p[10] >> 7 );
-    }
-    return i_pcr;
-}
-
 static inline void UpdateESScrambledState( es_out_t *out, const ts_es_t *p_es, bool b_scrambled )
 {
     for( ; p_es; p_es = p_es->p_next )
@@ -2044,32 +2006,23 @@ static int SeekToTime( demux_t *p_demux, const ts_pmt_t *p_pmt, vlc_tick_t i_see
             ts_pid_t *p_pid = GetPID(p_sys, i_pid);
             if( i_pid != 0x1FFF )
             {
-                unsigned i_skip = 4;
-                if ( p_pkt->p_buffer[3] & 0x20 ) // adaptation field
-                {
-                    if( p_pkt->i_buffer >= 4 + 2 + 5 )
-                    {
-                        if( p_pmt->i_pid_pcr == i_pid )
-                            i_pktpcr = GetPCR( p_pkt );
-                        i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
-                    }
-                }
+                if( p_pmt->i_pid_pcr == i_pid )
+                    i_pktpcr = GetPCR( p_pkt );
 
+                unsigned i_skip = PKTHeaderAndAFSize( p_pkt );
                 if( i_pktpcr == TS_90KHZ_INVALID && p_pid->type == TYPE_STREAM &&
                     ts_stream_Find_es( p_pid->u.p_stream, p_pmt ) &&
                    (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
                    (p_pkt->p_buffer[3] & 0xD0) == 0x10    /* Has payload but is not encrypted */
                 )
                 {
-                    ts_90khz_t i_pktdts = TS_90KHZ_INVALID;
-                    ts_90khz_t i_pktpts = TS_90KHZ_INVALID;
-                    uint8_t i_stream_id;
-                    if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
-                                                        p_pkt->i_buffer - i_skip, &i_skip,
-                                                        &i_pktdts, &i_pktpts, &i_stream_id, NULL ) )
+                    ts_pes_header_t pesh;
+                    ts_pes_header_init( &pesh );
+                    if ( VLC_SUCCESS == ParsePESHeader( NULL, &p_pkt->p_buffer[i_skip],
+                                                        p_pkt->i_buffer - i_skip, &pesh ) )
                     {
-                        if( i_pktdts != TS_90KHZ_INVALID )
-                            i_pktpcr = i_pktdts;
+                        if( pesh.i_dts != TS_90KHZ_INVALID )
+                            i_pktpcr = pesh.i_dts;
                     }
                 }
             }
@@ -2132,10 +2085,7 @@ static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, bool *pb_fou
         if( i_pid != 0x1FFF && (p_pkt->p_buffer[1] & 0x80) == 0 ) /* not corrupt */
         {
             bool b_pcrresult = true;
-            bool b_adaptfield = p_pkt->p_buffer[3] & 0x20;
-
-            if( b_adaptfield && p_pkt->i_buffer >= 4 + 2 + 5 )
-                i_pcr = GetPCR( p_pkt );
+            i_pcr = GetPCR( p_pkt );
 
             /* Designated PCR pid will be valid, don't repick (on the fly probing) */
             if( i_pcr != TS_90KHZ_INVALID && !p_pid->probed.i_pcr_count )
@@ -2149,21 +2099,16 @@ static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, bool *pb_fou
               )
             {
                 b_pcrresult = false;
-                ts_90khz_t i_dts = TS_90KHZ_INVALID;
-                ts_90khz_t i_pts = TS_90KHZ_INVALID;
-                uint8_t i_stream_id;
-                unsigned i_skip = 4;
-                if ( b_adaptfield ) // adaptation field
-                    i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
-
-                if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
-                                                    p_pkt->i_buffer - i_skip, &i_skip,
-                                                    &i_dts, &i_pts, &i_stream_id, NULL ) )
+                unsigned i_skip = PKTHeaderAndAFSize( p_pkt );
+                ts_pes_header_t pesh;
+                ts_pes_header_init( &pesh );
+                if ( VLC_SUCCESS == ParsePESHeader( NULL, &p_pkt->p_buffer[i_skip],
+                                                    p_pkt->i_buffer - i_skip, &pesh ) )
                 {
-                    if( i_dts != TS_90KHZ_INVALID )
-                        i_pcr = i_dts;
-                    else if( i_pts != TS_90KHZ_INVALID )
-                        i_pcr = i_pts;
+                    if( pesh.i_dts != TS_90KHZ_INVALID )
+                        i_pcr = pesh.i_dts;
+                    else if( pesh.i_pts != TS_90KHZ_INVALID )
+                        i_pcr = pesh.i_pts;
                 }
             }
 
@@ -2383,24 +2328,19 @@ static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, vlc_tick_t i_pcr)
         uint8_t header[34];
         const int i_max = block_ChainExtract( p_pes->gather.p_data, header, 34 );
 
-        if( i_max < 6 || header[0] != 0 || header[1] != 0 || header[2] != 1 )
+        ts_pes_header_t pesh;
+        ts_pes_header_init( &pesh );
+
+        if( ParsePESHeader( NULL, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
             continue;
 
-        unsigned i_skip = 0;
-        ts_90khz_t i_pktdts = TS_90KHZ_INVALID;
-        ts_90khz_t i_pktpts = TS_90KHZ_INVALID;
         vlc_tick_t i_dts = VLC_TICK_INVALID;
         vlc_tick_t i_pts = VLC_TICK_INVALID;
-        uint8_t i_stream_id;
-
-        if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
-                            &i_pktdts, &i_pktpts, &i_stream_id, NULL ) == VLC_EGENERIC )
-            continue;
 
-        if( i_pktdts != TS_90KHZ_INVALID )
-            i_dts = TimeStampWrapAround( i_pcr, FROM_SCALE(i_pktdts) );
-        if( i_pktpts != TS_90KHZ_INVALID )
-            i_pts = TimeStampWrapAround( i_pcr, FROM_SCALE(i_pktpts) );
+        if( pesh.i_dts != TS_90KHZ_INVALID )
+            i_dts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_dts) );
+        if( pesh.i_pts != TS_90KHZ_INVALID )
+            i_pts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_pts) );
 
         if (p_pmt->pcr.i_pcroffset > 0) {
             if( i_dts != VLC_TICK_INVALID )


=====================================
modules/demux/mpeg/ts_hotfixes.c
=====================================
@@ -44,113 +44,38 @@
 #include "ts_streams_private.h"
 #include "ts.h"
 #include "ts_hotfixes.h"
+#include "ts_packet.h"
 
 #include <assert.h>
 
-void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_t i_data, bool b_adaptfield )
+void ProbePES( demux_t *p_demux, ts_pid_t *pid, const block_t *p_pkt )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
-    const uint8_t *p_pes = p_pesstart;
 
-    if( b_adaptfield )
-    {
-        if ( i_data < 2 )
-            return;
-
-        uint8_t len = *p_pes;
-        p_pes++; i_data--;
+    unsigned i_skip = PKTHeaderAndAFSize( p_pkt );
+    ts_90khz_t pktpcr = GetPCR( p_pkt );
 
-        if(len == 0)
-        {
-            p_pes++; i_data--;/* stuffing */
-        }
-        else
-        {
-            if( i_data < len )
-                return;
-            if( len >= 7 && (p_pes[0] & 0x10) )
-                pid->probed.i_pcr_count++;
-            p_pes += len;
-            i_data -= len;
-        }
-    }
+    if( pktpcr != TS_90KHZ_INVALID )
+        pid->probed.i_pcr_count++;
 
-    if( i_data < 9 )
-        return;
+    size_t i_data = p_pkt->i_buffer - i_skip;
+    const uint8_t *p_pes = &p_pkt->p_buffer[i_skip];
 
-    if( p_pes[0] != 0 || p_pes[1] != 0 || p_pes[2] != 1 )
+    ts_pes_header_t pesh;
+    ts_pes_header_init( &pesh );
+    if( ParsePESHeader( NULL, p_pes, i_data, &pesh ) != VLC_SUCCESS )
         return;
 
-    size_t i_pesextoffset = 8;
-    ts_90khz_t i_dts = TS_90KHZ_INVALID;
-    if( p_pes[7] & 0x80 ) // PTS
-    {
-        i_pesextoffset += 5;
-        if ( i_data < i_pesextoffset ||
-            !ExtractPESTimestamp( &p_pes[9], p_pes[7] >> 6, &i_dts ) )
-            return;
+    if( pesh.i_dts != TS_90KHZ_INVALID )
         pid->probed.i_dts_count++;
-    }
-    if( p_pes[7] & 0x40 ) // DTS
-    {
-        i_pesextoffset += 5;
-        if ( i_data < i_pesextoffset ||
-            !ExtractPESTimestamp( &p_pes[14], 0x01, &i_dts ) )
-            return;
-    }
-    if( p_pes[7] & 0x20 ) // ESCR
-        i_pesextoffset += 6;
-    if( p_pes[7] & 0x10 ) // ESrate
-        i_pesextoffset += 3;
-    if( p_pes[7] & 0x08 ) // DSM
-        i_pesextoffset += 1;
-    if( p_pes[7] & 0x04 ) // CopyInfo
-        i_pesextoffset += 1;
-    if( p_pes[7] & 0x02 ) // PESCRC
-        i_pesextoffset += 2;
 
     if( pid->probed.i_fourcc != 0 )
         goto codecprobingend;
 
-    if ( i_data < i_pesextoffset )
-        return;
-
-     /* HeaderdataLength */
-    const size_t i_payloadoffset = 8 + 1 + p_pes[8];
-    i_pesextoffset += 1;
-
-    if ( i_data < i_pesextoffset || i_data < i_payloadoffset )
-        return;
-
-    i_data -= 8 + 1 + p_pes[8];
-
-    if( p_pes[7] & 0x01 ) // PESExt
-    {
-        size_t i_extension2_offset = 1;
-        if ( p_pes[i_pesextoffset] & 0x80 ) // private data
-            i_extension2_offset += 16;
-        if ( p_pes[i_pesextoffset] & 0x40 ) // pack
-            i_extension2_offset += 1;
-        if ( p_pes[i_pesextoffset] & 0x20 ) // seq
-            i_extension2_offset += 2;
-        if ( p_pes[i_pesextoffset] & 0x10 ) // P-STD
-            i_extension2_offset += 2;
-        if ( p_pes[i_pesextoffset] & 0x01 ) // Extension 2
-        {
-            uint8_t i_len = p_pes[i_pesextoffset + i_extension2_offset] & 0x7F;
-            i_extension2_offset += i_len;
-        }
-        if( i_data < i_extension2_offset )
-            return;
-
-        i_data -= i_extension2_offset;
-    }
-    /* (i_payloadoffset - i_pesextoffset) 0xFF stuffing */
-
-    if ( i_data < 4 )
+    if( i_data < pesh.i_size + 4 )
         return;
 
-    const uint8_t *p_data = &p_pes[i_payloadoffset];
+    const uint8_t *p_data = &p_pes[pesh.i_size];
     const uint8_t i_stream_id = pid->probed.i_stream_id = p_pes[3];
     /* NON MPEG audio & subpictures STREAM */
     if(i_stream_id == 0xBD)
@@ -197,15 +122,15 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
 
 codecprobingend:
     /* Track timestamps and flag missing PAT */
-    if( !p_sys->patfix.i_timesourcepid && i_dts != TS_90KHZ_INVALID )
+    if( !p_sys->patfix.i_timesourcepid && pesh.i_dts != TS_90KHZ_INVALID )
     {
-        p_sys->patfix.i_first_dts = FROM_SCALE(i_dts);
+        p_sys->patfix.i_first_dts = FROM_SCALE(pesh.i_dts);
         p_sys->patfix.i_timesourcepid = pid->i_pid;
     }
-    else if( p_sys->patfix.i_timesourcepid == pid->i_pid && i_dts != TS_90KHZ_INVALID &&
+    else if( p_sys->patfix.i_timesourcepid == pid->i_pid && pesh.i_dts != TS_90KHZ_INVALID &&
              p_sys->patfix.status == PAT_WAITING )
     {
-        if( FROM_SCALE(i_dts) - p_sys->patfix.i_first_dts > MIN_PAT_INTERVAL )
+        if( FROM_SCALE(pesh.i_dts) - p_sys->patfix.i_first_dts > MIN_PAT_INTERVAL )
             p_sys->patfix.status = PAT_MISSING;
     }
 


=====================================
modules/demux/mpeg/ts_hotfixes.h
=====================================
@@ -21,7 +21,7 @@
 
 #define MIN_PAT_INTERVAL VLC_TICK_FROM_SEC(1) // DVB is 500ms
 
-void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_t i_data, bool b_adaptfield );
+void ProbePES(demux_t *p_demux, ts_pid_t *pid, const block_t * );
 void MissingPATPMTFixup( demux_t *p_demux );
 
 #endif


=====================================
modules/demux/mpeg/ts_packet.h
=====================================
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * ts_packet.h : MPEG-TS packet headers
+ *****************************************************************************
+ * Copyright (C) 2025 - VideoLabs, VideoLAN and VLC authors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+#ifndef VLC_TS_PACKET_H
+#define VLC_TS_PACKET_H
+
+#include "timestamps.h"
+
+#define TS_PACKET_SIZE_188 188
+#define TS_PACKET_SIZE_192 192
+#define TS_PACKET_SIZE_204 204
+#define TS_PACKET_SIZE_MAX 204
+#define TS_HEADER_SIZE 4
+
+#define AS_BUF(pkt) pkt->p_buffer,pkt->i_buffer
+
+static inline unsigned PKTHeaderAndAFSize( const block_t *p_pkt )
+{
+    const uint8_t *p = p_pkt->p_buffer;
+    unsigned i_size = 4;
+    if ( p[3] & 0x30 ) // adaptation field
+        i_size += 1 + __MIN(p[4], 182);
+    return i_size;
+}
+
+static inline int PIDGet( const block_t *p )
+{
+    return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
+}
+
+static inline ts_90khz_t GetPCR( const block_t *p_pkt )
+{
+    const uint8_t *p = p_pkt->p_buffer;
+
+    ts_90khz_t i_pcr = TS_90KHZ_INVALID;
+
+    if(unlikely(p_pkt->i_buffer < 12))
+        return i_pcr;
+
+    const uint8_t i_adaption = p[3] & 0x30;
+
+    if( ( ( i_adaption == 0x30 && p[4] <= 182 ) ||   /* adaptation 0b11 */
+          ( i_adaption == 0x20 && p[4] == 183 ) ) && /* adaptation 0b10 */
+        ( p[4] >= 7 )  &&
+        ( p[5] & 0x10 ) ) /* PCR carry flag */
+    {
+        /* PCR is 33 bits */
+        i_pcr = ( (ts_90khz_t)p[6] << 25 ) |
+                ( (ts_90khz_t)p[7] << 17 ) |
+                ( (ts_90khz_t)p[8] << 9 ) |
+                ( (ts_90khz_t)p[9] << 1 ) |
+                ( (ts_90khz_t)p[10] >> 7 );
+    }
+    return i_pcr;
+}
+
+#endif



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6950a5cd1f326709d6967ba79aba858658921125...fe2328a408cec775a9fc2bc7fcbfd1f1d50c083f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6950a5cd1f326709d6967ba79aba858658921125...fe2328a408cec775a9fc2bc7fcbfd1f1d50c083f
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list