static void qdm2_decode_super_block(QDM2Context *q)

{

    GetBitContext gb;

    QDM2SubPacket header, *packet;

    int i, packet_bytes, sub_packet_size, sub_packets_D;

    unsigned int next_index = 0;



    memset(q->tone_level_idx_hi1, 0, sizeof(q->tone_level_idx_hi1));

    memset(q->tone_level_idx_mid, 0, sizeof(q->tone_level_idx_mid));

    memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2));



    q->sub_packets_B = 0;

    sub_packets_D    = 0;



    average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8]



    init_get_bits(&gb, q->compressed_data, q->compressed_size * 8);

    qdm2_decode_sub_packet_header(&gb, &header);



    if (header.type < 2 || header.type >= 8) {

        q->has_errors = 1;

        av_log(NULL, AV_LOG_ERROR, "bad superblock type\n");

        return;

    }



    q->superblocktype_2_3 = (header.type == 2 || header.type == 3);

    packet_bytes          = (q->compressed_size - get_bits_count(&gb) / 8);



    init_get_bits(&gb, header.data, header.size * 8);



    if (header.type == 2 || header.type == 4 || header.type == 5) {

        int csum = 257 * get_bits(&gb, 8);

        csum += 2 * get_bits(&gb, 8);



        csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum);



        if (csum != 0) {

            q->has_errors = 1;

            av_log(NULL, AV_LOG_ERROR, "bad packet checksum\n");

            return;

        }

    }



    q->sub_packet_list_B[0].packet = NULL;

    q->sub_packet_list_D[0].packet = NULL;



    for (i = 0; i < 6; i++)

        if (--q->fft_level_exp[i] < 0)

            q->fft_level_exp[i] = 0;



    for (i = 0; packet_bytes > 0; i++) {

        int j;



        if (i >= FF_ARRAY_ELEMS(q->sub_packet_list_A)) {

            SAMPLES_NEEDED_2("too many packet bytes");

            return;

        }



        q->sub_packet_list_A[i].next = NULL;



        if (i > 0) {

            q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i];



            /* seek to next block */

            init_get_bits(&gb, header.data, header.size * 8);

            skip_bits(&gb, next_index * 8);



            if (next_index >= header.size)

                break;

        }



        /* decode subpacket */

        packet = &q->sub_packets[i];

        qdm2_decode_sub_packet_header(&gb, packet);

        next_index      = packet->size + get_bits_count(&gb) / 8;

        sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2;



        if (packet->type == 0)

            break;



        if (sub_packet_size > packet_bytes) {

            if (packet->type != 10 && packet->type != 11 && packet->type != 12)

                break;

            packet->size += packet_bytes - sub_packet_size;

        }



        packet_bytes -= sub_packet_size;



        /* add subpacket to 'all subpackets' list */

        q->sub_packet_list_A[i].packet = packet;



        /* add subpacket to related list */

        if (packet->type == 8) {

            SAMPLES_NEEDED_2("packet type 8");

            return;

        } else if (packet->type >= 9 && packet->type <= 12) {

            /* packets for MPEG Audio like Synthesis Filter */

            QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet);

        } else if (packet->type == 13) {

            for (j = 0; j < 6; j++)

                q->fft_level_exp[j] = get_bits(&gb, 6);

        } else if (packet->type == 14) {

            for (j = 0; j < 6; j++)

                q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2);

        } else if (packet->type == 15) {

            SAMPLES_NEEDED_2("packet type 15")

            return;

        } else if (packet->type >= 16 && packet->type < 48 &&

                   !fft_subpackets[packet->type - 16]) {

            /* packets for FFT */

            QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet);

        }

    } // Packet bytes loop



    if (q->sub_packet_list_D[0].packet != NULL) {

        process_synthesis_subpackets(q, q->sub_packet_list_D);

        q->do_synth_filter = 1;

    } else if (q->do_synth_filter) {

        process_subpacket_10(q, NULL);

        process_subpacket_11(q, NULL);

        process_subpacket_12(q, NULL);

    }

}
