vlc | branch: master | Francois Cartegnie <fcvlc...@free.fr> | Fri Mar  9 
16:26:46 2018 +0100| [a1cc1ad610696aedb0bce853c03f5621e2d490c2] | committer: 
Francois Cartegnie

demux: libmp4: add box reader iref

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

 modules/demux/mp4/libmp4.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 modules/demux/mp4/libmp4.h | 19 ++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 02244e77ca..9906236489 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -4254,6 +4254,78 @@ static int MP4_ReadBox_SA3D( stream_t *p_stream, 
MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+static void MP4_FreeBox_Reference( MP4_Box_t *p_box )
+{
+    MP4_Box_data_refbox_t *p_data = p_box->data.p_refbox;
+    free( p_data->p_references );
+}
+
+static int MP4_ReadBox_Reference( stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER( MP4_Box_data_refbox_t, MP4_FreeBox_Reference );
+    MP4_Box_data_refbox_t *p_data = p_box->data.p_refbox;
+
+    if( p_box->p_father->data.p_iref->i_flags == 0 )
+        MP4_GET2BYTES( p_data->i_from_item_id );
+    else
+        MP4_GET4BYTES( p_data->i_from_item_id );
+    MP4_GET2BYTES( p_data->i_reference_count );
+
+    if( i_read / sizeof(*p_data->p_references) < p_data->i_reference_count )
+        MP4_READBOX_EXIT( 0 );
+
+    p_data->p_references = malloc( sizeof(*p_data->p_references) *
+                                   p_data->i_reference_count );
+    if( !p_data->p_references )
+        MP4_READBOX_EXIT( 0 );
+    for( uint16_t i=0; i<p_data->i_reference_count; i++ )
+    {
+        if( p_box->p_father->data.p_iref == 0 )
+            MP4_GET2BYTES( p_data->p_references[i].i_to_item_id );
+        else
+            MP4_GET4BYTES( p_data->p_references[i].i_to_item_id );
+    }
+
+    MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_iref( stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_iref_t, 12, NULL );
+    MP4_Box_data_iref_t *p_data = p_box->data.p_iref;
+    if( i_read < 4 )
+        MP4_READBOX_EXIT( 0 );
+
+    MP4_GET1BYTE( p_data->i_version );
+    MP4_GET3BYTES( p_data->i_flags );
+    if( p_data->i_version > 0 )
+        MP4_READBOX_EXIT( 0 );
+
+    assert( i_read == 0 );
+
+    uint32_t i = 0;
+    uint64_t i_remain = p_box->i_size - 12;
+    while ( i_remain > 8 )
+    {
+        MP4_Box_t *p_childbox = MP4_ReadBoxUsing( p_stream, p_box,
+                                                  MP4_ReadBox_Reference );
+        if( !p_childbox || i_remain < p_childbox->i_size )
+        {
+            MP4_BoxFree( p_childbox );
+            break;
+        }
+
+        MP4_BoxAddChild( p_box, p_childbox );
+        i_remain -= p_childbox->i_size;
+        i++;
+    }
+
+    if ( MP4_Seek( p_stream, p_box->i_pos + p_box->i_size ) )
+        MP4_READBOX_EXIT( 0 );
+
+    MP4_READBOX_EXIT( 1 );
+}
+
 static void MP4_FreeBox_iloc( MP4_Box_t *p_box )
 {
     MP4_Box_data_iloc_t *p_data = p_box->data.p_iloc;
@@ -5078,6 +5150,7 @@ static const struct
     { ATOM_iloc,    MP4_ReadBox_iloc,        ATOM_meta },
     { ATOM_iinf,    MP4_ReadBox_iinf,        ATOM_meta },
     { ATOM_infe,    MP4_ReadBox_infe,        ATOM_iinf },
+    { ATOM_iref,    MP4_ReadBox_iref,        ATOM_meta },
     { ATOM_pitm,    MP4_ReadBox_pitm,        ATOM_meta },
 
     /* HEIF specific meta references */
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 5561ad1058..b82961094c 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -400,6 +400,7 @@ typedef int64_t stime_t;
 #define ATOM_iloc VLC_FOURCC('i','l','o','c')
 #define ATOM_iinf VLC_FOURCC('i','i','n','f')
 #define ATOM_infe VLC_FOURCC('i','n','f','e')
+#define ATOM_iref VLC_FOURCC('i','r','e','f')
 #define ATOM_pitm VLC_FOURCC('p','i','t','m')
 /* HEIF specific meta */
 #define ATOM_iprp VLC_FOURCC('i','p','r','p')
@@ -1637,6 +1638,22 @@ typedef struct
 
 typedef struct
 {
+    uint32_t i_from_item_id;
+    uint16_t i_reference_count;
+    struct
+    {
+        uint32_t i_to_item_id;
+    } *p_references;
+} MP4_Box_data_refbox_t;
+
+typedef struct
+{
+    uint8_t i_version;
+    uint32_t i_flags;
+} MP4_Box_data_iref_t;
+
+typedef struct
+{
     uint8_t i_offset_size;
     uint8_t i_length_size;
     uint8_t i_base_offset_size;
@@ -1815,6 +1832,8 @@ typedef union MP4_Box_data_s
     MP4_Box_data_cbmp_t *p_cbmp;
     MP4_Box_data_SA3D_t *p_SA3D;
 
+    MP4_Box_data_refbox_t *p_refbox;
+    MP4_Box_data_iref_t *p_iref;
     MP4_Box_data_iloc_t *p_iloc;
     MP4_Box_data_iinf_t *p_iinf;
     MP4_Box_data_infe_t *p_infe;

_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to