Browse code

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

Kostya Shishkov authored on 2009/11/05 17:14:48
Showing 1 changed files
... ...
@@ -101,9 +101,30 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
101 101
     bpp = ((wc->flags & 3) + 1) << 3;
102 102
     chan = 1 + !(wc->flags & WV_MONO);
103 103
     rate = wv_rates[(wc->flags >> 23) & 0xF];
104
-    if(rate == -1){
105
-        av_log(ctx, AV_LOG_ERROR, "Unknown sampling rate\n");
106
-        return -1;
104
+    if(rate == -1 && !wc->block_parsed){
105
+        int64_t block_end = url_ftell(pb) + wc->blksize - 24;
106
+        if(url_is_streamed(pb)){
107
+            av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
108
+            return -1;
109
+        }
110
+        while(url_ftell(pb) < block_end){
111
+            int id, size;
112
+            id = get_byte(pb);
113
+            size = (id & 0x80) ? get_le24(pb) : get_byte(pb);
114
+            size <<= 1;
115
+            if(id&0x40)
116
+                size--;
117
+            if((id&0x3F) == 0x27){
118
+                rate = get_le24(pb);
119
+                break;
120
+            }else{
121
+                url_fskip(pb, size);
122
+            }
123
+        }
124
+        if(rate == -1){
125
+            av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
126
+            return -1;
127
+        }
107 128
     }
108 129
     if(!wc->bpp) wc->bpp = bpp;
109 130
     if(!wc->chan) wc->chan = chan;
... ...
@@ -117,7 +138,7 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
117 117
         av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
118 118
         return -1;
119 119
     }
120
-    if(wc->flags && rate != wc->rate){
120
+    if(wc->flags && rate != -1 && rate != wc->rate){
121 121
         av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
122 122
         return -1;
123 123
     }