[vlc-commits] demux: libmp4: read other iloc extents methods

Francois Cartegnie git at videolan.org
Mon Nov 19 14:04:45 CET 2018


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sat Nov 17 21:32:35 2018 +0100| [e7edb3f57739a8851f67d47aac08b2c27a4cc9df] | committer: Francois Cartegnie

demux: libmp4: read other iloc extents methods

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

 modules/demux/mp4/heif.c   | 64 ++++++++++++++++++++++++++++++++++++----------
 modules/demux/mp4/libmp4.c |  1 +
 modules/demux/mp4/libmp4.h |  1 +
 3 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/modules/demux/mp4/heif.c b/modules/demux/mp4/heif.c
index 745a7f37ef..3298667809 100644
--- a/modules/demux/mp4/heif.c
+++ b/modules/demux/mp4/heif.c
@@ -247,25 +247,61 @@ static block_t *ReadItemExtents( demux_t *p_demux, uint32_t i_item_id,
             }
         }
 
-        uint64_t i_base_offset = BOXDATA(p_iloc)->p_items[i].i_base_offset;
-        if( i_base_offset == 0 )
-        {
-            MP4_Box_t *mdat = MP4_BoxGet( p_sys->p_root, "mdat" );
-            if( !mdat )
-                break;
-            i_base_offset = mdat->i_pos + mp4_box_headersize( mdat );
-        }
-
         for( uint16_t j=0; j<BOXDATA(p_iloc)->p_items[i].i_extent_count; j++ )
         {
-            uint64_t i_offset = i_base_offset +
+            uint64_t i_offset = BOXDATA(p_iloc)->p_items[i].i_base_offset +
                                 BOXDATA(p_iloc)->p_items[i].p_extents[j].i_extent_offset;
             uint64_t i_length = BOXDATA(p_iloc)->p_items[i].p_extents[j].i_extent_length;
 
-            if( vlc_stream_Seek( p_demux->s, i_offset ) != VLC_SUCCESS )
-                break;
-            *pp_append = vlc_stream_Block( p_demux->s, i_length );
-            if( *pp_append )
+            if( BOXDATA(p_iloc)->p_items[i].i_construction_method < 2 )
+            {
+                /* Extents are in 1:file, 2:idat */
+                if( BOXDATA(p_iloc)->p_items[i].i_construction_method == 1 )
+                {
+                    MP4_Box_t *idat = MP4_BoxGet( p_sys->p_root, "meta/idat" );
+                    if(!idat)
+                        break;
+                    i_offset += idat->i_pos + mp4_box_headersize(idat);
+                }
+
+                if( vlc_stream_Seek( p_demux->s, i_offset ) != VLC_SUCCESS )
+                    break;
+                *pp_append = vlc_stream_Block( p_demux->s, i_length );
+            }
+            /* Extents are 3:iloc reference */
+            else if( BOXDATA(p_iloc)->p_items[i].i_construction_method == 2 )
+            {
+                /* FIXME ? That's totally untested and really complicated */
+                uint32_t i_extent_index = BOXDATA(p_iloc)->p_items[i].p_extents[j].i_extent_index;
+                if(i_extent_index == 0)
+                    i_extent_index = 1; /* Inferred. Indexes start 1 */
+                const MP4_Box_t *p_iref = MP4_BoxGet( p_sys->p_root, "meta/iref" );
+                if(!p_iref)
+                    break;
+                for( const MP4_Box_t *p_refbox = p_iref->p_first;
+                                      p_refbox; p_refbox = p_refbox->p_next )
+                {
+                    if( p_refbox->i_type != VLC_FOURCC('i','l','o','c') ||
+                        BOXDATA(p_refbox)->i_from_item_id == i_item_id )
+                        continue;
+
+                    for( uint16_t k=0; k< BOXDATA(p_refbox)->i_reference_count; k++ )
+                    {
+                        if( --i_extent_index > 0 )
+                            continue;
+                        if( BOXDATA(p_refbox)->p_references[k].i_to_item_id != i_item_id )
+                        {
+                            *pp_append = ReadItemExtents(p_demux,
+                                            BOXDATA(p_refbox)->p_references[k].i_to_item_id,
+                                            NULL);
+                        }
+                    }
+
+                    break;
+                }
+            }
+
+            while( *pp_append )
                 pp_append = &((*pp_append)->p_next);
         }
         break;
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 63afc1180d..07ded01c59 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -5131,6 +5131,7 @@ static const struct
     { ATOM_SA3D,    MP4_ReadBox_SA3D,        0 },
 
     /* iso4 brand meta references */
+    { ATOM_idat,    MP4_ReadBoxSkip,         ATOM_meta },
     { ATOM_iloc,    MP4_ReadBox_iloc,        ATOM_meta },
     { ATOM_iinf,    MP4_ReadBox_iinf,        ATOM_meta },
     { ATOM_infe,    MP4_ReadBox_infe,        ATOM_iinf },
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 69ed1a60a4..29de18c4ed 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -422,6 +422,7 @@ typedef int64_t stime_t;
 #define ATOM_SA3D VLC_FOURCC( 'S', 'A', '3', 'D' )
 
 /* iso4 meta references */
+#define ATOM_idat VLC_FOURCC('i','d','a','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')



More information about the vlc-commits mailing list