static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,

                                       int src_index, int ref_index, int const penalty_factor,

                                       int size, int h, int flags)

{

    MotionEstContext * const c= &s->me;

    me_cmp_func cmpf, chroma_cmpf;

    Minima minima[MAX_SAB_SIZE];

    const int minima_count= FFABS(c->dia_size);

    int i, j;

    LOAD_COMMON

    LOAD_COMMON2

    unsigned map_generation = c->map_generation;



    av_assert1(minima_count <= MAX_SAB_SIZE);



    cmpf        = s->mecc.me_cmp[size];

    chroma_cmpf = s->mecc.me_cmp[size + 1];



    /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can

      become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map

     */

    for(j=i=0; i<ME_MAP_SIZE && j<MAX_SAB_SIZE; i++){

        uint32_t key= map[i];



        key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));



        if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue;



        minima[j].height= score_map[i];

        minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;

        minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1);

        minima[j].x-= (1<<(ME_MAP_MV_BITS-1));

        minima[j].y-= (1<<(ME_MAP_MV_BITS-1));



        // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space

        if(   minima[j].x > xmax || minima[j].x < xmin

           || minima[j].y > ymax || minima[j].y < ymin)

            continue;



        minima[j].checked=0;

        if(minima[j].x || minima[j].y)

            minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor;



        j++;

    }



    qsort(minima, j, sizeof(Minima), minima_cmp);



    for(; j<minima_count; j++){

        minima[j].height=256*256*256*64;

        minima[j].checked=0;

        minima[j].x= minima[j].y=0;

    }



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

        const int x= minima[i].x;

        const int y= minima[i].y;

        int d;



        if(minima[i].checked) continue;



        if(   x >= xmax || x <= xmin

           || y >= ymax || y <= ymin)

           continue;



        SAB_CHECK_MV(x-1, y)

        SAB_CHECK_MV(x+1, y)

        SAB_CHECK_MV(x  , y-1)

        SAB_CHECK_MV(x  , y+1)



        minima[i].checked= 1;

    }



    best[0]= minima[0].x;

    best[1]= minima[0].y;

    dmin= minima[0].height;



    if(   best[0] < xmax && best[0] > xmin

       && best[1] < ymax && best[1] > ymin){

        int d;

        //ensure that the refernece samples for hpel refinement are in the map

        CHECK_MV(best[0]-1, best[1])

        CHECK_MV(best[0]+1, best[1])

        CHECK_MV(best[0], best[1]-1)

        CHECK_MV(best[0], best[1]+1)

    }

    return dmin;

}

static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,

                                       int src_index, int ref_index, int const penalty_factor,

                                       int size, int h, int flags)

{

    MotionEstContext * const c= &s->me;

    me_cmp_func cmpf, chroma_cmpf;

    Minima minima[MAX_SAB_SIZE];

    const int minima_count= FFABS(c->dia_size);

    int i, j;

    LOAD_COMMON

    LOAD_COMMON2

    unsigned map_generation = c->map_generation;



    av_assert1(minima_count <= MAX_SAB_SIZE);



    cmpf        = s->mecc.me_cmp[size];

    chroma_cmpf = s->mecc.me_cmp[size + 1];



    





    for(j=i=0; i<ME_MAP_SIZE && j<MAX_SAB_SIZE; i++){

        uint32_t key= map[i];



        key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));



        if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue;



        minima[j].height= score_map[i];

        minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;

        minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1);

        minima[j].x-= (1<<(ME_MAP_MV_BITS-1));

        minima[j].y-= (1<<(ME_MAP_MV_BITS-1));



        

        if(   minima[j].x > xmax || minima[j].x < xmin

           || minima[j].y > ymax || minima[j].y < ymin)

            continue;



        minima[j].checked=0;

        if(minima[j].x || minima[j].y)

            minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor;



        j++;

    }



    qsort(minima, j, sizeof(Minima), minima_cmp);



    for(; j<minima_count; j++){

        minima[j].height=256*256*256*64;

        minima[j].checked=0;

        minima[j].x= minima[j].y=0;

    }



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

        const int x= minima[i].x;

        const int y= minima[i].y;

        int d;



        if(minima[i].checked) continue;



        if(   x >= xmax || x <= xmin

           || y >= ymax || y <= ymin)

           continue;



        SAB_CHECK_MV(x-1, y)

        SAB_CHECK_MV(x+1, y)

        SAB_CHECK_MV(x  , y-1)

        SAB_CHECK_MV(x  , y+1)



        minima[i].checked= 1;

    }



    best[0]= minima[0].x;

    best[1]= minima[0].y;

    dmin= minima[0].height;



    if(   best[0] < xmax && best[0] > xmin

       && best[1] < ymax && best[1] > ymin){

        int d;

        

        CHECK_MV(best[0]-1, best[1])

        CHECK_MV(best[0]+1, best[1])

        CHECK_MV(best[0], best[1]-1)

        CHECK_MV(best[0], best[1]+1)

    }

    return dmin;

}

