vlc | branch: master | Francois Cartegnie <fcvlc...@free.fr> | Wed Sep 9 11:10:16 2015 +0200| [6879a4fc44cbef8151ea94094d0aa79bb1e38581] | committer: Francois Cartegnie
demux: mp4: ensure to load fragmented index Could be skipped as we stop parsing on moov and index can live between moov and moof > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6879a4fc44cbef8151ea94094d0aa79bb1e38581 --- modules/demux/mp4/libmp4.c | 57 ++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c index ce8daea..35b774d 100644 --- a/modules/demux/mp4/libmp4.c +++ b/modules/demux/mp4/libmp4.c @@ -264,7 +264,8 @@ static inline MP4_Box_t *MP4_ReadNextBox( stream_t *p_stream, MP4_Box_t *p_fathe * without container size, file position on exit is unknown *****************************************************************************/ static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream, - MP4_Box_t *p_container, const uint32_t stoplist[], bool b_indexed ) + MP4_Box_t *p_container, const uint32_t stoplist[], + const uint32_t excludelist[], bool b_indexed ) { /* Size of root container is set to 0 when unknown, for exemple * with a DASH stream. In that case, we skip the following check */ @@ -296,8 +297,7 @@ static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream, break; i_index = GetDWBE(&read[4]); } - - if( (p_box = MP4_ReadNextBox( p_stream, p_container )) ) + if( (p_box = MP4_ReadBoxRestricted( p_stream, p_container, NULL, excludelist )) ) { p_box->i_index = i_index; for(size_t i=0; stoplist && stoplist[i]; i++) @@ -334,7 +334,7 @@ int MP4_ReadBoxContainerChildren( stream_t *p_stream, MP4_Box_t *p_container, const uint32_t stoplist[] ) { return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_container, - stoplist, false ); + stoplist, NULL, false ); } static void MP4_BoxOffsetUp( MP4_Box_t *p_box, uint64_t i_offset ) @@ -451,7 +451,7 @@ static int MP4_ReadBox_ilst( stream_t *p_stream, MP4_Box_t *p_box ) msg_Warn( p_stream, "no handler for ilst atom" ); return 0; case HANDLER_mdta: - return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_box, NULL, true ); + return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_box, NULL, NULL, true ); case HANDLER_mdir: return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL ); default: @@ -4168,28 +4168,27 @@ MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s ) *****************************************************************************/ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) { - MP4_Box_t *p_root; int i_result; - p_root = calloc( 1, sizeof( MP4_Box_t ) ); - if( p_root == NULL ) + MP4_Box_t *p_vroot = calloc( 1, sizeof( MP4_Box_t ) ); + if( p_vroot == NULL ) return NULL; - p_root->i_type = ATOM_root; - p_root->i_shortsize = 1; + p_vroot->i_type = ATOM_root; + p_vroot->i_shortsize = 1; int64_t i_size = stream_Size( p_stream ); if( i_size > 0 ) - p_root->i_size = i_size; + p_vroot->i_size = i_size; /* could be a DASH stream for exemple, 0 means unknown or infinite size */ - CreateUUID( &p_root->i_uuid, p_root->i_type ); + CreateUUID( &p_vroot->i_uuid, p_vroot->i_type ); /* First get the moov */ const uint32_t stoplist[] = { ATOM_moov, ATOM_mdat, 0 }; - i_result = MP4_ReadBoxContainerChildren( p_stream, p_root, stoplist ); + i_result = MP4_ReadBoxContainerChildren( p_stream, p_vroot, stoplist ); /* mdat appeared first */ - if( i_result && !MP4_BoxGet( p_root, "moov" ) ) + if( i_result && !MP4_BoxGet( p_vroot, "moov" ) ) { bool b_seekable; if( stream_Control( p_stream, STREAM_CAN_SEEK, &b_seekable ) != VLC_SUCCESS || !b_seekable ) @@ -4200,20 +4199,26 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) /* continue loading up to moov */ const uint32_t stoplist[] = { ATOM_moov, 0 }; - i_result = MP4_ReadBoxContainerChildren( p_stream, p_root, stoplist ); + i_result = MP4_ReadBoxContainerChildren( p_stream, p_vroot, stoplist ); } if( !i_result ) goto error; /* If there is a mvex box, it means fragmented MP4, and we're done */ - if( MP4_BoxCount( p_root, "moov/mvex" ) > 0 ) - return p_root; + if( MP4_BoxCount( p_vroot, "moov/mvex" ) > 0 ) + { + /* Read a bit more atoms as we might have an index between moov and moof */ + const uint32_t stoplist[] = { ATOM_sidx, 0 }; + const uint32_t excludelist[] = { ATOM_moof, ATOM_mdat, 0 }; + MP4_ReadBoxContainerChildrenIndexed( p_stream, p_vroot, stoplist, excludelist, false ); + return p_vroot; + } if( stream_Tell( p_stream ) + 8 < (uint64_t) stream_Size( p_stream ) ) { /* Get the rest of the file */ - i_result = MP4_ReadBoxContainerChildren( p_stream, p_root, NULL ); + i_result = MP4_ReadBoxContainerChildren( p_stream, p_vroot, NULL ); if( !i_result ) goto error; @@ -4224,10 +4229,10 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) /* check if there is a cmov, if so replace compressed moov by uncompressed one */ - if( ( ( p_moov = MP4_BoxGet( p_root, "moov" ) ) && - ( p_cmov = MP4_BoxGet( p_root, "moov/cmov" ) ) ) || - ( ( p_moov = MP4_BoxGet( p_root, "foov" ) ) && - ( p_cmov = MP4_BoxGet( p_root, "foov/cmov" ) ) ) ) + if( ( ( p_moov = MP4_BoxGet( p_vroot, "moov" ) ) && + ( p_cmov = MP4_BoxGet( p_vroot, "moov/cmov" ) ) ) || + ( ( p_moov = MP4_BoxGet( p_vroot, "foov" ) ) && + ( p_cmov = MP4_BoxGet( p_vroot, "foov/cmov" ) ) ) ) { /* rename the compressed moov as a box to skip */ p_moov->i_type = ATOM_skip; @@ -4237,14 +4242,14 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) p_cmov->data.p_cmov->p_moov = NULL; /* make p_root father of this new moov */ - p_moov->p_father = p_root; + p_moov->p_father = p_vroot; /* insert this new moov box as first child of p_root */ - p_moov->p_next = p_root->p_first; - p_root->p_first = p_moov; + p_moov->p_next = p_vroot->p_first; + p_vroot->p_first = p_moov; } - return p_root; + return p_vroot; error: MP4_BoxFree( p_vroot ); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits