Skip to content
Snippets Groups Projects
vc1.c 144 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 qx = (s->mb_x << 5);
                    qy = (s->mb_y << 5);
                    X = (s->mb_width << 5) - 4;
                    Y = (s->mb_height << 5) - 4;
                    if(qx + px < -28) px = -28 - qx;
                    if(qy + py < -28) py = -28 - qy;
                    if(qx + px > X) px = X - qx;
                    if(qy + py > Y) py = Y - qy;
                } else {
                    qx = (s->mb_x << 6);
                    qy = (s->mb_y << 6);
                    X = (s->mb_width << 6) - 4;
                    Y = (s->mb_height << 6) - 4;
                    if(qx + px < -60) px = -60 - qx;
                    if(qy + py < -60) py = -60 - qy;
                    if(qx + px > X) px = X - qx;
                    if(qy + py > Y) py = Y - qy;
                }
            }
            /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
            if(0 && !s->first_slice_line && s->mb_x) {
                if(is_intra[xy - wrap])
    
                    sum = FFABS(px) + FFABS(py);
    
                    sum = FFABS(px - A[0]) + FFABS(py - A[1]);
    
                if(sum > 32) {
                    if(get_bits1(&s->gb)) {
                        px = A[0];
                        py = A[1];
                    } else {
                        px = C[0];
                        py = C[1];
                    }
                } else {
                    if(is_intra[xy - 2])
    
                        sum = FFABS(px) + FFABS(py);
    
                        sum = FFABS(px - C[0]) + FFABS(py - C[1]);
    
                    if(sum > 32) {
                        if(get_bits1(&s->gb)) {
                            px = A[0];
                            py = A[1];
                        } else {
                            px = C[0];
                            py = C[1];
                        }
                    }
                }
    
            /* store MV using signed modulus of MV range defined in 4.11 */
            s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
            s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
    
        if((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
    
            C = s->current_picture.motion_val[1][xy - 2];
            A = s->current_picture.motion_val[1][xy - wrap*2];
            off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
            B = s->current_picture.motion_val[1][xy - wrap*2 + off];
    
            if(!s->first_slice_line) { // predictor A is not out of bounds
                if(s->mb_width == 1) {
                    px = A[0];
                    py = A[1];
                } else {
                    px = mid_pred(A[0], B[0], C[0]);
                    py = mid_pred(A[1], B[1], C[1]);
                }
            } else if(s->mb_x) { // predictor C is not out of bounds
                px = C[0];
                py = C[1];
            } else {
                px = py = 0;
            }
            /* Pullback MV as specified in 8.3.5.3.4 */
            {
                int qx, qy, X, Y;
                if(v->profile < PROFILE_ADVANCED) {
                    qx = (s->mb_x << 5);
                    qy = (s->mb_y << 5);
                    X = (s->mb_width << 5) - 4;
                    Y = (s->mb_height << 5) - 4;
                    if(qx + px < -28) px = -28 - qx;
                    if(qy + py < -28) py = -28 - qy;
                    if(qx + px > X) px = X - qx;
                    if(qy + py > Y) py = Y - qy;
                } else {
                    qx = (s->mb_x << 6);
                    qy = (s->mb_y << 6);
                    X = (s->mb_width << 6) - 4;
                    Y = (s->mb_height << 6) - 4;
                    if(qx + px < -60) px = -60 - qx;
                    if(qy + py < -60) py = -60 - qy;
                    if(qx + px > X) px = X - qx;
                    if(qy + py > Y) py = Y - qy;
                }
            }
            /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
            if(0 && !s->first_slice_line && s->mb_x) {
                if(is_intra[xy - wrap])
    
                    sum = FFABS(px) + FFABS(py);
    
                    sum = FFABS(px - A[0]) + FFABS(py - A[1]);
    
                if(sum > 32) {
                    if(get_bits1(&s->gb)) {
                        px = A[0];
                        py = A[1];
                    } else {
                        px = C[0];
                        py = C[1];
                    }
                } else {
                    if(is_intra[xy - 2])
    
                        sum = FFABS(px) + FFABS(py);
    
                        sum = FFABS(px - C[0]) + FFABS(py - C[1]);
    
                    if(sum > 32) {
                        if(get_bits1(&s->gb)) {
                            px = A[0];
                            py = A[1];
                        } else {
                            px = C[0];
                            py = C[1];
                        }
                    }
                }
            }
            /* store MV using signed modulus of MV range defined in 4.11 */
    
            s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
            s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
        }
        s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
        s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
        s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
        s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
    
    /** Get predicted DC value for I-frames only
     * prediction dir: left=0, top=1
     * @param s MpegEncContext
     * @param[in] n block index in the current MB
     * @param dc_val_ptr Pointer to DC predictor
     * @param dir_ptr Prediction direction for use in AC prediction
    
    static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
    
    Måns Rullgård's avatar
    Måns Rullgård committed
                                  int16_t **dc_val_ptr, int *dir_ptr)
    
        int a, b, c, wrap, pred, scale;
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        int16_t *dc_val;
    
        static const uint16_t dcpred[32] = {
        -1, 1024,  512,  341,  256,  205,  171,  146,  128,
             114,  102,   93,   85,   79,   73,   68,   64,
              60,   57,   54,   51,   49,   47,   45,   43,
              41,   39,   38,   37,   35,   34,   33
        };
    
    anonymous's avatar
    anonymous committed
    
    
        /* find prediction - wmv3_dc_scale always used here in fact */
        if (n < 4)     scale = s->y_dc_scale;
        else           scale = s->c_dc_scale;
    
        wrap = s->block_wrap[n];
        dc_val= s->dc_val[0] + s->block_index[n];
    
        /* B A
         * C X
         */
        c = dc_val[ - 1];
        b = dc_val[ - 1 - wrap];
        a = dc_val[ - wrap];
    
            if (s->first_slice_line && (n!=2 && n!=3)) b=a=dcpred[scale];
    
            if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=dcpred[scale];
    
            if (s->first_slice_line && (n!=2 && n!=3)) b=a=0;
    
            if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=0;
    
        if (abs(a - b) <= abs(b - c)) {
            pred = c;
            *dir_ptr = 1;//left
        } else {
            pred = a;
            *dir_ptr = 0;//top
    
        /* update predictor */
        *dc_val_ptr = &dc_val[0];
        return pred;
    
    /** Get predicted DC value
     * prediction dir: left=0, top=1
     * @param s MpegEncContext
     * @param[in] n block index in the current MB
     * @param dc_val_ptr Pointer to DC predictor
     * @param dir_ptr Prediction direction for use in AC prediction
    
    static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
                                  int a_avail, int c_avail,
    
    Måns Rullgård's avatar
    Måns Rullgård committed
                                  int16_t **dc_val_ptr, int *dir_ptr)
    
        int a, b, c, wrap, pred, scale;
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        int16_t *dc_val;
    
        int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    
        int q1, q2 = 0;
    
        /* find prediction - wmv3_dc_scale always used here in fact */
        if (n < 4)     scale = s->y_dc_scale;
        else           scale = s->c_dc_scale;
    
        wrap = s->block_wrap[n];
        dc_val= s->dc_val[0] + s->block_index[n];
    
        /* B A
         * C X
         */
        c = dc_val[ - 1];
        b = dc_val[ - 1 - wrap];
        a = dc_val[ - wrap];
    
        /* scale predictors if needed */
        q1 = s->current_picture.qscale_table[mb_pos];
        if(c_avail && (n!= 1 && n!=3)) {
            q2 = s->current_picture.qscale_table[mb_pos - 1];
            if(q2 && q2 != q1)
    
                c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
    
        }
        if(a_avail && (n!= 2 && n!=3)) {
            q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
            if(q2 && q2 != q1)
    
                a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
    
        }
        if(a_avail && c_avail && (n!=3)) {
            int off = mb_pos;
            if(n != 1) off--;
            if(n != 2) off -= s->mb_stride;
            q2 = s->current_picture.qscale_table[off];
            if(q2 && q2 != q1)
    
                b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18;
    
        if(a_avail && c_avail) {
            if(abs(a - b) <= abs(b - c)) {
                pred = c;
                *dir_ptr = 1;//left
            } else {
                pred = a;
                *dir_ptr = 0;//top
            }
        } else if(a_avail) {
            pred = a;
            *dir_ptr = 0;//top
        } else if(c_avail) {
            pred = c;
            *dir_ptr = 1;//left
        } else {
            pred = 0;
            *dir_ptr = 1;//left
    
        /* update predictor */
        *dc_val_ptr = &dc_val[0];
        return pred;
    
     * @defgroup std_mb VC1 Macroblock-level functions in Simple/Main Profiles
     * @see 7.1.4, p91 and 8.1.1.7, p(1)04
    
    static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
    
        xy = s->block_index[n];
        wrap = s->b8_stride;
    
        /* B C
         * A X
         */
        a = s->coded_block[xy - 1       ];
        b = s->coded_block[xy - 1 - wrap];
        c = s->coded_block[xy     - wrap];
    
    
        /* store value */
        *coded_block_ptr = &s->coded_block[xy];
    
        return pred;
    
    anonymous's avatar
    anonymous committed
    }
    
    
    /**
     * Decode one AC coefficient
     * @param v The VC1 context
     * @param last Last coefficient
     * @param skip How much zero coefficients to skip
     * @param value Decoded AC coefficient value
     * @see 8.1.3.4
    
    static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset)
    
    anonymous's avatar
    anonymous committed
    {
        GetBitContext *gb = &v->s.gb;
    
        int index, escape, run = 0, level = 0, lst = 0;
    
    
        index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
    
        if (index != vc1_ac_sizes[codingset] - 1) {
            run = vc1_index_decode_table[codingset][index][0];
            level = vc1_index_decode_table[codingset][index][1];
            lst = index >= vc1_last_decode_table[codingset];
            if(get_bits(gb, 1))
                level = -level;
        } else {
            escape = decode210(gb);
    
                index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
    
                run = vc1_index_decode_table[codingset][index][0];
                level = vc1_index_decode_table[codingset][index][1];
                lst = index >= vc1_last_decode_table[codingset];
    
                if(escape == 0) {
                    if(lst)
                        level += vc1_last_delta_level_table[codingset][run];
                    else
                        level += vc1_delta_level_table[codingset][run];
                } else {
                    if(lst)
                        run += vc1_last_delta_run_table[codingset][level] + 1;
                    else
                        run += vc1_delta_run_table[codingset][level] + 1;
                }
    
                if(get_bits(gb, 1))
                    level = -level;
            } else {
                int sign;
                lst = get_bits(gb, 1);
                if(v->s.esc3_level_length == 0) {
                    if(v->pq < 8 || v->dquantfrm) { // table 59
                        v->s.esc3_level_length = get_bits(gb, 3);
                        if(!v->s.esc3_level_length)
                            v->s.esc3_level_length = get_bits(gb, 2) + 8;
                    } else { //table 60
                        v->s.esc3_level_length = get_prefix(gb, 1, 6) + 2;
                    }
                    v->s.esc3_run_length = 3 + get_bits(gb, 2);
                }
                run = get_bits(gb, v->s.esc3_run_length);
                sign = get_bits(gb, 1);
                level = get_bits(gb, v->s.esc3_level_length);
                if(sign)
                    level = -level;
            }
    
        *last = lst;
        *skip = run;
        *value = level;
    
    /** Decode intra block in intra frames - should be faster than decode_intra_block
     * @param v VC1Context
     * @param block block to decode
     * @param coded are AC coeffs present or not
     * @param codingset set of VLC to decode data
    
    static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset)
    
    anonymous's avatar
    anonymous committed
        GetBitContext *gb = &v->s.gb;
    
        MpegEncContext *s = &v->s;
        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;
    
        /* 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 (v->pq == 1) dcdiff = get_bits(gb, 10);
                else if (v->pq == 2) dcdiff = get_bits(gb, 9);
                else dcdiff = get_bits(gb, 8);
    
                if (v->pq == 1)
                    dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
                else if (v->pq == 2)
                    dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
    
            if (get_bits(gb, 1))
                dcdiff = -dcdiff;
    
        /* Prediction */
        dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
        *dc_val = dcdiff;
    
    anonymous's avatar
    anonymous committed
    
    
        /* 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;
        if (!coded) {
            goto not_coded;
    
        {
            int last = 0, skip, value;
            const int8_t *zz_table;
            int scale;
            int k;
    
                    zz_table = ff_vc1_horizontal_zz;
    
                    zz_table = ff_vc1_vertical_zz;
    
                zz_table = ff_vc1_normal_zz;
    
    
            ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
            ac_val2 = ac_val;
            if(dc_pred_dir) //left
                ac_val -= 16;
            else //top
                ac_val -= 16 * s->block_wrap[n];
    
            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(s->ac_pred) {
                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) ? -v->pq : v->pq;
                }
    
            if(s->ac_pred) i = 63;
        }
    
    not_coded:
        if(!coded) {
            int k, scale;
            ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
            ac_val2 = ac_val;
    
            scale = v->pq * 2 + v->halfpq;
            memset(ac_val2, 0, 16 * 2);
            if(dc_pred_dir) {//left
                ac_val -= 16;
                if(s->ac_pred)
                    memcpy(ac_val2, ac_val, 8 * 2);
            } else {//top
                ac_val -= 16 * s->block_wrap[n];
                if(s->ac_pred)
                    memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
    
            /* apply AC prediction if needed */
            if(s->ac_pred) {
                if(dc_pred_dir) { //left
                    for(k = 1; k < 8; k++) {
                        block[k << 3] = ac_val[k] * scale;
    
                        if(!v->pquantizer && block[k << 3])
    
                            block[k << 3] += (block[k << 3] < 0) ? -v->pq : v->pq;
                    }
                } else { //top
                    for(k = 1; k < 8; k++) {
                        block[k] = ac_val[k + 8] * scale;
    
                        if(!v->pquantizer && block[k])
    
                            block[k] += (block[k] < 0) ? -v->pq : v->pq;
                    }
                }
                i = 63;
            }
    
    /** Decode intra block in intra frames - should be faster than decode_intra_block
    
     * @param v VC1Context
     * @param block block to decode
     * @param coded are AC coeffs present or not
     * @param codingset set of VLC to decode data
    
    static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset, int mquant)
    
    anonymous's avatar
    anonymous committed
    {
    
    anonymous's avatar
    anonymous committed
        GetBitContext *gb = &v->s.gb;
    
        int dc_pred_dir = 0; /* Direction of the DC prediction used */
    
    Måns Rullgård's avatar
    Måns Rullgård committed
        int16_t *dc_val;
    
        int16_t *ac_val, *ac_val2;
        int dcdiff;
    
        int a_avail = v->a_avail, c_avail = v->c_avail;
    
        int use_pred = s->ac_pred;
        int scale;
    
        int q1, q2 = 0;
    
        int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    
    
        /* 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, v->a_avail, v->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 */
    
        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(dc_pred_dir && n==1) q2 = q1;
        if(!dc_pred_dir && n==2) q2 = q1;
        if(n==3) q2 = q1;
    
            int last = 0, skip, value;
            const int8_t *zz_table;
            int k;
    
    
                    zz_table = ff_vc1_horizontal_zz;
    
                    zz_table = ff_vc1_vertical_zz;
    
                zz_table = ff_vc1_normal_zz;
    
    
            while (!last) {
                vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
                i += skip;
                if(i > 63)
                    break;
                block[zz_table[i++]] = value;
    
    anonymous's avatar
    anonymous committed
            }
    
            /* apply AC prediction if needed */
    
                /* 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 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
    
                    } else { //top
                        for(k = 1; k < 8; k++)
    
                            block[k] += (ac_val[k + 8] * q2 * ff_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];
    
    anonymous's avatar
    anonymous committed
            }
    
            /* 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;
                }
    
        } else { // no AC coeffs
            int k;
    
            memset(ac_val2, 0, 16 * 2);
            if(dc_pred_dir) {//left
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                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;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        for(k = 1; k < 8; k++)
    
                            ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                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;
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        for(k = 1; k < 8; k++)
    
                            ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
    
            /* apply AC prediction if needed */
    
                if(dc_pred_dir) { //left
                    for(k = 1; k < 8; k++) {
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        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++) {
    
    Kostya Shishkov's avatar
    Kostya Shishkov committed
                        block[k] = ac_val2[k + 8] * scale;
    
                        if(!v->pquantizer && block[k])
    
                            block[k] += (block[k] < 0) ? -mquant : mquant;
                    }
                }
                i = 63;
    
    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(dc_pred_dir && n==1) q2 = q1;
        if(!dc_pred_dir && n==2) q2 = q1;
        if(n==3) q2 = q1;
    
    
        if(coded) {
            int last = 0, skip, value;
            const int8_t *zz_table;
            int k;
    
    
            zz_table = ff_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 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
    
                            block[k] += (ac_val[k + 8] * q2 * ff_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;
    
                            ac_val2[k] = (ac_val2[k] * q2 * ff_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;
    
                            ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_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 = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
    
            subblkpat = ~(get_vlc2(gb, ff_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->pq == mquant) ? v->halfpq : 0);
    
    
        // 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 = ff_vc1_simple_progressive_8x8_zz[i++];
    
                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 = ff_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);