[vlc-commits] demux: libmp4: read heif box ipma

Francois Cartegnie git at videolan.org
Tue Mar 13 19:09:36 CET 2018


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Mar  9 12:51:04 2018 +0100| [8c2171408755546337c06374b31d477b13a0b2f8] | committer: Francois Cartegnie

demux: libmp4: read heif box ipma

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

 modules/demux/mp4/libmp4.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
 modules/demux/mp4/libmp4.h | 17 ++++++++++
 2 files changed, 99 insertions(+)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 73618c1cfc..681b4f2708 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -4513,6 +4513,87 @@ static int MP4_ReadBox_ispe( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+static void MP4_FreeBox_ipma( MP4_Box_t *p_box )
+{
+    MP4_Box_data_ipma_t *p_data = p_box->data.p_ipma;
+    for( uint32_t i=0; i<p_data->i_entry_count; i++ )
+        free( p_data->p_entries[i].p_assocs );
+    free( p_data->p_entries );
+}
+
+static int MP4_ReadBox_ipma( stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER( MP4_Box_data_ipma_t, MP4_FreeBox_ipma );
+    MP4_Box_data_ipma_t *p_data = p_box->data.p_ipma;
+
+    uint8_t i_version;
+    uint32_t i_flags;
+    MP4_GET1BYTE( i_version );
+    MP4_GET3BYTES( i_flags );
+
+    MP4_GET4BYTES( p_data->i_entry_count );
+    if( (i_read / ((i_version < 1) ? 3 : 5) <  p_data->i_entry_count) )
+    {
+        p_data->i_entry_count = 0;
+        MP4_READBOX_EXIT( 0 );
+    }
+
+    p_data->p_entries = malloc( sizeof(p_data->p_entries[0]) * p_data->i_entry_count );
+    if( !p_data->p_entries )
+    {
+        p_data->i_entry_count = 0;
+        MP4_READBOX_EXIT( 0 );
+    }
+
+    for( uint32_t i=0; i<p_data->i_entry_count; i++ )
+    {
+        if( i_read < ((i_version < 1) ? 3 : 5) )
+        {
+            p_data->i_entry_count = i;
+            MP4_READBOX_EXIT( 0 );
+        }
+        if( i_version < 1 )
+            MP4_GET2BYTES( p_data->p_entries[i].i_item_id );
+        else
+            MP4_GET4BYTES( p_data->p_entries[i].i_item_id );
+        MP4_GET1BYTE( p_data->p_entries[i].i_association_count );
+
+        if( i_read / ((i_flags & 0x01) ? 2 : 1) <
+               p_data->p_entries[i].i_association_count )
+        {
+            p_data->i_entry_count = i;
+            MP4_READBOX_EXIT( 0 );
+        }
+
+        p_data->p_entries[i].p_assocs =
+                malloc( sizeof(p_data->p_entries[i].p_assocs[0]) *
+                        p_data->p_entries[i].i_association_count );
+        if( !p_data->p_entries[i].p_assocs )
+        {
+            p_data->p_entries[i].i_association_count = 0;
+            p_data->i_entry_count = i;
+            MP4_READBOX_EXIT( 0 );
+        }
+
+        for( uint8_t j=0; j<p_data->p_entries[i].i_association_count; j++ )
+        {
+            MP4_GET1BYTE( p_data->p_entries[i].p_assocs[j].i_property_index );
+            p_data->p_entries[i].p_assocs[j].b_essential =
+                    p_data->p_entries[i].p_assocs[j].i_property_index & 0x80;
+            p_data->p_entries[i].p_assocs[j].i_property_index &= 0x7F;
+            if( i_flags & 0x01 )
+            {
+                p_data->p_entries[i].p_assocs[j].i_property_index <<= 8;
+                uint8_t i_low;
+                MP4_GET1BYTE( i_low );
+                p_data->p_entries[i].p_assocs[j].i_property_index |= i_low;
+            }
+        }
+    }
+
+    MP4_READBOX_EXIT( 1 );
+}
+
 /* For generic */
 static int MP4_ReadBox_default( stream_t *p_stream, MP4_Box_t *p_box )
 {
@@ -5001,6 +5082,7 @@ static const struct
     { ATOM_iprp,    MP4_ReadBoxContainer,    ATOM_meta },
     { ATOM_ipco,    MP4_ReadBoxContainer,    ATOM_iprp },
     { ATOM_ispe,    MP4_ReadBox_ispe,        ATOM_ipco },
+    { ATOM_ipma,    MP4_ReadBox_ipma,        ATOM_iprp },
 
     /* Last entry */
     { 0,              MP4_ReadBox_default,   0 }
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 33993f6c6c..5561ad1058 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -405,6 +405,7 @@ typedef int64_t stime_t;
 #define ATOM_iprp VLC_FOURCC('i','p','r','p')
 #define ATOM_ipco VLC_FOURCC('i','p','c','o')
 #define ATOM_ispe VLC_FOURCC('i','s','p','e')
+#define ATOM_ipma VLC_FOURCC('i','p','m','a')
 
 #define HANDLER_mdta VLC_FOURCC('m', 'd', 't', 'a')
 #define HANDLER_mdir VLC_FOURCC('m', 'd', 'i', 'r')
@@ -1685,6 +1686,21 @@ typedef struct
     uint32_t i_height;
 } MP4_Box_data_ispe_t;
 
+typedef struct
+{
+    uint32_t i_entry_count;
+    struct
+    {
+        uint32_t i_item_id;
+        uint8_t  i_association_count;
+        struct
+        {
+            uint8_t b_essential;
+            uint16_t i_property_index;
+        } *p_assocs;
+    } *p_entries;
+} MP4_Box_data_ipma_t;
+
 /*
 typedef struct MP4_Box_data__s
 {
@@ -1804,6 +1820,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_infe_t *p_infe;
     MP4_Box_data_pitm_t *p_pitm;
     MP4_Box_data_ispe_t *p_ispe; /* heif */
+    MP4_Box_data_ipma_t *p_ipma; /* heif */
 
     /* for generic handlers */
     MP4_Box_data_binary_t *p_binary;



More information about the vlc-commits mailing list