[PATCH 3/5] Keep parsing wav until EOF if the input is seekable
Tomas Härdin
tomas.hardin
Thu Feb 17 16:53:36 CET 2011
---
libavformat/wav.c | 46 +++++++++++++++++++++++++++++++++-------------
1 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 7aef85e..0329f33 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -206,7 +206,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
static int wav_read_header(AVFormatContext *s,
AVFormatParameters *ap)
{
- int64_t size, av_uninit(data_size);
+ int64_t size, data_size = -1;
int64_t sample_count=0;
int rf64;
unsigned int tag;
@@ -214,7 +214,7 @@ static int wav_read_header(AVFormatContext *s,
AVStream *st;
WAVContext *wav = s->priv_data;
int ret, got_fmt = 0;
- int64_t next_tag_ofs;
+ int64_t next_tag_ofs, data_ofs = -1;
/* check RIFF header */
tag = avio_rl32(pb);
@@ -240,11 +240,18 @@ static int wav_read_header(AVFormatContext *s,
}
for (;;) {
- if (url_feof(pb))
- return -1;
size = next_tag(pb, &tag);
next_tag_ofs = url_ftell(pb) + size;
+ if (url_feof(pb)) {
+ if (data_ofs < 0) {
+ av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ break;
+ }
+
switch (tag) {
case MKTAG('f', 'm', 't', ' '):
if ((ret = wav_parse_fmt_tag(s, size, &st) < 0))
@@ -258,7 +265,21 @@ static int wav_read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA;
}
+ if (!rf64)
+ data_size = size;
+ if (!data_size) {
+ wav->data_end = INT64_MAX;
+ } else
+ wav->data_end= url_ftell(pb) + data_size;
+
+ /* we can't look for metadata past the data tag if streaming, so stop parsing */
+ if (pb->is_streamed)
goto break_loop;
+
+ /* keep going in order to parse footer metadata chunks */
+ data_ofs = url_ftell(pb);
+ next_tag_ofs = wav->data_end;
+ break;
case MKTAG('f','a','c','t'):
if(!sample_count)
sample_count = avio_rl32(pb);
@@ -267,17 +288,16 @@ static int wav_read_header(AVFormatContext *s,
avio_seek(pb, next_tag_ofs, SEEK_SET);
}
break_loop:
- if (rf64)
- size = data_size;
- if (size < 0)
- return -1;
- if (!size) {
- wav->data_end = INT64_MAX;
- } else
- wav->data_end= url_ftell(pb) + size;
+ if (data_size < 0) {
+ av_log(s, AV_LOG_ERROR, "data_size = %li\n", data_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!pb->is_streamed)
+ url_fseek(pb, data_ofs, SEEK_SET);
if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
- sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+ sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
if (sample_count)
st->duration = sample_count;
return 0;
--
1.7.1
--------------010105030406060308040202--
More information about the ffmpeg-devel
mailing list