On Tue, 12 Mar 2013 20:08:39 +0100, Kostya Shishkov <[email protected]> 
wrote:
> This will help in supporting old versions, e.g. version 3.93 uses the same
> range coder but different predictor and version 3.92 uses different range
> coder and predictor. Also this should not make decoding newer versions slower
> by introducing additional checks on versions.
> ---
>  libavcodec/apedec.c |  173 
> ++++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 116 insertions(+), 57 deletions(-)
> 
> diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
> index 60227a0..13d92e9 100644
> --- a/libavcodec/apedec.c
> +++ b/libavcodec/apedec.c
> @@ -161,8 +161,21 @@ 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 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 +244,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 +425,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;
>  
> -        pivot = rice->ksum >> 5;
> -        if (pivot == 0)
> -            pivot = 1;
> +    update_rice(rice, x);
> +
> +    /* Convert to signed */
> +    if (x & 1)
> +        return (x >> 1) + 1;
> +    else
> +        return -(x >> 1);
> +}
>  
> -        overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
> +static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice)
> +{
> +    unsigned int x, overflow;
> +    int base, pivot;
>  
> -        if (overflow == (MODEL_ELEMENTS - 1)) {
> -            overflow  = range_decode_bits(ctx, 16) << 16;
> -            overflow |= range_decode_bits(ctx, 16);
> -        }
> +    pivot = rice->ksum >> 5;
> +    if (pivot == 0)
> +        pivot = 1;
>  
> -        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;
> +    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);
>  
> -        x = base + overflow * pivot;
> +        base = (base_hi << bbits) + base_lo;
>      }
>  
> +    x = base + overflow * pivot;
> +
>      update_rice(rice, x);
>  
>      /* Convert to signed */
> @@ -471,15 +504,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_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(ctx, &ctx->riceY);
> -        if (stereo)
> -            *decoded1++ = ape_decode_value(ctx, &ctx->riceX);
> +        *decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY);
> +        *decoded1++ = ape_decode_value_3990(ctx, &ctx->riceX);
>      }
>  }
>  
> @@ -588,7 +647,7 @@ 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];
> @@ -615,7 +674,7 @@ 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];
> @@ -779,11 +838,11 @@ static void ape_unpack_mono(APEContext *ctx, int count)
>          return;
>      }
>  
> -    entropy_decode(ctx, count, 0);
> +    ctx->entropy_decode_mono(ctx, count);
>      ape_apply_filters(ctx, ctx->decoded[0], NULL, 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 +862,11 @@ static void ape_unpack_stereo(APEContext *ctx, int 
> count)
>          return;
>      }
>  
> -    entropy_decode(ctx, count, 1);
> +    ctx->entropy_decode_stereo(ctx, count);
>      ape_apply_filters(ctx, decoded0, decoded1, 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--) {
> -- 
> 1.7.9.5
> 

LGTM

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to