| @@ -176,6 +176,8 @@ static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode); · 175 unmodified lines |
| 176 | static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); | 176 | static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); |
| 177 | static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode); | 177 | static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode); |
| 178 | | 178 | |
| | 179 | static void predictor_decode_mono_3930(APEContext *ctx, int count); |
| | 180 | static void predictor_decode_stereo_3930(APEContext *ctx, int count); |
| 179 | static void predictor_decode_mono_3950(APEContext *ctx, int count); | 181 | static void predictor_decode_mono_3950(APEContext *ctx, int count); |
| 180 | static void predictor_decode_stereo_3950(APEContext *ctx, int count); | 182 | static void predictor_decode_stereo_3950(APEContext *ctx, int count); |
| 181 | | 183 | |
| @@ -255,8 +257,13 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) · 73 unmodified lines |
| 255 | s->entropy_decode_stereo = entropy_decode_stereo_3990; | 257 | s->entropy_decode_stereo = entropy_decode_stereo_3990; |
| 256 | } | 258 | } |
| 257 | | 259 | |
| 258 | s->predictor_decode_mono = predictor_decode_mono_3950; | 260 | if (s->fileversion < 3950) { |
| 259 | s->predictor_decode_stereo = predictor_decode_stereo_3950; | 261 | s->predictor_decode_mono = predictor_decode_mono_3930; |
| | 262 | s->predictor_decode_stereo = predictor_decode_stereo_3930; |
| | 263 | } else { |
| | 264 | s->predictor_decode_mono = predictor_decode_mono_3950; |
| | 265 | s->predictor_decode_stereo = predictor_decode_stereo_3950; |
| | 266 | } |
| 260 | | 267 | |
| 261 | ff_dsputil_init(&s->dsp, avctx); | 268 | ff_dsputil_init(&s->dsp, avctx); |
| 262 | avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; | 269 | avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; |
| @@ -603,6 +610,86 @@ static inline int APESIGN(int32_t x) { · 340 unmodified lines |
| 603 | return (x < 0) - (x > 0); | 610 | return (x < 0) - (x > 0); |
| 604 | } | 611 | } |
| 605 | | 612 | |
| | 613 | static av_always_inline int predictor_update_3930(APEPredictor *p, |
| | 614 | const int decoded, const int filter, |
| | 615 | const int delayA) |
| | 616 | { |
| | 617 | int32_t predictionA, sign; |
| | 618 | int32_t d0, d1, d2, d3; |
| | 619 | |
| | 620 | p->buf[delayA] = p->lastA[filter]; |
| | 621 | d0 = p->buf[delayA ]; |
| | 622 | d1 = p->buf[delayA ] - p->buf[delayA - 1]; |
| | 623 | d2 = p->buf[delayA - 1] - p->buf[delayA - 2]; |
| | 624 | d3 = p->buf[delayA - 2] - p->buf[delayA - 3]; |
| | 625 | |
| | 626 | predictionA = d0 * p->coeffsA[filter][0] + |
| | 627 | d1 * p->coeffsA[filter][1] + |
| | 628 | d2 * p->coeffsA[filter][2] + |
| | 629 | d3 * p->coeffsA[filter][3]; |
| | 630 | |
| | 631 | p->lastA[filter] = decoded + (predictionA >> 9); |
| | 632 | p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5); |
| | 633 | |
| | 634 | sign = APESIGN(decoded); |
| | 635 | p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign; |
| | 636 | p->coeffsA[filter][1] += ((d1 < 0) * 2 - 1) * sign; |
| | 637 | p->coeffsA[filter][2] += ((d2 < 0) * 2 - 1) * sign; |
| | 638 | p->coeffsA[filter][3] += ((d3 < 0) * 2 - 1) * sign; |
| | 639 | |
| | 640 | return p->filterA[filter]; |
| | 641 | } |
| | 642 | |
| | 643 | static void predictor_decode_stereo_3930(APEContext *ctx, int count) |
| | 644 | { |
| | 645 | APEPredictor *p = &ctx->predictor; |
| | 646 | int32_t *decoded0 = ctx->decoded[0]; |
| | 647 | int32_t *decoded1 = ctx->decoded[1]; |
| | 648 | |
| | 649 | ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count); |
| | 650 | |
| | 651 | while (count--) { |
| | 652 | /* Predictor Y */ |
| | 653 | int Y = *decoded1, X = *decoded0; |
| | 654 | *decoded0 = predictor_update_3930(p, Y, 0, YDELAYA); |
| | 655 | decoded0++; |
| | 656 | *decoded1 = predictor_update_3930(p, X, 1, XDELAYA); |
| | 657 | decoded1++; |
| | 658 | |
| | 659 | /* Combined */ |
| | 660 | p->buf++; |
| | 661 | |
| | 662 | /* Have we filled the history buffer? */ |
| | 663 | if (p->buf == p->historybuffer + HISTORY_SIZE) { |
| | 664 | memmove(p->historybuffer, p->buf, |
| | 665 | PREDICTOR_SIZE * sizeof(*p->historybuffer)); |
| | 666 | p->buf = p->historybuffer; |
| | 667 | } |
| | 668 | } |
| | 669 | } |
| | 670 | |
| | 671 | static void predictor_decode_mono_3930(APEContext *ctx, int count) |
| | 672 | { |
| | 673 | APEPredictor *p = &ctx->predictor; |
| | 674 | int32_t *decoded0 = ctx->decoded[0]; |
| | 675 | |
| | 676 | ape_apply_filters(ctx, ctx->decoded[0], NULL, count); |
| | 677 | |
| | 678 | while (count--) { |
| | 679 | *decoded0 = predictor_update_3930(p, *decoded0, 0, YDELAYA); |
| | 680 | decoded0++; |
| | 681 | |
| | 682 | p->buf++; |
| | 683 | |
| | 684 | /* Have we filled the history buffer? */ |
| | 685 | if (p->buf == p->historybuffer + HISTORY_SIZE) { |
| | 686 | memmove(p->historybuffer, p->buf, |
| | 687 | PREDICTOR_SIZE * sizeof(*p->historybuffer)); |
| | 688 | p->buf = p->historybuffer; |
| | 689 | } |
| | 690 | } |
| | 691 | } |
| | 692 | |
| 606 | static av_always_inline int predictor_update_filter(APEPredictor *p, | 693 | static av_always_inline int predictor_update_filter(APEPredictor *p, |
| 607 | const int decoded, const int filter, | 694 | const int decoded, const int filter, |
| 608 | const int delayA, const int delayB, | 695 | const int delayA, const int delayB, |