From: Gildas Bazin Date: Sat, 9 Apr 2005 11:27:23 +0000 (+0000) Subject: * src/input/demux.c: skip header id3tag in the core before loading the demux (id3tags... X-Git-Tag: 0.8.2~574 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=f2a0cc3fb4839b410102e069c736dc6d2d72dbe2;p=vlc * src/input/demux.c: skip header id3tag in the core before loading the demux (id3tags have a tendency to mess probing). * modules/demux/flac.c, modules/demux/mpeg/m4a.c,mpga.c: update id3tag parsing. * modules/demux/util/id3tag.c: id3tag parsing doesn't need to skip the id3tag header anymore. * modules/demux/util/id3.c: module removed because id3tag header skipping isn't needed anymore. --- diff --git a/configure.ac b/configure.ac index dcfd6224dc..183997bbf5 100644 --- a/configure.ac +++ b/configure.ac @@ -965,13 +965,13 @@ dnl dnl default modules dnl VLC_ADD_PLUGINS([dummy logger memcpy]) -VLC_ADD_PLUGINS([mpgv mpga m4v m4a h264 ps pva avi asf aac mp4 rawdv nsv real aiff mjpeg demuxdump flac]) +VLC_ADD_PLUGINS([mpgv mpga m4v m4a h264 ps pva avi asf mp4 rawdv nsv real aiff mjpeg demuxdump flac]) VLC_ADD_PLUGINS([cvdsub svcdsub spudec subsdec dvbsub mpeg_audio lpcm a52 dts cinepak flacdec]) VLC_ADD_PLUGINS([deinterlace invert adjust transform distort motionblur]) VLC_ADD_PLUGINS([fixed32tos16 s16tofixed32 u8tofixed32]) VLC_ADD_PLUGINS([trivial_resampler ugly_resampler]) VLC_ADD_PLUGINS([trivial_channel_mixer trivial_mixer]) -VLC_ADD_PLUGINS([id3 playlist export sgimb m3u xtag]) +VLC_ADD_PLUGINS([playlist export sgimb m3u xtag]) VLC_ADD_PLUGINS([i420_rgb rawvideo blend scale image logo]) VLC_ADD_PLUGINS([wav araw subtitle vobsub adpcm a52sys dtssys au ty voc xa nuv]) VLC_ADD_PLUGINS([access_directory access_file access_udp access_tcp]) diff --git a/modules/demux/flac.c b/modules/demux/flac.c index 28d452d334..4140ed32fc 100644 --- a/modules/demux/flac.c +++ b/modules/demux/flac.c @@ -73,28 +73,14 @@ static int Open( vlc_object_t * p_this ) int i_peek; byte_t *p_peek; es_format_t fmt; - vlc_meta_t *p_meta = NULL; - - /* Skip/parse possible id3 header */ - if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) - { - p_meta = (vlc_meta_t *)p_demux->p_private; - p_demux->p_private = NULL; - module_Unneed( p_demux, p_id3 ); - } /* Have a peep at the show. */ - if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) - { - goto error; - } + if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC; if( p_peek[0]!='f' || p_peek[1]!='L' || p_peek[2]!='a' || p_peek[3]!='C' ) { - if( strncmp( p_demux->psz_demux, "flac", 4 ) ) - { - goto error; - } + if( !p_demux->b_force ) return VLC_EGENERIC; + /* User forced */ msg_Err( p_demux, "this doesn't look like a flac stream, " "continuing anyway" ); @@ -105,20 +91,20 @@ static int Open( vlc_object_t * p_this ) p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', 'a', 'c' ) ); p_sys->b_start = VLC_TRUE; - p_sys->p_meta = p_meta; + p_sys->p_meta = 0; /* We need to read and store the STREAMINFO metadata */ i_peek = stream_Peek( p_demux->s, &p_peek, 8 ); if( p_peek[4] & 0x7F ) { msg_Err( p_demux, "this isn't a STREAMINFO metadata block" ); - goto error; + return VLC_EGENERIC; } if( ((p_peek[5]<<16)+(p_peek[6]<<8)+p_peek[7]) != (STREAMINFO_SIZE - 4) ) { msg_Err( p_demux, "invalid size for a STREAMINFO metadata block" ); - goto error; + return VLC_EGENERIC; } /* @@ -155,22 +141,20 @@ static int Open( vlc_object_t * p_this ) vlc_object_destroy( p_sys->p_packetizer ); msg_Err( p_demux, "cannot find flac packetizer" ); - goto error; + return VLC_EGENERIC; } p_sys->p_es = es_out_Add( p_demux->out, &fmt ); - return VLC_SUCCESS; - -error: - if( p_meta ) + /* Parse possible id3 header */ + if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) { - int b_seekable; - vlc_meta_Delete( p_meta ); - stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable ); - if( b_seekable ) stream_Seek( p_demux->s, 0 ); + p_sys->p_meta = (vlc_meta_t *)p_demux->p_private; + p_demux->p_private = NULL; + module_Unneed( p_demux, p_id3 ); } - return VLC_EGENERIC; + + return VLC_SUCCESS; } /***************************************************************************** @@ -244,18 +228,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) { /* demux_sys_t *p_sys = p_demux->p_sys; */ /* FIXME bitrate */ - if( i_query == DEMUX_SET_TIME ) - return VLC_EGENERIC; + if( i_query == DEMUX_SET_TIME ) return VLC_EGENERIC; else if( i_query == DEMUX_GET_META ) { vlc_meta_t **pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** ); - if( p_demux->p_sys->p_meta ) *pp_meta = vlc_meta_Duplicate( p_demux->p_sys->p_meta ); + if( p_demux->p_sys->p_meta ) + *pp_meta = vlc_meta_Duplicate( p_demux->p_sys->p_meta ); else *pp_meta = NULL; return VLC_SUCCESS; } - else - return demux2_vaControlHelper( p_demux->s, - 0, -1, - 8*0, 1, i_query, args ); + else return demux2_vaControlHelper( p_demux->s, 0, -1, + 8*0, 1, i_query, args ); } diff --git a/modules/demux/mpeg/m4a.c b/modules/demux/mpeg/m4a.c index b691640250..efed0426bd 100644 --- a/modules/demux/mpeg/m4a.c +++ b/modules/demux/mpeg/m4a.c @@ -71,7 +71,6 @@ static int Open( vlc_object_t * p_this ) demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; uint8_t *p_peek; - module_t *p_id3; int b_forced = VLC_FALSE; if( p_demux->psz_path ) @@ -89,12 +88,6 @@ static int Open( vlc_object_t * p_this ) return VLC_EGENERIC; } - /* skip possible id3 header */ - if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) - { - module_Unneed( p_demux, p_id3 ); - } - /* peek the begining (10 is for adts header) */ if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) { diff --git a/modules/demux/mpeg/mpga.c b/modules/demux/mpeg/mpga.c index d03880a0bb..78e26988ea 100644 --- a/modules/demux/mpeg/mpga.c +++ b/modules/demux/mpeg/mpga.c @@ -120,7 +120,6 @@ static int Open( vlc_object_t * p_this ) uint32_t header; uint8_t *p_peek; module_t *p_id3; - vlc_meta_t *p_meta = NULL; block_t *p_block_in, *p_block_out; if( p_demux->psz_path ) @@ -132,30 +131,14 @@ static int Open( vlc_object_t * p_this ) } } - /* Skip/parse possible id3 header */ - if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) - { - p_meta = (vlc_meta_t *)p_demux->p_private; - p_demux->p_private = NULL; - module_Unneed( p_demux, p_id3 ); - } - - if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) - { - if( p_meta ) vlc_meta_Delete( p_meta ); - return VLC_EGENERIC; - } + if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC; if( !HeaderCheck( header = GetDWBE( p_peek ) ) ) { vlc_bool_t b_ok = VLC_FALSE; int i_peek; - if( !p_demux->b_force && !b_forced ) - { - if( p_meta ) vlc_meta_Delete( p_meta ); - return VLC_EGENERIC; - } + if( !p_demux->b_force && !b_forced ) return VLC_EGENERIC; i_peek = stream_Peek( p_demux->s, &p_peek, 8096 ); while( i_peek > 4 ) @@ -168,11 +151,7 @@ static int Open( vlc_object_t * p_this ) p_peek += 1; i_peek -= 1; } - if( !b_ok && !p_demux->b_force ) - { - if( p_meta ) vlc_meta_Delete( p_meta ); - return VLC_EGENERIC; - } + if( !b_ok && !p_demux->b_force ) return VLC_EGENERIC; } p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); @@ -180,7 +159,7 @@ static int Open( vlc_object_t * p_this ) p_sys->p_es = 0; p_sys->p_packetizer = 0; p_sys->b_start = VLC_TRUE; - p_sys->meta = p_meta; + p_sys->meta = 0; p_demux->pf_demux = Demux; p_demux->pf_control = Control; @@ -290,6 +269,14 @@ static int Open( vlc_object_t * p_this ) p_sys->p_block_in = p_block_in; p_sys->p_block_out = p_block_out; + /* Parse possible id3 header */ + if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) ) + { + p_sys->meta = (vlc_meta_t *)p_demux->p_private; + p_demux->p_private = NULL; + module_Unneed( p_demux, p_id3 ); + } + return VLC_SUCCESS; } diff --git a/modules/demux/util/Modules.am b/modules/demux/util/Modules.am index e9f3b2abf0..aed4a4bcd0 100644 --- a/modules/demux/util/Modules.am +++ b/modules/demux/util/Modules.am @@ -1,7 +1,3 @@ -SOURCES_id3 = \ - id3.c \ - $(NULL) - SOURCES_id3tag = \ id3tag.c \ id3genres.h \ diff --git a/modules/demux/util/id3.c b/modules/demux/util/id3.c deleted file mode 100644 index 58dfc19321..0000000000 --- a/modules/demux/util/id3.c +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************** - * id3.c: simple id3 tag skipper - ***************************************************************************** - * Copyright (C) 2001 VideoLAN - * $Id$ - * - * Authors: Sigmund Augdal - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include /* malloc(), free() */ -#include - -#include -#include - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int SkipID3Tag ( vlc_object_t * ); - -/***************************************************************************** - * Module descriptor - *****************************************************************************/ -vlc_module_begin(); - set_description( _("Simple id3 tag skipper" ) ); - set_capability( "id3", 50 ); - set_callbacks( SkipID3Tag, NULL ); -vlc_module_end(); - -/**************************************************************************** - * SkipID3Tag : check if an ID3 tag is present, and skip it if it is - ****************************************************************************/ -static int SkipID3Tag( vlc_object_t *p_this ) -{ - demux_t *p_demux = (demux_t *)p_this; - uint8_t *p_peek; - int i_size; - uint8_t version, revision; - int b_footer; - - p_demux->p_private = NULL; - - msg_Dbg( p_demux, "checking for ID3 tag" ); - - /* get 10 byte id3 header */ - if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) return VLC_EGENERIC; - - if( p_peek[0] != 'I' || p_peek[1] != 'D' || p_peek[2] != '3' ) - { - return VLC_SUCCESS; - } - - version = p_peek[3]; /* These may become usfull later, */ - revision = p_peek[4]; /* but we ignore them for now */ - b_footer = p_peek[5] & 0x10; - i_size = (p_peek[6] << 21) + - (p_peek[7] << 14) + - (p_peek[8] << 7) + - p_peek[9]; - if ( b_footer ) - { - i_size += 10; - } - i_size += 10; - - /* Skip the entire tag */ - stream_Read( p_demux->s, NULL, i_size ); - - msg_Dbg( p_demux, "ID3v2.%d revision %d tag found, skiping %d bytes", - version, revision, i_size ); - - return VLC_SUCCESS; -} diff --git a/modules/demux/util/id3tag.c b/modules/demux/util/id3tag.c index f11ddab85e..37d3462ac0 100644 --- a/modules/demux/util/id3tag.c +++ b/modules/demux/util/id3tag.c @@ -128,96 +128,74 @@ static int ParseID3Tags( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; uint8_t *p_peek; - int i_size; - int i_size2; vlc_bool_t b_seekable; + int64_t i_init, i_pos; + int i_size; p_demux->p_private = NULL; msg_Dbg( p_demux, "checking for ID3 tag" ); stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable ); - if( b_seekable ) + if( !b_seekable ) return VLC_SUCCESS; + + i_init = stream_Tell( p_demux->s ); + + /* + * Look for a ID3v1 tag at the end of the file + */ + i_init = stream_Tell( p_demux->s ); + i_pos = stream_Size( p_demux->s ); + + while( i_pos > 128 ) /* while used so we can break; */ { - int64_t i_init; - int64_t i_pos; + stream_Seek( p_demux->s, i_pos - 128 ); - /*look for a ID3v1 tag at the end of the file*/ - i_init = stream_Tell( p_demux->s ); - i_pos = stream_Size( p_demux->s ); + /* get 10 byte id3 header */ + if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) break; - if ( i_pos >128 ) + i_size = id3_tag_query( p_peek, 10 ); + if( i_size == 128 ) { - stream_Seek( p_demux->s, i_pos - 128 ); + /* peek the entire tag */ + if( stream_Peek( p_demux->s, &p_peek, i_size ) < i_size ) break; - /* get 10 byte id3 header */ - if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) - { - msg_Err( p_demux, "cannot peek()" ); - return VLC_EGENERIC; - } + msg_Dbg( p_demux, "found ID3v1 tag" ); + ParseID3Tag( p_demux, p_peek, i_size ); + } - i_size2 = id3_tag_query( p_peek, 10 ); - if ( i_size2 == 128 ) - { - /* peek the entire tag */ - if ( stream_Peek( p_demux->s, &p_peek, i_size2 ) < i_size2 ) - { - msg_Err( p_demux, "cannot peek()" ); - return VLC_EGENERIC; - } - msg_Dbg( p_demux, "found ID3v1 tag" ); - ParseID3Tag( p_demux, p_peek, i_size2 ); - } + /* look for ID3v2.4 tag at end of file */ + /* get 10 byte ID3 footer */ + if( stream_Peek( p_demux->s, &p_peek, 128 ) < 128 ) break; - /* look for ID3v2.4 tag at end of file */ - /* get 10 byte ID3 footer */ - if( stream_Peek( p_demux->s, &p_peek, 128 ) < 128 ) - { - msg_Err( p_demux, "cannot peek()" ); - return VLC_EGENERIC; - } - i_size2 = id3_tag_query( p_peek + 118, 10 ); - if ( i_size2 < 0 && i_pos > -i_size2 ) - { /* id3v2.4 footer found */ - stream_Seek( p_demux->s , i_pos + i_size2 ); - /* peek the entire tag */ - if ( stream_Peek( p_demux->s, &p_peek, i_size2 ) < i_size2 ) - { - msg_Err( p_demux, "cannot peek()" ); - return VLC_EGENERIC; - } - msg_Dbg( p_demux, "found ID3v2 tag at end of file" ); - ParseID3Tag( p_demux, p_peek, i_size2 ); - } + i_size = id3_tag_query( p_peek + 118, 10 ); + if( i_size < 0 && i_pos > -i_size ) + { + /* id3v2.4 footer found */ + stream_Seek( p_demux->s , i_pos + i_size ); + /* peek the entire tag */ + if( stream_Peek( p_demux->s, &p_peek, i_size ) < i_size ) break; + + msg_Dbg( p_demux, "found ID3v2 tag at end of file" ); + ParseID3Tag( p_demux, p_peek, i_size ); } - stream_Seek( p_demux->s, i_init ); - } - /* get 10 byte id3 header */ - if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) - { - msg_Err( p_demux, "cannot peek()" ); - return VLC_EGENERIC; + break; } - i_size = id3_tag_query( p_peek, 10 ); - if ( i_size <= 0 ) - { - return VLC_SUCCESS; - } + /* + * Get 10 byte id3 header + */ + stream_Seek( p_demux->s, 0 ); + if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) goto end; - /* Read the entire tag */ - p_peek = malloc( i_size ); - if( !p_peek || stream_Read( p_demux->s, p_peek, i_size ) < i_size ) - { - msg_Err( p_demux, "cannot read ID3 tag" ); - if( p_peek ) free( p_peek ); - return VLC_EGENERIC; - } + if( (i_size = id3_tag_query( p_peek, 10 )) <= 0 ) goto end; + + if( stream_Peek( p_demux->s, &p_peek, i_size ) < i_size ) goto end; msg_Dbg( p_demux, "found ID3v2 tag" ); ParseID3Tag( p_demux, p_peek, i_size ); - free( p_peek ); + end: + stream_Seek( p_demux->s, i_init ); return VLC_SUCCESS; } diff --git a/src/input/demux.c b/src/input/demux.c index 17ff61f26d..87a20757d3 100644 --- a/src/input/demux.c +++ b/src/input/demux.c @@ -27,6 +27,8 @@ #include "input_internal.h" +static void SkipID3Tag( demux_t * ); + /***************************************************************************** * demux2_New: * if s is NULL then load a access_demux @@ -38,10 +40,7 @@ demux_t *__demux2_New( vlc_object_t *p_obj, demux_t *p_demux = vlc_object_create( p_obj, VLC_OBJECT_DEMUX ); char *psz_module; - if( p_demux == NULL ) - { - return NULL; - } + if( p_demux == NULL ) return NULL; /* Parse URL */ p_demux->psz_access = strdup( psz_access ); @@ -71,10 +70,8 @@ demux_t *__demux2_New( vlc_object_t *p_obj, p_demux->info.i_title = 0; p_demux->info.i_seekpoint = 0; - if( s ) - psz_module = p_demux->psz_demux; - else - psz_module = p_demux->psz_access; + if( s ) psz_module = p_demux->psz_demux; + else psz_module = p_demux->psz_access; if( s && *psz_module == '\0' && strrchr( p_demux->psz_path, '.' ) ) { @@ -143,6 +140,11 @@ demux_t *__demux2_New( vlc_object_t *p_obj, if( s ) { + /* ID3 tags will mess-up demuxer probing so we skip it here. + * ID3 parsers will called later on in the demuxer to access the + * skipped info. */ + SkipID3Tag( p_demux ); + p_demux->p_module = module_Need( p_demux, "demux2", psz_module, !strcmp( psz_module, p_demux->psz_demux ) ? @@ -529,3 +531,37 @@ static int DStreamThread( stream_t *s ) p_demux->b_die = VLC_TRUE; return VLC_SUCCESS; } + +/**************************************************************************** + * Utility functions + ****************************************************************************/ +static void SkipID3Tag( demux_t *p_demux ) +{ + uint8_t *p_peek; + uint8_t version, revision; + int i_size; + int b_footer; + + if( !p_demux->s ) return; + + /* Get 10 byte id3 header */ + if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 ) return; + + if( p_peek[0] != 'I' || p_peek[1] != 'D' || p_peek[2] != '3' ) return; + + version = p_peek[3]; + revision = p_peek[4]; + b_footer = p_peek[5] & 0x10; + i_size = (p_peek[6]<<21) + (p_peek[7]<<14) + (p_peek[8]<<7) + p_peek[9]; + + if( b_footer ) i_size += 10; + i_size += 10; + + /* Skip the entire tag */ + stream_Read( p_demux->s, NULL, i_size ); + + msg_Dbg( p_demux, "ID3v2.%d revision %d tag found, skiping %d bytes", + version, revision, i_size ); + + return; +}