| @@ -176,6 +176,8 @@ static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode); · 175 unmodified lines |
| 176 | 176 | static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); |
| 177 | 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 | 181 | static void predictor_decode_mono_3950(APEContext *ctx, int count); |
| 180 | 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 | 257 | s->entropy_decode_stereo = entropy_decode_stereo_3990; |
| 256 | 258 | } |
| 257 | 259 | |
| 258 | | − s->predictor_decode_mono = predictor_decode_mono_3950; |
| 259 | | − s->predictor_decode_stereo = predictor_decode_stereo_3950; |
| 260 | + if (s->fileversion < 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 | 268 | ff_dsputil_init(&s->dsp, avctx); |
| 262 | 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 | 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 | 693 | static av_always_inline int predictor_update_filter(APEPredictor *p, |
| 607 | 694 | const int decoded, const int filter, |
| 608 | 695 | const int delayA, const int delayB, |