fixed[i]= f;
fixed[mb_xy]= f;
static void guess_mv(MpegEncContext *s){    uint8_t fixed[s->mb_num];#define MV_FROZEN    3#define MV_CHANGED   2#define MV_UNCHANGED 1    const int mb_width = s->mb_width;    const int mb_height= s->mb_height;    int i, depth, num_avail;       num_avail=0;    for(i=0; i<s->mb_num; i++){        int f=0;        int error= s->error_status_table[i];        if(s->mb_type[i]&MB_TYPE_INTRA) f=MV_FROZEN; //intra //FIXME check        if(!(error&MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV                fixed[i]= f;        if(f==MV_FROZEN)            num_avail++;    }        if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){        int mb_x, mb_y;        i= -1;        for(mb_y=0; mb_y<s->mb_height; mb_y++){            for(mb_x=0; mb_x<s->mb_width; mb_x++){                i++;                                if(s->mb_type[i]&MB_TYPE_INTRA) continue;                if(!(s->error_status_table[i]&MV_ERROR)) continue;                s->mv_dir = MV_DIR_FORWARD;                s->mb_intra=0;                s->mv_type = MV_TYPE_16X16;                s->mb_skiped=0;		s->dsp.clear_blocks(s->block[0]);                s->mb_x= mb_x;                s->mb_y= mb_y;                s->mv[0][0][0]= 0;                s->mv[0][0][1]= 0;                MPV_decode_mb(s, s->block);            }        }        return;    }        for(depth=0;; depth++){        int changed, pass, none_left;        none_left=1;        changed=1;        for(pass=0; (changed || pass<2) && pass<10; pass++){            int i,mb_x, mb_y;int score_sum=0;             changed=0;            i= -1;            for(mb_y=0; mb_y<s->mb_height; mb_y++){                for(mb_x=0; mb_x<s->mb_width; mb_x++){                    int mv_predictor[8][2]={{0}};                    int pred_count=0;                    int j;                    int best_score=256*256*256*64;                    int best_pred=0;                    const int mot_stride= mb_width*2+2;                    const int mot_index= mb_x*2 + 1 + (mb_y*2+1)*mot_stride;                    int prev_x= s->motion_val[mot_index][0];                    int prev_y= s->motion_val[mot_index][1];                    i++;                    if((mb_x^mb_y^pass)&1) continue;                                        if(fixed[i]==MV_FROZEN) continue;                                        j=0;                    if(mb_x>0           && fixed[i-1       ]==MV_FROZEN) j=1;                    if(mb_x+1<mb_width  && fixed[i+1       ]==MV_FROZEN) j=1;                    if(mb_y>0           && fixed[i-mb_width]==MV_FROZEN) j=1;                    if(mb_y+1<mb_height && fixed[i+mb_width]==MV_FROZEN) j=1;                    if(j==0) continue;                    j=0;                    if(mb_x>0           && fixed[i-1       ]==MV_CHANGED) j=1;                    if(mb_x+1<mb_width  && fixed[i+1       ]==MV_CHANGED) j=1;                    if(mb_y>0           && fixed[i-mb_width]==MV_CHANGED) j=1;                    if(mb_y+1<mb_height && fixed[i+mb_width]==MV_CHANGED) j=1;                    if(j==0 && pass>1) continue;                                        none_left=0;                                        if(mb_x>0 && fixed[i-1]){                        mv_predictor[pred_count][0]= s->motion_val[mot_index - 2][0];                        mv_predictor[pred_count][1]= s->motion_val[mot_index - 2][1];                        pred_count++;                    }                    if(mb_x+1<mb_width && fixed[i+1]){                        mv_predictor[pred_count][0]= s->motion_val[mot_index + 2][0];                        mv_predictor[pred_count][1]= s->motion_val[mot_index + 2][1];                        pred_count++;                    }                    if(mb_y>0 && fixed[i-mb_width]){                        mv_predictor[pred_count][0]= s->motion_val[mot_index - mot_stride*2][0];                        mv_predictor[pred_count][1]= s->motion_val[mot_index - mot_stride*2][1];                        pred_count++;                    }                    if(mb_y+1<mb_height && fixed[i+mb_width]){                        mv_predictor[pred_count][0]= s->motion_val[mot_index + mot_stride*2][0];                        mv_predictor[pred_count][1]= s->motion_val[mot_index + mot_stride*2][1];                        pred_count++;                    }                    if(pred_count==0) continue;                                        if(pred_count>1){                        int sum_x=0, sum_y=0;                        int max_x, max_y, min_x, min_y;                        for(j=0; j<pred_count; j++){                            sum_x+= mv_predictor[j][0];                            sum_y+= mv_predictor[j][1];                        }                                            /* mean */                        mv_predictor[pred_count][0] = sum_x/j;                        mv_predictor[pred_count][1] = sum_y/j;                                            /* median */                        if(pred_count>=3){                            min_y= min_x= 99999;                            max_y= max_x=-99999;                        }else{                            min_x=min_y=max_x=max_y=0;                        }                        for(j=0; j<pred_count; j++){                            max_x= FFMAX(max_x, mv_predictor[j][0]);                            max_y= FFMAX(max_y, mv_predictor[j][1]);                            min_x= FFMIN(min_x, mv_predictor[j][0]);                            min_y= FFMIN(min_y, mv_predictor[j][1]);                        }                        mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;                        mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;                                                if(pred_count==4){                            mv_predictor[pred_count+1][0] /= 2;                            mv_predictor[pred_count+1][1] /= 2;                        }                        pred_count+=2;                    }                                        /* zero MV */                    pred_count++;                    /* last MV */                    mv_predictor[pred_count][0]= s->motion_val[mot_index][0];                    mv_predictor[pred_count][1]= s->motion_val[mot_index][1];                    pred_count++;                                                            s->mv_dir = MV_DIR_FORWARD;                    s->mb_intra=0;                    s->mv_type = MV_TYPE_16X16;                    s->mb_skiped=0;		    s->dsp.clear_blocks(s->block[0]);                    s->mb_x= mb_x;                    s->mb_y= mb_y;                    for(j=0; j<pred_count; j++){                        int score=0;                        uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;                        s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];                        s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];                        MPV_decode_mb(s, s->block);                                                if(mb_x>0 && fixed[i-1]){                            int k;                            for(k=0; k<16; k++)                                score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);                        }                        if(mb_x+1<mb_width && fixed[i+1]){                            int k;                            for(k=0; k<16; k++)                                score += ABS(src[k*s->linesize+15]-src[k*s->linesize+16]);                        }                        if(mb_y>0 && fixed[i-mb_width]){                            int k;                            for(k=0; k<16; k++)                                score += ABS(src[k-s->linesize   ]-src[k               ]);                        }                        if(mb_y+1<mb_height && fixed[i+mb_width]){                            int k;                            for(k=0; k<16; k++)                                score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]);                        }                                                if(score <= best_score){ // <= will favor the last MV                            best_score= score;                            best_pred= j;                        }                    }score_sum+= best_score;//FIXME no need to set s->motion_val[mot_index][0] explicit                    s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[best_pred][0];                    s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[best_pred][1];                    MPV_decode_mb(s, s->block);                                        if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){                        fixed[i]=MV_CHANGED;                        changed++;                    }else                        fixed[i]=MV_UNCHANGED;                }            }//            printf(".%d/%d", changed, score_sum); fflush(stdout);        }                if(none_left)             return;                    for(i=0; i<s->mb_num; i++){            if(fixed[i])                fixed[i]=MV_FROZEN;        }//        printf(":"); fflush(stdout);    }}