static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?

                        DCTELEM *block, int16_t *weight, DCTELEM *orig,

                        int n, int qscale){

    int16_t rem[64];

    DCTELEM d1[64];

    const int *qmat;

    const uint8_t *scantable= s->intra_scantable.scantable;

    const uint8_t *perm_scantable= s->intra_scantable.permutated;

//    unsigned int threshold1, threshold2;

//    int bias=0;

    int run_tab[65];

    int prev_run=0;

    int prev_level=0;

    int qmul, qadd, start_i, last_non_zero, i, dc;

    uint8_t * length;

    uint8_t * last_length;

    int lambda;

    int rle_index, run, q, sum;

#ifdef REFINE_STATS

static int count=0;

static int after_last=0;

static int to_zero=0;

static int from_zero=0;

static int raise=0;

static int lower=0;

static int messed_sign=0;

#endif



    if(basis[0][0] == 0)

        build_basis(s->dsp.idct_permutation);

    

    qmul= qscale*2;

    qadd= (qscale-1)|1;

    if (s->mb_intra) {

        if (!s->h263_aic) {

            if (n < 4)

                q = s->y_dc_scale;

            else

                q = s->c_dc_scale;

        } else{

            /* For AIC we skip quant/dequant of INTRADC */

            q = 1;

            qadd=0;

        }

        q <<= RECON_SHIFT-3;

        /* note: block[0] is assumed to be positive */

        dc= block[0]*q;

//        block[0] = (block[0] + (q >> 1)) / q;

        start_i = 1;

        qmat = s->q_intra_matrix[qscale];

//        if(s->mpeg_quant || s->out_format == FMT_MPEG1)

//            bias= 1<<(QMAT_SHIFT-1);

        length     = s->intra_ac_vlc_length;

        last_length= s->intra_ac_vlc_last_length;

    } else {

        dc= 0;

        start_i = 0;

        qmat = s->q_inter_matrix[qscale];

        length     = s->inter_ac_vlc_length;

        last_length= s->inter_ac_vlc_last_length;

    }

    last_non_zero = s->block_last_index[n];



#ifdef REFINE_STATS

{START_TIMER

#endif

    dc += (1<<(RECON_SHIFT-1));

    for(i=0; i<64; i++){

        rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME  use orig dirrectly insteadof copying to rem[]

    }

#ifdef REFINE_STATS

STOP_TIMER("memset rem[]")}

#endif

    sum=0;

    for(i=0; i<64; i++){

        int one= 36;

        int qns=4;

        int w;



        w= ABS(weight[i]) + qns*one;

        w= 15 + (48*qns*one + w/2)/w; // 16 .. 63



        weight[i] = w;

//        w=weight[i] = (63*qns + (w/2)) / w;

         

        assert(w>0);

        assert(w<(1<<6));

        sum += w*w;

    }

    lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);

#ifdef REFINE_STATS

