[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