Skip to content
Snippets Groups Projects
vc1.c 148 KiB
Newer Older
  • Learn to ignore specific revisions
  • anonymous's avatar
    anonymous committed
        return 0;
    }
    
    /** Decode intra block in inter frames - more generic version than vc1_decode_i_block
     * @param v VC1Context
     * @param block block to decode
     * @param coded are AC coeffs present or not
     * @param mquant block quantizer
     * @param codingset set of VLC to decode data
    
    static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant, int codingset)
    
        int dc_pred_dir = 0; /* Direction of the DC prediction used */
        int run_diff, i;
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        int16_t *dc_val;
    
        int16_t *ac_val, *ac_val2;
        int dcdiff;
        int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
        int a_avail = v->a_avail, c_avail = v->c_avail;
        int use_pred = s->ac_pred;
        int scale;
        int q1, q2 = 0;
    
        /* XXX: Guard against dumb values of mquant */
        mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );
    
        /* Set DC scale - y and c use the same */
        s->y_dc_scale = s->y_dc_scale_table[mquant];
        s->c_dc_scale = s->c_dc_scale_table[mquant];
    
        /* Get DC differential */
        if (n < 4) {
            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
        } else {
            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
        }
        if (dcdiff < 0){
            av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
            return -1;
        }
        if (dcdiff)
        {
            if (dcdiff == 119 /* ESC index value */)
            {
                /* TODO: Optimize */
                if (mquant == 1) dcdiff = get_bits(gb, 10);
                else if (mquant == 2) dcdiff = get_bits(gb, 9);
                else dcdiff = get_bits(gb, 8);
            }
            else
            {
                if (mquant == 1)
                    dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
                else if (mquant == 2)
                    dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
            }
            if (get_bits(gb, 1))
                dcdiff = -dcdiff;
        }
    
        /* Prediction */
        dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
        *dc_val = dcdiff;
    
        /* Store the quantized DC coeff, used for prediction */
    
        if (n < 4) {
            block[0] = dcdiff * s->y_dc_scale;
        } else {
            block[0] = dcdiff * s->c_dc_scale;
        }
        /* Skip ? */
        run_diff = 0;
        i = 0;
    
        //AC Decoding
        i = 1;
    
        /* check if AC is needed at all and adjust direction if needed */
        if(!a_avail) dc_pred_dir = 1;
        if(!c_avail) dc_pred_dir = 0;
        if(!a_avail && !c_avail) use_pred = 0;
        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
        ac_val2 = ac_val;
    
        scale = mquant * 2 + v->halfpq;
    
        if(dc_pred_dir) //left
            ac_val -= 16;
        else //top
            ac_val -= 16 * s->block_wrap[n];
    
        q1 = s->current_picture.qscale_table[mb_pos];
    
        if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
        if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
    
        if(n && n<4) q2 = q1;
    
        if(coded) {
            int last = 0, skip, value;
            const int8_t *zz_table;
            int k;
    
            zz_table = vc1_simple_progressive_8x8_zz;
    
            while (!last) {
                vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
                i += skip;
                if(i > 63)
                    break;
                block[zz_table[i++]] = value;
            }
    
            /* apply AC prediction if needed */
            if(use_pred) {
                /* scale predictors if needed*/
                if(q2 && q1!=q2) {
    
                    q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                    q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
    
    
                    if(dc_pred_dir) { //left
                        for(k = 1; k < 8; k++)
                            block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                    } else { //top
                        for(k = 1; k < 8; k++)
                            block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                    }
                } else {
                    if(dc_pred_dir) { //left
                        for(k = 1; k < 8; k++)
                            block[k << 3] += ac_val[k];
                    } else { //top
                        for(k = 1; k < 8; k++)
                            block[k] += ac_val[k + 8];
                    }
                }
            }
            /* save AC coeffs for further prediction */
            for(k = 1; k < 8; k++) {
                ac_val2[k] = block[k << 3];
                ac_val2[k + 8] = block[k];
            }
    
            /* scale AC coeffs */
            for(k = 1; k < 64; k++)
                if(block[k]) {
                    block[k] *= scale;
                    if(!v->pquantizer)
                        block[k] += (block[k] < 0) ? -mquant : mquant;
                }
    
            if(use_pred) i = 63;
        } else { // no AC coeffs
            int k;
    
            memset(ac_val2, 0, 16 * 2);
            if(dc_pred_dir) {//left
                if(use_pred) {
                    memcpy(ac_val2, ac_val, 8 * 2);
                    if(q2 && q1!=q2) {
    
                        q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                        q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
    
                        for(k = 1; k < 8; k++)
                            ac_val2[k] = (ac_val2[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                    }
                }
            } else {//top
                if(use_pred) {
                    memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
                    if(q2 && q1!=q2) {
    
                        q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
                        q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
    
                        for(k = 1; k < 8; k++)
                            ac_val2[k + 8] = (ac_val2[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
                    }
                }
            }
    
            /* apply AC prediction if needed */
            if(use_pred) {
                if(dc_pred_dir) { //left
                    for(k = 1; k < 8; k++) {
                        block[k << 3] = ac_val2[k] * scale;
                        if(!v->pquantizer && block[k << 3])
                            block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant;
                    }
                } else { //top
                    for(k = 1; k < 8; k++) {
                        block[k] = ac_val2[k + 8] * scale;
                        if(!v->pquantizer && block[k])
                            block[k] += (block[k] < 0) ? -mquant : mquant;
                    }
                }
                i = 63;
            }
        }
        s->block_last_index[n] = i;
    
        return 0;
    }
    
    /** Decode P block
     */
    static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block)
    {
        MpegEncContext *s = &v->s;
        GetBitContext *gb = &s->gb;
        int i, j;
        int subblkpat = 0;
        int scale, off, idx, last, skip, value;
        int ttblk = ttmb & 7;
    
        if(ttmb == -1) {
            ttblk = ttblk_to_tt[v->tt_index][get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
        }
        if(ttblk == TT_4X4) {
            subblkpat = ~(get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
        }
        if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) {
            subblkpat = decode012(gb);
            if(subblkpat) subblkpat ^= 3; //swap decoded pattern bits
            if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;
            if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;
        }
        scale = 2 * mquant + v->halfpq;
    
        // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
    
        if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
            subblkpat = 2 - (ttblk == TT_8X4_TOP);
    
        }
        if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
            subblkpat = 2 - (ttblk == TT_4X8_LEFT);
    
        }
        switch(ttblk) {
        case TT_8X8:
            i = 0;
            last = 0;
            while (!last) {
                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                i += skip;
                if(i > 63)
                    break;
                idx = vc1_simple_progressive_8x8_zz[i++];
                block[idx] = value * scale;
    
                if(!v->pquantizer)
                    block[idx] += (block[idx] < 0) ? -mquant : mquant;
    
            s->dsp.vc1_inv_trans_8x8(block);
    
            break;
        case TT_4X4:
            for(j = 0; j < 4; j++) {
                last = subblkpat & (1 << (3 - j));
                i = 0;
    
                off = (j & 1) * 4 + (j & 2) * 16;
    
                while (!last) {
                    vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                    i += skip;
                    if(i > 15)
                        break;
                    idx = vc1_simple_progressive_4x4_zz[i++];
                    block[idx + off] = value * scale;
    
                    if(!v->pquantizer)
                        block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
    
                if(!(subblkpat & (1 << (3 - j))))
    
                    s->dsp.vc1_inv_trans_4x4(block, j);
    
            }
            break;
        case TT_8X4:
            for(j = 0; j < 2; j++) {
                last = subblkpat & (1 << (1 - j));
                i = 0;
                off = j * 32;
                while (!last) {
                    vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                    i += skip;
                    if(i > 31)
                        break;
    
                    if(v->profile < PROFILE_ADVANCED)
                        idx = vc1_simple_progressive_8x4_zz[i++];
                    else
                        idx = vc1_adv_progressive_8x4_zz[i++];
    
                    block[idx + off] = value * scale;
    
                    if(!v->pquantizer)
                        block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
    
                if(!(subblkpat & (1 << (1 - j))))
    
                    s->dsp.vc1_inv_trans_8x4(block, j);
    
            }
            break;
        case TT_4X8:
            for(j = 0; j < 2; j++) {
                last = subblkpat & (1 << (1 - j));
                i = 0;
                off = j * 4;
                while (!last) {
                    vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                    i += skip;
                    if(i > 31)
                        break;
    
                    if(v->profile < PROFILE_ADVANCED)
                        idx = vc1_simple_progressive_4x8_zz[i++];
                    else
                        idx = vc1_adv_progressive_4x8_zz[i++];
    
                    block[idx + off] = value * scale;
    
                    if(!v->pquantizer)
                        block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
    
                if(!(subblkpat & (1 << (1 - j))))
    
                    s->dsp.vc1_inv_trans_4x8(block, j);
    
    /** Decode one P-frame MB (in Simple/Main profile)
     */
    
    static int vc1_decode_p_mb(VC1Context *v)
    
    {
        MpegEncContext *s = &v->s;
        GetBitContext *gb = &s->gb;
    
        int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    
        int cbp; /* cbp decoding stuff */
        int mqdiff, mquant; /* MB quantization */
    
        int ttmb = v->ttfrm; /* MB Transform type */
    
        int status;
    
        static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
          offset_table[6] = { 0, 1, 3, 7, 15, 31 };
        int mb_has_coeffs = 1; /* last_flag */
        int dmv_x, dmv_y; /* Differential MV components */
        int index, index1; /* LUT indices */
        int val, sign; /* temp values */
    
        int first_block = 1;
        int dst_idx, off;
    
        mquant = v->pq; /* Loosy initialization */
    
    
        if (v->mv_type_is_raw)
            fourmv = get_bits1(gb);
        else
            fourmv = v->mv_type_mb_plane[mb_pos];
        if (v->skip_is_raw)
            skipped = get_bits1(gb);
        else
    
            skipped = v->s.mbskip_table[mb_pos];
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
        s->dsp.clear_blocks(s->block[0]);
    
    
                if (s->mb_intra) {
                    s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
                    s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
                }
    
                s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                vc1_pred_mv(s, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
    
                /* FIXME Set DC val for inter block ? */
    
                if (s->mb_intra && !mb_has_coeffs)
                {
                    GET_MQUANT();
                    s->ac_pred = get_bits(gb, 1);
    
                }
                else if (mb_has_coeffs)
                {
                    if (s->mb_intra) s->ac_pred = get_bits(gb, 1);
    
                    cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
    
                s->current_picture.qscale_table[mb_pos] = mquant;
    
                if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
    
                    ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
    
                    s->dc_val[0][s->block_index[i]] = 0;
                    dst_idx += i >> 2;
    
                    off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                    v->mb_type[0][s->block_index[i]] = s->mb_intra;
    
                        /* check if prediction blocks A and C are available */
                        v->a_avail = v->c_avail = 0;
    
                        if(i == 2 || i == 3 || !s->first_slice_line)
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                            v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
                        if(i == 1 || i == 3 || s->mb_x)
                            v->c_avail = v->mb_type[0][s->block_index[i] - 1];
    
                        vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
    
                        if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
    
                        s->dsp.vc1_inv_trans_8x8(s->block[i]);
    
                        if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
    
                        for(j = 0; j < 64; j++) s->block[i][j] += 128;
                        s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
    
                        if(v->pq >= 9 && v->overlap) {
                            if(v->c_avail)
    
                                s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
    
                                s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
    
                        vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
    
                        if(!v->ttmbf && ttmb < 8) ttmb = -1;
                        first_block = 0;
    
                        if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
                            s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
    
                for(i = 0; i < 6; i++) {
                    v->mb_type[0][s->block_index[i]] = 0;
                    s->dc_val[0][s->block_index[i]] = 0;
                }
    
                s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                s->current_picture.qscale_table[mb_pos] = 0;
                vc1_pred_mv(s, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
    
            if (!skipped /* unskipped MB */)
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                int intra_count = 0, coded_inter = 0;
                int is_intra[6], is_coded[6];
    
                cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                for (i=0; i<6; i++)
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                    s->dc_val[0][s->block_index[i]] = 0;
                    s->mb_intra = 0;
                    if(i < 4) {
                        dmv_x = dmv_y = 0;
                        s->mb_intra = 0;
                        mb_has_coeffs = 0;
                        if(val) {
                            GET_MVDATA(dmv_x, dmv_y);
                        }
                        vc1_pred_mv(s, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
                        if(!s->mb_intra) vc1_mc_4mv_luma(v, i);
                        intra_count += s->mb_intra;
                        is_intra[i] = s->mb_intra;
                        is_coded[i] = mb_has_coeffs;
                    }
                    if(i&4){
                        is_intra[i] = (intra_count >= 3);
                        is_coded[i] = val;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                    if(i == 4) vc1_mc_4mv_chroma(v);
                    v->mb_type[0][s->block_index[i]] = is_intra[i];
                    if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i];
    
                // if there are no coded blocks then don't do anything more
    
                if(!intra_count && !coded_inter) return 0;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                dst_idx = 0;
                GET_MQUANT();
                s->current_picture.qscale_table[mb_pos] = mquant;
                /* test if block is intra and has pred */
                {
                    int intrapred = 0;
                    for(i=0; i<6; i++)
                        if(is_intra[i]) {
    
                            if(((!s->first_slice_line || (i==2 || i==3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
                                || ((s->mb_x || (i==1 || i==3)) && v->mb_type[0][s->block_index[i] - 1])) {
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                                intrapred = 1;
                                break;
                            }
                        }
                    if(intrapred)s->ac_pred = get_bits(gb, 1);
                    else s->ac_pred = 0;
                }
                if (!v->ttmbf && coded_inter)
    
                    ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                for (i=0; i<6; i++)
                {
                    dst_idx += i >> 2;
                    off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
                    s->mb_intra = is_intra[i];
                    if (is_intra[i]) {
                        /* check if prediction blocks A and C are available */
                        v->a_avail = v->c_avail = 0;
    
                        if(i == 2 || i == 3 || !s->first_slice_line)
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                            v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
                        if(i == 1 || i == 3 || s->mb_x)
                            v->c_avail = v->mb_type[0][s->block_index[i] - 1];
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant, (i&4)?v->codingset2:v->codingset);
    
                        if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
    
                        s->dsp.vc1_inv_trans_8x8(s->block[i]);
    
                        if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
    
                        for(j = 0; j < 64; j++) s->block[i][j] += 128;
    
                        s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        if(v->pq >= 9 && v->overlap) {
                            if(v->c_avail)
    
                                s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
    
                                s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                    } else if(is_coded[i]) {
                        status = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
                        if(!v->ttmbf && ttmb < 8) ttmb = -1;
                        first_block = 0;
    
                        if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
                            s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
    
                s->current_picture.qscale_table[mb_pos] = 0;
    
                for (i=0; i<6; i++) {
                    v->mb_type[0][s->block_index[i]] = 0;
                    s->dc_val[0][s->block_index[i]] = 0;
                }
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                    vc1_pred_mv(s, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]);
                    vc1_mc_4mv_luma(v, i);
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                vc1_mc_4mv_chroma(v);
                s->current_picture.qscale_table[mb_pos] = 0;
    
    /** Decode one B-frame MB (in Main profile)
     */
    static void vc1_decode_b_mb(VC1Context *v)
    {
        MpegEncContext *s = &v->s;
        GetBitContext *gb = &s->gb;
        int i, j;
        int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    
        int cbp = 0; /* cbp decoding stuff */
    
        int mqdiff, mquant; /* MB quantization */
        int ttmb = v->ttfrm; /* MB Transform type */
    
        static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
          offset_table[6] = { 0, 1, 3, 7, 15, 31 };
        int mb_has_coeffs = 0; /* last_flag */
        int index, index1; /* LUT indices */
        int val, sign; /* temp values */
        int first_block = 1;
        int dst_idx, off;
        int skipped, direct;
        int dmv_x[2], dmv_y[2];
    
        int bmvtype = BMV_TYPE_BACKWARD;
    
    
        mquant = v->pq; /* Loosy initialization */
        s->mb_intra = 0;
    
        if (v->dmb_is_raw)
            direct = get_bits1(gb);
        else
            direct = v->direct_mb_plane[mb_pos];
        if (v->skip_is_raw)
            skipped = get_bits1(gb);
        else
            skipped = v->s.mbskip_table[mb_pos];
    
        s->dsp.clear_blocks(s->block[0]);
        dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
        for(i = 0; i < 6; i++) {
            v->mb_type[0][s->block_index[i]] = 0;
            s->dc_val[0][s->block_index[i]] = 0;
        }
        s->current_picture.qscale_table[mb_pos] = 0;
    
        if (!direct) {
            if (!skipped) {
                GET_MVDATA(dmv_x[0], dmv_y[0]);
    
            }
            if(skipped || !s->mb_intra) {
                bmvtype = decode012(gb);
                switch(bmvtype) {
                case 0:
                    bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
                    break;
                case 1:
                    bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
                    break;
                case 2:
                    bmvtype = BMV_TYPE_INTERPOLATED;
    
        for(i = 0; i < 6; i++)
            v->mb_type[0][s->block_index[i]] = s->mb_intra;
    
    
            if(direct) bmvtype = BMV_TYPE_INTERPOLATED;
            vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
    
            vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
            return;
        }
        if (direct) {
            cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
            GET_MQUANT();
    
            s->current_picture.qscale_table[mb_pos] = mquant;
    
                ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
    
            dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
            vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
    
            vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
        } else {
            if(!mb_has_coeffs && !s->mb_intra) {
                /* no coded blocks - effectively skipped */
    
                vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
    
                vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
                return;
            }
            if(s->mb_intra && !mb_has_coeffs) {
                GET_MQUANT();
                s->current_picture.qscale_table[mb_pos] = mquant;
                s->ac_pred = get_bits1(gb);
                cbp = 0;
    
                vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
    
            } else {
                if(bmvtype == BMV_TYPE_INTERPOLATED) {
    
                    if(!mb_has_coeffs) {
                        /* interpolated skipped block */
    
                        vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
    
                vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
                if(!s->mb_intra) {
    
                    vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
    
                if(s->mb_intra)
                    s->ac_pred = get_bits1(gb);
                cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
                GET_MQUANT();
                s->current_picture.qscale_table[mb_pos] = mquant;
                if(!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                    ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
            }
        }
        dst_idx = 0;
        for (i=0; i<6; i++)
        {
            s->dc_val[0][s->block_index[i]] = 0;
            dst_idx += i >> 2;
            val = ((cbp >> (5 - i)) & 1);
            off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
            v->mb_type[0][s->block_index[i]] = s->mb_intra;
            if(s->mb_intra) {
                /* check if prediction blocks A and C are available */
                v->a_avail = v->c_avail = 0;
                if(i == 2 || i == 3 || !s->first_slice_line)
                    v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
                if(i == 1 || i == 3 || s->mb_x)
                    v->c_avail = v->mb_type[0][s->block_index[i] - 1];
    
                vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
    
                if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
    
                s->dsp.vc1_inv_trans_8x8(s->block[i]);
    
                if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
    
                for(j = 0; j < 64; j++) s->block[i][j] += 128;
                s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
            } else if(val) {
                vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block);
                if(!v->ttmbf && ttmb < 8) ttmb = -1;
                first_block = 0;
    
                if((i<4) || !(s->flags & CODEC_FLAG_GRAY))
                    s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
    
    static void vc1_decode_i_blocks(VC1Context *v)
    
        int cbp, val;
        uint8_t *coded_val;
        int mb_pos;
    
        /* select codingmode used for VLC tables selection */
        switch(v->y_ac_table_index){
        case 0:
            v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
            break;
        case 1:
            v->codingset = CS_HIGH_MOT_INTRA;
            break;
        case 2:
            v->codingset = CS_MID_RATE_INTRA;
            break;
        }
    
        switch(v->c_ac_table_index){
        case 0:
            v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
            break;
        case 1:
            v->codingset2 = CS_HIGH_MOT_INTER;
            break;
        case 2:
            v->codingset2 = CS_MID_RATE_INTER;
            break;
        }
    
        /* Set DC scale - y and c use the same */
        s->y_dc_scale = s->y_dc_scale_table[v->pq];
        s->c_dc_scale = s->c_dc_scale_table[v->pq];
    
        //do frame decode
        s->mb_x = s->mb_y = 0;
        s->mb_intra = 1;
    
        s->first_slice_line = 1;
    
        ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
        for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
            for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
                ff_init_block_index(s);
                ff_update_block_index(s);
                s->dsp.clear_blocks(s->block[0]);
                mb_pos = s->mb_x + s->mb_y * s->mb_width;
                s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
                s->current_picture.qscale_table[mb_pos] = v->pq;
    
                s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
                s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
    
    
                // do actual MB decoding and displaying
                cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
                v->s.ac_pred = get_bits(&v->s.gb, 1);
    
                for(k = 0; k < 6; k++) {
                    val = ((cbp >> (5 - k)) & 1);
    
                    if (k < 4) {
                        int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
                        val = val ^ pred;
                        *coded_val = val;
                    }
                    cbp |= val << (5 - k);
    
                    vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
    
    
                    s->dsp.vc1_inv_trans_8x8(s->block[k]);
    
                        for(j = 0; j < 64; j++) s->block[k][j] += 128;
    
                if(v->pq >= 9 && v->overlap) {
    
                        s->dsp.vc1_h_overlap(s->dest[0], s->linesize);
                        s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
    
                        if(!(s->flags & CODEC_FLAG_GRAY)) {
    
                            s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
                            s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
    
                    s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
                    s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
    
                    if(!s->first_slice_line) {
    
                        s->dsp.vc1_v_overlap(s->dest[0], s->linesize);
                        s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
    
                        if(!(s->flags & CODEC_FLAG_GRAY)) {
    
                            s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
                            s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
    
                    s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
                    s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
    
                if(get_bits_count(&s->gb) > v->bits) {
                    av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
                    return;
                }
            }
            ff_draw_horiz_band(s, s->mb_y * 16, 16);
    
            s->first_slice_line = 0;
    
    /** Decode blocks of I-frame for advanced profile
     */
    static void vc1_decode_i_blocks_adv(VC1Context *v)
    {
        int k, j;
        MpegEncContext *s = &v->s;
        int cbp, val;
        uint8_t *coded_val;
        int mb_pos;
        int mquant = v->pq;
        int mqdiff;
        int overlap;
        GetBitContext *gb = &s->gb;
    
        /* select codingmode used for VLC tables selection */
        switch(v->y_ac_table_index){
        case 0:
            v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
            break;
        case 1:
            v->codingset = CS_HIGH_MOT_INTRA;
            break;
        case 2:
            v->codingset = CS_MID_RATE_INTRA;
            break;
        }
    
        switch(v->c_ac_table_index){
        case 0:
            v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
            break;
        case 1:
            v->codingset2 = CS_HIGH_MOT_INTER;
            break;
        case 2:
            v->codingset2 = CS_MID_RATE_INTER;
            break;
        }
    
        //do frame decode
        s->mb_x = s->mb_y = 0;
        s->mb_intra = 1;
        s->first_slice_line = 1;
        ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
        for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
            for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
                ff_init_block_index(s);
                ff_update_block_index(s);
                s->dsp.clear_blocks(s->block[0]);
                mb_pos = s->mb_x + s->mb_y * s->mb_stride;
                s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
    
                s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
                s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
    
    
                // do actual MB decoding and displaying
                cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
                if(v->acpred_is_raw)
                    v->s.ac_pred = get_bits(&v->s.gb, 1);
                else
                    v->s.ac_pred = v->acpred_plane[mb_pos];
    
                if(v->condover == CONDOVER_SELECT) {
                    if(v->overflg_is_raw)
                        overlap = get_bits(&v->s.gb, 1);
                    else
                        overlap = v->over_flags_plane[mb_pos];
                } else
                    overlap = (v->condover == CONDOVER_ALL);
    
                GET_MQUANT();
    
                s->current_picture.qscale_table[mb_pos] = mquant;
    
                /* Set DC scale - y and c use the same */
                s->y_dc_scale = s->y_dc_scale_table[mquant];
                s->c_dc_scale = s->c_dc_scale_table[mquant];
    
    
                for(k = 0; k < 6; k++) {
                    val = ((cbp >> (5 - k)) & 1);
    
                    if (k < 4) {
                        int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
                        val = val ^ pred;
                        *coded_val = val;
                    }
                    cbp |= val << (5 - k);
    
                    v->a_avail = !s->first_slice_line || (k==2 || k==3);
                    v->c_avail = !!s->mb_x || (k==1 || k==3);
    
                    vc1_decode_i_block_adv(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2, mquant);
    
                    s->dsp.vc1_inv_trans_8x8(s->block[k]);
                    for(j = 0; j < 64; j++) s->block[k][j] += 128;
                }
    
                vc1_put_block(v, s->block);
                if(overlap) {
                    if(s->mb_x) {
    
                        s->dsp.vc1_h_overlap(s->dest[0], s->linesize);
                        s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
    
                            s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
                            s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
    
                    s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
                    s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
    
                    if(!s->first_slice_line) {
    
                        s->dsp.vc1_v_overlap(s->dest[0], s->linesize);
                        s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
    
                        if(!(s->flags & CODEC_FLAG_GRAY)) {
    
                            s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
                            s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
    
                    s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
                    s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
    
                }
    
                if(get_bits_count(&s->gb) > v->bits) {
                    av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
                    return;
                }
            }
            ff_draw_horiz_band(s, s->mb_y * 16, 16);
            s->first_slice_line = 0;
        }
    }
    
    
    static void vc1_decode_p_blocks(VC1Context *v)
    
        /* select codingmode used for VLC tables selection */
        switch(v->c_ac_table_index){
        case 0:
            v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
            break;
        case 1:
            v->codingset = CS_HIGH_MOT_INTRA;
            break;
        case 2:
            v->codingset = CS_MID_RATE_INTRA;
            break;
    
        switch(v->c_ac_table_index){
        case 0:
            v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
            break;
        case 1:
            v->codingset2 = CS_HIGH_MOT_INTER;
            break;
        case 2:
            v->codingset2 = CS_MID_RATE_INTER;
            break;
    
        ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
        s->first_slice_line = 1;
        for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
            for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
                ff_init_block_index(s);
                ff_update_block_index(s);
                s->dsp.clear_blocks(s->block[0]);
    
    
                if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                    av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
                    return;
    
            ff_draw_horiz_band(s, s->mb_y * 16, 16);
            s->first_slice_line = 0;
    
    static void vc1_decode_b_blocks(VC1Context *v)
    {
        MpegEncContext *s = &v->s;