[Ffmpeg-devel] Patch: wav decoder eof handling

Ulrich von Zadow coder
Tue Jun 27 18:07:11 CEST 2006


Hi,

here is an initial patch to fix the output of garbage at the end of a wav file. 
I've tested it using ffplay with 'standard' files (one data chunk at the end of 
the file) and files that have an additional chunk at the end of the file.

 > cat wave1.wav wave2.wav > doublewave.wav  :)

Tried that. Current ffmpeg will probably interpret the resulting file as a wav 
file and happily play back the whole thing, but more than one RIFF form is not 
legal in a RIFF file. The RIFF file specification (at 
http://www.tactilemedia.com/info/MCI_Control_Info.html) says the following: "A 
RIFF form is a chunk with a 'RIFF' chunk ID. The term also refers to a file 
format that follows the RIFF framework."

The Waveform Audio File Format is defined like this:

"The WAVE form is defined as follows. Programs must expect (and ignore) any 
unknown chunks encountered, as with all RIFF forms. However, <fmtck> must always 
occur before <wavedata>, and both of these chunks are mandatory in a WAVE file.

<WAVE-form> ?
RIFF( 'WAVE'
<fmt-ck> // Format
[<fact-ck>] // Fact chunk
[<cue-ck>] // Cue points
[<playlist-ck>] // Playlist
[<assoc-data-list>] // Associated data list
<wave-data> ) // Wave data
"

There must be exactly one <wave-data> element. According to the spec, this 
element can be composed of several 'data' chunks, and the patch was written to 
support this - although I don't have such a file here to test that. Of course I 
will, if a file like that exists and someone sends it to me.

Comments?

Regards,

   Uli


diff ffmpeg_orig/libavformat/wav.c ffmpeg/libavformat/wav.c
21a22,26
 > typedef struct {
 >     int wave_chunk_start;
 >     int wave_chunk_len;
 > } WAVIContext;
 >
206c211
< } WAVContext;
---
 > } WAVOContext;
210c215
<     WAVContext *wav = s->priv_data;
---
 >     WAVOContext *wav = s->priv_data;
246c251
<     WAVContext *wav = s->priv_data;
---
 >     WAVOContext *wav = s->priv_data;
333a339,341
 >     WAVIContext * wav_context = (WAVIContext*)s->priv_data;
 >     wav_context->wave_chunk_len = size;
 >     wav_context->wave_chunk_start = url_ftell(&s->pb);
344a353,372
 >     WAVIContext * wav_context = (WAVIContext*)s->priv_data;
 >     int64_t bytes_to_read = 
s->data_offset+(int64_t)(wav_context->wave_chunk_len)-url_ftell(&s->pb);
 >     if (bytes_to_read <= 0) {
 >         size = find_tag(&(s->pb), MKTAG('d', 'a', 't', 'a'));
 >         if (size < 0) {
 >             return AVERROR_IO;
 >         }
 >         WAVIContext * wav_context = (WAVIContext*)s->priv_data;
 >         wav_context->wave_chunk_len = size;
 >         wav_context->wave_chunk_start = url_ftell(&s->pb);
 >         bytes_to_read = (int64_t)(wav_context->wave_chunk_len);
 >     }
 >
354a383,386
 >     if (size > bytes_to_read) {
 >         size = bytes_to_read;
 >     }
396c428
<     0,
---
 >     sizeof(WAVIContext),
410c442
<     sizeof(WAVContext),
---
 >     sizeof(WAVOContext),






More information about the ffmpeg-devel mailing list