Commit 6879a4fc authored by Francois Cartegnie's avatar 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
parent 897e35aa
...@@ -264,7 +264,8 @@ static inline MP4_Box_t *MP4_ReadNextBox( stream_t *p_stream, MP4_Box_t *p_fathe ...@@ -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 * without container size, file position on exit is unknown
*****************************************************************************/ *****************************************************************************/
static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream, 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 /* Size of root container is set to 0 when unknown, for exemple
* with a DASH stream. In that case, we skip the following check */ * with a DASH stream. In that case, we skip the following check */
...@@ -296,8 +297,7 @@ static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream, ...@@ -296,8 +297,7 @@ static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream,
break; break;
i_index = GetDWBE(&read[4]); i_index = GetDWBE(&read[4]);
} }
if( (p_box = MP4_ReadBoxRestricted( p_stream, p_container, NULL, excludelist )) )
if( (p_box = MP4_ReadNextBox( p_stream, p_container )) )
{ {
p_box->i_index = i_index; p_box->i_index = i_index;
for(size_t i=0; stoplist && stoplist[i]; i++) 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, ...@@ -334,7 +334,7 @@ int MP4_ReadBoxContainerChildren( stream_t *p_stream, MP4_Box_t *p_container,
const uint32_t stoplist[] ) const uint32_t stoplist[] )
{ {
return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_container, 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 ) 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 ) ...@@ -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" ); msg_Warn( p_stream, "no handler for ilst atom" );
return 0; return 0;
case HANDLER_mdta: 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: case HANDLER_mdir:
return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL ); return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL );
default: default:
...@@ -4168,28 +4168,27 @@ MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s ) ...@@ -4168,28 +4168,27 @@ MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s )
*****************************************************************************/ *****************************************************************************/
MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream )
{ {
MP4_Box_t *p_root;
int i_result; int i_result;
p_root = calloc( 1, sizeof( MP4_Box_t ) ); MP4_Box_t *p_vroot = calloc( 1, sizeof( MP4_Box_t ) );
if( p_root == NULL ) if( p_vroot == NULL )
return NULL; return NULL;
p_root->i_type = ATOM_root; p_vroot->i_type = ATOM_root;
p_root->i_shortsize = 1; p_vroot->i_shortsize = 1;
int64_t i_size = stream_Size( p_stream ); int64_t i_size = stream_Size( p_stream );
if( i_size > 0 ) 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 */ /* 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 */ /* First get the moov */
const uint32_t stoplist[] = { ATOM_moov, ATOM_mdat, 0 }; 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 */ /* mdat appeared first */
if( i_result && !MP4_BoxGet( p_root, "moov" ) ) if( i_result && !MP4_BoxGet( p_vroot, "moov" ) )
{ {
bool b_seekable; bool b_seekable;
if( stream_Control( p_stream, STREAM_CAN_SEEK, &b_seekable ) != VLC_SUCCESS || !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 ) ...@@ -4200,20 +4199,26 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream )
/* continue loading up to moov */ /* continue loading up to moov */
const uint32_t stoplist[] = { ATOM_moov, 0 }; 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 ) if( !i_result )
goto error; goto error;
/* If there is a mvex box, it means fragmented MP4, and we're done */ /* If there is a mvex box, it means fragmented MP4, and we're done */
if( MP4_BoxCount( p_root, "moov/mvex" ) > 0 ) if( MP4_BoxCount( p_vroot, "moov/mvex" ) > 0 )
return p_root; {
/* 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 ) ) if( stream_Tell( p_stream ) + 8 < (uint64_t) stream_Size( p_stream ) )
{ {
/* Get the rest of the file */ /* 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 ) if( !i_result )
goto error; goto error;
...@@ -4224,10 +4229,10 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) ...@@ -4224,10 +4229,10 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream )
/* check if there is a cmov, if so replace /* check if there is a cmov, if so replace
compressed moov by uncompressed one */ compressed moov by uncompressed one */
if( ( ( p_moov = MP4_BoxGet( p_root, "moov" ) ) && if( ( ( p_moov = MP4_BoxGet( p_vroot, "moov" ) ) &&
( p_cmov = MP4_BoxGet( p_root, "moov/cmov" ) ) ) || ( p_cmov = MP4_BoxGet( p_vroot, "moov/cmov" ) ) ) ||
( ( p_moov = MP4_BoxGet( p_root, "foov" ) ) && ( ( p_moov = MP4_BoxGet( p_vroot, "foov" ) ) &&
( p_cmov = MP4_BoxGet( p_root, "foov/cmov" ) ) ) ) ( p_cmov = MP4_BoxGet( p_vroot, "foov/cmov" ) ) ) )
{ {
/* rename the compressed moov as a box to skip */ /* rename the compressed moov as a box to skip */
p_moov->i_type = ATOM_skip; p_moov->i_type = ATOM_skip;
...@@ -4237,14 +4242,14 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream ) ...@@ -4237,14 +4242,14 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *p_stream )
p_cmov->data.p_cmov->p_moov = NULL; p_cmov->data.p_cmov->p_moov = NULL;
/* make p_root father of this new moov */ /* 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 */ /* insert this new moov box as first child of p_root */
p_moov->p_next = p_root->p_first; p_moov->p_next = p_vroot->p_first;
p_root->p_first = p_moov; p_vroot->p_first = p_moov;
} }
return p_root; return p_vroot;
error: error:
MP4_BoxFree( p_vroot ); MP4_BoxFree( p_vroot );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment