[vlc-devel] [PATCH] wav: add RF64 support

Tobias Rapp t.rapp at noa-audio.com
Tue Apr 30 15:54:07 CEST 2013


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_ */
+
 #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;
 
     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;
+        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 )
+        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 );
-- 
1.7.9.5


-- 
NOA Audio Solutions Vertriebsges. m.b.H.   Tel: +43-1-5452700
Johannagasse 42/4                          Fax: +43-1-545270014
A - 1050 Wien                              Www: http://www.noa-audio.com





More information about the vlc-devel mailing list