static int FUNC_0(MpegEncContext * VAR_0, int *VAR_1, int VAR_2,

                                       int VAR_3, int VAR_4, int const VAR_5,

                                       int VAR_6, int VAR_7, int VAR_8)

{

    MotionEstContext * const c= &VAR_0->me;

    me_cmp_func cmpf, chroma_cmpf;

    Minima minima[MAX_SAB_SIZE];

    const int VAR_9= FFABS(c->dia_size);

    int VAR_10, VAR_11;

    LOAD_COMMON

    LOAD_COMMON2

    unsigned map_generation = c->map_generation;



    av_assert1(VAR_9 <= MAX_SAB_SIZE);



    cmpf        = VAR_0->mecc.me_cmp[VAR_6];

    chroma_cmpf = VAR_0->mecc.me_cmp[VAR_6 + 1];



    





    for(VAR_11=VAR_10=0; VAR_10<ME_MAP_SIZE && VAR_11<MAX_SAB_SIZE; VAR_10++){

        uint32_t key= map[VAR_10];



        key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));



        if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue;



        minima[VAR_11].height= score_map[VAR_10];

        minima[VAR_11].VAR_12= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;

        minima[VAR_11].VAR_13= key & ((1<<ME_MAP_MV_BITS)-1);

        minima[VAR_11].VAR_12-= (1<<(ME_MAP_MV_BITS-1));

        minima[VAR_11].VAR_13-= (1<<(ME_MAP_MV_BITS-1));



        

        if(   minima[VAR_11].VAR_12 > xmax || minima[VAR_11].VAR_12 < xmin

           || minima[VAR_11].VAR_13 > ymax || minima[VAR_11].VAR_13 < ymin)

            continue;



        minima[VAR_11].checked=0;

        if(minima[VAR_11].VAR_12 || minima[VAR_11].VAR_13)

            minima[VAR_11].height+= (mv_penalty[((minima[VAR_11].VAR_12)<<shift)-pred_x] + mv_penalty[((minima[VAR_11].VAR_13)<<shift)-pred_y])*VAR_5;



        VAR_11++;

    }



    qsort(minima, VAR_11, sizeof(Minima), minima_cmp);



    for(; VAR_11<VAR_9; VAR_11++){

        minima[VAR_11].height=256*256*256*64;

        minima[VAR_11].checked=0;

        minima[VAR_11].VAR_12= minima[VAR_11].VAR_13=0;

    }



    for(VAR_10=0; VAR_10<VAR_9; VAR_10++){

        const int VAR_12= minima[VAR_10].VAR_12;

        const int VAR_13= minima[VAR_10].VAR_13;

        int VAR_15;



        if(minima[VAR_10].checked) continue;



        if(   VAR_12 >= xmax || VAR_12 <= xmin

           || VAR_13 >= ymax || VAR_13 <= ymin)

           continue;



        SAB_CHECK_MV(VAR_12-1, VAR_13)

        SAB_CHECK_MV(VAR_12+1, VAR_13)

        SAB_CHECK_MV(VAR_12  , VAR_13-1)

        SAB_CHECK_MV(VAR_12  , VAR_13+1)



        minima[VAR_10].checked= 1;

    }



    VAR_1[0]= minima[0].VAR_12;

    VAR_1[1]= minima[0].VAR_13;

    VAR_2= minima[0].height;



    if(   VAR_1[0] < xmax && VAR_1[0] > xmin

       && VAR_1[1] < ymax && VAR_1[1] > ymin){

        int VAR_15;

        

        CHECK_MV(VAR_1[0]-1, VAR_1[1])

        CHECK_MV(VAR_1[0]+1, VAR_1[1])

        CHECK_MV(VAR_1[0], VAR_1[1]-1)

        CHECK_MV(VAR_1[0], VAR_1[1]+1)

    }

    return VAR_2;

}