{START_TIMER

#endif

    run=0;

    rle_index=0;

    for(i=start_i; i<=last_non_zero; i++){

        int j= perm_scantable[i];

        const int level= block[j];

        int coeff;

        

        if(level){

            if(level<0) coeff= qmul*level - qadd;

            else        coeff= qmul*level + qadd;

            run_tab[rle_index++]=run;

            run=0;



            s->dsp.add_8x8basis(rem, basis[j], coeff);

        }else{

            run++;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("init rem[]")

}

}



{START_TIMER

#endif

    for(;;){

        int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);

        int best_coeff=0;

        int best_change=0;

        int run2, best_unquant_change=0, analyze_gradient;

#ifdef REFINE_STATS

{START_TIMER

#endif

        analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3;



        if(analyze_gradient){

#ifdef REFINE_STATS

{START_TIMER

#endif

            for(i=0; i<64; i++){

                int w= weight[i];

            

                d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);

            }

#ifdef REFINE_STATS

STOP_TIMER("rem*w*w")}

{START_TIMER

#endif

            s->dsp.fdct(d1);

#ifdef REFINE_STATS

STOP_TIMER("dct")}

#endif

        }



        if(start_i){

            const int level= block[0];

            int change, old_coeff;



            assert(s->mb_intra);

            

            old_coeff= q*level;

            

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff;

                

                new_coeff= q*new_level;

                if(new_coeff >= 2048 || new_coeff < 0)

                    continue;



                score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff);

                if(score<best_score){

                    best_score= score;

                    best_coeff= 0;

                    best_change= change;

                    best_unquant_change= new_coeff - old_coeff;

                }

            }

        }

        

        run=0;

        rle_index=0;

        run2= run_tab[rle_index++];

        prev_level=0;

        prev_run=0;



        for(i=start_i; i<64; i++){

            int j= perm_scantable[i];

            const int level= block[j];

            int change, old_coeff;



            if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1)

                break;



            if(level){

                if(level<0) old_coeff= qmul*level - qadd;

                else        old_coeff= qmul*level + qadd;

                run2= run_tab[rle_index++]; //FIXME ! maybe after last

            }else{

                old_coeff=0;

                run2--;

                assert(run2>=0 || i >= last_non_zero );

            }

            

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff, unquant_change;

                

                score=0;

                if(s->avctx->quantizer_noise_shaping < 2 && ABS(new_level) > ABS(level))

                   continue;



                if(new_level){

                    if(new_level<0) new_coeff= qmul*new_level - qadd;

                    else            new_coeff= qmul*new_level + qadd;

                    if(new_coeff >= 2048 || new_coeff <= -2048)

                        continue;

                    //FIXME check for overflow

                    

                    if(level){

                        if(level < 63 && level > -63){

                            if(i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - length[UNI_AC_ENC_INDEX(run, level+64)];

                            else

                                score +=   last_length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - last_length[UNI_AC_ENC_INDEX(run, level+64)];

                        }

                    }else{

                        assert(ABS(new_level)==1);

                        

                        if(analyze_gradient){

                            int g= d1[ scantable[i] ];

                            if(g && (g^new_level) >= 0)

                                continue;

                        }



                        if(i < last_non_zero){

                            int next_i= i + run2 + 1;

                            int next_level= block[ perm_scantable[next_i] ] + 64;

                            

                            if(next_level&(~127))

                                next_level= 0;



                            if(next_i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, 65)]

                                         + length[UNI_AC_ENC_INDEX(run2, next_level)]

                                         - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                            else

                                score +=  length[UNI_AC_ENC_INDEX(run, 65)]

                                        + last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                        - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                        }else{

                            score += last_length[UNI_AC_ENC_INDEX(run, 65)];

                            if(prev_level){

                                score +=  length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                        - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                            }

                        }

                    }

                }else{

                    new_coeff=0;

                    assert(ABS(level)==1);



                    if(i < last_non_zero){

                        int next_i= i + run2 + 1;

                        int next_level= block[ perm_scantable[next_i] ] + 64;

                            

                        if(next_level&(~127))

                            next_level= 0;



                        if(next_i < last_non_zero)

                            score +=   length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                        else

                            score +=   last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                    }else{

                        score += -last_length[UNI_AC_ENC_INDEX(run, 65)];

                        if(prev_level){

                            score +=  last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                    - length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                        }

                    }

                }

                

                score *= lambda;



                unquant_change= new_coeff - old_coeff;

                assert((score < 100*lambda && score > -100*lambda) || lambda==0);

                

                score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);

                if(score<best_score){

                    best_score= score;

                    best_coeff= i;

                    best_change= change;

                    best_unquant_change= unquant_change;

                }

            }

            if(level){

                prev_level= level + 64;

                if(prev_level&(~127))

                    prev_level= 0;

                prev_run= run;

                run=0;

            }else{

                run++;

            }

        }

#ifdef REFINE_STATS

STOP_TIMER("iterative step")}

#endif



        if(best_change){

            int j= perm_scantable[ best_coeff ];

            

            block[j] += best_change;

            

            if(best_coeff > last_non_zero){

                last_non_zero= best_coeff;

                assert(block[j]);

#ifdef REFINE_STATS

after_last++;

#endif

            }else{

#ifdef REFINE_STATS

if(block[j]){

    if(block[j] - best_change){

        if(ABS(block[j]) > ABS(block[j] - best_change)){

            raise++;

        }else{

            lower++;

        }

    }else{

        from_zero++;

    }

}else{

    to_zero++;

}

#endif

                for(; last_non_zero>=start_i; last_non_zero--){

                    if(block[perm_scantable[last_non_zero]])

                        break;

                }

            }

#ifdef REFINE_STATS

count++;

if(256*256*256*64 % count == 0){

    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);

}

#endif

            run=0;

            rle_index=0;

            for(i=start_i; i<=last_non_zero; i++){

                int j= perm_scantable[i];

                const int level= block[j];

        

                 if(level){

                     run_tab[rle_index++]=run;

                     run=0;

                 }else{

                     run++;

                 }

            }

            

            s->dsp.add_8x8basis(rem, basis[j], best_unquant_change);

        }else{

            break;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("iterative search")

}

}

#endif



    return last_non_zero;

}

static int dct_quantize_refine(MpegEncContext *s, 

                        DCTELEM *block, int16_t *weight, DCTELEM *orig,

                        int n, int qscale){

    int16_t rem[64];

    DCTELEM d1[64];

    const int *qmat;

    const uint8_t *scantable= s->intra_scantable.scantable;

    const uint8_t *perm_scantable= s->intra_scantable.permutated;





    int run_tab[65];

    int prev_run=0;

    int prev_level=0;

    int qmul, qadd, start_i, last_non_zero, i, dc;

    uint8_t * length;

    uint8_t * last_length;

    int lambda;

    int rle_index, run, q, sum;

#ifdef REFINE_STATS

static int count=0;

static int after_last=0;

static int to_zero=0;

static int from_zero=0;

static int raise=0;

static int lower=0;

static int messed_sign=0;

#endif



    if(basis[0][0] == 0)

        build_basis(s->dsp.idct_permutation);

    

    qmul= qscale*2;

    qadd= (qscale-1)|1;

    if (s->mb_intra) {

        if (!s->h263_aic) {

            if (n < 4)

                q = s->y_dc_scale;

            else

                q = s->c_dc_scale;

        } else{

            

            q = 1;

            qadd=0;

        }

        q <<= RECON_SHIFT-3;

        

        dc= block[0]*q;



        start_i = 1;

        qmat = s->q_intra_matrix[qscale];





        length     = s->intra_ac_vlc_length;

        last_length= s->intra_ac_vlc_last_length;

    } else {

        dc= 0;

        start_i = 0;

        qmat = s->q_inter_matrix[qscale];

        length     = s->inter_ac_vlc_length;

        last_length= s->inter_ac_vlc_last_length;

    }

    last_non_zero = s->block_last_index[n];



#ifdef REFINE_STATS

{START_TIMER

#endif

    dc += (1<<(RECON_SHIFT-1));

    for(i=0; i<64; i++){

        rem[i]= dc - (orig[i]<<RECON_SHIFT); 

    }

#ifdef REFINE_STATS

STOP_TIMER("memset rem[]")}

#endif

    sum=0;

    for(i=0; i<64; i++){

        int one= 36;

        int qns=4;

        int w;



        w= ABS(weight[i]) + qns*one;

        w= 15 + (48*qns*one + w/2)/w; 



        weight[i] = w;



         

        assert(w>0);

        assert(w<(1<<6));

        sum += w*w;

    }

    lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);

