mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-24 03:39:45 +00:00
ape: make version-dependent decoding functions called via pointers
This will help in supporting old versions, e.g. version 3.93 uses the same range coder but different predictor and version 3.82 uses different range coder and predictor. Also this should not make decoding newer versions slower by introducing additional checks on versions.
This commit is contained in:
parent
81cf53e133
commit
b164d66e35
@ -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,66 +428,29 @@ 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;
|
||||
|
||||
pivot = rice->ksum >> 5;
|
||||
if (pivot == 0)
|
||||
pivot = 1;
|
||||
|
||||
overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
|
||||
|
||||
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);
|
||||
|
||||
base = (base_hi << bbits) + base_lo;
|
||||
}
|
||||
|
||||
x = base + overflow * pivot;
|
||||
av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
x += overflow << tmpk;
|
||||
|
||||
update_rice(rice, x);
|
||||
|
||||
@ -471,15 +461,87 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice)
|
||||
return -(x >> 1);
|
||||
}
|
||||
|
||||
static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo)
|
||||
static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice)
|
||||
{
|
||||
unsigned int x, overflow;
|
||||
int base, pivot;
|
||||
|
||||
pivot = rice->ksum >> 5;
|
||||
if (pivot == 0)
|
||||
pivot = 1;
|
||||
|
||||
overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
|
||||
|
||||
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);
|
||||
|
||||
base = (base_hi << bbits) + base_lo;
|
||||
}
|
||||
|
||||
x = base + overflow * pivot;
|
||||
|
||||
update_rice(rice, x);
|
||||
|
||||
/* Convert to signed */
|
||||
if (x & 1)
|
||||
return (x >> 1) + 1;
|
||||
else
|
||||
return -(x >> 1);
|
||||
}
|
||||
|
||||
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--) {
|
||||
|
Loading…
Reference in New Issue
Block a user