|
|
|
@@ -161,8 +161,24 @@ typedef struct APEContext { |
|
|
|
const uint8_t *ptr; ///< current position in frame data |
|
|
|
|
|
|
|
int error; |
|
|
|
|
|
|
|
void (*entropy_decode_mono)(struct APEContext *ctx, int blockstodecode); |
|
|
|
void (*entropy_decode_stereo)(struct APEContext *ctx, int blockstodecode); |
|
|
|
void (*predictor_decode_mono)(struct APEContext *ctx, int count); |
|
|
|
void (*predictor_decode_stereo)(struct APEContext *ctx, int count); |
|
|
|
} APEContext; |
|
|
|
|
|
|
|
static void ape_apply_filters(APEContext *ctx, int32_t *decoded0, |
|
|
|
int32_t *decoded1, int count); |
|
|
|
|
|
|
|
static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode); |
|
|
|
static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode); |
|
|
|
static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); |
|
|
|
static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode); |
|
|
|
|
|
|
|
static void predictor_decode_mono_3950(APEContext *ctx, int count); |
|
|
|
static void predictor_decode_stereo_3950(APEContext *ctx, int count); |
|
|
|
|
|
|
|
// TODO: dsputilize |
|
|
|
|
|
|
|
static av_cold int ape_decode_close(AVCodecContext *avctx) |
|
|
|
@@ -231,6 +247,17 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) |
|
|
|
filter_alloc_fail); |
|
|
|
} |
|
|
|
|
|
|
|
if (s->fileversion < 3990) { |
|
|
|
s->entropy_decode_mono = entropy_decode_mono_3900; |
|
|
|
s->entropy_decode_stereo = entropy_decode_stereo_3900; |
|
|
|
} else { |
|
|
|
s->entropy_decode_mono = entropy_decode_mono_3990; |
|
|
|
s->entropy_decode_stereo = entropy_decode_stereo_3990; |
|
|
|
} |
|
|
|
|
|
|
|
s->predictor_decode_mono = predictor_decode_mono_3950; |
|
|
|
s->predictor_decode_stereo = predictor_decode_stereo_3950; |
|
|
|
|
|
|
|
ff_dsputil_init(&s->dsp, avctx); |
|
|
|
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; |
|
|
|
|
|
|
|
@@ -401,67 +428,76 @@ static inline void update_rice(APERice *rice, unsigned int x) |
|
|
|
rice->k++; |
|
|
|
} |
|
|
|
|
|
|
|
static inline int ape_decode_value(APEContext *ctx, APERice *rice) |
|
|
|
static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) |
|
|
|
{ |
|
|
|
unsigned int x, overflow; |
|
|
|
int tmpk; |
|
|
|
|
|
|
|
if (ctx->fileversion < 3990) { |
|
|
|
int tmpk; |
|
|
|
overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); |
|
|
|
|
|
|
|
overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); |
|
|
|
if (overflow == (MODEL_ELEMENTS - 1)) { |
|
|
|
tmpk = range_decode_bits(ctx, 5); |
|
|
|
overflow = 0; |
|
|
|
} else |
|
|
|
tmpk = (rice->k < 1) ? 0 : rice->k - 1; |
|
|
|
|
|
|
|
if (overflow == (MODEL_ELEMENTS - 1)) { |
|
|
|
tmpk = range_decode_bits(ctx, 5); |
|
|
|
overflow = 0; |
|
|
|
} else |
|
|
|
tmpk = (rice->k < 1) ? 0 : rice->k - 1; |
|
|
|
|
|
|
|
if (tmpk <= 16) |
|
|
|
x = range_decode_bits(ctx, tmpk); |
|
|
|
else if (tmpk <= 32) { |
|
|
|
x = range_decode_bits(ctx, 16); |
|
|
|
x |= (range_decode_bits(ctx, tmpk - 16) << 16); |
|
|
|
} else { |
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
x += overflow << tmpk; |
|
|
|
if (tmpk <= 16) |
|
|
|
x = range_decode_bits(ctx, tmpk); |
|
|
|
else if (tmpk <= 32) { |
|
|
|
x = range_decode_bits(ctx, 16); |
|
|
|
x |= (range_decode_bits(ctx, tmpk - 16) << 16); |
|
|
|
} else { |
|
|
|
int base, pivot; |
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
x += overflow << tmpk; |
|
|
|
|
|
|
|
update_rice(rice, x); |
|
|
|
|
|
|
|
/* Convert to signed */ |
|
|
|
if (x & 1) |
|
|
|
return (x >> 1) + 1; |
|
|
|
else |
|
|
|
return -(x >> 1); |
|
|
|
} |
|
|
|
|
|
|
|
pivot = rice->ksum >> 5; |
|
|
|
if (pivot == 0) |
|
|
|
pivot = 1; |
|
|
|
static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice) |
|
|
|
{ |
|
|
|
unsigned int x, overflow; |
|
|
|
int base, pivot; |
|
|
|
|
|
|
|
overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); |
|
|
|
pivot = rice->ksum >> 5; |
|
|
|
if (pivot == 0) |
|
|
|
pivot = 1; |
|
|
|
|
|
|
|
if (overflow == (MODEL_ELEMENTS - 1)) { |
|
|
|
overflow = range_decode_bits(ctx, 16) << 16; |
|
|
|
overflow |= range_decode_bits(ctx, 16); |
|
|
|
} |
|
|
|
overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); |
|
|
|
|
|
|
|
if (pivot < 0x10000) { |
|
|
|
base = range_decode_culfreq(ctx, pivot); |
|
|
|
range_decode_update(ctx, 1, base); |
|
|
|
} else { |
|
|
|
int base_hi = pivot, base_lo; |
|
|
|
int bbits = 0; |
|
|
|
|
|
|
|
while (base_hi & ~0xFFFF) { |
|
|
|
base_hi >>= 1; |
|
|
|
bbits++; |
|
|
|
} |
|
|
|
base_hi = range_decode_culfreq(ctx, base_hi + 1); |
|
|
|
range_decode_update(ctx, 1, base_hi); |
|
|
|
base_lo = range_decode_culfreq(ctx, 1 << bbits); |
|
|
|
range_decode_update(ctx, 1, base_lo); |
|
|
|
|
|
|
|
base = (base_hi << bbits) + base_lo; |
|
|
|
if (overflow == (MODEL_ELEMENTS - 1)) { |
|
|
|
overflow = range_decode_bits(ctx, 16) << 16; |
|
|
|
overflow |= range_decode_bits(ctx, 16); |
|
|
|
} |
|
|
|
|
|
|
|
if (pivot < 0x10000) { |
|
|
|
base = range_decode_culfreq(ctx, pivot); |
|
|
|
range_decode_update(ctx, 1, base); |
|
|
|
} else { |
|
|
|
int base_hi = pivot, base_lo; |
|
|
|
int bbits = 0; |
|
|
|
|
|
|
|
while (base_hi & ~0xFFFF) { |
|
|
|
base_hi >>= 1; |
|
|
|
bbits++; |
|
|
|
} |
|
|
|
base_hi = range_decode_culfreq(ctx, base_hi + 1); |
|
|
|
range_decode_update(ctx, 1, base_hi); |
|
|
|
base_lo = range_decode_culfreq(ctx, 1 << bbits); |
|
|
|
range_decode_update(ctx, 1, base_lo); |
|
|
|
|
|
|
|
x = base + overflow * pivot; |
|
|
|
base = (base_hi << bbits) + base_lo; |
|
|
|
} |
|
|
|
|
|
|
|
x = base + overflow * pivot; |
|
|
|
|
|
|
|
update_rice(rice, x); |
|
|
|
|
|
|
|
/* Convert to signed */ |
|
|
|
@@ -471,15 +507,41 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice) |
|
|
|
return -(x >> 1); |
|
|
|
} |
|
|
|
|
|
|
|
static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) |
|
|
|
static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode) |
|
|
|
{ |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
|
|
|
|
while (blockstodecode--) |
|
|
|
*decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY); |
|
|
|
} |
|
|
|
|
|
|
|
static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode) |
|
|
|
{ |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
int32_t *decoded1 = ctx->decoded[1]; |
|
|
|
|
|
|
|
while (blockstodecode--) { |
|
|
|
*decoded0++ = ape_decode_value(ctx, &ctx->riceY); |
|
|
|
if (stereo) |
|
|
|
*decoded1++ = ape_decode_value(ctx, &ctx->riceX); |
|
|
|
*decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY); |
|
|
|
*decoded1++ = ape_decode_value_3900(ctx, &ctx->riceX); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode) |
|
|
|
{ |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
|
|
|
|
while (blockstodecode--) |
|
|
|
*decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY); |
|
|
|
} |
|
|
|
|
|
|
|
static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode) |
|
|
|
{ |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
int32_t *decoded1 = ctx->decoded[1]; |
|
|
|
|
|
|
|
while (blockstodecode--) { |
|
|
|
*decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY); |
|
|
|
*decoded1++ = ape_decode_value_3990(ctx, &ctx->riceX); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -588,12 +650,14 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, |
|
|
|
return p->filterA[filter]; |
|
|
|
} |
|
|
|
|
|
|
|
static void predictor_decode_stereo(APEContext *ctx, int count) |
|
|
|
static void predictor_decode_stereo_3950(APEContext *ctx, int count) |
|
|
|
{ |
|
|
|
APEPredictor *p = &ctx->predictor; |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
int32_t *decoded1 = ctx->decoded[1]; |
|
|
|
|
|
|
|
ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count); |
|
|
|
|
|
|
|
while (count--) { |
|
|
|
/* Predictor Y */ |
|
|
|
*decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, |
|
|
|
@@ -615,12 +679,14 @@ static void predictor_decode_stereo(APEContext *ctx, int count) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void predictor_decode_mono(APEContext *ctx, int count) |
|
|
|
static void predictor_decode_mono_3950(APEContext *ctx, int count) |
|
|
|
{ |
|
|
|
APEPredictor *p = &ctx->predictor; |
|
|
|
int32_t *decoded0 = ctx->decoded[0]; |
|
|
|
int32_t predictionA, currentA, A, sign; |
|
|
|
|
|
|
|
ape_apply_filters(ctx, ctx->decoded[0], NULL, count); |
|
|
|
|
|
|
|
currentA = p->lastA[0]; |
|
|
|
|
|
|
|
while (count--) { |
|
|
|
@@ -779,11 +845,10 @@ static void ape_unpack_mono(APEContext *ctx, int count) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
entropy_decode(ctx, count, 0); |
|
|
|
ape_apply_filters(ctx, ctx->decoded[0], NULL, count); |
|
|
|
ctx->entropy_decode_mono(ctx, count); |
|
|
|
|
|
|
|
/* Now apply the predictor decoding */ |
|
|
|
predictor_decode_mono(ctx, count); |
|
|
|
ctx->predictor_decode_mono(ctx, count); |
|
|
|
|
|
|
|
/* Pseudo-stereo - just copy left channel to right channel */ |
|
|
|
if (ctx->channels == 2) { |
|
|
|
@@ -803,11 +868,10 @@ static void ape_unpack_stereo(APEContext *ctx, int count) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
entropy_decode(ctx, count, 1); |
|
|
|
ape_apply_filters(ctx, decoded0, decoded1, count); |
|
|
|
ctx->entropy_decode_stereo(ctx, count); |
|
|
|
|
|
|
|
/* Now apply the predictor decoding */ |
|
|
|
predictor_decode_stereo(ctx, count); |
|
|
|
ctx->predictor_decode_stereo(ctx, count); |
|
|
|
|
|
|
|
/* Decorrelate and scale to output depth */ |
|
|
|
while (count--) { |
|
|
|
|