static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, unsigned int c, const unsigned int *div_blocks, unsigned int *js_blocks) { ALSSpecificConfig *sconf = &ctx->sconf; unsigned int offset = 0; unsigned int b; ALSBlockData bd[2] = { { 0 } }; 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]; bd[0].quant_cof = ctx->quant_cof[0]; bd[0].lpc_cof = ctx->lpc_cof[0]; bd[0].prev_raw_samples = ctx->prev_raw_samples; 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]; bd[1].quant_cof = ctx->quant_cof[0]; bd[1].lpc_cof = ctx->lpc_cof[0]; bd[1].prev_raw_samples = ctx->prev_raw_samples; bd[1].js_blocks = *(js_blocks + 1); // decode all blocks for (b = 0; b < ctx->num_blocks; b++) { unsigned int s; bd[0].block_length = div_blocks[b]; bd[1].block_length = div_blocks[b]; bd[0].raw_samples = ctx->raw_samples[c ] + offset; bd[1].raw_samples = ctx->raw_samples[c + 1] + offset; bd[0].raw_other = bd[1].raw_samples; bd[1].raw_other = bd[0].raw_samples; if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) { // damaged block, write zero for the rest of the frame zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); return -1; } // reconstruct joint-stereo blocks if (bd[0].js_blocks) { if (bd[1].js_blocks) av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n"); for (s = 0; s < div_blocks[b]; s++) bd[0].raw_samples[s] = bd[1].raw_samples[s] - bd[0].raw_samples[s]; } else if (bd[1].js_blocks) { for (s = 0; s < div_blocks[b]; s++) bd[1].raw_samples[s] = bd[1].raw_samples[s] + bd[0].raw_samples[s]; } offset += div_blocks[b]; bd[0].ra_block = 0; bd[1].ra_block = 0; } // store carryover raw samples, // the others channel raw samples are stored by the calling function. memmove(ctx->raw_samples[c] - sconf->max_order, ctx->raw_samples[c] - sconf->max_order + sconf->frame_length, sizeof(*ctx->raw_samples[c]) * sconf->max_order); return 0; }