static int FUNC_0(MpegEncContext * VAR_0, int *VAR_1, int VAR_2,
int VAR_3, int VAR_4, int const VAR_5,
int VAR_6, int VAR_7, int VAR_8)
{ MotionEstContext * const c= &VAR_0->me; me_cmp_func cmpf, chroma_cmpf; Minima minima[MAX_SAB_SIZE]; const int VAR_9= FFABS(c->dia_size); int VAR_10, VAR_11; LOAD_COMMON
LOAD_COMMON2
unsigned map_generation = c->map_generation; av_assert1(VAR_9 <= MAX_SAB_SIZE); cmpf        = VAR_0->mecc.me_cmp[VAR_6]; chroma_cmpf = VAR_0->mecc.me_cmp[VAR_6 + 1]; for(VAR_11=VAR_10=0; VAR_10<ME_MAP_SIZE && VAR_11<MAX_SAB_SIZE; VAR_10++){ uint32_t key= map[VAR_10]; key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1)); if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue; minima[VAR_11].height= score_map[VAR_10]; minima[VAR_11].VAR_12= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS; minima[VAR_11].VAR_13= key & ((1<<ME_MAP_MV_BITS)-1); minima[VAR_11].VAR_12-= (1<<(ME_MAP_MV_BITS-1)); minima[VAR_11].VAR_13-= (1<<(ME_MAP_MV_BITS-1)); if(   minima[VAR_11].VAR_12 > xmax || minima[VAR_11].VAR_12 < xmin
|| minima[VAR_11].VAR_13 > ymax || minima[VAR_11].VAR_13 < ymin)
continue; minima[VAR_11].checked=0; if(minima[VAR_11].VAR_12 || minima[VAR_11].VAR_13)
minima[VAR_11].height+= (mv_penalty[((minima[VAR_11].VAR_12)<<shift)-pred_x] + mv_penalty[((minima[VAR_11].VAR_13)<<shift)-pred_y])*VAR_5; VAR_11++; } qsort(minima, VAR_11, sizeof(Minima), minima_cmp); for(; VAR_11<VAR_9; VAR_11++){ minima[VAR_11].height=256*256*256*64; minima[VAR_11].checked=0; minima[VAR_11].VAR_12= minima[VAR_11].VAR_13=0; } for(VAR_10=0; VAR_10<VAR_9; VAR_10++){ const int VAR_12= minima[VAR_10].VAR_12; const int VAR_13= minima[VAR_10].VAR_13; int VAR_15; if(minima[VAR_10].checked) continue; if(   VAR_12 >= xmax || VAR_12 <= xmin
|| VAR_13 >= ymax || VAR_13 <= ymin)
continue; SAB_CHECK_MV(VAR_12-1, VAR_13)
SAB_CHECK_MV(VAR_12+1, VAR_13)
SAB_CHECK_MV(VAR_12  , VAR_13-1)
SAB_CHECK_MV(VAR_12  , VAR_13+1)
minima[VAR_10].checked= 1; } VAR_1[0]= minima[0].VAR_12; VAR_1[1]= minima[0].VAR_13; VAR_2= minima[0].height; if(   VAR_1[0] < xmax && VAR_1[0] > xmin
&& VAR_1[1] < ymax && VAR_1[1] > ymin){ int VAR_15; CHECK_MV(VAR_1[0]-1, VAR_1[1])
CHECK_MV(VAR_1[0]+1, VAR_1[1])
CHECK_MV(VAR_1[0], VAR_1[1]-1)
CHECK_MV(VAR_1[0], VAR_1[1]+1)
} return VAR_2; }