*(int32_t*)mv_cache[1][0]= *(int32_t*)s->motion_val[mot_xy-1]; *(int32_t*)mv_cache[2][0]= *(int32_t*)s->motion_val[mot_xy-1+mot_stride];
*(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1]; *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride];
static inline void MPV_motion(MpegEncContext *s,                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,                              int dir, uint8_t **ref_picture,                               op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16]){    int dxy, mx, my, src_x, src_y, motion_x, motion_y;    int mb_x, mb_y, i;    uint8_t *ptr, *dest;    mb_x = s->mb_x;    mb_y = s->mb_y;    if(s->obmc && s->pict_type != B_TYPE){        int16_t mv_cache[4][4][2];        const int xy= s->mb_x + s->mb_y*s->mb_stride;        const int mot_stride= s->mb_width*2 + 2;        const int mot_xy= 1 + mb_x*2 + (mb_y*2 + 1)*mot_stride;        assert(!s->mb_skiped);                        memcpy(mv_cache[1][1], s->motion_val[mot_xy           ], sizeof(int16_t)*4);        memcpy(mv_cache[2][1], s->motion_val[mot_xy+mot_stride], sizeof(int16_t)*4);        memcpy(mv_cache[3][1], s->motion_val[mot_xy+mot_stride], sizeof(int16_t)*4);        if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){            memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);        }else{            memcpy(mv_cache[0][1], s->motion_val[mot_xy-mot_stride], sizeof(int16_t)*4);        }        if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){            *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1];            *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1];        }else{            *(int32_t*)mv_cache[1][0]= *(int32_t*)s->motion_val[mot_xy-1];            *(int32_t*)mv_cache[2][0]= *(int32_t*)s->motion_val[mot_xy-1+mot_stride];        }        if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){            *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2];            *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2];        }else{            *(int32_t*)mv_cache[1][3]= *(int32_t*)s->motion_val[mot_xy+2];            *(int32_t*)mv_cache[2][3]= *(int32_t*)s->motion_val[mot_xy+2+mot_stride];        }                mx = 0;        my = 0;        for(i=0;i<4;i++) {            const int x= (i&1)+1;            const int y= (i>>1)+1;            int16_t mv[5][2]= {                {mv_cache[y][x  ][0], mv_cache[y][x  ][1]},                {mv_cache[y-1][x][0], mv_cache[y-1][x][1]},                {mv_cache[y][x-1][0], mv_cache[y][x-1][1]},                {mv_cache[y][x+1][0], mv_cache[y][x+1][1]},                {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};            //FIXME cleanup            obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,                        ref_picture[0],                        mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,                        pix_op[1],                        mv);            mx += mv[0][0];            my += mv[0][1];        }        if(!(s->flags&CODEC_FLAG_GRAY))            chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);        return;    }       switch(s->mv_type) {    case MV_TYPE_16X16:#ifdef CONFIG_RISKY        if(s->mcsel){            if(s->real_sprite_warping_points==1){                gmc1_motion(s, dest_y, dest_cb, dest_cr, 0,                            ref_picture, 0);            }else{                gmc_motion(s, dest_y, dest_cb, dest_cr, 0,                            ref_picture, 0);            }        }else if(s->quarter_sample){            qpel_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture, 0,                        0, pix_op, qpix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 16);        }else if(s->mspel){            ff_mspel_motion(s, dest_y, dest_cb, dest_cr,                        ref_picture, pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 16);        }else#endif        {            mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture, 0,                        0, pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 16);        }                   break;    case MV_TYPE_8X8:        mx = 0;        my = 0;        if(s->quarter_sample){            for(i=0;i<4;i++) {                motion_x = s->mv[dir][i][0];                motion_y = s->mv[dir][i][1];                dxy = ((motion_y & 3) << 2) | (motion_x & 3);                src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;                src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;                                    /* WARNING: do no forget half pels */                src_x = clip(src_x, -16, s->width);                if (src_x == s->width)                    dxy &= ~3;                src_y = clip(src_y, -16, s->height);                if (src_y == s->height)                    dxy &= ~12;                                    ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);                if(s->flags&CODEC_FLAG_EMU_EDGE){                    if(   (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8                        || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){                        ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);                        ptr= s->edge_emu_buffer;                    }                }                dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;                qpix_op[1][dxy](dest, ptr, s->linesize);                mx += s->mv[dir][i][0]/2;                my += s->mv[dir][i][1]/2;            }        }else{            for(i=0;i<4;i++) {                hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,                            ref_picture[0],                            mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,                            s->width, s->height, s->linesize,                            s->h_edge_pos, s->v_edge_pos,                            8, 8, pix_op[1],                            s->mv[dir][i][0], s->mv[dir][i][1]);                mx += s->mv[dir][i][0];                my += s->mv[dir][i][1];            }        }        if(!(s->flags&CODEC_FLAG_GRAY))            chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);        break;    case MV_TYPE_FIELD:        if (s->picture_structure == PICT_FRAME) {            if(s->quarter_sample){                /* top field */                qpel_motion(s, dest_y, dest_cb, dest_cr, 0,                            ref_picture, s->field_select[dir][0] ? s->linesize : 0,                            1, pix_op, qpix_op,                            s->mv[dir][0][0], s->mv[dir][0][1], 8);                /* bottom field */                qpel_motion(s, dest_y, dest_cb, dest_cr, s->linesize,                            ref_picture, s->field_select[dir][1] ? s->linesize : 0,                            1, pix_op, qpix_op,                            s->mv[dir][1][0], s->mv[dir][1][1], 8);            }else{                /* top field */                       mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                            ref_picture, s->field_select[dir][0] ? s->linesize : 0,                            1, pix_op,                            s->mv[dir][0][0], s->mv[dir][0][1], 8);                /* bottom field */                mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,                            ref_picture, s->field_select[dir][1] ? s->linesize : 0,                            1, pix_op,                            s->mv[dir][1][0], s->mv[dir][1][1], 8);            }        } else {            int offset;            if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){                offset= s->field_select[dir][0] ? s->linesize : 0;            }else{                ref_picture= s->current_picture.data;                offset= s->field_select[dir][0] ? s->linesize : -s->linesize;             }             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture, offset,                        0, pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 16);        }        break;    case MV_TYPE_16X8:{        int offset;         uint8_t ** ref2picture;            if(s->picture_structure == s->field_select[dir][0] + 1 || s->pict_type == B_TYPE || s->first_field){                ref2picture= ref_picture;                offset= s->field_select[dir][0] ? s->linesize : 0;            }else{                ref2picture= s->current_picture.data;                offset= s->field_select[dir][0] ? s->linesize : -s->linesize;             }             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref2picture, offset,                        0, pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 8);            if(s->picture_structure == s->field_select[dir][1] + 1 || s->pict_type == B_TYPE || s->first_field){                ref2picture= ref_picture;                offset= s->field_select[dir][1] ? s->linesize : 0;            }else{                ref2picture= s->current_picture.data;                offset= s->field_select[dir][1] ? s->linesize : -s->linesize;             }             // I know it is ugly but this is the only way to fool emu_edge without rewrite mpeg_motion            mpeg_motion(s, dest_y+16*s->linesize, dest_cb+8*s->uvlinesize, dest_cr+8*s->uvlinesize,                        0,                        ref2picture, offset,                        0, pix_op,                        s->mv[dir][1][0], s->mv[dir][1][1]+16, 8);        }                break;    case MV_TYPE_DMV:    {    op_pixels_func (*dmv_pix_op)[4];    int offset;        dmv_pix_op = s->dsp.put_pixels_tab;        if(s->picture_structure == PICT_FRAME){            //put top field from top field            mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture, 0,                        1, dmv_pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 8);            //put bottom field from bottom field            mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,                        ref_picture, s->linesize,                        1, dmv_pix_op,                        s->mv[dir][0][0], s->mv[dir][0][1], 8);            dmv_pix_op = s->dsp.avg_pixels_tab;                     //avg top field from bottom field            mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture, s->linesize,                        1, dmv_pix_op,                        s->mv[dir][2][0], s->mv[dir][2][1], 8);            //avg bottom field from top field            mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,                        ref_picture, 0,                        1, dmv_pix_op,                        s->mv[dir][3][0], s->mv[dir][3][1], 8);        }else{            offset=(s->picture_structure == PICT_BOTTOM_FIELD)?                          s->linesize : 0;            //put field from the same parity            //same parity is never in the same frame            mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,                        ref_picture,offset,                        0,dmv_pix_op,                        s->mv[dir][0][0],s->mv[dir][0][1],16);            // after put we make avg of the same block            dmv_pix_op=s->dsp.avg_pixels_tab;             //opposite parity is always in the same frame if this is second field            if(!s->first_field){                ref_picture = s->current_picture.data;                    //top field is one linesize from frame beginig                offset=(s->picture_structure == PICT_BOTTOM_FIELD)?                         -s->linesize : s->linesize;            }else                 offset=(s->picture_structure == PICT_BOTTOM_FIELD)?                         0 : s->linesize;            //avg field from the opposite parity            mpeg_motion(s, dest_y, dest_cb, dest_cr,0,                        ref_picture, offset,                        0,dmv_pix_op,                        s->mv[dir][2][0],s->mv[dir][2][1],16);        }    }    break;    default: assert(0);    }}