#ifdef REFINE_STATS

{START_TIMER

#endif

    run=0;

    rle_index=0;

    for(i=start_i; i<=last_non_zero; i++){

        int j= perm_scantable[i];

        const int level= block[j];

        int coeff;

        

        if(level){

            if(level<0) coeff= qmul*level - qadd;

            else        coeff= qmul*level + qadd;

            run_tab[rle_index++]=run;

            run=0;



            s->dsp.add_8x8basis(rem, basis[j], coeff);

        }else{

            run++;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("init rem[]")

}

}



{START_TIMER

#endif

    for(;;){

        int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);

        int best_coeff=0;

        int best_change=0;

        int run2, best_unquant_change=0, analyze_gradient;

#ifdef REFINE_STATS

{START_TIMER

#endif

        analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3;



        if(analyze_gradient){

#ifdef REFINE_STATS

{START_TIMER

#endif

            for(i=0; i<64; i++){

                int w= weight[i];

            

                d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);

            }

#ifdef REFINE_STATS

STOP_TIMER("rem*w*w")}

{START_TIMER

#endif

            s->dsp.fdct(d1);

#ifdef REFINE_STATS

STOP_TIMER("dct")}

#endif

        }



        if(start_i){

            const int level= block[0];

            int change, old_coeff;



            assert(s->mb_intra);

            

            old_coeff= q*level;

            

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff;

                

                new_coeff= q*new_level;

                if(new_coeff >= 2048 || new_coeff < 0)

                    continue;



                score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff);

                if(score<best_score){

                    best_score= score;

                    best_coeff= 0;

                    best_change= change;

                    best_unquant_change= new_coeff - old_coeff;

                }

            }

        }

        

        run=0;

        rle_index=0;

        run2= run_tab[rle_index++];

        prev_level=0;

        prev_run=0;



        for(i=start_i; i<64; i++){

            int j= perm_scantable[i];

            const int level= block[j];

            int change, old_coeff;



            if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1)

                break;



            if(level){

                if(level<0) old_coeff= qmul*level - qadd;

                else        old_coeff= qmul*level + qadd;

                run2= run_tab[rle_index++]; 

            }else{

                old_coeff=0;

                run2--;

                assert(run2>=0 || i >= last_non_zero );

            }

            

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff, unquant_change;

                

                score=0;

                if(s->avctx->quantizer_noise_shaping < 2 && ABS(new_level) > ABS(level))

                   continue;



                if(new_level){

                    if(new_level<0) new_coeff= qmul*new_level - qadd;

                    else            new_coeff= qmul*new_level + qadd;

                    if(new_coeff >= 2048 || new_coeff <= -2048)

                        continue;

                    

                    

                    if(level){

                        if(level < 63 && level > -63){

                            if(i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - length[UNI_AC_ENC_INDEX(run, level+64)];

                            else

                                score +=   last_length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - last_length[UNI_AC_ENC_INDEX(run, level+64)];

                        }

                    }else{

                        assert(ABS(new_level)==1);

                        

                        if(analyze_gradient){

                            int g= d1[ scantable[i] ];

                            if(g && (g^new_level) >= 0)

                                continue;

                        }



                        if(i < last_non_zero){

                            int next_i= i + run2 + 1;

                            int next_level= block[ perm_scantable[next_i] ] + 64;

                            

                            if(next_level&(~127))

                                next_level= 0;



                            if(next_i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, 65)]

                                         + length[UNI_AC_ENC_INDEX(run2, next_level)]

                                         - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                            else

                                score +=  length[UNI_AC_ENC_INDEX(run, 65)]

                                        + last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                        - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                        }else{

                            score += last_length[UNI_AC_ENC_INDEX(run, 65)];

                            if(prev_level){

                                score +=  length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                        - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                            }

                        }

                    }

                }else{

                    new_coeff=0;

                    assert(ABS(level)==1);



                    if(i < last_non_zero){

                        int next_i= i + run2 + 1;

                        int next_level= block[ perm_scantable[next_i] ] + 64;

                            

                        if(next_level&(~127))

                            next_level= 0;



                        if(next_i < last_non_zero)

                            score +=   length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                        else

                            score +=   last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                    }else{

                        score += -last_length[UNI_AC_ENC_INDEX(run, 65)];

                        if(prev_level){

                            score +=  last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                    - length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                        }

                    }

                }

                

                score *= lambda;



                unquant_change= new_coeff - old_coeff;

                assert((score < 100*lambda && score > -100*lambda) || lambda==0);

                

                score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);

                if(score<best_score){

                    best_score= score;

                    best_coeff= i;

                    best_change= change;

                    best_unquant_change= unquant_change;

                }

            }

            if(level){

                prev_level= level + 64;

                if(prev_level&(~127))

                    prev_level= 0;

                prev_run= run;

                run=0;

            }else{

                run++;

            }

        }

