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;



    

    als_id                      = get_bits_long(&gb, 32);

    avctx->sample_rate          = m4ac.sample_rate;

    skip_bits_long(&gb, 32); 

    sconf->samples              = get_bits_long(&gb, 32);

    avctx->channels             = m4ac.channels;

    skip_bits(&gb, 16);      

    skip_bits(&gb, 3);       

    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_bits1(&gb);         





    

    if (als_id != MKBETAG('A','L','S','\0'))

        return -1;



    ctx->cur_frame_length = sconf->frame_length;



    

    if (sconf->chan_config)

        sconf->chan_config_info = get_bits(&gb, 16);

    





    

    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;

    }





    

    

    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;





    

    if (get_bits_left(&gb) < ht_size)

        return -1;



    if (ht_size > INT32_MAX)

        return -1;



    skip_bits_long(&gb, ht_size);





    

    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);

    }





    



    dprint_specific_config(ctx);



    return 0;

}
