Commit f29dbe1e authored by François Cartegnie's avatar François Cartegnie 🤞

demux: libmp4: read iloc

parent 10fac2e6
......@@ -4252,6 +4252,170 @@ static int MP4_ReadBox_SA3D( stream_t *p_stream, MP4_Box_t *p_box )
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;
for( uint32_t i=0; i<p_data->i_item_count; i++ )
free( p_data->p_items[i].p_extents );
free( p_data->p_items );
}
static int MP4_ReadBox_iloc( stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_READBOX_ENTER( MP4_Box_data_iloc_t, MP4_FreeBox_iloc );
MP4_Box_data_iloc_t *p_data = p_box->data.p_iloc;
uint16_t i_foo;
uint8_t i_version;
uint32_t i_flags;
MP4_GET1BYTE( i_version );
MP4_GET3BYTES( i_flags );
VLC_UNUSED(i_flags);
MP4_GET1BYTE( p_data->i_offset_size );
p_data->i_length_size = p_data->i_offset_size & 0x0F;
p_data->i_offset_size >>= 4;
MP4_GET1BYTE( p_data->i_base_offset_size );
if( i_version == 0 )
p_data->i_index_size = 0;
else
p_data->i_index_size = p_data->i_base_offset_size & 0x0F;
p_data->i_base_offset_size >>= 4;
/* Only accept 0,4,8 */
if( (p_data->i_offset_size & 0xF3) || p_data->i_offset_size > 8 ||
(p_data->i_length_size & 0xF3) || p_data->i_length_size > 8 ||
(p_data->i_base_offset_size & 0xF3) || p_data->i_base_offset_size > 8 ||
(p_data->i_index_size & 0xF3) || p_data->i_index_size > 8 )
MP4_READBOX_EXIT( 0 );
if( i_version < 2 )
MP4_GET2BYTES( p_data->i_item_count );
else if( i_version == 2 )
MP4_GET4BYTES( p_data->i_item_count );
else
MP4_READBOX_EXIT( 0 );
if( i_read / 6 < p_data->i_item_count )
MP4_READBOX_EXIT( 0 );
p_data->p_items = malloc( p_data->i_item_count * sizeof(p_data->p_items[0]) );
if( !p_data->p_items )
MP4_READBOX_EXIT( 0 );
for( uint32_t i=0; i<p_data->i_item_count; i++ )
{
if( i_version < 2 )
MP4_GET2BYTES( p_data->p_items[i].i_item_id );
else
MP4_GET4BYTES( p_data->p_items[i].i_item_id );
if( i_version > 0 )
{
MP4_GET2BYTES( i_foo );
p_data->p_items[i].i_construction_method = i_foo & 0x0F;
}
MP4_GET2BYTES( p_data->p_items[i].i_data_reference_index );
switch( p_data->i_base_offset_size )
{
case 4: MP4_GET4BYTES( p_data->p_items[i].i_base_offset ); break;
case 8: MP4_GET8BYTES( p_data->p_items[i].i_base_offset ); break;
default: break;
}
MP4_GET2BYTES( p_data->p_items[i].i_extent_count );
uint64_t i_entrysize = (( i_version > 0 ) ? p_data->i_index_size : 0) +
p_data->i_offset_size + p_data->i_length_size;
if( i_read / i_entrysize < p_data->p_items[i].i_extent_count )
{
p_data->i_item_count = i;
MP4_READBOX_EXIT( 0 );
}
p_data->p_items[i].p_extents = malloc( p_data->p_items[i].i_extent_count *
sizeof(p_data->p_items[i].p_extents[0]) );
for( uint16_t j=0; j<p_data->p_items[i].i_extent_count; j++ )
{
if( i_version > 0 )
{
switch( p_data->i_index_size )
{
case 4: MP4_GET4BYTES( p_data->p_items[i].p_extents[j].i_extent_index ); break;
case 8: MP4_GET8BYTES( p_data->p_items[i].p_extents[j].i_extent_index ); break;
default: break;
}
}
switch( p_data->i_offset_size )
{
case 4: MP4_GET4BYTES( p_data->p_items[i].p_extents[j].i_extent_offset ); break;
case 8: MP4_GET8BYTES( p_data->p_items[i].p_extents[j].i_extent_offset ); break;
default: break;
}
switch( p_data->i_length_size )
{
case 4: MP4_GET4BYTES( p_data->p_items[i].p_extents[j].i_extent_length ); break;
case 8: MP4_GET8BYTES( p_data->p_items[i].p_extents[j].i_extent_length ); break;
default: break;
}
}
}
MP4_READBOX_EXIT( 1 );
}
static int MP4_ReadBox_iinf( stream_t *p_stream, MP4_Box_t *p_box )
{
const uint8_t *p_versionpeek;
size_t i_peek = vlc_stream_Peek( p_stream, &p_versionpeek, 9 );
if( i_peek < 9 )
return 0;
size_t i_header = 12 + (( p_versionpeek[8] == 0 ) ? 2 : 4);
MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_iinf_t, i_header, NULL );
if( i_read + 8 < i_header )
MP4_READBOX_EXIT( 0 );
uint8_t i_version;
uint32_t i_flags;
MP4_GET1BYTE( i_version );
MP4_GET3BYTES( i_flags ); VLC_UNUSED(i_flags);
if( i_version > 2 )
MP4_READBOX_EXIT( 0 );
if( i_version == 0 )
MP4_GET2BYTES( p_box->data.p_iinf->i_entry_count );
else
MP4_GET4BYTES( p_box->data.p_iinf->i_entry_count );
assert( i_read == 0 );
uint32_t i = 0;
uint64_t i_remain = p_box->i_size - 16;
while ( i_remain > 8 && i < p_box->data.p_iinf->i_entry_count )
{
MP4_Box_t *p_childbox = MP4_ReadBox( p_stream, p_box );
if( !p_childbox || i_remain < p_childbox->i_size )
{
MP4_BoxFree( p_childbox );
p_box->data.p_iinf->i_entry_count = i;
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 );
}
/* For generic */
static int MP4_ReadBox_default( stream_t *p_stream, MP4_Box_t *p_box )
{
......@@ -4730,6 +4894,10 @@ static const struct
/* Ambisonics */
{ ATOM_SA3D, MP4_ReadBox_SA3D, 0 },
/* iso4 brand meta references */
{ ATOM_iloc, MP4_ReadBox_iloc, ATOM_meta },
{ ATOM_iinf, MP4_ReadBox_iinf, ATOM_meta },
/* Last entry */
{ 0, MP4_ReadBox_default, 0 }
};
......
......@@ -396,6 +396,10 @@ typedef int64_t stime_t;
#define ATOM_SA3D VLC_FOURCC( 'S', 'A', '3', 'D' )
/* iso4 meta references */
#define ATOM_iloc VLC_FOURCC('i','l','o','c')
#define ATOM_iinf VLC_FOURCC('i','i','n','f')
#define HANDLER_mdta VLC_FOURCC('m', 'd', 't', 'a')
#define HANDLER_mdir VLC_FOURCC('m', 'd', 'i', 'r')
#define HANDLER_ID32 ATOM_ID32
......@@ -1621,6 +1625,34 @@ typedef struct
uint32_t i_num_channels;
} MP4_Box_data_SA3D_t;
typedef struct
{
uint8_t i_offset_size;
uint8_t i_length_size;
uint8_t i_base_offset_size;
uint8_t i_index_size;
uint32_t i_item_count;
struct
{
uint32_t i_item_id;
uint8_t i_construction_method;
uint16_t i_data_reference_index;
uint64_t i_base_offset;
uint16_t i_extent_count;
struct
{
uint64_t i_extent_index;
uint64_t i_extent_offset;
uint64_t i_extent_length;
} *p_extents;
} *p_items;
} MP4_Box_data_iloc_t;
typedef struct
{
uint32_t i_entry_count;
} MP4_Box_data_iinf_t;
/*
typedef struct MP4_Box_data__s
{
......@@ -1735,6 +1767,9 @@ typedef union MP4_Box_data_s
MP4_Box_data_cbmp_t *p_cbmp;
MP4_Box_data_SA3D_t *p_SA3D;
MP4_Box_data_iloc_t *p_iloc;
MP4_Box_data_iinf_t *p_iinf;
/* for generic handlers */
MP4_Box_data_binary_t *p_binary;
MP4_Box_data_data_t *p_data;
......
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