Commit b0c9dced authored by Francois Cartegnie's avatar Francois Cartegnie

demux: mp4: use data type for cover

And fix reading
parent 59d398f7
...@@ -1333,6 +1333,14 @@ static int MP4_frg_Seek( demux_t *p_demux, double f ) ...@@ -1333,6 +1333,14 @@ static int MP4_frg_Seek( demux_t *p_demux, double f )
} }
} }
static bool imageTypeCompatible( const MP4_Box_data_data_t *p_data )
{
return p_data && (
p_data->e_wellknowntype == DATA_WKT_PNG ||
p_data->e_wellknowntype == DATA_WKT_JPEG ||
p_data->e_wellknowntype == DATA_WKT_BMP );
}
/***************************************************************************** /*****************************************************************************
* Control: * Control:
*****************************************************************************/ *****************************************************************************/
...@@ -1343,6 +1351,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1343,6 +1351,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
double f, *pf; double f, *pf;
int64_t i64, *pi64; int64_t i64, *pi64;
const char *psz_roots[] = { "/moov/udta/meta/ilst",
"/moov/meta/ilst",
"/moov/udta/meta",
"/moov/udta",
"/meta/ilst",
"/udta",
NULL };
switch( i_query ) switch( i_query )
{ {
case DEMUX_GET_POSITION: case DEMUX_GET_POSITION:
...@@ -1411,16 +1427,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1411,16 +1427,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t*** ); input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t*** );
int *pi_int = va_arg( args, int * ); int *pi_int = va_arg( args, int * );
MP4_Box_t *p_covr = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst/covr" ); MP4_Box_t *p_data = NULL;
if ( !p_covr ) return VLC_EGENERIC; MP4_Box_t *p_udta = NULL;
MP4_Box_t *p_box; size_t i_count = 0;
int i_count = 0; int i_index = 0;
for( p_box = p_covr->p_first; p_box != NULL; p_box = p_box->p_next ) for( ; psz_roots[i_index] && !p_udta; i_index++ )
{
p_udta = MP4_BoxGet( p_sys->p_root, psz_roots[i_index] );
if (p_udta)
{
p_data = MP4_BoxGet( p_udta, "covr/data" );
for( ; p_data; p_data = p_data->p_next )
{ {
if ( p_box->i_type == ATOM_data && p_box->data.p_data->i_blob >= 16 ) if ( p_data->i_type == ATOM_data &&
imageTypeCompatible( BOXDATA(p_data) ) )
i_count++; i_count++;
} }
}
}
if ( i_count == 0 ) if ( i_count == 0 )
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -1431,30 +1456,32 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1431,30 +1456,32 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
char *psz_mime; char *psz_mime;
char *psz_filename; char *psz_filename;
i_count = 0; i_count = 0;
for( p_box = p_covr->p_first; p_box != NULL; p_box = p_box->p_next ) p_data = MP4_BoxGet( p_udta, "covr/data" );
for( ; p_data; p_data = p_data->p_next )
{ {
if ( p_box->i_type != ATOM_data || p_box->data.p_data->i_blob < 16 ) if ( p_data->i_type != ATOM_data || !imageTypeCompatible( BOXDATA(p_data) ) )
continue; continue;
if ( !memcmp( p_box->data.p_data->p_blob, switch( BOXDATA(p_data)->e_wellknowntype )
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8 ) )
{ {
case DATA_WKT_PNG:
psz_mime = strdup( "image/png" ); psz_mime = strdup( "image/png" );
} break;
else if ( !memcmp( p_box->data.p_data->p_blob, "\xFF\xD8", 2 ) ) case DATA_WKT_JPEG:
{
psz_mime = strdup( "image/jpeg" ); psz_mime = strdup( "image/jpeg" );
} break;
else case DATA_WKT_BMP:
{ psz_mime = strdup( "image/bmp" );
break;
default:
continue; continue;
} }
if ( asprintf( &psz_filename, "picture%u", i_count ) >= 0 ) if ( asprintf( &psz_filename, "%s/covr/data[%"PRIu64"]", psz_roots[i_index - 1], i_count ) >= 0 )
{ {
(*ppp_attach)[i_count++] = (*ppp_attach)[i_count++] =
vlc_input_attachment_New( psz_filename, psz_mime, NULL, vlc_input_attachment_New( psz_filename, psz_mime, NULL,
p_box->data.p_data->p_blob, p_box->data.p_data->i_blob ); BOXDATA(p_data)->p_blob, BOXDATA(p_data)->i_blob );
free( psz_filename ); free( psz_filename );
} }
...@@ -1476,36 +1503,36 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1476,36 +1503,36 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*); vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
const char *psz_roots[] = { "/moov/udta/meta/ilst", MP4_Box_t *p_data = NULL;
"/moov/meta/ilst", MP4_Box_t *p_udta = NULL;
"/moov/udta/meta",
"/moov/udta",
"/meta/ilst",
"/udta",
NULL };
const MP4_Box_t *p_covr = NULL;
const MP4_Box_t *p_udta = NULL;
for( int i_index = 0; psz_roots[i_index] && !p_udta; i_index++ ) for( int i_index = 0; psz_roots[i_index] && !p_udta; i_index++ )
{ {
p_udta = MP4_BoxGet( p_sys->p_root, psz_roots[i_index] ); p_udta = MP4_BoxGet( p_sys->p_root, psz_roots[i_index] );
if ( p_udta ) if ( p_udta )
{ {
p_covr = MP4_BoxGet( p_sys->p_root, "covr/data[0]" ); p_data = MP4_BoxGet( p_udta, "covr/data" );
if ( p_covr ) if ( p_data && imageTypeCompatible( BOXDATA(p_data) ) )
vlc_meta_SetArtURL( p_meta, "attachment://picture0" ); {
char *psz_attachment;
if ( -1 != asprintf( &psz_attachment, "attachment://%s/covr/data[0]",
psz_roots[i_index] ) )
{
vlc_meta_SetArtURL( p_meta, psz_attachment );
free( psz_attachment );
}
}
} }
} }
if( p_udta == NULL && p_covr == NULL ) if( p_udta == NULL && p_data == NULL )
return VLC_EGENERIC; return VLC_EGENERIC;
for( const MP4_Box_t * p_string = p_udta->p_first; p_string != NULL; for( const MP4_Box_t * p_string = p_udta->p_first; p_string != NULL;
p_string = p_string->p_next ) p_string = p_string->p_next )
{ {
if( !p_string || !BOXDATA(p_string) ) if( !p_string || !BOXDATA(p_string) ) /* !WARN could be data atoms ! */
continue; continue;
/* FIXME FIXME: should convert from whatever the character /* FIXME FIXME: should convert from whatever the character
......
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