diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index adf41ecd89..d5b3b9ef2f 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -54,6 +54,7 @@ typedef struct WAVDemuxContext { int spdif; int smv_cur_pt; int smv_given_first; + int unaligned; // e.g. if an odd number of bytes ID3 tag was prepended } WAVDemuxContext; #if CONFIG_WAV_DEMUXER @@ -64,16 +65,16 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag) return avio_rl32(pb); } -/* RIFF chunks are always on a even offset. */ -static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence) +/* RIFF chunks are always at even offsets relative to where they start. */ +static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence) { - offset += offset < INT64_MAX && offset & 1; + offset += offset < INT64_MAX && offset + wav->unaligned & 1; return avio_seek(s, offset, whence); } /* return the size of the found tag */ -static int64_t find_tag(AVIOContext *pb, uint32_t tag1) +static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1) { unsigned int tag; int64_t size; @@ -84,7 +85,7 @@ static int64_t find_tag(AVIOContext *pb, uint32_t tag1) size = next_tag(pb, &tag); if (tag == tag1) break; - wav_seek_tag(pb, size, SEEK_CUR); + wav_seek_tag(wav, pb, size, SEEK_CUR); } return size; } @@ -247,6 +248,8 @@ static int wav_read_header(AVFormatContext *s) int ret, got_fmt = 0; int64_t next_tag_ofs, data_ofs = -1; + wav->unaligned = avio_tell(s->pb) & 1; + wav->smv_data_ofs = -1; /* check RIFF header */ @@ -383,7 +386,7 @@ static int wav_read_header(AVFormatContext *s) /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || - wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) { + wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) { break; } } @@ -511,7 +514,7 @@ smv_out: if (CONFIG_W64_DEMUXER && wav->w64) left = find_guid(s->pb, ff_w64_guid_data) - 24; else - left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); + left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a')); if (left < 0) { wav->audio_eof = 1; if (wav->smv_data_ofs > 0 && !wav->smv_eof)