static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) { ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; GetBitContext *gb = &ctx->gb; unsigned int div_blocks[32]; ///< block sizes. unsigned int c; unsigned int js_blocks[2]; uint32_t bs_info = 0; // skip the size of the ra unit if present in the frame if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame) skip_bits_long(gb, 32); if (sconf->mc_coding && sconf->joint_stereo) { ctx->js_switch = get_bits1(gb); align_get_bits(gb); } if (!sconf->mc_coding || ctx->js_switch) { int independent_bs = !sconf->joint_stereo; for (c = 0; c < avctx->channels; c++) { js_blocks[0] = 0; js_blocks[1] = 0; get_block_sizes(ctx, div_blocks, &bs_info); // if joint_stereo and block_switching is set, independent decoding // is signaled via the first bit of bs_info if (sconf->joint_stereo && sconf->block_switching) if (bs_info >> 31) independent_bs = 2; // if this is the last channel, it has to be decoded independently if (c == avctx->channels - 1) independent_bs = 1; if (independent_bs) { if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks)) return -1; independent_bs--; } else { if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks)) return -1; c++; } // store carryover raw samples 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); } } else { // multi-channel coding ALSBlockData bd; int b; int *reverted_channels = ctx->reverted_channels; unsigned int offset = 0; for (c = 0; c < avctx->channels; c++) if (ctx->chan_data[c] < ctx->chan_data_buffer) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data!\n"); return -1; } memset(&bd, 0, sizeof(ALSBlockData)); memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels); bd.ra_block = ra_frame; bd.prev_raw_samples = ctx->prev_raw_samples; get_block_sizes(ctx, div_blocks, &bs_info); for (b = 0; b < ctx->num_blocks; b++) { 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]; bd.lpc_cof = ctx->lpc_cof[c]; bd.quant_cof = ctx->quant_cof[c]; bd.raw_samples = ctx->raw_samples[c] + offset; bd.raw_other = NULL; read_block(ctx, &bd); if (read_channel_data(ctx, ctx->chan_data[c], c)) return -1; } for (c = 0; c < avctx->channels; c++) if (revert_channel_correlation(ctx, &bd, ctx->chan_data, reverted_channels, offset, c)) 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]; bd.lpc_cof = ctx->lpc_cof[c]; bd.quant_cof = ctx->quant_cof[c]; bd.raw_samples = ctx->raw_samples[c] + offset; decode_block(ctx, &bd); } memset(reverted_channels, 0, avctx->channels * sizeof(*reverted_channels)); offset += div_blocks[b]; bd.ra_block = 0; } // store carryover raw samples for (c = 0; c < avctx->channels; c++) 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); } // TODO: read_diff_float_data return 0; }