Add the handling of the INT32INFO block to the WavPack decoder.
authorDavid Bryant <david@WavPack.com>
Sun, 5 Aug 2007 05:56:34 +0000 (05:56 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sun, 5 Aug 2007 05:56:34 +0000 (05:56 +0000)
Patch by David Bryant david at $codecname dot com
Thread: [FFmpeg-devel] [PATCH] handle INT32INFO in WavPack decoder

Originally committed as revision 9932 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/wavpack.c
libavformat/wv.c

index e79d4a570e4900be664bf1e6535b7b3d91c6953b..9a0664198470321dc27f26b629c5dc96dffba1be 100644 (file)
@@ -76,6 +76,7 @@ typedef struct WavpackContext {
     int terms;
     Decorr decorr[MAX_TERMS];
     int zero, one, zeroes;
+    int and, or, shift;
 } WavpackContext;
 
 // exponent table copied from WavPack source
@@ -235,7 +236,7 @@ static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst)
 {
     int i, j, count = 0;
     int last, t;
-    int A, B, L, L2, R, R2;
+    int A, B, L, L2, R, R2, bit;
     int pos = 0;
     uint32_t crc = 0xFFFFFFFF;
 
@@ -299,9 +300,10 @@ static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst)
         if(s->joint)
             L += (R -= (L >> 1));
         crc = (crc * 3 + L) * 3 + R;
-        *dst++ = L;
-        *dst++ = R;
-
+        bit = (L & s->and) | s->or;
+        *dst++ = ((L + bit) << s->shift) - bit;
+        bit = (R & s->and) | s->or;
+        *dst++ = ((R + bit) << s->shift) - bit;
         count++;
     }while(!last && count < s->samples);
 
@@ -316,7 +318,7 @@ static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst)
 {
     int i, j, count = 0;
     int last, t;
-    int A, S, T;
+    int A, S, T, bit;
     int pos = 0;
     uint32_t crc = 0xFFFFFFFF;
 
@@ -344,7 +346,8 @@ static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst)
         }
         pos = (pos + 1) & 7;
         crc = crc * 3 + S;
-        *dst++ = S;
+        bit = (S & s->and) | s->or;
+        *dst++ = ((S + bit) << s->shift) - bit;
         count++;
     }while(!last && count < s->samples);
 
@@ -389,6 +392,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
     }
 
     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
+    s->and = s->or = s->shift = 0;
 
     s->samples = AV_RL32(buf); buf += 4;
     if(!s->samples){
@@ -509,6 +513,23 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
             }
             got_entropy = 1;
             break;
+        case WP_ID_INT32INFO:
+            if(size != 4 || *buf){
+                av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf);
+                buf += ssize;
+                continue;
+            }
+            if(buf[1])
+                s->shift = buf[1];
+            else if(buf[2]){
+                s->and = s->or = 1;
+                s->shift = buf[2];
+            }else if(buf[3]){
+                s->and = 1;
+                s->shift = buf[3];
+            }
+            buf += 4;
+            break;
         case WP_ID_DATA:
             init_get_bits(&s->gb, buf, size * 8);
             s->data_size = size * 8;
index 40f94f950eb9e46ed3a2bdb628591c6cf28138f4..fcadaa01b33045d53f08d885d8a01bd75d7e0dc5 100644 (file)
@@ -105,10 +105,6 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
         av_log(ctx, AV_LOG_ERROR, "Hybrid coding mode is not supported\n");
         return -1;
     }
-    if(wc->flags & WV_INT32){
-        av_log(ctx, AV_LOG_ERROR, "Integer point data is not supported\n");
-        return -1;
-    }
 
     bpp = ((wc->flags & 3) + 1) << 3;
     chan = 1 + !(wc->flags & WV_MONO);