#ifdef REFINE_STATS

STOP_TIMER("iterative step")}

#endif



        if(best_change){

            int j= perm_scantable[ best_coeff ];

            

            block[j] += best_change;

            

            if(best_coeff > last_non_zero){

                last_non_zero= best_coeff;

                assert(block[j]);

#ifdef REFINE_STATS

after_last++;

#endif

            }else{

#ifdef REFINE_STATS

if(block[j]){

    if(block[j] - best_change){

        if(ABS(block[j]) > ABS(block[j] - best_change)){

            raise++;

        }else{

            lower++;

        }

    }else{

        from_zero++;

    }

}else{

    to_zero++;

}

#endif

                for(; last_non_zero>=start_i; last_non_zero--){

                    if(block[perm_scantable[last_non_zero]])

                        break;

                }

            }

#ifdef REFINE_STATS

count++;

if(256*256*256*64 % count == 0){

    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);

}

#endif

            run=0;

            rle_index=0;

            for(i=start_i; i<=last_non_zero; i++){

                int j= perm_scantable[i];

                const int level= block[j];

        

                 if(level){

                     run_tab[rle_index++]=run;

                     run=0;

                 }else{

                     run++;

                 }

            }

            

            s->dsp.add_8x8basis(rem, basis[j], best_unquant_change);

        }else{

            break;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("iterative search")

}

}

#endif



    return last_non_zero;

}

    DCTELEM d1[64];
static int FUNC_0(MpegEncContext *VAR_0, 

                        DCTELEM *VAR_1, int16_t *VAR_2, DCTELEM *VAR_3,

                        int VAR_4, int VAR_5){

    int16_t rem[64];

    DCTELEM d1[64];

    const int *VAR_6;

    const uint8_t *VAR_7= VAR_0->intra_scantable.VAR_7;

    const uint8_t *VAR_8= VAR_0->intra_scantable.permutated;





    int VAR_9[65];

    int VAR_10=0;

    int VAR_11=0;

    int VAR_12, VAR_13, VAR_14, VAR_15, VAR_16, VAR_17;

    uint8_t * length;

    uint8_t * last_length;

    int VAR_18;

    int VAR_19, VAR_20, VAR_21, VAR_22;

#ifdef REFINE_STATS

static int count=0;

static int after_last=0;

static int to_zero=0;

static int from_zero=0;

static int raise=0;

static int lower=0;

static int messed_sign=0;

#endif



    if(basis[0][0] == 0)

        build_basis(VAR_0->dsp.idct_permutation);

    

    VAR_12= VAR_5*2;

    VAR_13= (VAR_5-1)|1;

    if (VAR_0->mb_intra) {

        if (!VAR_0->h263_aic) {

            if (VAR_4 < 4)

                VAR_21 = VAR_0->y_dc_scale;

            else

                VAR_21 = VAR_0->c_dc_scale;

        } else{

            

            VAR_21 = 1;

            VAR_13=0;

        }

        VAR_21 <<= RECON_SHIFT-3;

        

        VAR_17= VAR_1[0]*VAR_21;



        VAR_14 = 1;

        VAR_6 = VAR_0->q_intra_matrix[VAR_5];





        length     = VAR_0->intra_ac_vlc_length;

        last_length= VAR_0->intra_ac_vlc_last_length;

    } else {

        VAR_17= 0;

        VAR_14 = 0;

        VAR_6 = VAR_0->q_inter_matrix[VAR_5];

        length     = VAR_0->inter_ac_vlc_length;

        last_length= VAR_0->inter_ac_vlc_last_length;

    }

    VAR_15 = VAR_0->block_last_index[VAR_4];



#ifdef REFINE_STATS

{START_TIMER

#endif

    VAR_17 += (1<<(RECON_SHIFT-1));

    for(VAR_16=0; VAR_16<64; VAR_16++){

        rem[VAR_16]= VAR_17 - (VAR_3[VAR_16]<<RECON_SHIFT); 

    }

#ifdef REFINE_STATS

STOP_TIMER("memset rem[]")}

#endif

    VAR_22=0;

    for(VAR_16=0; VAR_16<64; VAR_16++){

        int VAR_23= 36;

        int VAR_24=4;

        int VAR_35;



        VAR_35= ABS(VAR_2[VAR_16]) + VAR_24*VAR_23;

        VAR_35= 15 + (48*VAR_24*VAR_23 + VAR_35/2)/VAR_35; 



        VAR_2[VAR_16] = VAR_35;



         

        assert(VAR_35>0);

        assert(VAR_35<(1<<6));

        VAR_22 += VAR_35*VAR_35;

    }

    VAR_18= VAR_22*(uint64_t)VAR_0->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);

