const int time_bp= time_pp - time_pb; int bx, by; int mx, my, mx2, my2; uint8_t *ref_picture= s->me_scratchpad - (mb_x - 1 + (mb_y - 1)*s->linesize)*16;
int mx, my, xmin, xmax, ymin, ymax;
static inline int direct_search(MpegEncContext * s,                                int mb_x, int mb_y){    int P[10][2];    const int mot_stride = s->mb_width + 2;    const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;    int dmin, dmin2;    int motion_fx, motion_fy, motion_bx, motion_by, motion_bx0, motion_by0;    int motion_dx, motion_dy;    const int motion_px= s->p_mv_table[mot_xy][0];    const int motion_py= s->p_mv_table[mot_xy][1];    const int time_pp= s->pp_time;    const int time_pb= s->pb_time;    const int time_bp= time_pp - time_pb;    int bx, by;    int mx, my, mx2, my2;    uint8_t *ref_picture= s->me_scratchpad - (mb_x - 1 + (mb_y - 1)*s->linesize)*16;    int16_t (*mv_table)[2]= s->b_direct_mv_table;/*    uint16_t *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; */ // f_code of the prev frame    /* thanks to iso-mpeg the rounding is different for the zero vector, so we need to handle that ... */    motion_fx= (motion_px*time_pb)/time_pp;    motion_fy= (motion_py*time_pb)/time_pp;    motion_bx0= (-motion_px*time_bp)/time_pp;    motion_by0= (-motion_py*time_bp)/time_pp;    motion_dx= motion_dy=0;    dmin2= check_bidir_mv(s, mb_x, mb_y,                           motion_fx, motion_fy,                          motion_bx0, motion_by0,                          motion_fx, motion_fy,                          motion_bx0, motion_by0) - s->qscale;    motion_bx= motion_fx - motion_px;    motion_by= motion_fy - motion_py;    for(by=-1; by<2; by++){        for(bx=-1; bx<2; bx++){            uint8_t *dest_y = s->me_scratchpad + (by+1)*s->linesize*16 + (bx+1)*16;            uint8_t *ptr;            int dxy;            int src_x, src_y;            const int width= s->width;            const int height= s->height;            dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);            src_x = (mb_x + bx) * 16 + (motion_fx >> 1);            src_y = (mb_y + by) * 16 + (motion_fy >> 1);            src_x = clip(src_x, -16, width);            if (src_x == width) dxy &= ~1;            src_y = clip(src_y, -16, height);            if (src_y == height) dxy &= ~2;            ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x;            s->dsp.put_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);            dxy = ((motion_by & 1) << 1) | (motion_bx & 1);            src_x = (mb_x + bx) * 16 + (motion_bx >> 1);            src_y = (mb_y + by) * 16 + (motion_by >> 1);            src_x = clip(src_x, -16, width);            if (src_x == width) dxy &= ~1;            src_y = clip(src_y, -16, height);            if (src_y == height) dxy &= ~2;	    s->dsp.avg_pixels_tab[0][dxy](dest_y    , ptr    , s->linesize, 16);        }    }    P_LAST[0]        = mv_table[mot_xy    ][0];    P_LAST[1]        = mv_table[mot_xy    ][1];    P_LEFT[0]        = mv_table[mot_xy - 1][0];    P_LEFT[1]        = mv_table[mot_xy - 1][1];    P_LAST_RIGHT[0]  = mv_table[mot_xy + 1][0];    P_LAST_RIGHT[1]  = mv_table[mot_xy + 1][1];    P_LAST_BOTTOM[0] = mv_table[mot_xy + mot_stride][0];    P_LAST_BOTTOM[1] = mv_table[mot_xy + mot_stride][1];/*    if(P_LEFT[0]       > (rel_xmax<<shift)) P_LEFT[0]       = (rel_xmax<<shift);    if(P_LAST_RIGHT[0] < (rel_xmin<<shift)) P_LAST_RIGHT[0] = (rel_xmin<<shift);    if(P_LAST_BOTTOM[1]< (rel_ymin<<shift)) P_LAST_BOTTOM[1]= (rel_ymin<<shift);*/    /* special case for first line */    if ((mb_y == 0 || s->first_slice_line)) {    } else {        P_TOP[0] = mv_table[mot_xy - mot_stride             ][0];        P_TOP[1] = mv_table[mot_xy - mot_stride             ][1];        P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1         ][0];        P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1         ][1];            P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);        P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);    }    dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, -16, -16, 15, 15, ref_picture);    if(mx==0 && my==0) dmin=99999999; // not representable, due to rounding stuff    if(dmin2<dmin){         dmin= dmin2;        mx=0;        my=0;    }#if 1    mx2= mx= mx*2;     my2= my= my*2;    for(by=-1; by<2; by++){        if(my2+by < -32) continue;        for(bx=-1; bx<2; bx++){            if(bx==0 && by==0) continue;            if(mx2+bx < -32) continue;            dmin2= check_bidir_mv(s, mb_x, mb_y,                           mx2+bx+motion_fx, my2+by+motion_fy,                          mx2+bx+motion_bx, my2+by+motion_by,                          mx2+bx+motion_fx, my2+by+motion_fy,                          motion_bx, motion_by) - s->qscale;                        if(dmin2<dmin){                dmin=dmin2;                mx= mx2 + bx;                my= my2 + by;            }        }    }#else    mx*=2; my*=2;#endif    if(mx==0 && my==0){        motion_bx= motion_bx0;        motion_by= motion_by0;    }    s->b_direct_mv_table[mot_xy][0]= mx;    s->b_direct_mv_table[mot_xy][1]= my;    s->b_direct_forw_mv_table[mot_xy][0]= motion_fx + mx;    s->b_direct_forw_mv_table[mot_xy][1]= motion_fy + my;    s->b_direct_back_mv_table[mot_xy][0]= motion_bx + mx;    s->b_direct_back_mv_table[mot_xy][1]= motion_by + my;    return dmin;}