Commit 67b1761f authored by Tomas Härdin's avatar Tomas Härdin Committed by Anton Khirnov

wav: keep parsing until EOF if the input is seekable and we know the size of the data tag

Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent 90f2ee8c
...@@ -296,7 +296,7 @@ static int wav_read_header(AVFormatContext *s, ...@@ -296,7 +296,7 @@ static int wav_read_header(AVFormatContext *s,
AVStream *st; AVStream *st;
WAVContext *wav = s->priv_data; WAVContext *wav = s->priv_data;
int ret, got_fmt = 0; int ret, got_fmt = 0;
int64_t next_tag_ofs; int64_t next_tag_ofs, data_ofs = -1;
/* check RIFF header */ /* check RIFF header */
tag = avio_rl32(pb); tag = avio_rl32(pb);
...@@ -327,13 +327,13 @@ static int wav_read_header(AVFormatContext *s, ...@@ -327,13 +327,13 @@ static int wav_read_header(AVFormatContext *s,
avio_skip(pb, size - 16); /* skip rest of ds64 chunk */ avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
} }
for (;;) { for (;;) {
if (pb->eof_reached)
return -1;
size = next_tag(pb, &tag); size = next_tag(pb, &tag);
next_tag_ofs = avio_tell(pb) + size; next_tag_ofs = avio_tell(pb) + size;
if (pb->eof_reached)
break;
switch (tag) { switch (tag) {
case MKTAG('f', 'm', 't', ' '): case MKTAG('f', 'm', 't', ' '):
/* only parse the first 'fmt ' tag found */ /* only parse the first 'fmt ' tag found */
...@@ -350,26 +350,43 @@ static int wav_read_header(AVFormatContext *s, ...@@ -350,26 +350,43 @@ static int wav_read_header(AVFormatContext *s,
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
goto break_loop; if (rf64) {
next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
} else {
data_size = size;
next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
}
data_ofs = avio_tell(pb);
/* don't look for footer metadata if we can't seek or if we don't
* know where the data tag ends
*/
if (!pb->seekable || (!rf64 && !size))
goto break_loop;
break;
case MKTAG('f','a','c','t'): case MKTAG('f','a','c','t'):
if (!sample_count) if (!sample_count)
sample_count = avio_rl32(pb); sample_count = avio_rl32(pb);
break; break;
} }
avio_seek(pb, next_tag_ofs, SEEK_SET);
/* seek to next tag unless we know that we'll run into EOF */
if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
break;
}
} }
break_loop: break_loop:
if (rf64) if (data_ofs < 0) {
size = data_size; av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
if (size < 0) return AVERROR_INVALIDDATA;
return -1; }
if (!size) {
wav->data_end = INT64_MAX; avio_seek(pb, data_ofs, SEEK_SET);
} else
wav->data_end= avio_tell(pb) + size;
if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id)) 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) if (sample_count)
st->duration = sample_count; st->duration = sample_count;
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment