static av_cold int read_specific_config(ALSDecContext *ctx) { GetBitContext gb; uint64_t ht_size; int i, config_offset; MPEG4AudioConfig m4ac; ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; uint32_t als_id, header_size, trailer_size; init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata, avctx->extradata_size * 8, 1); if (config_offset < 0) return -1; skip_bits_long(&gb, config_offset); if (get_bits_left(&gb) < (30 << 3)) return -1; // read the fixed items als_id = get_bits_long(&gb, 32); avctx->sample_rate = m4ac.sample_rate; skip_bits_long(&gb, 32); // sample rate already known sconf->samples = get_bits_long(&gb, 32); avctx->channels = m4ac.channels; skip_bits(&gb, 16); // number of channels already knwon skip_bits(&gb, 3); // skip file_type sconf->resolution = get_bits(&gb, 3); sconf->floating = get_bits1(&gb); sconf->msb_first = get_bits1(&gb); sconf->frame_length = get_bits(&gb, 16) + 1; sconf->ra_distance = get_bits(&gb, 8); sconf->ra_flag = get_bits(&gb, 2); sconf->adapt_order = get_bits1(&gb); sconf->coef_table = get_bits(&gb, 2); sconf->long_term_prediction = get_bits1(&gb); sconf->max_order = get_bits(&gb, 10); sconf->block_switching = get_bits(&gb, 2); sconf->bgmc = get_bits1(&gb); sconf->sb_part = get_bits1(&gb); sconf->joint_stereo = get_bits1(&gb); sconf->mc_coding = get_bits1(&gb); sconf->chan_config = get_bits1(&gb); sconf->chan_sort = get_bits1(&gb); sconf->crc_enabled = get_bits1(&gb); sconf->rlslms = get_bits1(&gb); skip_bits(&gb, 5); // skip 5 reserved bits skip_bits1(&gb); // skip aux_data_enabled // check for ALSSpecificConfig struct if (als_id != MKBETAG('A','L','S','\0')) return -1; ctx->cur_frame_length = sconf->frame_length; // read channel config if (sconf->chan_config) sconf->chan_config_info = get_bits(&gb, 16); // TODO: use this to set avctx->channel_layout // read channel sorting if (sconf->chan_sort && avctx->channels > 1) { int chan_pos_bits = av_ceil_log2(avctx->channels); int bits_needed = avctx->channels * chan_pos_bits + 7; if (get_bits_left(&gb) < bits_needed) return -1; if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos)))) return AVERROR(ENOMEM); for (i = 0; i < avctx->channels; i++) { sconf->chan_pos[i] = get_bits(&gb, chan_pos_bits); if (sconf->chan_pos[i] >= avctx->channels) { av_log(avctx, AV_LOG_WARNING, "Invalid original channel position.\n"); sconf->chan_sort = 0; break; } } align_get_bits(&gb); } else { sconf->chan_sort = 0; } // read fixed header and trailer sizes, // if size = 0xFFFFFFFF then there is no data field! if (get_bits_left(&gb) < 64) return -1; header_size = get_bits_long(&gb, 32); trailer_size = get_bits_long(&gb, 32); if (header_size == 0xFFFFFFFF) header_size = 0; if (trailer_size == 0xFFFFFFFF) trailer_size = 0; ht_size = ((int64_t)(header_size) + (int64_t)(trailer_size)) << 3; // skip the header and trailer data if (get_bits_left(&gb) < ht_size) return -1; if (ht_size > INT32_MAX) return -1; skip_bits_long(&gb, ht_size); // initialize CRC calculation if (sconf->crc_enabled) { if (get_bits_left(&gb) < 32) return -1; if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); ctx->crc = 0xFFFFFFFF; ctx->crc_org = ~get_bits_long(&gb, 32); } else skip_bits_long(&gb, 32); } // no need to read the rest of ALSSpecificConfig (ra_unit_size & aux data) dprint_specific_config(ctx); return 0; }