diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-02-05 02:01:03 +0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2012-02-06 22:22:01 +0400 |
commit | ac3f8d317c5d1e78340b57ebd2b5c1317e175bc2 (patch) | |
tree | 3994bd897b623401282db8affa187cddc7a07de8 /libavformat/ape.c | |
parent | c2c316158fb670f61abfa108cb940ba31264b0f8 (diff) |
ape: calculate final packet size instead of guessing
Calculates based on total file size and wavetaillength from the header.
Falls back to multiplying finalframeblocks by 8 instead of 4 so that it will
at least be overestimating for 24-bit. Currently it can underestimate the
final packet size, leading to decoding errors.
Diffstat (limited to 'libavformat/ape.c')
-rw-r--r-- | libavformat/ape.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/libavformat/ape.c b/libavformat/ape.c index c650a54ad4..8145db3a76 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -159,8 +159,8 @@ static int ape_read_header(AVFormatContext * s) AVStream *st; uint32_t tag; int i; - int total_blocks; - int64_t pts; + int total_blocks, final_size = 0; + int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); @@ -289,8 +289,17 @@ static int ape_read_header(AVFormatContext * s) ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } - ape->frames[ape->totalframes - 1].size = ape->finalframeblocks * 4; ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; + /* calculate final packet size from total file size, if available */ + file_size = avio_size(pb); + if (file_size > 0) { + final_size = file_size - ape->frames[ape->totalframes - 1].pos - + ape->wavtaillength; + final_size -= final_size & 3; + } + if (file_size <= 0 || final_size <= 0) + final_size = ape->finalframeblocks * 8; + ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ |