[vlc-commits] demux: libmp4: read atom sgpd

Francois Cartegnie git at videolan.org
Fri Mar 25 10:01:18 CET 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Mar 24 20:21:25 2016 +0100| [5a6878b31f834891f58b0ba2c346ac9c12188cb1] | committer: Francois Cartegnie

demux: libmp4: read atom sgpd

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

 modules/demux/mp4/libmp4.c |  104 ++++++++++++++++++++++++++++++++++++++++++++
 modules/demux/mp4/libmp4.h |   20 +++++++++
 2 files changed, 124 insertions(+)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 0bc1f3c..9316d2d 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -1743,6 +1743,108 @@ static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+static void MP4_FreeBox_sgpd( MP4_Box_t *p_box )
+{
+    MP4_Box_data_sgpd_t *p_sgpd = p_box->data.p_sgpd;
+    free( p_sgpd->p_entries );
+}
+
+static int MP4_ReadBox_sgpd( stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER( MP4_Box_data_sgpd_t, MP4_FreeBox_sgpd );
+    MP4_Box_data_sgpd_t *p_sgpd = p_box->data.p_sgpd;
+    uint32_t i_flags;
+    uint32_t i_default_length = 0;
+
+    if ( i_read < 8 )
+        MP4_READBOX_EXIT( 0 );
+
+    MP4_GET1BYTE( p_sgpd->i_version );
+    MP4_GET3BYTES( i_flags );
+    if( i_flags != 0 )
+        MP4_READBOX_EXIT( 0 );
+
+    MP4_GETFOURCC( p_sgpd->i_grouping_type );
+
+    switch( p_sgpd->i_grouping_type )
+    {
+        case SAMPLEGROUP_rap:
+            break;
+
+        default:
+#ifdef MP4_VERBOSE
+    msg_Dbg( p_stream,
+        "read box: \"sgpd\" grouping type %4.4s (unimplemented)", (char*) &p_sgpd->i_grouping_type );
+#endif
+            MP4_READBOX_EXIT( 1 );
+    }
+
+    if( p_sgpd->i_version == 1 )
+    {
+        if( i_read < 8 )
+            MP4_READBOX_EXIT( 0 );
+        MP4_GET4BYTES( i_default_length );
+    }
+    else if( p_sgpd->i_version >= 2 )
+    {
+        if( i_read < 8 )
+            MP4_READBOX_EXIT( 0 );
+        MP4_GET4BYTES( p_sgpd->i_default_sample_description_index );
+    }
+
+    MP4_GET4BYTES( p_sgpd->i_entry_count );
+
+    p_sgpd->p_entries = malloc( p_sgpd->i_entry_count * sizeof(*p_sgpd->p_entries) );
+    if( !p_sgpd->p_entries )
+        MP4_READBOX_EXIT( 0 );
+
+    uint32_t i = 0;
+    for( ; i<p_sgpd->i_entry_count; i++ )
+    {
+        uint32_t i_description_length = i_default_length;
+        if( p_sgpd->i_version == 1 && i_default_length == 0 )
+        {
+            if( i_read < 4 )
+                break;
+            MP4_GET4BYTES( i_description_length );
+        }
+
+        if( p_sgpd->i_version == 1 && i_read < i_description_length )
+            break;
+
+        switch( p_sgpd->i_grouping_type )
+        {
+            case SAMPLEGROUP_rap:
+                {
+                    if( i_read < 1 )
+                    {
+                        p_sgpd->i_entry_count = 0;
+                        MP4_FreeBox_sgpd( p_box );
+                        MP4_READBOX_EXIT( 0 );
+                    }
+                    uint8_t i_data;
+                    MP4_GET1BYTE( i_data );
+                    p_sgpd->p_entries[i].rap.i_num_leading_samples_known = i_data & 0x80;
+                    p_sgpd->p_entries[i].rap.i_num_leading_samples = i_data & 0x7F;
+                }
+                break;
+
+            default:
+                assert(0);
+        }
+    }
+
+    if( i != p_sgpd->i_entry_count )
+        p_sgpd->i_entry_count = i;
+
+#ifdef MP4_VERBOSE
+    msg_Dbg( p_stream,
+        "read box: \"sgpd\" grouping type %4.4s", (char*) &p_sgpd->i_grouping_type );
+#endif
+
+    MP4_READBOX_EXIT( 1 );
+}
+
 static void MP4_FreeBox_stsdext_chan( MP4_Box_t *p_box )
 {
     MP4_Box_data_chan_t *p_chan = p_box->data.p_chan;
@@ -3754,6 +3856,8 @@ static const struct
     /* Samples groups specific information */
     { ATOM_sbgp,    MP4_ReadBox_sbgp,         ATOM_stbl },
     { ATOM_sbgp,    MP4_ReadBox_sbgp,         ATOM_traf },
+    { ATOM_sgpd,    MP4_ReadBox_sgpd,         ATOM_stbl },
+    { ATOM_sgpd,    MP4_ReadBox_sgpd,         ATOM_traf },
 
     /* Quicktime preview atoms, all at root */
     { ATOM_pnot,    MP4_ReadBox_pnot,         0 },
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 0575b3c..25aa2ea 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -94,6 +94,7 @@ typedef int64_t stime_t;
 #define ATOM_stco VLC_FOURCC( 's', 't', 'c', 'o' )
 #define ATOM_co64 VLC_FOURCC( 'c', 'o', '6', '4' )
 #define ATOM_sbgp VLC_FOURCC( 's', 'b', 'g', 'p' )
+#define ATOM_sgpd VLC_FOURCC( 's', 'g', 'p', 'd' )
 #define ATOM_stss VLC_FOURCC( 's', 't', 's', 's' )
 #define ATOM_stsh VLC_FOURCC( 's', 't', 's', 'h' )
 #define ATOM_stdp VLC_FOURCC( 's', 't', 'd', 'p' )
@@ -345,6 +346,8 @@ typedef int64_t stime_t;
 #define HANDLER_mdta VLC_FOURCC('m', 'd', 't', 'a')
 #define HANDLER_mdir VLC_FOURCC('m', 'd', 'i', 'r')
 
+#define SAMPLEGROUP_rap  VLC_FOURCC('r', 'a', 'p', ' ')
+
 /* Do you want some debug information on all read boxes ? */
 #ifndef NDEBUG
 # define MP4_VERBOSE  1
@@ -1151,6 +1154,22 @@ typedef struct
 {
     uint8_t i_version;
     uint32_t i_grouping_type;
+    uint32_t i_default_sample_description_index;
+    uint32_t i_entry_count;
+    union
+    {
+        struct
+        {
+            uint8_t i_num_leading_samples_known;
+            uint8_t i_num_leading_samples;
+        } rap;
+    } *p_entries;
+} MP4_Box_data_sgpd_t;
+
+typedef struct
+{
+    uint8_t i_version;
+    uint32_t i_grouping_type;
     uint32_t i_grouping_type_parameter;
     uint32_t i_entry_count;
     struct
@@ -1432,6 +1451,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_ctts_t *p_ctts;
 
     MP4_Box_data_sbgp_t *p_sbgp;
+    MP4_Box_data_sgpd_t *p_sgpd;
 
     MP4_Box_data_sample_vide_t *p_sample_vide;
     MP4_Box_data_sample_soun_t *p_sample_soun;



More information about the vlc-commits mailing list