[vlc-commits] demux: ts: decode object stream commands

Francois Cartegnie git at videolan.org
Tue Mar 31 21:22:40 CEST 2015


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Mar 30 17:42:59 2015 +0200| [1bc2d77be86606637ac68d44f231ac47ef7c3d3b] | committer: Francois Cartegnie

demux: ts: decode object stream commands

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

 modules/demux/mpeg4_iod.c |  113 +++++++++++++++++++++++++++++++++++++++------
 modules/demux/mpeg4_iod.h |    2 +
 2 files changed, 100 insertions(+), 15 deletions(-)

diff --git a/modules/demux/mpeg4_iod.c b/modules/demux/mpeg4_iod.c
index 6a623f1..f9fa145 100644
--- a/modules/demux/mpeg4_iod.c
+++ b/modules/demux/mpeg4_iod.c
@@ -107,6 +107,7 @@ static char* ODGetURL( unsigned *pi_data, const uint8_t **pp_data )
 typedef union
 {
     od_descriptor_t *p_od;
+    od_descriptor_t **pp_ods;
     es_mpeg4_descriptor_t *es_descr;
     decoder_config_descriptor_t *p_dec_config;
     sl_config_descriptor_t *sl_descr;
@@ -373,18 +374,28 @@ static uint8_t OD_Desc_Read( vlc_object_t *p_object, unsigned *pi_data, const ui
         {
             case ODTag_ObjectDescr:
             {
+                od_descriptor_t *p_od = calloc( 1, sizeof( od_descriptor_t ) );
+                if( !p_od )
+                    break;
+                od_read_params_t childparams;
+                childparams.p_od = params.pp_ods[i_read_count] = p_od;
                 /* od_descriptor_t *p_iod = (od_descriptor_t *) param; */
                 if ( !ODObjectDescriptorRead( p_object, i_descriptor_data,
-                                               p_descriptor_data, params ) )
+                                               p_descriptor_data, childparams ) )
                 {};
                 break;
             }
 
             case ODTag_InitialObjectDescr:
             {
+                od_descriptor_t *p_iod = calloc( 1, sizeof( od_descriptor_t ) );
+                if( !p_iod )
+                    break;
+                od_read_params_t childparams;
+                childparams.p_od = params.pp_ods[i_read_count] = p_iod;
                 /* od_descriptor_t *p_iod = (od_descriptor_t *) param; */
                 if ( !OD_InitialObjectDesc_Read( p_object, i_descriptor_data,
-                                                  p_descriptor_data, params ) )
+                                                  p_descriptor_data, childparams ) )
                 {};
                 break;
             }
@@ -438,24 +449,19 @@ static uint8_t OD_Desc_Read( vlc_object_t *p_object, unsigned *pi_data, const ui
     return i_read_count;
 }
 
-static od_descriptor_t *ODInit( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data,
-                                 uint8_t i_start_tag, uint8_t i_min, uint8_t i_max )
+static uint8_t ODInit( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data,
+                       uint8_t i_start_tag, uint8_t i_min, uint8_t i_max, od_descriptor_t **pp_ods )
 {
-    /* Initial Object Descriptor must follow */
-    od_descriptor_t *p_iod = calloc( 1, sizeof( od_descriptor_t ) );
-    if( !p_iod )
-        return NULL;
-
     od_read_params_t params;
-    params.p_od = p_iod;
-    if ( OD_Desc_Read( p_object, &i_data, &p_data, i_start_tag, i_max, params ) < i_min )
+    params.pp_ods = pp_ods;
+    uint8_t i_read = OD_Desc_Read( p_object, &i_data, &p_data, i_start_tag, i_max, params );
+    if ( i_read < i_min )
     {
         od_debug( p_object, "   cannot read first tag 0x%"PRIx8, i_start_tag );
-        free( p_iod );
-        return NULL;
+        return 0;
     }
 
-    return p_iod;
+    return i_read;
 }
 
 od_descriptor_t *IODNew( vlc_object_t *p_object, unsigned i_data, const uint8_t *p_data )
@@ -481,7 +487,14 @@ od_descriptor_t *IODNew( vlc_object_t *p_object, unsigned i_data, const uint8_t
         return NULL;
     }
 
