[vlc-commits] demux: mp4: read covr atoms (fix #8091)
Francois Cartegnie
git at videolan.org
Wed Mar 26 07:43:38 CET 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Mar 26 07:37:56 2014 +0100| [c9cce4e91f34b96b2cbaa9b39aadb6a65852e674] | committer: Francois Cartegnie
demux: mp4: read covr atoms (fix #8091)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c9cce4e91f34b96b2cbaa9b39aadb6a65852e674
---
modules/demux/mp4/libmp4.c | 25 ++++++++++++++
modules/demux/mp4/libmp4.h | 9 ++++++
modules/demux/mp4/mp4.c | 77 +++++++++++++++++++++++++++++++++++++++++---
3 files changed, 107 insertions(+), 4 deletions(-)
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index ab6edc8..52ae9ca 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -2622,6 +2622,29 @@ static void MP4_FreeBox_name( MP4_Box_t *p_box )
FREENULL( p_box->data.p_name->psz_text );
}
+static int MP4_ReadBox_data( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_READBOX_ENTER( MP4_Box_data_data_t );
+
+ /* What's that header ?? */
+ if ( i_read <= 8 )
+ MP4_READBOX_EXIT( 0 );
+
+ p_box->data.p_data->p_blob = malloc( i_read - 8 );
+ if ( !p_box->data.p_data->p_blob )
+ MP4_READBOX_EXIT( 0 );
+
+ p_box->data.p_data->i_blob = i_read - 8;
+ memcpy( p_box->data.p_data->p_blob, p_peek + 8, i_read - 8 );
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static void MP4_FreeBox_data( MP4_Box_t *p_box )
+{
+ free( p_box->data.p_data->p_blob );
+}
+
static int MP4_ReadBox_0xa9xxx( stream_t *p_stream, MP4_Box_t *p_box )
{
uint16_t i16;
@@ -3380,6 +3403,8 @@ static const struct
/* iTunes/Quicktime meta info */
{ ATOM_meta, MP4_ReadBox_meta, MP4_FreeBox_Common },
{ ATOM_name, MP4_ReadBox_name, MP4_FreeBox_name },
+ { ATOM_covr, MP4_ReadBoxContainer, MP4_FreeBox_Common },
+ { ATOM_data, MP4_ReadBox_data, MP4_FreeBox_data },
/* found in smoothstreaming */
{ ATOM_traf, MP4_ReadBoxContainer, MP4_FreeBox_Common },
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index c6c0aaf..aac5e3f 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -261,6 +261,7 @@
#define ATOM_meta VLC_FOURCC( 'm', 'e', 't', 'a' )
#define ATOM_ilst VLC_FOURCC( 'i', 'l', 's', 't' )
+#define ATOM_covr VLC_FOURCC( 'c', 'o', 'v', 'r' )
#define ATOM_chap VLC_FOURCC( 'c', 'h', 'a', 'p' )
@@ -1164,6 +1165,12 @@ typedef struct
uint8_t *p_hvcC;
} MP4_Box_data_hvcC_t;
+typedef struct
+{
+ uint8_t *p_blob;
+ uint32_t i_blob;
+} MP4_Box_data_data_t;
+
/*
typedef struct MP4_Box_data__s
{
@@ -1250,6 +1257,8 @@ typedef union MP4_Box_data_s
MP4_Box_data_tfxd_t *p_tfxd;
MP4_Box_data_hvcC_t *p_hvcC;
+ MP4_Box_data_data_t *p_data;
+
void *p_payload; /* for unknow type */
} MP4_Box_data_t;
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index 99435b5..c3038f4 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -952,19 +952,89 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
*pf = p_sys->f_fps;
return VLC_SUCCESS;
+ case DEMUX_GET_ATTACHMENTS:
+ {
+ input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t*** );
+ int *pi_int = va_arg( args, int * );
+
+ MP4_Box_t *p_covr = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst/covr" );
+ if ( !p_covr ) return VLC_EGENERIC;
+ MP4_Box_t *p_box;
+ int i_count = 0;
+
+ for( p_box = p_covr->p_first; p_box != NULL; p_box = p_box->p_next )
+ {
+ if ( p_box->i_type == ATOM_data && p_box->data.p_data->i_blob >= 16 )
+ i_count++;
+ }
+
+ if ( i_count == 0 )
+ return VLC_EGENERIC;
+
+ *ppp_attach = (input_attachment_t**)
+ malloc( sizeof(input_attachment_t*) * i_count );
+ if( !(*ppp_attach) ) return VLC_ENOMEM;
+ char *psz_mime;
+ char *psz_filename;
+ i_count = 0;
+ for( p_box = p_covr->p_first; p_box != NULL; p_box = p_box->p_next )
+ {
+ if ( p_box->i_type != ATOM_data || p_box->data.p_data->i_blob < 16 )
+ continue;
+
+ if ( !memcmp( p_box->data.p_data->p_blob,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8 ) )
+ {
+ psz_mime = strdup( "image/png" );
+ }
+ else if ( !memcmp( p_box->data.p_data->p_blob, "\xFF\xD8", 2 ) )
+ {
+ psz_mime = strdup( "image/jpeg" );
+ }
+ else
+ {
+ continue;
+ }
+
+ if ( asprintf( &psz_filename, "picture%u", i_count ) >= 0 )
+ {
+ (*ppp_attach)[i_count++] =
+ vlc_input_attachment_New( psz_filename, psz_mime, NULL,
+ p_box->data.p_data->p_blob, p_box->data.p_data->i_blob );
+ free( psz_filename );
+ }
+
+ free( psz_mime );
+ }
+
+ if ( i_count == 0 )
+ {
+ free( *ppp_attach );
+ return VLC_EGENERIC;
+ }
+
+ *pi_int = i_count;
+
+ return VLC_SUCCESS;
+ }
+
case DEMUX_GET_META:
{
vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
MP4_Box_t *p_0xa9xxx;
+ MP4_Box_t *p_covr = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst/covr/data[0]" );
+ if ( p_covr )
+ vlc_meta_SetArtURL( p_meta, "attachment://picture0" );
+
MP4_Box_t *p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst" );
if( p_udta == NULL )
{
p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
- if( p_udta == NULL )
- {
+ if( p_udta == NULL && p_covr == NULL )
return VLC_EGENERIC;
- }
+ else
+ return VLC_SUCCESS;
}
for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;
@@ -1146,7 +1216,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_SET_NEXT_DEMUX_TIME:
case DEMUX_SET_GROUP:
case DEMUX_HAS_UNSUPPORTED_META:
- case DEMUX_GET_ATTACHMENTS:
case DEMUX_GET_PTS_DELAY:
case DEMUX_CAN_RECORD:
return VLC_EGENERIC;
More information about the vlc-commits
mailing list