summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2009-11-05 08:14:48 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2009-11-05 08:14:48 +0000
commit7aa2d42db6ae20d3a640646c94122a75be794ba8 (patch)
treeebb75b568147ecad97157bf0045bbdce36132360
parentaa926a480f2f84a87dc1fbf42d40fe23bae82ae1 (diff)
If custom sampling rate is set in WavPack file, parse first block to find
actual value. This fixes issue 1518. Originally committed as revision 20461 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/wv.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/libavformat/wv.c b/libavformat/wv.c
index e5c93f5cdd..abc46fad1b 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -101,9 +101,30 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
bpp = ((wc->flags & 3) + 1) << 3;
chan = 1 + !(wc->flags & WV_MONO);
rate = wv_rates[(wc->flags >> 23) & 0xF];
- if(rate == -1){
- av_log(ctx, AV_LOG_ERROR, "Unknown sampling rate\n");
- return -1;
+ if(rate == -1 && !wc->block_parsed){
+ int64_t block_end = url_ftell(pb) + wc->blksize - 24;
+ if(url_is_streamed(pb)){
+ av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
+ return -1;
+ }
+ while(url_ftell(pb) < block_end){
+ int id, size;
+ id = get_byte(pb);
+ size = (id & 0x80) ? get_le24(pb) : get_byte(pb);
+ size <<= 1;
+ if(id&0x40)
+ size--;
+ if((id&0x3F) == 0x27){
+ rate = get_le24(pb);
+ break;
+ }else{
+ url_fskip(pb, size);
+ }
+ }
+ if(rate == -1){
+ av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
+ return -1;
+ }
}
if(!wc->bpp) wc->bpp = bpp;
if(!wc->chan) wc->chan = chan;
@@ -117,7 +138,7 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
return -1;
}
- if(wc->flags && rate != wc->rate){
+ if(wc->flags && rate != -1 && rate != wc->rate){
av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
return -1;
}