#ifdef REFINE_STATS

{START_TIMER

#endif

    VAR_20=0;

    VAR_19=0;

    for(VAR_16=VAR_14; VAR_16<=VAR_15; VAR_16++){

        int VAR_44= VAR_8[VAR_16];

        const int VAR_44= VAR_1[VAR_44];

        int VAR_28;

        

        if(VAR_44){

            if(VAR_44<0) VAR_28= VAR_12*VAR_44 - VAR_13;

            else        VAR_28= VAR_12*VAR_44 + VAR_13;

            VAR_9[VAR_19++]=VAR_20;

            VAR_20=0;



            VAR_0->dsp.add_8x8basis(rem, basis[VAR_44], VAR_28);

        }else{

            VAR_20++;

        }

    }

#ifdef REFINE_STATS

if(VAR_15>0){

STOP_TIMER("init rem[]")

}

}



{START_TIMER

#endif

    for(;;){

        int VAR_29=VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[0], 0);

        int VAR_30=0;

        int VAR_31=0;

        int VAR_32, VAR_33=0, VAR_34;

#ifdef REFINE_STATS

{START_TIMER

#endif

        VAR_34 = VAR_15 > 2 || VAR_0->avctx->quantizer_noise_shaping >= 3;



        if(VAR_34){

#ifdef REFINE_STATS

{START_TIMER

#endif

            for(VAR_16=0; VAR_16<64; VAR_16++){

                int VAR_35= VAR_2[VAR_16];

            

                d1[VAR_16] = (rem[VAR_16]*VAR_35*VAR_35 + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);

            }

#ifdef REFINE_STATS

STOP_TIMER("rem*VAR_35*VAR_35")}

{START_TIMER

#endif

            VAR_0->dsp.fdct(d1);

#ifdef REFINE_STATS

STOP_TIMER("dct")}

#endif

        }



        if(VAR_14){

            const int VAR_44= VAR_1[0];

            int VAR_40, VAR_40;



            assert(VAR_0->mb_intra);

            

            VAR_40= VAR_21*VAR_44;

            

            for(VAR_40=-1; VAR_40<=1; VAR_40+=2){

                int VAR_40= VAR_44 + VAR_40;

                int VAR_40, VAR_40;

                

                VAR_40= VAR_21*VAR_40;

                if(VAR_40 >= 2048 || VAR_40 < 0)

                    continue;



                VAR_40= VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[0], VAR_40 - VAR_40);

                if(VAR_40<VAR_29){

                    VAR_29= VAR_40;

                    VAR_30= 0;

                    VAR_31= VAR_40;

                    VAR_33= VAR_40 - VAR_40;

                }

            }

        }

        

        VAR_20=0;

        VAR_19=0;

        VAR_32= VAR_9[VAR_19++];

        VAR_11=0;

        VAR_10=0;



        for(VAR_16=VAR_14; VAR_16<64; VAR_16++){

            int VAR_44= VAR_8[VAR_16];

            const int VAR_44= VAR_1[VAR_44];

            int VAR_40, VAR_40;



            if(VAR_0->avctx->quantizer_noise_shaping < 3 && VAR_16 > VAR_15 + 1)

                break;



            if(VAR_44){

                if(VAR_44<0) VAR_40= VAR_12*VAR_44 - VAR_13;

                else        VAR_40= VAR_12*VAR_44 + VAR_13;

                VAR_32= VAR_9[VAR_19++]; 

            }else{

                VAR_40=0;

                VAR_32--;

                assert(VAR_32>=0 || VAR_16 >= VAR_15 );

            }

            

            for(VAR_40=-1; VAR_40<=1; VAR_40+=2){

                int VAR_40= VAR_44 + VAR_40;

                int VAR_40, VAR_40, VAR_40;

                

                VAR_40=0;

                if(VAR_0->avctx->quantizer_noise_shaping < 2 && ABS(VAR_40) > ABS(VAR_44))

                   continue;



                if(VAR_40){

                    if(VAR_40<0) VAR_40= VAR_12*VAR_40 - VAR_13;

                    else            VAR_40= VAR_12*VAR_40 + VAR_13;

                    if(VAR_40 >= 2048 || VAR_40 <= -2048)

                        continue;

                    

                    

                    if(VAR_44){

                        if(VAR_44 < 63 && VAR_44 > -63){

                            if(VAR_16 < VAR_15)

                                VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20, VAR_40+64)]

                                         - length[UNI_AC_ENC_INDEX(VAR_20, VAR_44+64)];

                            else

                                VAR_40 +=   last_length[UNI_AC_ENC_INDEX(VAR_20, VAR_40+64)]

                                         - last_length[UNI_AC_ENC_INDEX(VAR_20, VAR_44+64)];

                        }

                    }else{

                        assert(ABS(VAR_40)==1);

                        

                        if(VAR_34){

                            int VAR_41= d1[ VAR_7[VAR_16] ];

                            if(VAR_41 && (VAR_41^VAR_40) >= 0)

                                continue;

                        }



                        if(VAR_16 < VAR_15){

                            int VAR_44= VAR_16 + VAR_32 + 1;

                            int VAR_44= VAR_1[ VAR_8[VAR_44] ] + 64;

                            

                            if(VAR_44&(~127))

                                VAR_44= 0;



                            if(VAR_44 < VAR_15)

                                VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20, 65)]

                                         + length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]

                                         - length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)];

                            else

                                VAR_40 +=  length[UNI_AC_ENC_INDEX(VAR_20, 65)]

                                        + last_length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]

                                        - last_length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)];

                        }else{

                            VAR_40 += last_length[UNI_AC_ENC_INDEX(VAR_20, 65)];

                            if(VAR_11){

                                VAR_40 +=  length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]

                                        - last_length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)];

                            }

                        }

                    }

                }else{

                    VAR_40=0;

                    assert(ABS(VAR_44)==1);



                    if(VAR_16 < VAR_15){

                        int VAR_44= VAR_16 + VAR_32 + 1;

                        int VAR_44= VAR_1[ VAR_8[VAR_44] ] + 64;

                            

                        if(VAR_44&(~127))

                            VAR_44= 0;



                        if(VAR_44 < VAR_15)

                            VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]

                                     - length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]

                                     - length[UNI_AC_ENC_INDEX(VAR_20, 65)];

                        else

                            VAR_40 +=   last_length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]

                                     - last_length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]

                                     - length[UNI_AC_ENC_INDEX(VAR_20, 65)];

                    }else{

                        VAR_40 += -last_length[UNI_AC_ENC_INDEX(VAR_20, 65)];

                        if(VAR_11){

                            VAR_40 +=  last_length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]

                                    - length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)];

                        }

                    }

                }

                

                VAR_40 *= VAR_18;



                VAR_40= VAR_40 - VAR_40;

                assert((VAR_40 < 100*VAR_18 && VAR_40 > -100*VAR_18) || VAR_18==0);

                

                VAR_40+= VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[VAR_44], VAR_40);

                if(VAR_40<VAR_29){

                    VAR_29= VAR_40;

                    VAR_30= VAR_16;

                    VAR_31= VAR_40;

                    VAR_33= VAR_40;

                }

            }

            if(VAR_44){

                VAR_11= VAR_44 + 64;

                if(VAR_11&(~127))

                    VAR_11= 0;

                VAR_10= VAR_20;

                VAR_20=0;

            }else{

                VAR_20++;

            }

        }

