X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fwav.c;h=8380fab9407b0b42db9059710adc5d3faafaa5ec;hb=e91b6fac50039e215c5d587e1aeca79d4b2dd9f5;hp=eeef17a56799ae1c5bbbedbadd3b77bd30f6901b;hpb=bb3d29ee2d00f5e5be4693edb131f1a0cc8e1d0b;p=vlc diff --git a/modules/demux/wav.c b/modules/demux/wav.c index eeef17a567..8380fab940 100644 --- a/modules/demux/wav.c +++ b/modules/demux/wav.c @@ -1,7 +1,7 @@ /***************************************************************************** * wav.c : wav file input module for vlc ***************************************************************************** - * Copyright (C) 2001-2003 the VideoLAN team + * Copyright (C) 2001-2008 the VideoLAN team * $Id$ * * Authors: Laurent Aimar @@ -24,9 +24,13 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* malloc(), free() */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include #include #include #include @@ -38,10 +42,10 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); vlc_module_begin(); - set_description( _("WAV demuxer") ); + set_description( N_("WAV demuxer") ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_DEMUX ); - set_capability( "demux2", 142 ); + set_capability( "demux", 142 ); set_callbacks( Open, Close ); vlc_module_end(); @@ -65,11 +69,11 @@ struct demux_sys_t date_t pts; uint32_t i_channel_mask; - vlc_bool_t b_chan_reorder; /* do we need channel reordering */ + bool b_chan_reorder; /* do we need channel reordering */ int pi_chan_table[AOUT_CHAN_MAX]; }; -#define __EVEN( x ) ( ( (x)%2 != 0 ) ? ((x)+1) : (x) ) +#define __EVEN( x ) (((x) + 1) & ~1) static int ChunkFind( demux_t *, const char *, unsigned int * ); @@ -101,8 +105,9 @@ 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; - unsigned int i_size, i_extended; + const uint8_t *p_peek; + uint32_t i_size; + unsigned int i_extended; const char *psz_name; WAVEFORMATEXTENSIBLE *p_wf_ext = NULL; @@ -135,7 +140,8 @@ static int Open( vlc_object_t * p_this ) msg_Err( p_demux, "cannot find 'fmt ' chunk" ); goto error; } - if( i_size < sizeof( WAVEFORMATEX ) - 2 ) /* XXX -2 isn't a typo */ + i_size += 2; + if( i_size < sizeof( WAVEFORMATEX ) ) { msg_Err( p_demux, "invalid 'fmt ' chunk" ); goto error; @@ -143,14 +149,15 @@ static int Open( vlc_object_t * p_this ) stream_Read( p_demux->s, NULL, 8 ); /* Cannot fail */ /* load waveformatex */ - p_wf_ext = malloc( __EVEN( i_size ) + 2 ); + p_wf_ext = malloc( i_size ); if( p_wf_ext == NULL ) goto error; p_wf = (WAVEFORMATEX *)p_wf_ext; p_wf->cbSize = 0; - if( stream_Read( p_demux->s, - p_wf, __EVEN( i_size ) ) < (int)__EVEN( i_size ) ) + i_size -= 2; + if( stream_Read( p_demux->s, p_wf, i_size ) != (int)i_size + || ( ( i_size & 1 ) && stream_Read( p_demux->s, NULL, 1 ) != 1 ) ) { msg_Err( p_demux, "cannot load 'fmt ' chunk" ); goto error; @@ -164,14 +171,17 @@ static int Open( vlc_object_t * p_this ) p_sys->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign ); p_sys->fmt.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8; p_sys->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample ); - p_sys->fmt.i_extra = GetWLE( &p_wf->cbSize ); + if( i_size >= sizeof(WAVEFORMATEX) ) + p_sys->fmt.i_extra = __MIN( GetWLE( &p_wf->cbSize ), i_size - sizeof(WAVEFORMATEX) ); i_extended = 0; /* Handle new WAVE_FORMAT_EXTENSIBLE wav files */ /* see the following link for more information: * http://www.microsoft.com/whdc/device/audio/multichaud.mspx#EFAA */ if( GetWLE( &p_wf->wFormatTag ) == WAVE_FORMAT_EXTENSIBLE && - i_size >= sizeof( WAVEFORMATEXTENSIBLE ) ) + i_size >= sizeof( WAVEFORMATEXTENSIBLE ) && + ( p_sys->fmt.i_extra + sizeof( WAVEFORMATEX ) + >= sizeof( WAVEFORMATEXTENSIBLE ) ) ) { unsigned i, i_channel_mask; GUID guid_subformat; @@ -221,7 +231,7 @@ static int Open( vlc_object_t * p_this ) } msg_Dbg( p_demux, "format: 0x%4.4x, fourcc: %4.4s, channels: %d, " - "freq: %d Hz, bitrate: %dKo/s, blockalign: %d, bits/samples: %d, " + "freq: %u Hz, bitrate: %uKo/s, blockalign: %d, bits/samples: %d, " "extra size: %d", GetWLE( &p_wf->wFormatTag ), (char *)&p_sys->fmt.i_codec, p_sys->fmt.audio.i_channels, p_sys->fmt.audio.i_rate, @@ -259,7 +269,7 @@ static int Open( vlc_object_t * p_this ) case VLC_FOURCC( 'm', 'p', 'g', 'a' ): case VLC_FOURCC( 'a', '5', '2', ' ' ): /* FIXME set end of area FIXME */ - goto relay; + goto error; default: msg_Err( p_demux, "unsupported codec (%4.4s)", (char*)&p_sys->fmt.i_codec ); @@ -291,7 +301,6 @@ static int Open( vlc_object_t * p_this ) error: free( p_wf ); -relay: free( p_sys ); return VLC_EGENERIC; } @@ -364,7 +373,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) i_end = p_sys->i_data_pos + p_sys->i_data_size; } - return demux2_vaControlHelper( p_demux->s, p_sys->i_data_pos, i_end, + return demux_vaControlHelper( p_demux->s, p_sys->i_data_pos, i_end, p_sys->fmt.i_bitrate, p_sys->fmt.audio.i_blockalign, i_query, args ); @@ -375,21 +384,21 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) *****************************************************************************/ static int ChunkFind( demux_t *p_demux, const char *fcc, unsigned int *pi_size ) { - uint8_t *p_peek; + const uint8_t *p_peek; for( ;; ) { - int i_size; + uint32_t i_size; if( stream_Peek( p_demux->s, &p_peek, 8 ) < 8 ) { - msg_Err( p_demux, "cannot peek()" ); + msg_Err( p_demux, "cannot peek" ); return VLC_EGENERIC; } i_size = GetDWLE( p_peek + 4 ); - msg_Dbg( p_demux, "chunk: fcc=`%4.4s` size=%d", p_peek, i_size ); + msg_Dbg( p_demux, "chunk: fcc=`%4.4s` size=%"PRIu32, p_peek, i_size ); if( !memcmp( p_peek, fcc, 4 ) ) { @@ -400,11 +409,11 @@ static int ChunkFind( demux_t *p_demux, const char *fcc, unsigned int *pi_size ) return VLC_SUCCESS; } - i_size = __EVEN( i_size ) + 8; - if( stream_Read( p_demux->s, NULL, i_size ) != i_size ) - { + /* Skip chunk */ + if( stream_Read( p_demux->s, NULL, 8 ) != 8 + || stream_Read( p_demux->s, NULL, i_size ) != i_size + || ((i_size & 1) && stream_Read( p_demux->s, NULL, 1 ) != 1 )) return VLC_EGENERIC; - } } }