From efd63823e640b67d3c575e37a291eddf5f6268d2 Mon Sep 17 00:00:00 2001 From: Sprezz Date: Mon, 6 Dec 2010 15:18:50 +0000 Subject: [PATCH] alsdec: Correct the ALS decoder by storing some parameters per-channel rather than just per-block. Patch by Sprezz [sprezzatura gmx com]. Fixes Issue 2387. Originally committed as revision 25898 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/alsdec.c | 103 +++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 9b71b2dbb8..116e5e2f82 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -205,6 +205,10 @@ typedef struct { uint8_t *bgmc_lut; ///< pointer at lookup tables used for BGMC int *bgmc_lut_status; ///< pointer at lookup table status flags used for BGMC int ltp_lag_length; ///< number of bits used for ltp lag value + int *const_block; ///< contains const_block flags for all channels + unsigned int *shift_lsbs; ///< contains shift_lsbs flags for all channels + unsigned int *opt_order; ///< contains opt_order flags for all channels + int *store_prev_samples; ///< contains store_prev_samples flags for all channels int *use_ltp; ///< contains use_ltp flags for all channels int *ltp_lag; ///< contains ltp lag values for all channels int **ltp_gain; ///< gain values for ltp 5-tap filter for a channel @@ -227,12 +231,11 @@ typedef struct { typedef struct { unsigned int block_length; ///< number of samples within the block unsigned int ra_block; ///< if true, this is a random access block - int const_block; ///< if true, this is a constant value block - int32_t const_val; ///< the sample value of a constant block + int *const_block; ///< if true, this is a constant value block int js_blocks; ///< true if this block contains a difference signal - unsigned int shift_lsbs; ///< shift of values for this block - unsigned int opt_order; ///< prediction order of this block - int store_prev_samples;///< if true, carryover samples have to be stored + unsigned int *shift_lsbs; ///< shift of values for this block + unsigned int *opt_order; ///< prediction order of this block + int *store_prev_samples;///< if true, carryover samples have to be stored int *use_ltp; ///< if true, long-term prediction is used int *ltp_lag; ///< lag value for long-term prediction int *ltp_gain; ///< gain values for ltp 5-tap filter @@ -554,20 +557,20 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) AVCodecContext *avctx = ctx->avctx; GetBitContext *gb = &ctx->gb; - bd->const_val = 0; - bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence) + *bd->raw_samples = 0; + *bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence) bd->js_blocks = get_bits1(gb); // skip 5 reserved bits skip_bits(gb, 5); - if (bd->const_block) { + if (*bd->const_block) { unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample; - bd->const_val = get_sbits_long(gb, const_val_bits); + *bd->raw_samples = get_sbits_long(gb, const_val_bits); } // ensure constant block decoding by reusing this field - bd->const_block = 1; + *bd->const_block = 1; } @@ -575,9 +578,9 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) */ static void decode_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) { - int smp = bd->block_length; - int32_t val = bd->const_val; - int32_t *dst = bd->raw_samples; + int smp = bd->block_length - 1; + int32_t val = *bd->raw_samples; + int32_t *dst = bd->raw_samples + 1; // write raw samples into buffer for (; smp; smp--) @@ -604,12 +607,12 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) // ensure variable block decoding by reusing this field - bd->const_block = 0; + *bd->const_block = 0; - bd->opt_order = 1; + *bd->opt_order = 1; bd->js_blocks = get_bits1(gb); - opt_order = bd->opt_order; + opt_order = *bd->opt_order; // determine the number of subblocks for entropy decoding if (!sconf->bgmc && !sconf->sb_part) { @@ -649,21 +652,21 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) } if (get_bits1(gb)) - bd->shift_lsbs = get_bits(gb, 4) + 1; + *bd->shift_lsbs = get_bits(gb, 4) + 1; - bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || bd->shift_lsbs; + *bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || *bd->shift_lsbs; if (!sconf->rlslms) { if (sconf->adapt_order) { int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, 2, sconf->max_order + 1)); - bd->opt_order = get_bits(gb, opt_order_length); + *bd->opt_order = get_bits(gb, opt_order_length); } else { - bd->opt_order = sconf->max_order; + *bd->opt_order = sconf->max_order; } - opt_order = bd->opt_order; + opt_order = *bd->opt_order; if (opt_order) { int add_base; @@ -840,7 +843,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) unsigned int block_length = bd->block_length; unsigned int smp = 0; unsigned int k; - int opt_order = bd->opt_order; + int opt_order = *bd->opt_order; int sb; int64_t y; int32_t *quant_cof = bd->quant_cof; @@ -885,7 +888,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) parcor_to_lpc(k, quant_cof, lpc_cof); // store previous samples in case that they have to be altered - if (bd->store_prev_samples) + if (*bd->store_prev_samples) memcpy(bd->prev_raw_samples, raw_samples - sconf->max_order, sizeof(*bd->prev_raw_samples) * sconf->max_order); @@ -906,9 +909,9 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) } // reconstruct shifted signal - if (bd->shift_lsbs) + if (*bd->shift_lsbs) for (sb = -1; sb >= -sconf->max_order; sb--) - raw_samples[sb] >>= bd->shift_lsbs; + raw_samples[sb] >>= *bd->shift_lsbs; } // reverse linear prediction coefficients for efficiency @@ -933,7 +936,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) raw_samples = bd->raw_samples; // restore previous samples in case that they have been altered - if (bd->store_prev_samples) + if (*bd->store_prev_samples) memcpy(raw_samples - sconf->max_order, bd->prev_raw_samples, sizeof(*raw_samples) * sconf->max_order); @@ -947,6 +950,7 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) { GetBitContext *gb = &ctx->gb; + *bd->shift_lsbs = 0; // read block type flag and read the samples accordingly if (get_bits1(gb)) { if (read_var_block_data(ctx, bd)) @@ -966,16 +970,16 @@ static int decode_block(ALSDecContext *ctx, ALSBlockData *bd) unsigned int smp; // read block type flag and read the samples accordingly - if (bd->const_block) + if (*bd->const_block) decode_const_block_data(ctx, bd); else if (decode_var_block_data(ctx, bd)) return -1; // TODO: read RLSLMS extension data - if (bd->shift_lsbs) + if (*bd->shift_lsbs) for (smp = 0; smp < bd->block_length; smp++) - bd->raw_samples[smp] <<= bd->shift_lsbs; + bd->raw_samples[smp] <<= *bd->shift_lsbs; return 0; } @@ -1026,6 +1030,10 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, memset(&bd, 0, sizeof(ALSBlockData)); bd.ra_block = ra_frame; + bd.const_block = ctx->const_block; + bd.shift_lsbs = ctx->shift_lsbs; + bd.opt_order = ctx->opt_order; + bd.store_prev_samples = ctx->store_prev_samples; bd.use_ltp = ctx->use_ltp; bd.ltp_lag = ctx->ltp_lag; bd.ltp_gain = ctx->ltp_gain[0]; @@ -1036,7 +1044,6 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, for (b = 0; b < ctx->num_blocks; b++) { - bd.shift_lsbs = 0; bd.block_length = div_blocks[b]; if (read_decode_block(ctx, &bd)) { @@ -1066,6 +1073,10 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, memset(bd, 0, 2 * sizeof(ALSBlockData)); bd[0].ra_block = ra_frame; + bd[0].const_block = ctx->const_block; + bd[0].shift_lsbs = ctx->shift_lsbs; + bd[0].opt_order = ctx->opt_order; + bd[0].store_prev_samples = ctx->store_prev_samples; bd[0].use_ltp = ctx->use_ltp; bd[0].ltp_lag = ctx->ltp_lag; bd[0].ltp_gain = ctx->ltp_gain[0]; @@ -1075,6 +1086,10 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, bd[0].js_blocks = *js_blocks; bd[1].ra_block = ra_frame; + bd[1].const_block = ctx->const_block; + bd[1].shift_lsbs = ctx->shift_lsbs; + bd[1].opt_order = ctx->opt_order; + bd[1].store_prev_samples = ctx->store_prev_samples; bd[1].use_ltp = ctx->use_ltp; bd[1].ltp_lag = ctx->ltp_lag; bd[1].ltp_gain = ctx->ltp_gain[0]; @@ -1087,9 +1102,6 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, for (b = 0; b < ctx->num_blocks; b++) { unsigned int s; - bd[0].shift_lsbs = 0; - bd[1].shift_lsbs = 0; - bd[0].block_length = div_blocks[b]; bd[1].block_length = div_blocks[b]; @@ -1207,6 +1219,10 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, return -1; } + bd->const_block = ctx->const_block + c; + bd->shift_lsbs = ctx->shift_lsbs + c; + bd->opt_order = ctx->opt_order + c; + bd->store_prev_samples = ctx->store_prev_samples + c; bd->use_ltp = ctx->use_ltp + c; bd->ltp_lag = ctx->ltp_lag + c; bd->ltp_gain = ctx->ltp_gain[c]; @@ -1340,10 +1356,13 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) get_block_sizes(ctx, div_blocks, &bs_info); for (b = 0; b < ctx->num_blocks; b++) { - bd.shift_lsbs = 0; bd.block_length = div_blocks[b]; for (c = 0; c < avctx->channels; c++) { + bd.const_block = ctx->const_block + c; + bd.shift_lsbs = ctx->shift_lsbs + c; + bd.opt_order = ctx->opt_order + c; + bd.store_prev_samples = ctx->store_prev_samples + c; bd.use_ltp = ctx->use_ltp + c; bd.ltp_lag = ctx->ltp_lag + c; bd.ltp_gain = ctx->ltp_gain[c]; @@ -1363,6 +1382,10 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) return -1; for (c = 0; c < avctx->channels; c++) { + bd.const_block = ctx->const_block + c; + bd.shift_lsbs = ctx->shift_lsbs + c; + bd.opt_order = ctx->opt_order + c; + bd.store_prev_samples = ctx->store_prev_samples + c; bd.use_ltp = ctx->use_ltp + c; bd.ltp_lag = ctx->ltp_lag + c; bd.ltp_gain = ctx->ltp_gain[c]; @@ -1522,6 +1545,10 @@ static av_cold int decode_end(AVCodecContext *avctx) ff_bgmc_end(&ctx->bgmc_lut, &ctx->bgmc_lut_status); + av_freep(&ctx->const_block); + av_freep(&ctx->shift_lsbs); + av_freep(&ctx->opt_order); + av_freep(&ctx->store_prev_samples); av_freep(&ctx->use_ltp); av_freep(&ctx->ltp_lag); av_freep(&ctx->ltp_gain); @@ -1616,13 +1643,19 @@ static av_cold int decode_init(AVCodecContext *avctx) } // allocate and assign lag and gain data buffer for ltp mode + ctx->const_block = av_malloc (sizeof(*ctx->const_block) * num_buffers); + ctx->shift_lsbs = av_malloc (sizeof(*ctx->shift_lsbs) * num_buffers); + ctx->opt_order = av_malloc (sizeof(*ctx->opt_order) * num_buffers); + ctx->store_prev_samples = av_malloc(sizeof(*ctx->store_prev_samples) * num_buffers); ctx->use_ltp = av_mallocz(sizeof(*ctx->use_ltp) * num_buffers); ctx->ltp_lag = av_malloc (sizeof(*ctx->ltp_lag) * num_buffers); ctx->ltp_gain = av_malloc (sizeof(*ctx->ltp_gain) * num_buffers); ctx->ltp_gain_buffer = av_malloc (sizeof(*ctx->ltp_gain_buffer) * num_buffers * 5); - if (!ctx->use_ltp || !ctx->ltp_lag || + if (!ctx->const_block || !ctx->shift_lsbs || + !ctx->opt_order || !ctx->store_prev_samples || + !ctx->use_ltp || !ctx->ltp_lag || !ctx->ltp_gain || !ctx->ltp_gain_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); decode_end(avctx);