Commit 14c5e914 authored by Damien Fouilleul's avatar Damien Fouilleul

- mp4 demux: support for iTunes/Quicktime META info

parent df02a09a
......@@ -2087,10 +2087,10 @@ static int MP4_ReadBox_0xa9xxx( stream_t *p_stream, MP4_Box_t *p_box )
p_box->data.p_0xa9xxx->psz_text = NULL;
MP4_GET2BYTES( i_length );
MP4_GET2BYTES( i_dummy );
if( i_length > 0 )
{
MP4_GET2BYTES( i_dummy );
if( i_length > i_read ) i_length = i_read;
p_box->data.p_0xa9xxx->psz_text = malloc( i_length + 1 );
......@@ -2106,6 +2106,47 @@ static int MP4_ReadBox_0xa9xxx( stream_t *p_stream, MP4_Box_t *p_box )
p_box->data.p_0xa9xxx->psz_text );
#endif
}
else
{
/* try iTune/Quicktime format, rewind to start */
p_peek -= 2; i_read += 2;
// we are expecting a 'data' box
uint32_t i_data_len;
uint32_t i_data_tag;
MP4_GET4BYTES( i_data_len );
if( i_data_len > i_read ) i_data_len = i_read;
MP4_GETFOURCC( i_data_tag );
if( (i_data_len > 0) && (i_data_tag == VLC_FOURCC('d', 'a', 't', 'a')) )
{
/* data box contains a version/flags field */
uint32_t i_version;
uint32_t i_reserved;
MP4_GET4BYTES( i_version );
MP4_GET4BYTES( i_reserved );
// version should be 0, flags should be 1 for text, 0 for data
if( i_version == 0x00000001 )
{
// the rest is the text
i_data_len -= 12;
p_box->data.p_0xa9xxx->psz_text = malloc( i_data_len + 1 );
memcpy( p_box->data.p_0xa9xxx->psz_text,
p_peek, i_data_len );
p_box->data.p_0xa9xxx->psz_text[i_data_len] = '\0';
#ifdef MP4_VERBOSE
msg_Dbg( p_stream,
"read box: \"%4.4s\" text=`%s'",
(char*)&p_box->i_type,
p_box->data.p_0xa9xxx->psz_text );
#endif
}
else
{
// TODO: handle data values for ID3 tag values, track num or cover art,etc...
}
}
}
MP4_READBOX_EXIT( 1 );
}
......@@ -2114,6 +2155,25 @@ static void MP4_FreeBox_0xa9xxx( MP4_Box_t *p_box )
FREENULL( p_box->data.p_0xa9xxx->psz_text );
}
static int MP4_ReadBox_meta( stream_t *p_stream, MP4_Box_t *p_box )
{
uint8_t meta_data[8];
int i_actually_read;
// skip over box header
i_actually_read = stream_Read( p_stream, meta_data, 8 );
if( i_actually_read < 8 )
return 0;
/* meta content starts with a 4 byte version/flags value (should be 0) */
i_actually_read = stream_Read( p_stream, meta_data, 4 );
if( i_actually_read < 4 )
return 0;
/* then it behaves like a container */
return MP4_ReadBoxContainerRaw( p_stream, p_box );
}
/* For generic */
static int MP4_ReadBox_default( stream_t *p_stream, MP4_Box_t *p_box )
{
......@@ -2184,6 +2244,7 @@ static struct
{ FOURCC_tref, MP4_ReadBoxContainer, MP4_FreeBox_Common },
{ FOURCC_gmhd, MP4_ReadBoxContainer, MP4_FreeBox_Common },
{ FOURCC_wave, MP4_ReadBoxContainer, MP4_FreeBox_Common },
{ FOURCC_ilst, MP4_ReadBoxContainer, MP4_FreeBox_Common },
/* specific box */
{ FOURCC_ftyp, MP4_ReadBox_ftyp, MP4_FreeBox_ftyp },
......@@ -2338,6 +2399,9 @@ static struct
{ FOURCC_0xa9ope,MP4_ReadBox_0xa9xxx, MP4_FreeBox_0xa9xxx },
{ FOURCC_0xa9com,MP4_ReadBox_0xa9xxx, MP4_FreeBox_0xa9xxx },
/* iTunes/Quicktime meta info */
{ FOURCC_meta, MP4_ReadBox_meta, MP4_FreeBox_Common },
/* Last entry */
{ 0, MP4_ReadBox_default, NULL }
};
......
......@@ -209,6 +209,9 @@
#define FOURCC_0xa9gen VLC_FOURCC( 0xa9, 'g', 'e', 'n' )
#define FOURCC_WLOC VLC_FOURCC( 'W', 'L', 'O', 'C' )
#define FOURCC_meta VLC_FOURCC( 'm', 'e', 't', 'a' )
#define FOURCC_ilst VLC_FOURCC( 'i', 'l', 's', 't' )
/* Do you want some debug information on all read boxes ? */
#define MP4_VERBOSE 1
......
......@@ -783,16 +783,23 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_META:
{
vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
MP4_Box_t *p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
MP4_Box_t *p_0xa9xxx;
MP4_Box_t *p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst" );
if( p_udta == NULL )
{
return VLC_EGENERIC;
p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
if( p_udta == NULL )
{
return VLC_EGENERIC;
}
}
for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;
p_0xa9xxx = p_0xa9xxx->p_next )
{
char *psz_utf;
if( !p_0xa9xxx || !p_0xa9xxx->data.p_0xa9xxx )
continue;
psz_utf = strdup( p_0xa9xxx->data.p_0xa9xxx->psz_text );
......@@ -805,7 +812,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
switch( p_0xa9xxx->i_type )
{
case FOURCC_0xa9nam: /* Full name */
vlc_meta_SetArtist( p_meta, psz_utf );
vlc_meta_SetTitle( p_meta, psz_utf );
break;
case FOURCC_0xa9aut:
vlc_meta_SetArtist( p_meta, psz_utf );
......@@ -826,9 +833,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
vlc_meta_SetGenre( p_meta, psz_utf );
break;
case FOURCC_0xa9alb: /* Album */
vlc_meta_SetAlbum( p_meta, psz_utf );
break;
case FOURCC_0xa9swr:
case FOURCC_0xa9inf: /* Information */
case FOURCC_0xa9alb: /* Album */
case FOURCC_0xa9dir: /* Director */
case FOURCC_0xa9dis: /* Disclaimer */
case FOURCC_0xa9enc: /* Encoded By */
......
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