Mercurial > libavcodec.hg
comparison wavpack.c @ 5539:1c67999f81c8 libavcodec
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
author | kostya |
---|---|
date | Mon, 13 Aug 2007 05:36:50 +0000 |
parents | 33a32de3c1bc |
children | d92fa6e5fc8c |
comparison
equal
deleted
inserted
replaced
5538:33a32de3c1bc | 5539:1c67999f81c8 |
---|---|
26 * @file wavpack.c | 26 * @file wavpack.c |
27 * WavPack lossless audio decoder | 27 * WavPack lossless audio decoder |
28 */ | 28 */ |
29 | 29 |
30 #define WV_JOINT_STEREO 0x00000010 | 30 #define WV_JOINT_STEREO 0x00000010 |
31 #define WV_FALSE_STEREO 0x40000000 | |
31 | 32 |
32 enum WP_ID_Flags{ | 33 enum WP_ID_Flags{ |
33 WP_IDF_MASK = 0x1F, | 34 WP_IDF_MASK = 0x1F, |
34 WP_IDF_IGNORE = 0x20, | 35 WP_IDF_IGNORE = 0x20, |
35 WP_IDF_ODD = 0x40, | 36 WP_IDF_ODD = 0x40, |
64 int samplesB[8]; | 65 int samplesB[8]; |
65 } Decorr; | 66 } Decorr; |
66 | 67 |
67 typedef struct WavpackContext { | 68 typedef struct WavpackContext { |
68 AVCodecContext *avctx; | 69 AVCodecContext *avctx; |
69 int stereo; | 70 int stereo, stereo_in; |
70 int joint; | 71 int joint; |
71 uint32_t CRC; | 72 uint32_t CRC; |
72 GetBitContext gb; | 73 GetBitContext gb; |
73 int data_size; // in bits | 74 int data_size; // in bits |
74 int samples; | 75 int samples; |
384 *data_size = 0; | 385 *data_size = 0; |
385 return 0; | 386 return 0; |
386 } | 387 } |
387 | 388 |
388 memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); | 389 memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); |
390 memset(s->median, 0, sizeof(s->median)); | |
389 s->and = s->or = s->shift = 0; | 391 s->and = s->or = s->shift = 0; |
390 | 392 |
391 s->samples = AV_RL32(buf); buf += 4; | 393 s->samples = AV_RL32(buf); buf += 4; |
392 if(!s->samples){ | 394 if(!s->samples){ |
393 *data_size = 0; | 395 *data_size = 0; |
396 /* should not happen but who knows */ | 398 /* should not happen but who knows */ |
397 if(s->samples * 2 * avctx->channels > *data_size){ | 399 if(s->samples * 2 * avctx->channels > *data_size){ |
398 av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n"); | 400 av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n"); |
399 return -1; | 401 return -1; |
400 } | 402 } |
403 s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo; | |
401 s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4; | 404 s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4; |
402 s->CRC = AV_RL32(buf); buf += 4; | 405 s->CRC = AV_RL32(buf); buf += 4; |
403 // parse metadata blocks | 406 // parse metadata blocks |
404 while(buf < buf_end){ | 407 while(buf < buf_end){ |
405 id = *buf++; | 408 id = *buf++; |
441 case WP_ID_DECWEIGHTS: | 444 case WP_ID_DECWEIGHTS: |
442 if(!got_terms){ | 445 if(!got_terms){ |
443 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); | 446 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); |
444 continue; | 447 continue; |
445 } | 448 } |
446 weights = size >> s->stereo; | 449 weights = size >> s->stereo_in; |
447 if(weights > MAX_TERMS || weights > s->terms){ | 450 if(weights > MAX_TERMS || weights > s->terms){ |
448 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); | 451 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); |
449 buf += ssize; | 452 buf += ssize; |
450 continue; | 453 continue; |
451 } | 454 } |
452 for(i = 0; i < weights; i++) { | 455 for(i = 0; i < weights; i++) { |
453 t = (int8_t)(*buf++); | 456 t = (int8_t)(*buf++); |
454 s->decorr[s->terms - i - 1].weightA = t << 3; | 457 s->decorr[s->terms - i - 1].weightA = t << 3; |
455 if(s->decorr[s->terms - i - 1].weightA > 0) | 458 if(s->decorr[s->terms - i - 1].weightA > 0) |
456 s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; | 459 s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; |
457 if(s->stereo){ | 460 if(s->stereo_in){ |
458 t = (int8_t)(*buf++); | 461 t = (int8_t)(*buf++); |
459 s->decorr[s->terms - i - 1].weightB = t << 3; | 462 s->decorr[s->terms - i - 1].weightB = t << 3; |
460 if(s->decorr[s->terms - i - 1].weightB > 0) | 463 if(s->decorr[s->terms - i - 1].weightB > 0) |
461 s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; | 464 s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; |
462 } | 465 } |
471 t = 0; | 474 t = 0; |
472 for(i = s->terms - 1; (i >= 0) && (t < size); i--) { | 475 for(i = s->terms - 1; (i >= 0) && (t < size); i--) { |
473 if(s->decorr[i].value > 8){ | 476 if(s->decorr[i].value > 8){ |
474 s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; | 477 s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; |
475 s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; | 478 s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; |
476 if(s->stereo){ | 479 if(s->stereo_in){ |
477 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; | 480 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; |
478 s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; | 481 s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; |
479 t += 4; | 482 t += 4; |
480 } | 483 } |
481 t += 4; | 484 t += 4; |
484 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; | 487 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; |
485 t += 4; | 488 t += 4; |
486 }else{ | 489 }else{ |
487 for(j = 0; j < s->decorr[i].value; j++){ | 490 for(j = 0; j < s->decorr[i].value; j++){ |
488 s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; | 491 s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; |
489 if(s->stereo){ | 492 if(s->stereo_in){ |
490 s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; | 493 s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; |
491 } | 494 } |
492 } | 495 } |
493 t += s->decorr[i].value * 2 * avctx->channels; | 496 t += s->decorr[i].value * 2 * (s->stereo_in + 1); |
494 } | 497 } |
495 } | 498 } |
496 got_samples = 1; | 499 got_samples = 1; |
497 break; | 500 break; |
498 case WP_ID_ENTROPY: | 501 case WP_ID_ENTROPY: |
499 if(size != 6 * avctx->channels){ | 502 if(size != 6 * (s->stereo_in + 1)){ |
500 av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * avctx->channels, size); | 503 av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size); |
501 buf += ssize; | 504 buf += ssize; |
502 continue; | 505 continue; |
503 } | 506 } |
504 for(i = 0; i < 3 * avctx->channels; i++){ | 507 for(i = 0; i < 3 * (s->stereo_in + 1); i++){ |
505 s->median[i] = wp_exp2(AV_RL16(buf)); | 508 s->median[i] = wp_exp2(AV_RL16(buf)); |
506 buf += 2; | 509 buf += 2; |
507 } | 510 } |
508 got_entropy = 1; | 511 got_entropy = 1; |
509 break; | 512 break; |
554 if(!got_bs){ | 557 if(!got_bs){ |
555 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); | 558 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); |
556 return -1; | 559 return -1; |
557 } | 560 } |
558 | 561 |
559 if(s->stereo) | 562 if(s->stereo_in) |
560 samplecount = wv_unpack_stereo(s, &s->gb, samples); | 563 samplecount = wv_unpack_stereo(s, &s->gb, samples); |
561 else | 564 else{ |
562 samplecount = wv_unpack_mono(s, &s->gb, samples); | 565 samplecount = wv_unpack_mono(s, &s->gb, samples); |
566 if(s->stereo){ | |
567 int16_t *dst = samples + samplecount * 2; | |
568 int16_t *src = samples + samplecount; | |
569 int cnt = samplecount; | |
570 while(cnt--){ | |
571 *--dst = *--src; | |
572 *--dst = *src; | |
573 } | |
574 samplecount *= 2; | |
575 } | |
576 } | |
563 *data_size = samplecount * 2; | 577 *data_size = samplecount * 2; |
564 | 578 |
565 return buf_size; | 579 return buf_size; |
566 } | 580 } |
567 | 581 |