static int decode_subframe(WMAProDecodeCtx *s)
{
    int offset = s->samples_per_frame;
    int subframe_len = s->samples_per_frame;
    int i;
    int total_samples   = s->samples_per_frame * s->num_channels;
    int transmit_coeffs = 0;
    int cur_subwoofer_cutoff;
    s->subframe_offset = get_bits_count(&s->gb);
    for (i = 0; i < s->num_channels; i++) {
        s->channel[i].grouped = 0;
        if (offset > s->channel[i].decoded_samples) {
            offset = s->channel[i].decoded_samples;
            subframe_len =
                s->channel[i].subframe_len[s->channel[i].cur_subframe];
        }
    }
    av_dlog(s->avctx,
            "processing subframe with offset %i len %i\n", offset, subframe_len);
    s->channels_for_cur_subframe = 0;
    for (i = 0; i < s->num_channels; i++) {
        const int cur_subframe = s->channel[i].cur_subframe;
        total_samples -= s->channel[i].decoded_samples;
        if (offset == s->channel[i].decoded_samples &&
            subframe_len == s->channel[i].subframe_len[cur_subframe]) {
            total_samples -= s->channel[i].subframe_len[cur_subframe];
            s->channel[i].decoded_samples +=
                s->channel[i].subframe_len[cur_subframe];
            s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i;
            ++s->channels_for_cur_subframe;
        }
    }
    if (!total_samples)
        s->parsed_all_subframes = 1;
    av_dlog(s->avctx, "subframe is part of %i channels\n",
            s->channels_for_cur_subframe);
    s->table_idx         = av_log2(s->samples_per_frame/subframe_len);
    s->num_bands         = s->num_sfb[s->table_idx];
    s->cur_sfb_offsets   = s->sfb_offsets[s->table_idx];
    cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx];
    for (i = 0; i < s->channels_for_cur_subframe; i++) {
        int c = s->channel_indexes_for_cur_subframe[i];
        s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1)
                                                  + offset];
    }
    s->subframe_len = subframe_len;
    s->esc_len = av_log2(s->subframe_len - 1) + 1;
    if (get_bits1(&s->gb)) {
        int num_fill_bits;
        if (!(num_fill_bits = get_bits(&s->gb, 2))) {
            int len = get_bits(&s->gb, 4);
            num_fill_bits = get_bits(&s->gb, len) + 1;
        }
        if (num_fill_bits >= 0) {
            if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) {
                av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\n");
                return AVERROR_INVALIDDATA;
            }
            skip_bits_long(&s->gb, num_fill_bits);
        }
    }
    if (get_bits1(&s->gb)) {
        av_log_ask_for_sample(s->avctx, "reserved bit set\n");
        return AVERROR_INVALIDDATA;
    }
    if (decode_channel_transform(s) < 0)
        return AVERROR_INVALIDDATA;
    for (i = 0; i < s->channels_for_cur_subframe; i++) {
        int c = s->channel_indexes_for_cur_subframe[i];
        if ((s->channel[c].transmit_coefs = get_bits1(&s->gb)))
            transmit_coeffs = 1;
    }
    if (transmit_coeffs) {
        int step;
        int quant_step = 90 * s->bits_per_sample >> 4;
        if ((s->transmit_num_vec_coeffs = get_bits1(&s->gb))) {
            int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
            for (i = 0; i < s->channels_for_cur_subframe; i++) {
                int c = s->channel_indexes_for_cur_subframe[i];
                s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
            }
        } else {
            for (i = 0; i < s->channels_for_cur_subframe; i++) {
                int c = s->channel_indexes_for_cur_subframe[i];
                s->channel[c].num_vec_coeffs = s->subframe_len;
            }
        }
        step = get_sbits(&s->gb, 6);
        quant_step += step;
        if (step == -32 || step == 31) {
            const int sign = (step == 31) - 1;
            int quant = 0;
            while (get_bits_count(&s->gb) + 5 < s->num_saved_bits &&
                   (step = get_bits(&s->gb, 5)) == 31) {
                quant += 31;
            }
            quant_step += ((quant + step) ^ sign) - sign;
        }
        if (quant_step < 0) {
            av_log(s->avctx, AV_LOG_DEBUG, "negative quant step\n");
        }
        if (s->channels_for_cur_subframe == 1) {
            s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step;
        } else {
            int modifier_len = get_bits(&s->gb, 3);
            for (i = 0; i < s->channels_for_cur_subframe; i++) {
                int c = s->channel_indexes_for_cur_subframe[i];
                s->channel[c].quant_step = quant_step;
                if (get_bits1(&s->gb)) {
                    if (modifier_len) {
                        s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1;
                    } else
                        ++s->channel[c].quant_step;
                }
            }
        }
        if (decode_scale_factors(s) < 0)
            return AVERROR_INVALIDDATA;
    }
    av_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n",
            get_bits_count(&s->gb) - s->subframe_offset);
    for (i = 0; i < s->channels_for_cur_subframe; i++) {
        int c = s->channel_indexes_for_cur_subframe[i];
        if (s->channel[c].transmit_coefs &&
            get_bits_count(&s->gb) < s->num_saved_bits) {
            decode_coeffs(s, c);
        } else
            memset(s->channel[c].coeffs, 0,
                   sizeof(*s->channel[c].coeffs) * subframe_len);
    }
    av_dlog(s->avctx, "BITSTREAM: subframe length was %i\n",
            get_bits_count(&s->gb) - s->subframe_offset);
    if (transmit_coeffs) {
        FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS];
        inverse_channel_transform(s);
        for (i = 0; i < s->channels_for_cur_subframe; i++) {
            int c = s->channel_indexes_for_cur_subframe[i];
            const int* sf = s->channel[c].scale_factors;
            int b;
            if (c == s->lfe_channel)
                memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) *
                       (subframe_len - cur_subwoofer_cutoff));
            for (b = 0; b < s->num_bands; b++) {
                const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);
                const int exp = s->channel[c].quant_step -
                            (s->channel[c].max_scale_factor - *sf++) *
                            s->channel[c].scale_factor_step;
                const float quant = pow(10.0, exp / 20.0);
                int start = s->cur_sfb_offsets[b];
                s->dsp.vector_fmul_scalar(s->tmp + start,
                                          s->channel[c].coeffs + start,
                                          quant, end - start);
            }
            mdct->imdct_half(mdct, s->channel[c].coeffs, s->tmp);
        }
    }
    wmapro_window(s);
    for (i = 0; i < s->channels_for_cur_subframe; i++) {
        int c = s->channel_indexes_for_cur_subframe[i];
        if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) {
            av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n");
            return AVERROR_INVALIDDATA;
        }
        ++s->channel[c].cur_subframe;
    }
    return 0;
}
['static int decode_subframe(WMAProDecodeCtx *s)\n{\n    int offset = s->samples_per_frame;\n    int subframe_len = s->samples_per_frame;\n    int i;\n    int total_samples   = s->samples_per_frame * s->num_channels;\n    int transmit_coeffs = 0;\n    int cur_subwoofer_cutoff;\n    s->subframe_offset = get_bits_count(&s->gb);\n    for (i = 0; i < s->num_channels; i++) {\n        s->channel[i].grouped = 0;\n        if (offset > s->channel[i].decoded_samples) {\n            offset = s->channel[i].decoded_samples;\n            subframe_len =\n                s->channel[i].subframe_len[s->channel[i].cur_subframe];\n        }\n    }\n    av_dlog(s->avctx,\n            "processing subframe with offset %i len %i\\n", offset, subframe_len);\n    s->channels_for_cur_subframe = 0;\n    for (i = 0; i < s->num_channels; i++) {\n        const int cur_subframe = s->channel[i].cur_subframe;\n        total_samples -= s->channel[i].decoded_samples;\n        if (offset == s->channel[i].decoded_samples &&\n            subframe_len == s->channel[i].subframe_len[cur_subframe]) {\n            total_samples -= s->channel[i].subframe_len[cur_subframe];\n            s->channel[i].decoded_samples +=\n                s->channel[i].subframe_len[cur_subframe];\n            s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i;\n            ++s->channels_for_cur_subframe;\n        }\n    }\n    if (!total_samples)\n        s->parsed_all_subframes = 1;\n    av_dlog(s->avctx, "subframe is part of %i channels\\n",\n            s->channels_for_cur_subframe);\n    s->table_idx         = av_log2(s->samples_per_frame/subframe_len);\n    s->num_bands         = s->num_sfb[s->table_idx];\n    s->cur_sfb_offsets   = s->sfb_offsets[s->table_idx];\n    cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx];\n    for (i = 0; i < s->channels_for_cur_subframe; i++) {\n        int c = s->channel_indexes_for_cur_subframe[i];\n        s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1)\n                                                  + offset];\n    }\n    s->subframe_len = subframe_len;\n    s->esc_len = av_log2(s->subframe_len - 1) + 1;\n    if (get_bits1(&s->gb)) {\n        int num_fill_bits;\n        if (!(num_fill_bits = get_bits(&s->gb, 2))) {\n            int len = get_bits(&s->gb, 4);\n            num_fill_bits = get_bits(&s->gb, len) + 1;\n        }\n        if (num_fill_bits >= 0) {\n            if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) {\n                av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\\n");\n                return AVERROR_INVALIDDATA;\n            }\n            skip_bits_long(&s->gb, num_fill_bits);\n        }\n    }\n    if (get_bits1(&s->gb)) {\n        av_log_ask_for_sample(s->avctx, "reserved bit set\\n");\n        return AVERROR_INVALIDDATA;\n    }\n    if (decode_channel_transform(s) < 0)\n        return AVERROR_INVALIDDATA;\n    for (i = 0; i < s->channels_for_cur_subframe; i++) {\n        int c = s->channel_indexes_for_cur_subframe[i];\n        if ((s->channel[c].transmit_coefs = get_bits1(&s->gb)))\n            transmit_coeffs = 1;\n    }\n    if (transmit_coeffs) {\n        int step;\n        int quant_step = 90 * s->bits_per_sample >> 4;\n        if ((s->transmit_num_vec_coeffs = get_bits1(&s->gb))) {\n            int num_bits = av_log2((s->subframe_len + 3)/4) + 1;\n            for (i = 0; i < s->channels_for_cur_subframe; i++) {\n                int c = s->channel_indexes_for_cur_subframe[i];\n                s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;\n            }\n        } else {\n            for (i = 0; i < s->channels_for_cur_subframe; i++) {\n                int c = s->channel_indexes_for_cur_subframe[i];\n                s->channel[c].num_vec_coeffs = s->subframe_len;\n            }\n        }\n        step = get_sbits(&s->gb, 6);\n        quant_step += step;\n        if (step == -32 || step == 31) {\n            const int sign = (step == 31) - 1;\n            int quant = 0;\n            while (get_bits_count(&s->gb) + 5 < s->num_saved_bits &&\n                   (step = get_bits(&s->gb, 5)) == 31) {\n                quant += 31;\n            }\n            quant_step += ((quant + step) ^ sign) - sign;\n        }\n        if (quant_step < 0) {\n            av_log(s->avctx, AV_LOG_DEBUG, "negative quant step\\n");\n        }\n        if (s->channels_for_cur_subframe == 1) {\n            s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step;\n        } else {\n            int modifier_len = get_bits(&s->gb, 3);\n            for (i = 0; i < s->channels_for_cur_subframe; i++) {\n                int c = s->channel_indexes_for_cur_subframe[i];\n                s->channel[c].quant_step = quant_step;\n                if (get_bits1(&s->gb)) {\n                    if (modifier_len) {\n                        s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1;\n                    } else\n                        ++s->channel[c].quant_step;\n                }\n            }\n        }\n        if (decode_scale_factors(s) < 0)\n            return AVERROR_INVALIDDATA;\n    }\n    av_dlog(s->avctx, "BITSTREAM: subframe header length was %i\\n",\n            get_bits_count(&s->gb) - s->subframe_offset);\n    for (i = 0; i < s->channels_for_cur_subframe; i++) {\n        int c = s->channel_indexes_for_cur_subframe[i];\n        if (s->channel[c].transmit_coefs &&\n            get_bits_count(&s->gb) < s->num_saved_bits) {\n            decode_coeffs(s, c);\n        } else\n            memset(s->channel[c].coeffs, 0,\n                   sizeof(*s->channel[c].coeffs) * subframe_len);\n    }\n    av_dlog(s->avctx, "BITSTREAM: subframe length was %i\\n",\n            get_bits_count(&s->gb) - s->subframe_offset);\n    if (transmit_coeffs) {\n        FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS];\n        inverse_channel_transform(s);\n        for (i = 0; i < s->channels_for_cur_subframe; i++) {\n            int c = s->channel_indexes_for_cur_subframe[i];\n            const int* sf = s->channel[c].scale_factors;\n            int b;\n            if (c == s->lfe_channel)\n                memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) *\n                       (subframe_len - cur_subwoofer_cutoff));\n            for (b = 0; b < s->num_bands; b++) {\n                const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);\n                const int exp = s->channel[c].quant_step -\n                            (s->channel[c].max_scale_factor - *sf++) *\n                            s->channel[c].scale_factor_step;\n                const float quant = pow(10.0, exp / 20.0);\n                int start = s->cur_sfb_offsets[b];\n                s->dsp.vector_fmul_scalar(s->tmp + start,\n                                          s->channel[c].coeffs + start,\n                                          quant, end - start);\n            }\n            mdct->imdct_half(mdct, s->channel[c].coeffs, s->tmp);\n        }\n    }\n    wmapro_window(s);\n    for (i = 0; i < s->channels_for_cur_subframe; i++) {\n        int c = s->channel_indexes_for_cur_subframe[i];\n        if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) {\n            av_log(s->avctx, AV_LOG_ERROR, "broken subframe\\n");\n            return AVERROR_INVALIDDATA;\n        }\n        ++s->channel[c].cur_subframe;\n    }\n    return 0;\n}', 'static av_always_inline av_const int av_log2_c(unsigned int v)\n{\n    int n = 0;\n    if (v & 0xffff0000) {\n        v >>= 16;\n        n += 16;\n    }\n    if (v & 0xff00) {\n        v >>= 8;\n        n += 8;\n    }\n    n += ff_log2_tab[v];\n    return n;\n}']