mot_est_comp.c
上传用户:enenge
上传日期:2007-01-08
资源大小:96k
文件大小:21k
- /**************************************************************************
- * *
- * This code is developed by Adam Li. This software is an *
- * implementation of a part of one or more MPEG-4 Video tools as *
- * specified in ISO/IEC 14496-2 standard. Those intending to use this *
- * software module in hardware or software products are advised that its *
- * use may infringe existing patents or copyrights, and any such use *
- * would be at such party's own risk. The original developer of this *
- * software module and his/her company, and subsequent editors and their *
- * companies (including Project Mayo), will have no liability for use of *
- * this software or modifications or derivatives thereof. *
- * *
- * Project Mayo gives users of the Codec a license to this software *
- * module or modifications thereof for use in hardware or software *
- * products claiming conformance to the MPEG-4 Video Standard as *
- * described in the Open DivX license. *
- * *
- * The complete Open DivX license can be found at *
- * http://www.projectmayo.com/opendivx/license.php . *
- * *
- **************************************************************************/
- /**************************************************************************
- *
- * mot_est_comp.c
- *
- * Copyright (C) 2001 Project Mayo
- *
- * Adam Li
- *
- * DivX Advance Research Center <darc@projectmayo.com>
- *
- **************************************************************************/
- /* This file contains some functions to do motion estimation and */
- /* for the current image in one pass. */
- /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
- /* Please see seperate acknowledgement file for a list of contributors. */
- #include "vm_common_defs.h"
- #include "mom_util.h"
- #include "mot_util.h"
- #include "mot_est_mb.h"
- extern FILE *ftrace;
- /* For correct rounding of chrominance vectors */
- static Int roundtab16[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
- Void MotionEstCompPicture (
- SInt *curr,
- SInt *prev,
- SInt *prev_ipol_y,
- SInt *prev_ipol_u,
- SInt *prev_ipol_v,
- Int prev_x,
- Int prev_y,
- Int vop_width,
- Int vop_height,
- Int enable_8x8_mv,
- Int edge,
- Int sr_for,
- Int f_code,
- Int rounding_type,
- Int br_x,
- Int br_y,
- Int br_width,
- Int br_height,
- SInt *curr_comp_y,
- SInt *curr_comp_u,
- SInt *curr_comp_v,
- Float *mad,
- Float *mv16_w,
- Float *mv16_h,
- Float *mv8_w,
- Float *mv8_h,
- SInt *mode16
- );
- Void GetPred_Chroma (
- Int x_curr,
- Int y_curr,
- Int dx,
- Int dy,
- SInt *prev_u,
- SInt *prev_v,
- SInt *comp_u,
- SInt *comp_v,
- Int width,
- Int width_prev,
- Int prev_x_min,
- Int prev_y_min,
- Int prev_x_max,
- Int prev_y_max,
- Int rounding_control
- );
- /***********************************************************CommentBegin******
- *
- * -- MotionEstimationCompensation -- Estimates the motion vectors and
- * do motion compensation
- *
- * Purpose :
- * Estimates the motion vectors in advanced/not_advanced unrestricted
- * mode. The output are four images containing x/y components of
- * MV's (one per 8x8 block), modes (one value per MB). The motion
- * compensation is also performed.
- *
- * Description :
- * 1) memory is allocated for these images.
- * 2) mot_x/mot_y have 4 identical vector for a MB coded inter 16
- * 3) mot_x/mot_y have 4 identical zero vectors for a MB coded intra
- * 4) if _NO_ESTIMATION_ is used, the output is the following:
- * - mot_x : all MV's are 0.0
- * - mot_y : all MV's are 0.0
- * - mode : all modes are MB_INTRA (IGNORING THE SHAPE)
- *
- * Based on: CodeOneOrTwo (TMN5, coder.c)
- *
- ***********************************************************CommentEnd********/
- Void
- MotionEstimationCompensation (
- Vop *curr_vop, /* <-- current Vop (for luminance) */
- Vop *prev_rec_vop, /* <-- reference Vop (reconstructed)(1/2 pixel) */
- Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
- Int edge, /* <-- restricted(==0)/unrestricted(==edge) mode */
- Int f_code, /* <-- MV search range 1/2 pel: 1=32,2=64,...,7=2048*/
- Vop *curr_comp_vop, /* <-> motion compensated current VOP */
- Float *mad, /* <-> mad value of the ME/MC result */
- Image **mot_x, /* --> horizontal MV coordinates */
- Image **mot_y, /* --> vertical MV coordinates */
- Image **mode /* --> modes for each MB */
- )
- {
- Image *pr_rec_y; /* Reference image (reconstructed) */
- Image *pi_y; /* Interp.ref.image Y */
- Image *mode16;
- Image *mv16_w;
- Image *mv16_h;
- Image *mv8_w;
- Image *mv8_h;
- SInt *prev_ipol_y, /* Interp.ref.image Y (subimage) */
- *prev_orig_y; /* Ref. original image with edge (subimage) */
- Int vop_width, vop_height;
- Int br_x;
- Int br_y;
- Int br_height;
- Int br_width;
- Int mv_h, mv_w;
- /*GETBBR*/
- br_y=curr_vop->ver_spat_ref;
- br_x=curr_vop->hor_spat_ref;
- br_height=curr_vop->height;
- br_width=curr_vop->width;
- mv_h=br_height/MB_SIZE;
- mv_w=br_width/MB_SIZE;
- /*
- ** WE SUPPOSE prev_rec_vop & prev_vop HAVE EQUAL SIZE AND POSITIONS
- */
- vop_width=prev_rec_vop->width;
- vop_height=prev_rec_vop->height;
- /*
- ** Get images and interpolate them
- */
- pr_rec_y = prev_rec_vop->y_chan;
- prev_orig_y = (SInt*)GetImageData(pr_rec_y);
- pi_y = AllocImage (2*vop_width, 2*vop_height, SHORT_TYPE);
- InterpolateImage(pr_rec_y, pi_y, GetVopRoundingType(curr_vop));
- prev_ipol_y = (SInt*)GetImageData(pi_y);
- /*
- * allocate memory for mv's and modes data
- *
- */
- mode16=AllocImage (mv_w,mv_h,SHORT_TYPE);
- SetConstantImage (mode16,(Float)MBM_INTRA);
- /*
- ** mv16 have 2x2 repeted the mv value to share the functions of
- ** mv prediction between CodeVopVotion and MotionEstimation
- */
- mv16_w=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
- mv16_h=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
- mv8_w =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
- mv8_h =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
- SetConstantImage (mv16_h,+0.0);
- SetConstantImage (mv16_w,+0.0);
- SetConstantImage (mv8_h,+0.0);
- SetConstantImage (mv8_w,+0.0);
- SetConstantImage (curr_comp_vop->u_chan, 0);
- SetConstantImage (curr_comp_vop->v_chan, 0);
- /* Compute motion vectors and modes for each MB
- ** (TMN5 functions)
- */
- MotionEstCompPicture(
- (SInt *)GetImageData(GetVopY(curr_vop)), //curr_vop,
- prev_orig_y, /* Y padd with edge */
- prev_ipol_y, /* Y interpolated (from pi_y) */
- (SInt*)GetImageData(prev_rec_vop->u_chan) + (vop_width/2) * (16/2) + (16/2),
- (SInt*)GetImageData(prev_rec_vop->v_chan) + (vop_width/2) * (16/2) + (16/2),
- prev_rec_vop->hor_spat_ref,
- prev_rec_vop->ver_spat_ref,
- vop_width,vop_height,
- enable_8x8_mv,
- edge,
- GetVopSearchRangeFor(curr_vop),
- f_code,
- GetVopRoundingType(curr_vop),
- br_x,br_y, /* pos. of the bounding rectangle */
- br_width,br_height, /* dims. of the bounding rectangle */
- (SInt*)GetImageData(curr_comp_vop->y_chan),
- (SInt*)GetImageData(curr_comp_vop->u_chan),
- (SInt*)GetImageData(curr_comp_vop->v_chan),
- mad,
- (Float*)GetImageData(mv16_w),
- (Float*)GetImageData(mv16_h),
- (Float*)GetImageData(mv8_w),
- (Float*)GetImageData(mv8_h),
- (SInt*) GetImageData(mode16)
- );
- /* Convert output to MOMUSYS format */
- GetMotionImages(mv16_w, mv16_h, mv8_w, mv8_h, mode16, mot_x, mot_y, mode);
- /* Deallocate dynamic memory */
- FreeImage(mv16_w); FreeImage(mv16_h);
- FreeImage(mv8_w); FreeImage(mv8_h);
- FreeImage(mode16);
- FreeImage(pi_y);
- }
- /***********************************************************CommentBegin******
- *
- * -- MotionEstCompPicture -- Computes MV's and predictor errors and
- * do motion compensation
- *
- * Purpose :
- * Computes MV's (8x8 and 16x16) and predictor errors for the whole
- * vop. Perform motion compensation for the whole vop.
- *
- ***********************************************************CommentEnd********/
- Void
- MotionEstCompPicture(
- SInt *curr, /* <-- Current VOP */
- SInt *prev, /* <-- Original Y padd with edge */
- SInt *prev_ipol, /* <-- Y interpolated (from pi_y) */
- SInt *prev_u, /* <-- Original U padd with edge */
- SInt *prev_v, /* <-- Original V padd with edge */
- Int prev_x, /* <-- absolute horiz. position of previous vop */
- Int prev_y, /* <-- absolute verti. position of previous vop */
- Int vop_width, /* <-- horizontal previous vop dimension */
- Int vop_height, /* <-- vertical previous vop dimension */
- Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
- Int edge, /* <-- edge arround the reference vop */
- Int sr_for, /* <-- forward search range */
- Int f_code, /* MW QPEL 07-JUL-1998 *//* <-- MV search range 1/2 or 1/4 pel: 1=32,2=64,...,7=2048*/
- Int rounding_type, /* <-- The rounding type of the current vop */
- Int br_x, /* <-- absolute horiz. position of the current vop */
- Int br_y, /* <-- absolute verti. position of the current vop */
- Int br_width, /* <-- current bounding rectangule width */
- Int br_height, /* <-- current bounding rectangle height */
- SInt *curr_comp_y, /* <-> motion compensated current Y */
- SInt *curr_comp_u, /* <-> motion compensated current U */
- SInt *curr_comp_v, /* <-> motion compensated current V */
- Float *mad, /* <-> the mad value of current ME/MC result */
- Float *mv16_w, /* --> predicted horizontal 16x16 MV(if approp.) */
- Float *mv16_h, /* --> predicted vertical 16x16 MV (if approp.) */
- Float *mv8_w, /* --> predicted horizontal 8x8 MV (if approp.) */
- Float *mv8_h, /* --> predicted vertical 8x8 MV (if approp.) */
- SInt *mode16 /* --> mode of the preditect motion vector */
- )
- {
- Int i, j, k;
- SInt curr_mb[MB_SIZE][MB_SIZE];
- SInt curr_comp_mb_16[MB_SIZE][MB_SIZE];
- SInt curr_comp_mb_8[MB_SIZE][MB_SIZE];
- Int sad8 = MV_MAX_ERROR, sad16, sad;
- Int imas_w, imas_h, Mode;
- Int posmode, pos16, pos8;
- Int min_error16,
- min_error8_0, min_error8_1, min_error8_2, min_error8_3;
- // SInt *curr = (SInt *)GetImageData(GetVopY(curr_vop));
- /***************************************************************************
- array of flags, which contains for the MB and for each one of the 4 Blocks
- the following info sequentially:
- xm, 1 if the lower search (x axis) is completed (no 1/2 search can be done)
- 0, do 1/2 search in the lower bound (x axis)
- xM, 1 if the upper search (x axis) is completed (no 1/2 search can be done)
- 0, do 1/2 search in the upper bound (x axis)
- ym, 1 if the lower search (y axis) is completed (no 1/2 search can be done)
- 0, do 1/2 search in the lower bound (y axis)
- yM, 1 if the upper search (y axis) is completed (no 1/2 search can be done)
- 0, do 1/2 search in the upper bound (y axis)
- ***************************************************************************/
- SInt *halfpelflags;
- Float hint_mv_w, hint_mv_h;
- Int xsum,ysum,dx,dy;
- Int prev_x_min,prev_x_max,prev_y_min,prev_y_max;
- prev_x_min = 2 * prev_x + 2 * 16;
- prev_y_min = 2 * prev_y + 2 * 16;
- prev_x_max = prev_x_min + 2 * vop_width - 4 * 16;
- prev_y_max = prev_y_min + 2 * vop_height - 4 * 16;
- imas_w=br_width/MB_SIZE;
- imas_h=br_height/MB_SIZE;
- /* Do motion estimation and store result in array */
- halfpelflags=(SInt*)malloc(5*4*sizeof(SInt));
- /* halfpelflags=(SInt*)malloc(9*4*sizeof(SInt)); */
- sad = 0;
- for ( j=0; j< (br_height/MB_SIZE); j++)
- {
- hint_mv_w = hint_mv_h = 0.f;
- for ( i=0; i< (br_width/MB_SIZE); i++)
- {
- /* Integer pel search */
- Int min_error;
- posmode = j * imas_w + i;
- pos16 = pos8 = 2*j*2*imas_w + 2*i;
- MBMotionEstimation(curr,
- prev, br_x, br_y,
- br_width, i, j, prev_x, prev_y,
- vop_width, vop_height, enable_8x8_mv, edge,
- f_code, sr_for,
- hint_mv_w, hint_mv_h, // the hint seeds
- mv16_w, mv16_h,
- mv8_w, mv8_h, &min_error, halfpelflags);
- /* Inter/Intra decision */
- Mode = ChooseMode(curr,
- i*MB_SIZE,j*MB_SIZE, min_error, br_width);
- hint_mv_w = mv16_w[pos16];
- hint_mv_h = mv16_h[pos16];
- LoadArea(curr, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, (SInt *)curr_mb);
- /* 0==MBM_INTRA,1==MBM_INTER16||MBM_INTER8 */
- if ( Mode != 0)
- {
- FindSubPel (i*MB_SIZE,j*MB_SIZE, prev_ipol,
- &curr_mb[0][0], 16, 16 , 0,
- br_x-prev_x,br_y-prev_y,vop_width, vop_height,
- edge, halfpelflags, &curr_comp_mb_16[0][0],
- &mv16_w[pos16], &mv16_h[pos16], &min_error16);
- /* sad16(0,0) already decreased by Nb/2+1 in FindHalfPel() */
- sad16 = min_error16;
- mode16[posmode] = MBM_INTER16;
- if (enable_8x8_mv)
- {
- xsum = 0; ysum = 0;
- FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
- &curr_mb[0][0], 8, 8 , 0,
- br_x-prev_x,br_y-prev_y, vop_width, vop_height,
- edge, halfpelflags, &curr_comp_mb_8[0][0],
- &mv8_w[pos8], &mv8_h[pos8], &min_error8_0);
- xsum += (Int)(2*(mv8_w[pos8]));
- ysum += (Int)(2*(mv8_h[pos8]));
- FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
- &curr_mb[0][8], 8, 8 , 1,
- br_x-prev_x,br_y-prev_y, vop_width,vop_height,
- edge, halfpelflags, &curr_comp_mb_8[0][8],
- &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_1);
- xsum += (Int)(2*(mv8_w[pos8+1]));
- ysum += (Int)(2*(mv8_h[pos8+1]));
- pos8+=2*imas_w;
- FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
- &curr_mb[8][0], 8, 8 , 2,
- br_x-prev_x,br_y-prev_y, vop_width,vop_height,
- edge, halfpelflags, &curr_comp_mb_8[8][0],
- &mv8_w[pos8], &mv8_h[pos8], &min_error8_2);
- xsum += (Int)(2*(mv8_w[pos8]));
- ysum += (Int)(2*(mv8_h[pos8]));
- FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
- &curr_mb[8][8], 8, 8 , 3,
- br_x-prev_x,br_y-prev_y, vop_width,vop_height,
- edge, halfpelflags, &curr_comp_mb_8[8][8],
- &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_3);
- xsum += (Int)(2*(mv8_w[pos8+1]));
- ysum += (Int)(2*(mv8_h[pos8+1]));
- sad8 = min_error8_0+min_error8_1+min_error8_2+min_error8_3;
- /* Choose 8x8 or 16x16 vectors */
- if (sad8 < (sad16 -(128+1)))
- mode16[posmode] = MBM_INTER8;
- } /* end of enable_8x8_mv mode */
- /* When choose 16x16 vectors */
- /* sad16(0,0) was decreased by MB_Nb, now add it back */
- if ((mv16_w[pos16]==0.0) && (mv16_h[pos16]==0.0) && (mode16[posmode]==MBM_INTER16))
- sad16 += 128+1;
- /* calculate motion vectors for chroma compensation */
- if(mode16[posmode] == MBM_INTER8)
- {
- dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);
- dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);
- sad += sad8;
- }
- else /* mode == MBM_INTER16 */
- {
- dx = (Int)(2 * mv16_w[pos16]);
- dy = (Int)(2 * mv16_h[pos16]);
- dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
- dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
- sad += sad16;
- }
- GetPred_Chroma (i*MB_SIZE, j*MB_SIZE, dx, dy,
- prev_u, prev_v, curr_comp_u, curr_comp_v,
- br_width, vop_width,
- prev_x_min/4,prev_y_min/4,prev_x_max/4,prev_y_max/4, rounding_type);
- } /* end of mode non zero */
- else /* mode = 0 INTRA */
- {
- mode16[posmode] = MBM_INTRA;
- for (k = 0; k < MB_SIZE*MB_SIZE; k++)
- {
- // for INTRA MB, set compensated 0 to generate correct error image
- curr_comp_mb_16[k/MB_SIZE][k%MB_SIZE] = 0;
- // for INTRA_MB, SAD is recalculated from image instead of using min_error
- sad += curr_mb[k/MB_SIZE][k%MB_SIZE];
- }
- }
- if (mode16[posmode] == MBM_INTER8)
- SetArea((SInt*)curr_comp_mb_8, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
- else
- SetArea((SInt*)curr_comp_mb_16, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
- } /* end of i loop */
- } /* end of j loop */
- *mad = (float)sad/(br_width*br_height);
- free((Char*)halfpelflags);
- return;
- }
- /***********************************************************CommentBegin******
- *
- * unrestricted_MC_chro
- *
- * Purpose :
- * To make unrestricted MC
- *
- ***********************************************************CommentEnd********/
- /*Int unrestricted_MC_chro(Int x,Int y, Int npix,
- Int prev_x_min,Int prev_y_min,
- Int prev_x_max, Int prev_y_max)
- {
- if (x < prev_x_min) x = prev_x_min;
- else if (x >=prev_x_max) x = prev_x_max-1;
- if (y < prev_y_min) y = prev_y_min;
- else if (y >=prev_y_max) y = prev_y_max-1;
- return(x+y*npix);
- }*/
- #define unrestricted_MC_chro(x,y,npix,prev_x_min,prev_y_min,prev_x_max,prev_y_max) ((x)+(y)*(npix))
- /***********************************************************CommentBegin******
- *
- * -- GetPred_Chroma -- Predicts chrominance macroblock
- *
- * Purpose :
- * Does the chrominance prediction for P-frames
- *
- * Arguments in :
- * current position in image,
- * motionvectors,
- * pointers to compensated and previous Vops,
- * width of the compensated Vop
- * width of the previous/reference Vop
- *
- ***********************************************************CommentEnd********/
- Void GetPred_Chroma (
- Int x_curr,
- Int y_curr,
- Int dx,
- Int dy,
- SInt *prev_u,
- SInt *prev_v,
- SInt *comp_u,
- SInt *comp_v,
- Int width,
- Int width_prev,
- Int prev_x_min,
- Int prev_y_min,
- Int prev_x_max,
- Int prev_y_max,
- Int rounding_control)
- {
- Int m,n;
- Int x, y, ofx, ofy, lx;
- Int xint, yint;
- Int xh, yh;
- Int index1,index2,index3,index4;
- lx = width_prev/2;
- x = x_curr>>1;
- y = y_curr>>1;
- xint = dx>>1;
- xh = dx & 1;
- yint = dy>>1;
- yh = dy & 1;
- if (!xh && !yh)
- {
- for (n = 0; n < 8; n++)
- {
- for (m = 0; m < 8; m++)
- {
- ofx = x + xint + m;
- ofy = y + yint + n;
- index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- comp_u[(y+n)*width/2+x+m]
- = *(prev_u+index1);
- comp_v[(y+n)*width/2+x+m]
- = *(prev_v+index1);
- }
- }
- }
- else if (!xh && yh)
- {
- for (n = 0; n < 8; n++)
- {
- for (m = 0; m < 8; m++)
- {
- ofx = x + xint + m;
- ofy = y + yint + n;
- index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- index2 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- comp_u[(y+n)*width/2+x+m]
- = (*(prev_u+index1) +
- *(prev_u+index2) + 1- rounding_control)>>1;
- comp_v[(y+n)*width/2+x+m]
- = (*(prev_v+index1) +
- *(prev_v+index2) + 1- rounding_control)>>1;
- }
- }
- }
- else if (xh && !yh)
- {
- for (n = 0; n < 8; n++)
- {
- for (m = 0; m < 8; m++)
- {
- ofx = x + xint + m;
- ofy = y + yint + n;
- index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- comp_u[(y+n)*width/2+x+m]
- = (*(prev_u+index1) +
- *(prev_u+index2) + 1- rounding_control)>>1;
- comp_v[(y+n)*width/2+x+m]
- = (*(prev_v+index1) +
- *(prev_v+index2) + 1- rounding_control)>>1;
- }
- }
- }
- else
- { /* xh && yh */
- for (n = 0; n < 8; n++)
- {
- for (m = 0; m < 8; m++)
- {
- ofx = x + xint + m;
- ofy = y + yint + n;
- index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- index3 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- index4 = unrestricted_MC_chro(ofx+xh,ofy+yh,lx,prev_x_min,
- prev_y_min,prev_x_max,prev_y_max);
- comp_u[(y+n)*width/2+x+m]
- = (*(prev_u+index1)+
- *(prev_u+index2)+
- *(prev_u+index3)+
- *(prev_u+index4)+
- 2- rounding_control)>>2;
- comp_v[(y+n)*width/2+x+m]
- = (*(prev_v+index1)+
- *(prev_v+index2)+
- *(prev_v+index3)+
- *(prev_v+index4)+
- 2- rounding_control)>>2;
- }
- }
- }
- return;
- }