#ifdef REFINE_STATS

STOP_TIMER("iterative step")}

#endif



        if(VAR_31){

            int VAR_44= VAR_8[ VAR_30 ];

            

            VAR_1[VAR_44] += VAR_31;

            

            if(VAR_30 > VAR_15){

                VAR_15= VAR_30;

                assert(VAR_1[VAR_44]);

#ifdef REFINE_STATS

after_last++;

#endif

            }else{

#ifdef REFINE_STATS

if(VAR_1[VAR_44]){

    if(VAR_1[VAR_44] - VAR_31){

        if(ABS(VAR_1[VAR_44]) > ABS(VAR_1[VAR_44] - VAR_31)){

            raise++;

        }else{

            lower++;

        }

    }else{

        from_zero++;

    }

}else{

    to_zero++;

}

#endif

                for(; VAR_15>=VAR_14; VAR_15--){

                    if(VAR_1[VAR_8[VAR_15]])

                        break;

                }

            }

#ifdef REFINE_STATS

count++;

if(256*256*256*64 % count == 0){

    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\VAR_4", after_last, to_zero, from_zero, raise, lower, messed_sign, VAR_0->mb_x, VAR_0->mb_y, VAR_0->picture_number);

}

#endif

            VAR_20=0;

            VAR_19=0;

            for(VAR_16=VAR_14; VAR_16<=VAR_15; VAR_16++){

                int VAR_44= VAR_8[VAR_16];

                const int VAR_44= VAR_1[VAR_44];

        

                 if(VAR_44){

                     VAR_9[VAR_19++]=VAR_20;

                     VAR_20=0;

                 }else{

                     VAR_20++;

                 }

            }

            

            VAR_0->dsp.add_8x8basis(rem, basis[VAR_44], VAR_33);

        }else{

            break;

        }

    }

#ifdef REFINE_STATS

if(VAR_15>0){

STOP_TIMER("iterative search")

}

}

#endif



    return VAR_15;

}