-    return ODInit( p_object, i_data, p_data, ODTag_InitialObjectDescr, 1, 1 );
+    od_descriptor_t * ods[1];
+    uint8_t i_count = ODInit( p_object, i_data, p_data, ODTag_InitialObjectDescr, 1, 1, ods );
+    if( !i_count )
+    {
+        ODFree( ods[0] );
+        return NULL;
+    }
+    return ods[0];
 }
 
 void ODFree( od_descriptor_t *p_iod )
@@ -608,3 +621,73 @@ sl_header_data DecodeSLHeader( unsigned i_data, const uint8_t *p_data,
 
     return ret;
 }
+
+/*****************************************************************************
+ * OD Commands Parser
+ *****************************************************************************/
+#define ODTag_ObjectDescrUpdate 0x01
+#define ODTag_ObjectDescrRemove 0x02
+
+static void ObjectDescrUpdateCommandRead( vlc_object_t *p_object, od_descriptors_t *p_ods,
+                                          unsigned i_data, const uint8_t *p_data )
+{
+    od_descriptor_t *p_odsread[255];
+    uint8_t i_count = ODInit( p_object, i_data, p_data, ODTag_ObjectDescr, 1, 255, p_odsread );
+    for( int i=0; i<i_count; i++ )
+    {
+        od_descriptor_t *p_od = p_odsread[i];
+        int i_pos = -1;
+        ARRAY_BSEARCH( p_ods->objects, ->i_ID, int, p_od->i_ID, i_pos );
+        if ( i_pos > -1 )
+        {
+            ODFree( p_ods->objects.p_elems[i_pos] );
+            p_ods->objects.p_elems[i_pos] = p_od;
+        }
+        else
+        {
+            ARRAY_APPEND( p_ods->objects, p_od );
+        }
+    }
+}
+
+static void ObjectDescrRemoveCommandRead( vlc_object_t *p_object, od_descriptors_t *p_ods,
+                                          unsigned i_data, const uint8_t *p_data )
+{
+    VLC_UNUSED(p_object);
+    bs_t s;
+    bs_init( &s, p_data, i_data );
+    for( unsigned i=0; i< (i_data * 8 / 10); i++ )
+    {
+        uint16_t i_id = bs_read( &s, 10 );
+        int i_pos = -1;
+        ARRAY_BSEARCH( p_ods->objects, ->i_ID, int, i_id, i_pos );
+        if( i_pos > -1 )
+            ARRAY_REMOVE( p_ods->objects, i_pos );
+    }
+}
+
+void DecodeODCommand( vlc_object_t *p_object, od_descriptors_t *p_ods,
+                      unsigned i_data, const uint8_t *p_data )
+{
+    while( i_data )
+    {
+        const uint8_t i_tag = ODGetBytes( &i_data, &p_data, 1 );
+        const unsigned i_length = ODDescriptorLength( &i_data, &p_data );
+        if( !i_length || i_length > i_data )
+            break;
+        od_debug( p_object, "Decode tag 0x%x length %d", i_tag, i_length );
+        switch( i_tag )
+        {
+            case ODTag_ObjectDescrUpdate:
+                ObjectDescrUpdateCommandRead( p_object, p_ods, i_data, p_data );
+                break;
+            case ODTag_ObjectDescrRemove:
+                ObjectDescrRemoveCommandRead( p_object, p_ods, i_data, p_data );
+                break;
+            default:
+                break;
+        }
+        p_data += i_length;
+        i_data -= i_data;
+    }
+}
diff --git a/modules/demux/mpeg4_iod.h b/modules/demux/mpeg4_iod.h
index 3060420..4fca130 100644
--- a/modules/demux/mpeg4_iod.h
+++ b/modules/demux/mpeg4_iod.h
@@ -103,3 +103,5 @@ void ODFree( od_descriptor_t *p_od );
 
 sl_header_data DecodeSLHeader( unsigned i_data, const uint8_t *p_data,
                                const sl_config_descriptor_t *sl );
+void DecodeODCommand( vlc_object_t *p_object, od_descriptors_t *,
+                      unsigned i_data, const uint8_t *p_data );



More information about the vlc-commits mailing list