mirror of https://git.ffmpeg.org/ffmpeg.git
wav: keep parsing until EOF if the input is seekable and we know the size of the data tag
Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
parent
90f2ee8cb4
commit
67b1761fcb
|
@ -296,7 +296,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);
|
||||
|
@ -327,13 +327,13 @@ static int wav_read_header(AVFormatContext *s,
|
|||
avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
if (pb->eof_reached)
|
||||
return -1;
|
||||
size = next_tag(pb, &tag);
|
||||
next_tag_ofs = avio_tell(pb) + size;
|
||||
|
||||
if (pb->eof_reached)
|
||||
break;
|
||||
|
||||
switch (tag) {
|
||||
case MKTAG('f', 'm', 't', ' '):
|
||||
/* only parse the first 'fmt ' tag found */
|
||||
|
@ -350,26 +350,43 @@ static int wav_read_header(AVFormatContext *s,
|
|||
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'):
|
||||
if (!sample_count)
|
||||
sample_count = avio_rl32(pb);
|
||||
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:
|
||||
if (rf64)
|
||||
size = data_size;
|
||||
if (size < 0)
|
||||
return -1;
|
||||
if (!size) {
|
||||
wav->data_end = INT64_MAX;
|
||||
} else
|
||||
wav->data_end= avio_tell(pb) + size;
|
||||
if (data_ofs < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
avio_seek(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;
|
||||
|
|
Loading…
Reference in New Issue