Browse code

Support for WavPack version 0x410 (false stereo chunks)

Patch by David Bryant printf("david@%s.com",wv_demuxer.long_name);
Thread [PATCH] handle WavPack stream version 0x410

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

David Bryant authored on 2007/08/13 14:36:50
Showing 2 changed files
... ...
@@ -28,6 +28,7 @@
28 28
  */
29 29
 
30 30
 #define WV_JOINT_STEREO 0x00000010
31
+#define WV_FALSE_STEREO 0x40000000
31 32
 
32 33
 enum WP_ID_Flags{
33 34
     WP_IDF_MASK   = 0x1F,
... ...
@@ -66,7 +67,7 @@ typedef struct Decorr {
66 66
 
67 67
 typedef struct WavpackContext {
68 68
     AVCodecContext *avctx;
69
-    int stereo;
69
+    int stereo, stereo_in;
70 70
     int joint;
71 71
     uint32_t CRC;
72 72
     GetBitContext gb;
... ...
@@ -386,6 +387,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
386 386
     }
387 387
 
388 388
     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
389
+    memset(s->median, 0, sizeof(s->median));
389 390
     s->and = s->or = s->shift = 0;
390 391
 
391 392
     s->samples = AV_RL32(buf); buf += 4;
... ...
@@ -398,6 +400,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
398 398
         av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n");
399 399
         return -1;
400 400
     }
401
+    s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo;
401 402
     s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4;
402 403
     s->CRC = AV_RL32(buf); buf += 4;
403 404
     // parse metadata blocks
... ...
@@ -443,7 +446,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
443 443
                 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
444 444
                 continue;
445 445
             }
446
-            weights = size >> s->stereo;
446
+            weights = size >> s->stereo_in;
447 447
             if(weights > MAX_TERMS || weights > s->terms){
448 448
                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
449 449
                 buf += ssize;
... ...
@@ -454,7 +457,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
454 454
                 s->decorr[s->terms - i - 1].weightA = t << 3;
455 455
                 if(s->decorr[s->terms - i - 1].weightA > 0)
456 456
                     s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
457
-                if(s->stereo){
457
+                if(s->stereo_in){
458 458
                     t = (int8_t)(*buf++);
459 459
                     s->decorr[s->terms - i - 1].weightB = t << 3;
460 460
                     if(s->decorr[s->terms - i - 1].weightB > 0)
... ...
@@ -473,7 +476,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
473 473
                 if(s->decorr[i].value > 8){
474 474
                     s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
475 475
                     s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2;
476
-                    if(s->stereo){
476
+                    if(s->stereo_in){
477 477
                         s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
478 478
                         s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2;
479 479
                         t += 4;
... ...
@@ -486,22 +489,22 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
486 486
                 }else{
487 487
                     for(j = 0; j < s->decorr[i].value; j++){
488 488
                         s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;
489
-                        if(s->stereo){
489
+                        if(s->stereo_in){
490 490
                             s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
491 491
                         }
492 492
                     }
493
-                    t += s->decorr[i].value * 2 * avctx->channels;
493
+                    t += s->decorr[i].value * 2 * (s->stereo_in + 1);
494 494
                 }
495 495
             }
496 496
             got_samples = 1;
497 497
             break;
498 498
         case WP_ID_ENTROPY:
499
-            if(size != 6 * avctx->channels){
500
-                av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * avctx->channels, size);
499
+            if(size != 6 * (s->stereo_in + 1)){
500
+                av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size);
501 501
                 buf += ssize;
502 502
                 continue;
503 503
             }
504
-            for(i = 0; i < 3 * avctx->channels; i++){
504
+            for(i = 0; i < 3 * (s->stereo_in + 1); i++){
505 505
                 s->median[i] = wp_exp2(AV_RL16(buf));
506 506
                 buf += 2;
507 507
             }
... ...
@@ -556,10 +559,21 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
556 556
         return -1;
557 557
     }
558 558
 
559
-    if(s->stereo)
559
+    if(s->stereo_in)
560 560
         samplecount = wv_unpack_stereo(s, &s->gb, samples);
561
-    else
561
+    else{
562 562
         samplecount = wv_unpack_mono(s, &s->gb, samples);
563
+        if(s->stereo){
564
+            int16_t *dst = samples + samplecount * 2;
565
+            int16_t *src = samples + samplecount;
566
+            int cnt = samplecount;
567
+            while(cnt--){
568
+                *--dst = *--src;
569
+                *--dst = *src;
570
+            }
571
+            samplecount *= 2;
572
+        }
573
+    }
563 574
     *data_size = samplecount * 2;
564 575
 
565 576
     return buf_size;
... ...
@@ -86,7 +86,7 @@ static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
86 86
     }
87 87
     wc->blksize = size;
88 88
     ver = get_le16(pb);
89
-    if(ver < 0x402 || ver > 0x40F){
89
+    if(ver < 0x402 || ver > 0x410){
90 90
         av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
91 91
         return -1;
92 92
     }