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
... | ... |
@@ -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 |
} |