|
|
|
@ -198,9 +198,11 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) |
|
|
|
|
s->compression_level = AV_RL16(avctx->extradata + 2); |
|
|
|
|
s->flags = AV_RL16(avctx->extradata + 4); |
|
|
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); |
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", |
|
|
|
|
s->compression_level, s->flags); |
|
|
|
|
if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", |
|
|
|
|
s->compression_level); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
s->fset = s->compression_level / 1000 - 1; |
|
|
|
@ -524,7 +526,10 @@ static inline int APESIGN(int32_t x) { |
|
|
|
|
return (x < 0) - (x > 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_always_inline int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) |
|
|
|
|
static av_always_inline int predictor_update_filter(APEPredictor *p, |
|
|
|
|
const int decoded, const int filter, |
|
|
|
|
const int delayA, const int delayB, |
|
|
|
|
const int adaptA, const int adaptB) |
|
|
|
|
{ |
|
|
|
|
int32_t predictionA, predictionB, sign; |
|
|
|
|
|
|
|
|
@ -576,9 +581,11 @@ static void predictor_decode_stereo(APEContext * ctx, int count) |
|
|
|
|
|
|
|
|
|
while (count--) { |
|
|
|
|
/* Predictor Y */ |
|
|
|
|
*decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB); |
|
|
|
|
*decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, |
|
|
|
|
YADAPTCOEFFSA, YADAPTCOEFFSB); |
|
|
|
|
decoded0++; |
|
|
|
|
*decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB); |
|
|
|
|
*decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, |
|
|
|
|
XADAPTCOEFFSA, XADAPTCOEFFSB); |
|
|
|
|
decoded1++; |
|
|
|
|
|
|
|
|
|
/* Combined */ |
|
|
|
@ -655,14 +662,17 @@ static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order |
|
|
|
|
do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) |
|
|
|
|
static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, |
|
|
|
|
int32_t *data, int count, int order, int fracbits) |
|
|
|
|
{ |
|
|
|
|
int res; |
|
|
|
|
int absres; |
|
|
|
|
|
|
|
|
|
while (count--) { |
|
|
|
|
/* round fixedpoint scalar product */ |
|
|
|
|
res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data)); |
|
|
|
|
res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, |
|
|
|
|
f->adaptcoeffs - order, |
|
|
|
|
order, APESIGN(*data)); |
|
|
|
|
res = (res + (1 << (fracbits - 1))) >> fracbits; |
|
|
|
|
res += *data; |
|
|
|
|
*data++ = res; |
|
|
|
@ -681,7 +691,8 @@ static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t |
|
|
|
|
/* Update the adaption coefficients */ |
|
|
|
|
absres = FFABS(res); |
|
|
|
|
if (absres) |
|
|
|
|
*f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); |
|
|
|
|
*f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> |
|
|
|
|
(25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); |
|
|
|
|
else |
|
|
|
|
*f->adaptcoeffs = 0; |
|
|
|
|
|
|
|
|
@ -721,7 +732,9 @@ static void ape_apply_filters(APEContext * ctx, int32_t * decoded0, |
|
|
|
|
for (i = 0; i < APE_FILTER_LEVELS; i++) { |
|
|
|
|
if (!ape_filter_orders[ctx->fset][i]) |
|
|
|
|
break; |
|
|
|
|
apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]); |
|
|
|
|
apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, |
|
|
|
|
ape_filter_orders[ctx->fset][i], |
|
|
|
|
ape_filter_fracbits[ctx->fset][i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -734,7 +747,8 @@ static void init_frame_decoder(APEContext * ctx) |
|
|
|
|
for (i = 0; i < APE_FILTER_LEVELS; i++) { |
|
|
|
|
if (!ape_filter_orders[ctx->fset][i]) |
|
|
|
|
break; |
|
|
|
|
init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]); |
|
|
|
|
init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], |
|
|
|
|
ape_filter_orders[ctx->fset][i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -805,7 +819,9 @@ static int ape_decode_frame(AVCodecContext * avctx, |
|
|
|
|
|
|
|
|
|
/* should not happen but who knows */ |
|
|
|
|
if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { |
|
|
|
|
av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels); |
|
|
|
|
av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled " |
|
|
|
|
"in lavc! (max is %d where you have %d)\n", |
|
|
|
|
*data_size, s->samples * 2 * avctx->channels); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|