[vlc-commits] demux: ts: fix parsing of program_map

Francois Cartegnie git at videolan.org
Sun Mar 12 20:23:35 CET 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sun Mar 12 14:54:36 2017 +0100| [8924974ac13958b2850a9923f07cc11e918279a1] | committer: Francois Cartegnie

demux: ts: fix parsing of program_map

and removes descriptors storage

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

 modules/demux/mpeg/ps.h | 149 +++++++++++++++++++++++++-----------------------
 1 file changed, 77 insertions(+), 72 deletions(-)

diff --git a/modules/demux/mpeg/ps.h b/modules/demux/mpeg/ps.h
index 0dc22bf..10bc4e3 100644
--- a/modules/demux/mpeg/ps.h
+++ b/modules/demux/mpeg/ps.h
@@ -94,6 +94,7 @@ static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm, int i_id, bloc
 {
     tk->i_skip = 0;
     tk->i_id = i_id;
+
     if( ( i_id&0xff00 ) == 0xbd00 ) /* 0xBD00 -> 0xBDFF, Private Stream 1 */
     {
         if( ( i_id&0xf8 ) == 0x88 || /* 0x88 -> 0x8f - Can be DTS-HD primary audio in evob */
@@ -420,7 +421,7 @@ static inline int ps_pkt_parse_system( block_t *p_pkt, ps_psm_t *p_psm,
             case 0xB7:
                 if( &p_pkt->p_buffer[p_pkt->i_buffer] - p < 6 )
                     return VLC_EGENERIC;
-                i_id = (PS_STREAM_ID_EXTENDED << 8) | (p[2] & 0x7F);
+                i_id = ((int)PS_STREAM_ID_EXTENDED << 8) | (p[2] & 0x7F);
                 p += 6;
                 break;
             default:
@@ -481,17 +482,19 @@ static inline int ps_pkt_parse_pes( vlc_object_t *p_object, block_t *p_pes, int
     return VLC_SUCCESS;
 }
 
+typedef struct
+{
+    /* Language is iso639-2T */
+    uint8_t lang[3];
+} ps_descriptors_t;
+
 /* Program stream map handling */
 typedef struct ps_es_t
 {
     int i_type;
     int i_id;
 
-    int i_descriptor;
-    uint8_t *p_descriptor;
-
-    /* Language is iso639-2T */
-    uint8_t lang[3];
+    ps_descriptors_t desc;
 
 } ps_es_t;
 
@@ -499,26 +502,29 @@ struct ps_psm_t
 {
     int i_version;
 
-    int     i_es;
-    ps_es_t **es;
+    size_t  i_es;
+    ps_es_t *es;
+
+    ps_descriptors_t uniqueextdesc;
 };
 
 static inline int ps_id_to_type( const ps_psm_t *p_psm, int i_id )
 {
-    int i;
+    size_t i;
     for( i = 0; p_psm && i < p_psm->i_es; i++ )
     {
-        if( p_psm->es[i]->i_id == i_id ) return p_psm->es[i]->i_type;
+        if( p_psm->es[i].i_id == i_id ) return p_psm->es[i].i_type;
     }
     return 0;
 }
 
 static inline const uint8_t *ps_id_to_lang( const ps_psm_t *p_psm, int i_id )
 {
-    int i;
+    size_t i;
     for( i = 0; p_psm && i < p_psm->i_es; i++ )
     {
-        if( p_psm->es[i]->i_id == i_id ) return p_psm->es[i]->lang;
+        if( p_psm->es[i].i_id == i_id )
+            return p_psm->es[i].desc.lang;
     }
     return 0;
 }
@@ -528,42 +534,64 @@ static inline void ps_psm_init( ps_psm_t *p_psm )
     p_psm->i_version = 0xFFFF;
     p_psm->i_es = 0;
     p_psm->es = 0;
+    memset( &p_psm->uniqueextdesc, 0, 3 );
 }
 
 static inline void ps_psm_destroy( ps_psm_t *p_psm )
 {
-    while( p_psm->i_es-- )
-    {
-        free( p_psm->es[p_psm->i_es]->p_descriptor );
-        free( p_psm->es[p_psm->i_es] );
-    }
     free( p_psm->es );
-
-    p_psm->es = 0;
+    p_psm->es = NULL;
     p_psm->i_es = 0;
 }
 
+static inline void ps_parse_descriptors( const uint8_t *p_data, size_t i_data,
+                                        ps_descriptors_t *p_desc )
+{
+    while( i_data > 3 && i_data > 2u + p_data[1] )
+    {
+        switch( p_data[0] )
+        {
+            case 0x0A: /* ISO_639_language_descriptor */
+                if( i_data >= 6 )
+                    memcpy( p_desc->lang, &p_data[2], 3 );
+                break;
+
+            default:
+                break;
+        }
+        p_data += 2 + p_data[1];
+        i_data -= 2 + p_data[1];
+    }
+}
+
 static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt,
                                ps_track_t tk[PS_TK_COUNT], es_out_t *out )
 {
-    int i_buffer = p_pkt->i_buffer;
+    size_t i_buffer = p_pkt->i_buffer;
     uint8_t *p_buffer = p_pkt->p_buffer;
-    int i_length, i_version, i_info_length, i_es_base;
+    size_t i_length, i_info_length, i_es_base;
+    int i_version;
+    bool b_single_extension;
 
-    if( !p_psm || p_buffer[3] != 0xbc ) return VLC_EGENERIC;
+    if( !p_psm || p_buffer[3] != PS_STREAM_ID_MAP )
+        return VLC_EGENERIC;
 
-    i_length = (uint16_t)(p_buffer[4] << 8) + p_buffer[5] + 6;
+    i_length = GetWBE(&p_buffer[4]) + 6;
     if( i_length > i_buffer ) return VLC_EGENERIC;
 
-    //i_current_next_indicator = (p_buffer[6] & 0x01);
+    if((p_buffer[6] & 0x80) == 0) /* current_next_indicator */
+        return VLC_EGENERIC;
+
+    b_single_extension = p_buffer[6] & 0x40;
     i_version = (p_buffer[6] & 0xf8);
 
     if( p_psm->i_version == i_version ) return VLC_EGENERIC;
 
     ps_psm_destroy( p_psm );
 
-    i_info_length = (uint16_t)(p_buffer[8] << 8) + p_buffer[9];
-    if( i_info_length + 10 > i_length ) return VLC_EGENERIC;
+    i_info_length = GetWBE(&p_buffer[8]);
+    if( i_info_length + 10 > i_length )
+        return VLC_EGENERIC;
 
     /* Elementary stream map */
     /* int i_esm_length = (uint16_t)(p_buffer[ 10 + i_info_length ] << 8) +
@@ -572,64 +600,41 @@ static inline int ps_psm_fill( ps_psm_t *p_psm, block_t *p_pkt,
 
     while( i_es_base + 4 < i_length )
     {
-        ps_es_t **tmp_es;
-        ps_es_t es;
-        es.lang[0] = es.lang[1] = es.lang[2] = 0;
+        ps_es_t *tmp_es = realloc( p_psm->es, sizeof(ps_es_t) * (p_psm->i_es+1) );
+        if( tmp_es == NULL )
+            break;
+        p_psm->es = tmp_es;
 
-        es.i_type = p_buffer[ i_es_base  ];
-        es.i_id = p_buffer[ i_es_base + 1 ];
-        i_info_length = (uint16_t)(p_buffer[ i_es_base + 2 ] << 8) +
-            p_buffer[ i_es_base + 3 ];
+        ps_es_t *p_es = &p_psm->es[ p_psm->i_es++ ];
+        p_es->i_type = p_buffer[ i_es_base  ];
+        p_es->i_id = p_buffer[ i_es_base + 1 ];
 
-        if( i_es_base + 4 + i_info_length > i_length ) break;
+        i_info_length = GetWBE(&p_buffer[ i_es_base + 2 ]);
+
+        if( i_es_base + 4 + i_info_length > i_length )
+            break;
 
         /* TODO Add support for VC-1 stream:
          *      stream_type=0xea, stream_id=0xfd AND registration
          *      descriptor 0x5 with format_identifier == 0x56432D31 (VC-1)
          *      (I need a sample that use PSM with VC-1) */
 
-        es.p_descriptor = 0;
-        es.i_descriptor = i_info_length;
-        if( i_info_length > 0 )
+        if( p_es->i_id == PS_STREAM_ID_EXTENDED && b_single_extension == 0 )
         {
-            int i = 0;
-
-            es.p_descriptor = malloc( i_info_length );
-            if( es.p_descriptor )
-            {
-                memcpy( es.p_descriptor, p_buffer + i_es_base + 4, i_info_length);
-
-                while( i <= es.i_descriptor - 2 )
-                {
-                    /* Look for the ISO639 language descriptor */
-                    if( es.p_descriptor[i] != 0x0a )
-                    {
-                        i += es.p_descriptor[i+1] + 2;
-                        continue;
-                    }
-
-                    if( i <= es.i_descriptor - 6 )
-                    {
-                        es.lang[0] = es.p_descriptor[i+2];
-                        es.lang[1] = es.p_descriptor[i+3];
-                        es.lang[2] = es.p_descriptor[i+4];
-                    }
-                    break;
-                }
-            }
+            if( i_info_length < 3 )
+                break;
+            p_es->i_id = (p_es->i_id << 8) | (p_buffer[i_es_base + 6] & 0x7F);
+            ps_parse_descriptors( &p_buffer[i_es_base + 4 + 3],
+                                  i_info_length - 3,
+                                  &p_psm->uniqueextdesc );
         }
-
-        tmp_es = realloc( p_psm->es, sizeof(ps_es_t *) * (p_psm->i_es+1) );
-        if( tmp_es )
+        else
         {
-            p_psm->es = tmp_es;
-            p_psm->es[p_psm->i_es] = malloc( sizeof(ps_es_t) );
-            if( p_psm->es[p_psm->i_es] )
-            {
-                *p_psm->es[p_psm->i_es++] = es;
-                i_es_base += 4 + i_info_length;
-            }
+            ps_parse_descriptors( &p_buffer[i_es_base + 4],
+                                  i_info_length, &p_es->desc );
         }
+
+        i_es_base += 4 + i_info_length;
     }
 
     /* TODO: CRC */



More information about the vlc-commits mailing list