static int FUNC_0(MpegEncContext *VAR_0,
DCTELEM *VAR_1, int16_t *VAR_2, DCTELEM *VAR_3,
int VAR_4, int VAR_5){ int16_t rem[64]; DCTELEM d1[64]; const int *VAR_6; const uint8_t *VAR_7= VAR_0->intra_scantable.VAR_7; const uint8_t *VAR_8= VAR_0->intra_scantable.permutated; int VAR_9[65]; int VAR_10=0; int VAR_11=0; int VAR_12, VAR_13, VAR_14, VAR_15, VAR_16, VAR_17; uint8_t * length; uint8_t * last_length; int VAR_18; int VAR_19, VAR_20, VAR_21, VAR_22; #ifdef REFINE_STATS
static int count=0; static int after_last=0; static int to_zero=0; static int from_zero=0; static int raise=0; static int lower=0; static int messed_sign=0; #endif
if(basis[0][0] == 0)
build_basis(VAR_0->dsp.idct_permutation); VAR_12= VAR_5*2; VAR_13= (VAR_5-1)|1; if (VAR_0->mb_intra) { if (!VAR_0->h263_aic) { if (VAR_4 < 4)
VAR_21 = VAR_0->y_dc_scale; else
VAR_21 = VAR_0->c_dc_scale; } else{ VAR_21 = 1; VAR_13=0; } VAR_21 <<= RECON_SHIFT-3; VAR_17= VAR_1[0]*VAR_21; VAR_14 = 1; VAR_6 = VAR_0->q_intra_matrix[VAR_5]; length     = VAR_0->intra_ac_vlc_length; last_length= VAR_0->intra_ac_vlc_last_length; } else { VAR_17= 0; VAR_14 = 0; VAR_6 = VAR_0->q_inter_matrix[VAR_5]; length     = VAR_0->inter_ac_vlc_length; last_length= VAR_0->inter_ac_vlc_last_length; } VAR_15 = VAR_0->block_last_index[VAR_4]; #ifdef REFINE_STATS
{START_TIMER #endif
VAR_17 += (1<<(RECON_SHIFT-1)); for(VAR_16=0; VAR_16<64; VAR_16++){ rem[VAR_16]= VAR_17 - (VAR_3[VAR_16]<<RECON_SHIFT); } #ifdef REFINE_STATS
STOP_TIMER("memset rem[]")} #endif
VAR_22=0; for(VAR_16=0; VAR_16<64; VAR_16++){ int VAR_23= 36; int VAR_24=4; int VAR_35; VAR_35= ABS(VAR_2[VAR_16]) + VAR_24*VAR_23; VAR_35= 15 + (48*VAR_24*VAR_23 + VAR_35/2)/VAR_35; VAR_2[VAR_16] = VAR_35; assert(VAR_35>0); assert(VAR_35<(1<<6)); VAR_22 += VAR_35*VAR_35; } VAR_18= VAR_22*(uint64_t)VAR_0->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6); #ifdef REFINE_STATS
{START_TIMER #endif
VAR_20=0; VAR_19=0; for(VAR_16=VAR_14; VAR_16<=VAR_15; VAR_16++){ int VAR_44= VAR_8[VAR_16]; const int VAR_44= VAR_1[VAR_44]; int VAR_28; if(VAR_44){ if(VAR_44<0) VAR_28= VAR_12*VAR_44 - VAR_13; else        VAR_28= VAR_12*VAR_44 + VAR_13; VAR_9[VAR_19++]=VAR_20; VAR_20=0; VAR_0->dsp.add_8x8basis(rem, basis[VAR_44], VAR_28); }else{ VAR_20++; } } #ifdef REFINE_STATS
if(VAR_15>0){ STOP_TIMER("init rem[]")
} } {START_TIMER #endif
for(;;){ int VAR_29=VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[0], 0); int VAR_30=0; int VAR_31=0; int VAR_32, VAR_33=0, VAR_34; #ifdef REFINE_STATS
{START_TIMER #endif
VAR_34 = VAR_15 > 2 || VAR_0->avctx->quantizer_noise_shaping >= 3; if(VAR_34){ #ifdef REFINE_STATS
{START_TIMER #endif
for(VAR_16=0; VAR_16<64; VAR_16++){ int VAR_35= VAR_2[VAR_16]; d1[VAR_16] = (rem[VAR_16]*VAR_35*VAR_35 + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12); } #ifdef REFINE_STATS
STOP_TIMER("rem*VAR_35*VAR_35")} {START_TIMER #endif
VAR_0->dsp.fdct(d1); #ifdef REFINE_STATS
STOP_TIMER("dct")} #endif
} if(VAR_14){ const int VAR_44= VAR_1[0]; int VAR_40, VAR_40; assert(VAR_0->mb_intra); VAR_40= VAR_21*VAR_44; for(VAR_40=-1; VAR_40<=1; VAR_40+=2){ int VAR_40= VAR_44 + VAR_40; int VAR_40, VAR_40; VAR_40= VAR_21*VAR_40; if(VAR_40 >= 2048 || VAR_40 < 0)
continue; VAR_40= VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[0], VAR_40 - VAR_40); if(VAR_40<VAR_29){ VAR_29= VAR_40; VAR_30= 0; VAR_31= VAR_40; VAR_33= VAR_40 - VAR_40; } } } VAR_20=0; VAR_19=0; VAR_32= VAR_9[VAR_19++]; VAR_11=0; VAR_10=0; for(VAR_16=VAR_14; VAR_16<64; VAR_16++){ int VAR_44= VAR_8[VAR_16]; const int VAR_44= VAR_1[VAR_44]; int VAR_40, VAR_40; if(VAR_0->avctx->quantizer_noise_shaping < 3 && VAR_16 > VAR_15 + 1)
break; if(VAR_44){ if(VAR_44<0) VAR_40= VAR_12*VAR_44 - VAR_13; else        VAR_40= VAR_12*VAR_44 + VAR_13; VAR_32= VAR_9[VAR_19++]; }else{ VAR_40=0; VAR_32--; assert(VAR_32>=0 || VAR_16 >= VAR_15 ); } for(VAR_40=-1; VAR_40<=1; VAR_40+=2){ int VAR_40= VAR_44 + VAR_40; int VAR_40, VAR_40, VAR_40; VAR_40=0; if(VAR_0->avctx->quantizer_noise_shaping < 2 && ABS(VAR_40) > ABS(VAR_44))
continue; if(VAR_40){ if(VAR_40<0) VAR_40= VAR_12*VAR_40 - VAR_13; else            VAR_40= VAR_12*VAR_40 + VAR_13; if(VAR_40 >= 2048 || VAR_40 <= -2048)
continue; if(VAR_44){ if(VAR_44 < 63 && VAR_44 > -63){ if(VAR_16 < VAR_15)
VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20, VAR_40+64)]
- length[UNI_AC_ENC_INDEX(VAR_20, VAR_44+64)]; else
VAR_40 +=   last_length[UNI_AC_ENC_INDEX(VAR_20, VAR_40+64)]
- last_length[UNI_AC_ENC_INDEX(VAR_20, VAR_44+64)]; } }else{ assert(ABS(VAR_40)==1); if(VAR_34){ int VAR_41= d1[ VAR_7[VAR_16] ]; if(VAR_41 && (VAR_41^VAR_40) >= 0)
continue; } if(VAR_16 < VAR_15){ int VAR_44= VAR_16 + VAR_32 + 1; int VAR_44= VAR_1[ VAR_8[VAR_44] ] + 64; if(VAR_44&(~127))
VAR_44= 0; if(VAR_44 < VAR_15)
VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20, 65)]
+ length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]
- length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]; else
VAR_40 +=  length[UNI_AC_ENC_INDEX(VAR_20, 65)]
+ last_length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]
- last_length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]; }else{ VAR_40 += last_length[UNI_AC_ENC_INDEX(VAR_20, 65)]; if(VAR_11){ VAR_40 +=  length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]
- last_length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]; } } } }else{ VAR_40=0; assert(ABS(VAR_44)==1); if(VAR_16 < VAR_15){ int VAR_44= VAR_16 + VAR_32 + 1; int VAR_44= VAR_1[ VAR_8[VAR_44] ] + 64; if(VAR_44&(~127))
VAR_44= 0; if(VAR_44 < VAR_15)
VAR_40 +=   length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]
- length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]
- length[UNI_AC_ENC_INDEX(VAR_20, 65)]; else
VAR_40 +=   last_length[UNI_AC_ENC_INDEX(VAR_20 + VAR_32 + 1, VAR_44)]
- last_length[UNI_AC_ENC_INDEX(VAR_32, VAR_44)]
- length[UNI_AC_ENC_INDEX(VAR_20, 65)]; }else{ VAR_40 += -last_length[UNI_AC_ENC_INDEX(VAR_20, 65)]; if(VAR_11){ VAR_40 +=  last_length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]
- length[UNI_AC_ENC_INDEX(VAR_10, VAR_11)]; } } } VAR_40 *= VAR_18; VAR_40= VAR_40 - VAR_40; assert((VAR_40 < 100*VAR_18 && VAR_40 > -100*VAR_18) || VAR_18==0); VAR_40+= VAR_0->dsp.try_8x8basis(rem, VAR_2, basis[VAR_44], VAR_40); if(VAR_40<VAR_29){ VAR_29= VAR_40; VAR_30= VAR_16; VAR_31= VAR_40; VAR_33= VAR_40; } } if(VAR_44){ VAR_11= VAR_44 + 64; if(VAR_11&(~127))
VAR_11= 0; VAR_10= VAR_20; VAR_20=0; }else{ VAR_20++; } } #ifdef REFINE_STATS
STOP_TIMER("iterative step")} #endif
if(VAR_31){ int VAR_44= VAR_8[ VAR_30 ]; VAR_1[VAR_44] += VAR_31; if(VAR_30 > VAR_15){ VAR_15= VAR_30; assert(VAR_1[VAR_44]); #ifdef REFINE_STATS
after_last++; #endif
}else{ #ifdef REFINE_STATS
if(VAR_1[VAR_44]){ if(VAR_1[VAR_44] - VAR_31){ if(ABS(VAR_1[VAR_44]) > ABS(VAR_1[VAR_44] - VAR_31)){ raise++; }else{ lower++; } }else{ from_zero++; } }else{ to_zero++; } #endif
for(; VAR_15>=VAR_14; VAR_15--){ if(VAR_1[VAR_8[VAR_15]])
break; } } #ifdef REFINE_STATS
count++; if(256*256*256*64 % count == 0){ printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\VAR_4", after_last, to_zero, from_zero, raise, lower, messed_sign, VAR_0->mb_x, VAR_0->mb_y, VAR_0->picture_number); } #endif
VAR_20=0; VAR_19=0; for(VAR_16=VAR_14; VAR_16<=VAR_15; VAR_16++){ int VAR_44= VAR_8[VAR_16]; const int VAR_44= VAR_1[VAR_44]; if(VAR_44){ VAR_9[VAR_19++]=VAR_20; VAR_20=0; }else{ VAR_20++; } } VAR_0->dsp.add_8x8basis(rem, basis[VAR_44], VAR_33); }else{ break; } } #ifdef REFINE_STATS
if(VAR_15>0){ STOP_TIMER("iterative search")
} } #endif
return VAR_15; }