[vlc-devel] [PATCH] wav: add RF64 support
Rémi Denis-Courmont
remi at remlab.net
Tue Apr 30 16:45:19 CEST 2013
Le mardi 30 avril 2013 16:54:07, Tobias Rapp a écrit :
> Add support for wave files > 4GB. See also the EBU specification at
> http://tech.ebu.ch/docs/tech/tech3306-2009.pdf
>
> ---
> include/vlc_codecs.h | 12 ++++++++++++
> modules/demux/wav.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
> +--- 2 files changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/include/vlc_codecs.h b/include/vlc_codecs.h
> index f2b8daf..db09924 100644
> --- a/include/vlc_codecs.h
> +++ b/include/vlc_codecs.h
> @@ -109,6 +109,18 @@ _WAVEHEADER {
> } WAVEHEADER;
> #endif /* _WAVEHEADER_ */
>
> +#ifndef _WAVEDATASIZE64_
> +#define _WAVEDATASIZE64_
> +typedef struct
> +ATTR_PACKED
> +_WAVEDATASIZE64 {
> + uint64_t RiffSize;
> + uint64_t DataSize;
> + uint64_t SampleCount;
> + uint32_t TableLength;
> +} WAVEDATASIZE64;
> +#endif /* _WAVEDATASIZE64_ */
> +
Errm, is this actually defined by Windows? If not, I don't see the point in
pretending it is. Also note that packed is not portable.
> #ifndef _VLC_BITMAPINFOHEADER_
> #define _VLC_BITMAPINFOHEADER_
>
> diff --git a/modules/demux/wav.c b/modules/demux/wav.c
> index 6aefc92..de7e740 100644
> --- a/modules/demux/wav.c
> +++ b/modules/demux/wav.c
> @@ -61,7 +61,7 @@ struct demux_sys_t
> es_out_id_t *p_es;
>
> int64_t i_data_pos;
> - unsigned int i_data_size;
> + int64_t i_data_size;
Why is this signed?
>
> unsigned int i_frame_size;
> int i_frame_samples;
> @@ -100,18 +100,22 @@ static int Open( vlc_object_t * p_this )
> demux_sys_t *p_sys;
>
> const uint8_t *p_peek;
> + bool b_is_rf64;
> unsigned int i_size;
> unsigned int i_extended;
> const char *psz_name;
>
> WAVEFORMATEXTENSIBLE *p_wf_ext = NULL;
> WAVEFORMATEX *p_wf = NULL;
> + WAVEDATASIZE64 *p_wds = NULL;
>
> /* Is it a wav file ? */
> if( stream_Peek( p_demux->s, &p_peek, 12 ) < 12 )
> return VLC_EGENERIC;
>
> - if( memcmp( p_peek, "RIFF", 4 ) || memcmp( &p_peek[8], "WAVE", 4 ) )
> + b_is_rf64 = ( memcmp( p_peek, "RF64", 4 ) == 0 );
> + if( ( !b_is_rf64 && memcmp( p_peek, "RIFF", 4 ) ) ||
> + memcmp( &p_peek[8], "WAVE", 4 ) )
> {
> return VLC_EGENERIC;
> }
> @@ -123,6 +127,7 @@ static int Open( vlc_object_t * p_this )
> return VLC_ENOMEM;
>
> p_sys->p_es = NULL;
> + p_sys->i_data_size = 0;
> p_sys->i_chans_to_reorder = 0;
> p_sys->i_channel_mask = 0;
>
> @@ -130,6 +135,41 @@ static int Open( vlc_object_t * p_this )
> if( stream_Read( p_demux->s, NULL, 12 ) != 12 )
> goto error;
>
> + if( b_is_rf64 )
> + {
> + /* search datasize64 chunk */
> + if( ChunkFind( p_demux, "ds64", &i_size ) )
> + {
> + msg_Err( p_demux, "cannot find 'ds64' chunk" );
> + goto error;
> + }
> + i_size += 2;
Integer overflow.
> + if( i_size < sizeof( WAVEDATASIZE64 ) )
> + {
> + msg_Err( p_demux, "invalid 'ds64' chunk" );
> + goto error;
> + }
> + if( stream_Read( p_demux->s, NULL, 8 ) != 8 )
> + goto error;
> +
> + /* load datasize64 */
> + p_wds = malloc( i_size );
> + if( unlikely( !p_wds ) )
> + goto error;
> +
> + i_size -= 2;
> + if( stream_Read( p_demux->s, p_wds, i_size ) != (int)i_size ||
> + ( ( i_size & 1 ) && stream_Read( p_demux->s, NULL, 1 ) != 1 )
> ) + {
> + msg_Err( p_demux, "cannot load 'ds64' chunk" );
> + free( p_wds );
> + goto error;
> + }
> + p_sys->i_data_size = GetQWLE(&p_wds->DataSize);
> +
> + free( p_wds );
> + }
> +
> /* search fmt chunk */
> if( ChunkFind( p_demux, "fmt ", &i_size ) )
> {
> @@ -365,11 +405,13 @@ static int Open( vlc_object_t * p_this )
>
> msg_Dbg( p_demux, "found %s audio format", psz_name );
>
> - if( ChunkFind( p_demux, "data", &p_sys->i_data_size ) )
> + if( ChunkFind( p_demux, "data", &i_size ) )
> {
> msg_Err( p_demux, "cannot find 'data' chunk" );
> goto error;
> }
> + if( !b_is_rf64 || i_size < UINT32_MAX )
Isn't this a tautology?
> + p_sys->i_data_size = i_size;
> if( stream_Read( p_demux->s, NULL, 8 ) != 8 )
> goto error;
> p_sys->i_data_pos = stream_Tell( p_demux->s );
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list