static int decode_frame(FLACContext *s)
{
    int bs_code, sr_code, bps_code, i;
    int ch_mode, bps, blocksize, samplerate;
    GetBitContext *gb = &s->gb;

    /* frame sync code */
    skip_bits(&s->gb, 16);

    /* block size and sample rate codes */
    bs_code = get_bits(gb, 4);
    sr_code = get_bits(gb, 4);

    /* channels and decorrelation */
    ch_mode = get_bits(gb, 4);
    if (ch_mode < FLAC_MAX_CHANNELS && s->channels == ch_mode+1) {
        ch_mode = FLAC_CHMODE_INDEPENDENT;
    } else if (ch_mode > FLAC_CHMODE_MID_SIDE || s->channels != 2) {
        av_log(s->avctx, AV_LOG_ERROR, "unsupported channel assignment %d (channels=%d)\n",
               ch_mode, s->channels);
        return -1;
    }

    /* bits per sample */
    bps_code = get_bits(gb, 3);
    if (bps_code == 0)
        bps= s->bps;
    else if ((bps_code != 3) && (bps_code != 7))
        bps = sample_size_table[bps_code];
    else {
        av_log(s->avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n",
               bps_code);
        return -1;
    }
    if (bps > 16) {
        s->avctx->sample_fmt = SAMPLE_FMT_S32;
        s->sample_shift = 32 - bps;
        s->is32 = 1;
    } else {
        s->avctx->sample_fmt = SAMPLE_FMT_S16;
        s->sample_shift = 16 - bps;
        s->is32 = 0;
    }
    s->bps = s->avctx->bits_per_raw_sample = bps;

    /* reserved bit */
    if (get_bits1(gb)) {
        av_log(s->avctx, AV_LOG_ERROR, "broken stream, invalid padding\n");
        return -1;
    }

    /* sample or frame count */
    if (get_utf8(gb) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n");
        return -1;
    }

    /* blocksize */
    if (bs_code == 0) {
        av_log(s->avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n");
        return -1;
    } else if (bs_code == 6)
        blocksize = get_bits(gb, 8)+1;
    else if (bs_code == 7)
        blocksize = get_bits(gb, 16)+1;
    else
        blocksize = ff_flac_blocksize_table[bs_code];

    if (blocksize > s->max_blocksize) {
        av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", blocksize,
               s->max_blocksize);
        return -1;
    }

    /* sample rate */
    if (sr_code == 0)
        samplerate= s->samplerate;
    else if (sr_code < 12)
        samplerate = ff_flac_sample_rate_table[sr_code];
    else if (sr_code == 12)
        samplerate = get_bits(gb, 8) * 1000;
    else if (sr_code == 13)
        samplerate = get_bits(gb, 16);
    else if (sr_code == 14)
        samplerate = get_bits(gb, 16) * 10;
    else {
        av_log(s->avctx, AV_LOG_ERROR, "illegal sample rate code %d\n",
               sr_code);
        return -1;
    }

    /* header CRC-8 check */
    skip_bits(gb, 8);
    if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,
               get_bits_count(gb)/8)) {
        av_log(s->avctx, AV_LOG_ERROR, "header crc mismatch\n");
        return -1;
    }

    s->blocksize    = blocksize;
    s->samplerate   = samplerate;
    s->bps          = bps;
    s->ch_mode      = ch_mode;

//    dump_headers(s->avctx, (FLACStreaminfo *)s);

    /* subframes */
    for (i = 0; i < s->channels; i++) {
        if (decode_subframe(s, i) < 0)
            return -1;
    }

    align_get_bits(gb);

    /* frame footer */
    skip_bits(gb, 16); /* data crc */

    return 0;
}