r1026: Videoscope layout tweaks.
[cinelerra_cv/ct.git] / quicktime / encore50 / mot_est_comp.c
blob31851b7a8427ce93fd8b4cdd12fe1580d2368e82
2 /**************************************************************************
3 * *
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
13 * *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
18 * *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
21 * *
22 **************************************************************************/
24 /**************************************************************************
26 * mot_est_comp.c
28 * Copyright (C) 2001 Project Mayo
30 * Adam Li
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some functions to do motion estimation and */
37 /* for the current image in one pass. */
38 /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
39 /* Please see seperate acknowledgement file for a list of contributors. */
41 #include "vm_common_defs.h"
42 #include "mom_util.h"
43 #include "mot_util.h"
44 #include "mot_est_mb.h"
46 extern FILE *ftrace;
48 /* For correct rounding of chrominance vectors */
49 static Int roundtab16[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
51 Void MotionEstCompPicture (
52 SInt *curr,
53 SInt *prev,
54 SInt *prev_ipol_y,
55 SInt *prev_ipol_u,
56 SInt *prev_ipol_v,
57 Int prev_x,
58 Int prev_y,
59 Int vop_width,
60 Int vop_height,
61 Int enable_8x8_mv,
62 Int edge,
63 Int sr_for,
64 Int f_code,
65 Int rounding_type,
66 Int br_x,
67 Int br_y,
68 Int br_width,
69 Int br_height,
70 SInt *curr_comp_y,
71 SInt *curr_comp_u,
72 SInt *curr_comp_v,
73 Float *mad,
74 Float *mv16_w,
75 Float *mv16_h,
76 Float *mv8_w,
77 Float *mv8_h,
78 SInt *mode16
80 Void GetPred_Chroma (
81 Int x_curr,
82 Int y_curr,
83 Int dx,
84 Int dy,
85 SInt *prev_u,
86 SInt *prev_v,
87 SInt *comp_u,
88 SInt *comp_v,
89 Int width,
90 Int width_prev,
91 Int prev_x_min,
92 Int prev_y_min,
93 Int prev_x_max,
94 Int prev_y_max,
95 Int rounding_control
98 /***********************************************************CommentBegin******
100 * -- MotionEstimationCompensation -- Estimates the motion vectors and
101 * do motion compensation
103 * Purpose :
104 * Estimates the motion vectors in advanced/not_advanced unrestricted
105 * mode. The output are four images containing x/y components of
106 * MV's (one per 8x8 block), modes (one value per MB). The motion
107 * compensation is also performed.
109 * Description :
110 * 1) memory is allocated for these images.
111 * 2) mot_x/mot_y have 4 identical vector for a MB coded inter 16
112 * 3) mot_x/mot_y have 4 identical zero vectors for a MB coded intra
113 * 4) if _NO_ESTIMATION_ is used, the output is the following:
114 * - mot_x : all MV's are 0.0
115 * - mot_y : all MV's are 0.0
116 * - mode : all modes are MB_INTRA (IGNORING THE SHAPE)
118 * Based on: CodeOneOrTwo (TMN5, coder.c)
120 ***********************************************************CommentEnd********/
122 Void
123 MotionEstimationCompensation (
124 Vop *curr_vop, /* <-- current Vop (for luminance) */
125 Vop *prev_rec_vop, /* <-- reference Vop (reconstructed)(1/2 pixel) */
126 Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
127 Int edge, /* <-- restricted(==0)/unrestricted(==edge) mode */
128 Int f_code, /* <-- MV search range 1/2 pel: 1=32,2=64,...,7=2048*/
129 Vop *curr_comp_vop, /* <-> motion compensated current VOP */
130 Float *mad, /* <-> mad value of the ME/MC result */
131 Image **mot_x, /* --> horizontal MV coordinates */
132 Image **mot_y, /* --> vertical MV coordinates */
133 Image **mode /* --> modes for each MB */
136 Image *pr_rec_y; /* Reference image (reconstructed) */
137 Image *pi_y; /* Interp.ref.image Y */
139 Image *mode16;
140 Image *mv16_w;
141 Image *mv16_h;
142 Image *mv8_w;
143 Image *mv8_h;
145 SInt *prev_ipol_y, /* Interp.ref.image Y (subimage) */
146 *prev_orig_y; /* Ref. original image with edge (subimage) */
148 Int vop_width, vop_height;
150 Int br_x;
151 Int br_y;
152 Int br_height;
153 Int br_width;
154 Int mv_h, mv_w;
156 /*GETBBR*/
157 br_y=curr_vop->ver_spat_ref;
158 br_x=curr_vop->hor_spat_ref;
159 br_height=curr_vop->height;
160 br_width=curr_vop->width;
161 mv_h=br_height/MB_SIZE;
162 mv_w=br_width/MB_SIZE;
165 ** WE SUPPOSE prev_rec_vop & prev_vop HAVE EQUAL SIZE AND POSITIONS
168 vop_width=prev_rec_vop->width;
169 vop_height=prev_rec_vop->height;
172 ** Get images and interpolate them
175 pr_rec_y = prev_rec_vop->y_chan;
176 prev_orig_y = (SInt*)GetImageData(pr_rec_y);
177 pi_y = AllocImage (2*vop_width, 2*vop_height, SHORT_TYPE);
178 InterpolateImage(pr_rec_y, pi_y, GetVopRoundingType(curr_vop));
179 prev_ipol_y = (SInt*)GetImageData(pi_y);
182 * allocate memory for mv's and modes data
186 mode16=AllocImage (mv_w,mv_h,SHORT_TYPE);
187 SetConstantImage (mode16,(Float)MBM_INTRA);
190 ** mv16 have 2x2 repeted the mv value to share the functions of
191 ** mv prediction between CodeVopVotion and MotionEstimation
194 mv16_w=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
195 mv16_h=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
196 mv8_w =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
197 mv8_h =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
198 SetConstantImage (mv16_h,+0.0);
199 SetConstantImage (mv16_w,+0.0);
200 SetConstantImage (mv8_h,+0.0);
201 SetConstantImage (mv8_w,+0.0);
203 SetConstantImage (curr_comp_vop->u_chan, 0);
204 SetConstantImage (curr_comp_vop->v_chan, 0);
206 /* Compute motion vectors and modes for each MB
207 ** (TMN5 functions)
210 MotionEstCompPicture(
211 (SInt *)GetImageData(GetVopY(curr_vop)), //curr_vop,
212 prev_orig_y, /* Y padd with edge */
213 prev_ipol_y, /* Y interpolated (from pi_y) */
214 (SInt*)GetImageData(prev_rec_vop->u_chan) + (vop_width/2) * (16/2) + (16/2),
215 (SInt*)GetImageData(prev_rec_vop->v_chan) + (vop_width/2) * (16/2) + (16/2),
216 prev_rec_vop->hor_spat_ref,
217 prev_rec_vop->ver_spat_ref,
218 vop_width,vop_height,
219 enable_8x8_mv,
220 edge,
221 GetVopSearchRangeFor(curr_vop),
222 f_code,
223 GetVopRoundingType(curr_vop),
224 br_x,br_y, /* pos. of the bounding rectangle */
225 br_width,br_height, /* dims. of the bounding rectangle */
226 (SInt*)GetImageData(curr_comp_vop->y_chan),
227 (SInt*)GetImageData(curr_comp_vop->u_chan),
228 (SInt*)GetImageData(curr_comp_vop->v_chan),
229 mad,
230 (Float*)GetImageData(mv16_w),
231 (Float*)GetImageData(mv16_h),
232 (Float*)GetImageData(mv8_w),
233 (Float*)GetImageData(mv8_h),
234 (SInt*) GetImageData(mode16)
237 /* Convert output to MOMUSYS format */
238 GetMotionImages(mv16_w, mv16_h, mv8_w, mv8_h, mode16, mot_x, mot_y, mode);
240 /* Deallocate dynamic memory */
241 FreeImage(mv16_w); FreeImage(mv16_h);
242 FreeImage(mv8_w); FreeImage(mv8_h);
243 FreeImage(mode16);
244 FreeImage(pi_y);
247 /***********************************************************CommentBegin******
249 * -- MotionEstCompPicture -- Computes MV's and predictor errors and
250 * do motion compensation
252 * Purpose :
253 * Computes MV's (8x8 and 16x16) and predictor errors for the whole
254 * vop. Perform motion compensation for the whole vop.
256 ***********************************************************CommentEnd********/
258 Void
259 MotionEstCompPicture(
260 SInt *curr, /* <-- Current VOP */
261 SInt *prev, /* <-- Original Y padd with edge */
262 SInt *prev_ipol, /* <-- Y interpolated (from pi_y) */
263 SInt *prev_u, /* <-- Original U padd with edge */
264 SInt *prev_v, /* <-- Original V padd with edge */
265 Int prev_x, /* <-- absolute horiz. position of previous vop */
266 Int prev_y, /* <-- absolute verti. position of previous vop */
267 Int vop_width, /* <-- horizontal previous vop dimension */
268 Int vop_height, /* <-- vertical previous vop dimension */
269 Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
270 Int edge, /* <-- edge arround the reference vop */
271 Int sr_for, /* <-- forward search range */
272 Int f_code, /* MW QPEL 07-JUL-1998 *//* <-- MV search range 1/2 or 1/4 pel: 1=32,2=64,...,7=2048*/
273 Int rounding_type, /* <-- The rounding type of the current vop */
274 Int br_x, /* <-- absolute horiz. position of the current vop */
275 Int br_y, /* <-- absolute verti. position of the current vop */
276 Int br_width, /* <-- current bounding rectangule width */
277 Int br_height, /* <-- current bounding rectangle height */
278 SInt *curr_comp_y, /* <-> motion compensated current Y */
279 SInt *curr_comp_u, /* <-> motion compensated current U */
280 SInt *curr_comp_v, /* <-> motion compensated current V */
281 Float *mad, /* <-> the mad value of current ME/MC result */
282 Float *mv16_w, /* --> predicted horizontal 16x16 MV(if approp.) */
283 Float *mv16_h, /* --> predicted vertical 16x16 MV (if approp.) */
284 Float *mv8_w, /* --> predicted horizontal 8x8 MV (if approp.) */
285 Float *mv8_h, /* --> predicted vertical 8x8 MV (if approp.) */
286 SInt *mode16 /* --> mode of the preditect motion vector */
289 Int i, j, k;
290 SInt curr_mb[MB_SIZE][MB_SIZE];
291 SInt curr_comp_mb_16[MB_SIZE][MB_SIZE];
292 SInt curr_comp_mb_8[MB_SIZE][MB_SIZE];
293 Int sad8 = MV_MAX_ERROR, sad16, sad;
294 Int imas_w, imas_h, Mode;
295 Int posmode, pos16, pos8;
296 Int min_error16,
297 min_error8_0, min_error8_1, min_error8_2, min_error8_3;
298 // SInt *curr = (SInt *)GetImageData(GetVopY(curr_vop));
299 /***************************************************************************
300 array of flags, which contains for the MB and for each one of the 4 Blocks
301 the following info sequentially:
302 xm, 1 if the lower search (x axis) is completed (no 1/2 search can be done)
303 0, do 1/2 search in the lower bound (x axis)
304 xM, 1 if the upper search (x axis) is completed (no 1/2 search can be done)
305 0, do 1/2 search in the upper bound (x axis)
306 ym, 1 if the lower search (y axis) is completed (no 1/2 search can be done)
307 0, do 1/2 search in the lower bound (y axis)
308 yM, 1 if the upper search (y axis) is completed (no 1/2 search can be done)
309 0, do 1/2 search in the upper bound (y axis)
310 ***************************************************************************/
311 SInt *halfpelflags;
312 Float hint_mv_w, hint_mv_h;
313 Int xsum,ysum,dx,dy;
314 Int prev_x_min,prev_x_max,prev_y_min,prev_y_max;
316 prev_x_min = 2 * prev_x + 2 * 16;
317 prev_y_min = 2 * prev_y + 2 * 16;
318 prev_x_max = prev_x_min + 2 * vop_width - 4 * 16;
319 prev_y_max = prev_y_min + 2 * vop_height - 4 * 16;
321 imas_w=br_width/MB_SIZE;
322 imas_h=br_height/MB_SIZE;
324 /* Do motion estimation and store result in array */
326 halfpelflags=(SInt*)malloc(5*4*sizeof(SInt));
327 /* halfpelflags=(SInt*)malloc(9*4*sizeof(SInt)); */
328 sad = 0;
330 for ( j=0; j< (br_height/MB_SIZE); j++)
332 hint_mv_w = hint_mv_h = 0.f;
333 for ( i=0; i< (br_width/MB_SIZE); i++)
335 /* Integer pel search */
336 Int min_error;
338 posmode = j * imas_w + i;
339 pos16 = pos8 = 2*j*2*imas_w + 2*i;
341 MBMotionEstimation(curr,
342 prev, br_x, br_y,
343 br_width, i, j, prev_x, prev_y,
344 vop_width, vop_height, enable_8x8_mv, edge,
345 f_code, sr_for,
346 hint_mv_w, hint_mv_h, // the hint seeds
347 mv16_w, mv16_h,
348 mv8_w, mv8_h, &min_error, halfpelflags);
350 /* Inter/Intra decision */
351 Mode = ChooseMode(curr,
352 i*MB_SIZE,j*MB_SIZE, min_error, br_width);
354 hint_mv_w = mv16_w[pos16];
355 hint_mv_h = mv16_h[pos16];
357 LoadArea(curr, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, (SInt *)curr_mb);
359 /* 0==MBM_INTRA,1==MBM_INTER16||MBM_INTER8 */
360 if ( Mode != 0)
362 FindSubPel (i*MB_SIZE,j*MB_SIZE, prev_ipol,
363 &curr_mb[0][0], 16, 16 , 0,
364 br_x-prev_x,br_y-prev_y,vop_width, vop_height,
365 edge, halfpelflags, &curr_comp_mb_16[0][0],
366 &mv16_w[pos16], &mv16_h[pos16], &min_error16);
368 /* sad16(0,0) already decreased by Nb/2+1 in FindHalfPel() */
369 sad16 = min_error16;
370 mode16[posmode] = MBM_INTER16;
372 if (enable_8x8_mv)
374 xsum = 0; ysum = 0;
376 FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
377 &curr_mb[0][0], 8, 8 , 0,
378 br_x-prev_x,br_y-prev_y, vop_width, vop_height,
379 edge, halfpelflags, &curr_comp_mb_8[0][0],
380 &mv8_w[pos8], &mv8_h[pos8], &min_error8_0);
381 xsum += (Int)(2*(mv8_w[pos8]));
382 ysum += (Int)(2*(mv8_h[pos8]));
384 FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
385 &curr_mb[0][8], 8, 8 , 1,
386 br_x-prev_x,br_y-prev_y, vop_width,vop_height,
387 edge, halfpelflags, &curr_comp_mb_8[0][8],
388 &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_1);
389 xsum += (Int)(2*(mv8_w[pos8+1]));
390 ysum += (Int)(2*(mv8_h[pos8+1]));
392 pos8+=2*imas_w;
394 FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
395 &curr_mb[8][0], 8, 8 , 2,
396 br_x-prev_x,br_y-prev_y, vop_width,vop_height,
397 edge, halfpelflags, &curr_comp_mb_8[8][0],
398 &mv8_w[pos8], &mv8_h[pos8], &min_error8_2);
399 xsum += (Int)(2*(mv8_w[pos8]));
400 ysum += (Int)(2*(mv8_h[pos8]));
402 FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,
403 &curr_mb[8][8], 8, 8 , 3,
404 br_x-prev_x,br_y-prev_y, vop_width,vop_height,
405 edge, halfpelflags, &curr_comp_mb_8[8][8],
406 &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_3);
407 xsum += (Int)(2*(mv8_w[pos8+1]));
408 ysum += (Int)(2*(mv8_h[pos8+1]));
410 sad8 = min_error8_0+min_error8_1+min_error8_2+min_error8_3;
412 /* Choose 8x8 or 16x16 vectors */
413 if (sad8 < (sad16 -(128+1)))
414 mode16[posmode] = MBM_INTER8;
415 } /* end of enable_8x8_mv mode */
417 /* When choose 16x16 vectors */
418 /* sad16(0,0) was decreased by MB_Nb, now add it back */
419 if ((mv16_w[pos16]==0.0) && (mv16_h[pos16]==0.0) && (mode16[posmode]==MBM_INTER16))
420 sad16 += 128+1;
422 /* calculate motion vectors for chroma compensation */
423 if(mode16[posmode] == MBM_INTER8)
425 dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);
426 dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);
427 sad += sad8;
429 else /* mode == MBM_INTER16 */
431 dx = (Int)(2 * mv16_w[pos16]);
432 dy = (Int)(2 * mv16_h[pos16]);
433 dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
434 dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
435 sad += sad16;
438 GetPred_Chroma (i*MB_SIZE, j*MB_SIZE, dx, dy,
439 prev_u, prev_v, curr_comp_u, curr_comp_v,
440 br_width, vop_width,
441 prev_x_min/4,prev_y_min/4,prev_x_max/4,prev_y_max/4, rounding_type);
443 } /* end of mode non zero */
444 else /* mode = 0 INTRA */
446 mode16[posmode] = MBM_INTRA;
447 for (k = 0; k < MB_SIZE*MB_SIZE; k++)
449 // for INTRA MB, set compensated 0 to generate correct error image
450 curr_comp_mb_16[k/MB_SIZE][k%MB_SIZE] = 0;
451 // for INTRA_MB, SAD is recalculated from image instead of using min_error
452 sad += curr_mb[k/MB_SIZE][k%MB_SIZE];
456 if (mode16[posmode] == MBM_INTER8)
457 SetArea((SInt*)curr_comp_mb_8, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
458 else
459 SetArea((SInt*)curr_comp_mb_16, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);
460 } /* end of i loop */
461 } /* end of j loop */
463 *mad = (float)sad/(br_width*br_height);
465 free((Char*)halfpelflags);
466 return;
470 /***********************************************************CommentBegin******
472 * unrestricted_MC_chro
474 * Purpose :
475 * To make unrestricted MC
477 ***********************************************************CommentEnd********/
478 /*Int unrestricted_MC_chro(Int x,Int y, Int npix,
479 Int prev_x_min,Int prev_y_min,
480 Int prev_x_max, Int prev_y_max)
483 if (x < prev_x_min) x = prev_x_min;
484 else if (x >=prev_x_max) x = prev_x_max-1;
486 if (y < prev_y_min) y = prev_y_min;
487 else if (y >=prev_y_max) y = prev_y_max-1;
488 return(x+y*npix);
491 #define unrestricted_MC_chro(x,y,npix,prev_x_min,prev_y_min,prev_x_max,prev_y_max) ((x)+(y)*(npix))
494 /***********************************************************CommentBegin******
496 * -- GetPred_Chroma -- Predicts chrominance macroblock
498 * Purpose :
499 * Does the chrominance prediction for P-frames
501 * Arguments in :
502 * current position in image,
503 * motionvectors,
504 * pointers to compensated and previous Vops,
505 * width of the compensated Vop
506 * width of the previous/reference Vop
508 ***********************************************************CommentEnd********/
510 Void GetPred_Chroma (
511 Int x_curr,
512 Int y_curr,
513 Int dx,
514 Int dy,
515 SInt *prev_u,
516 SInt *prev_v,
517 SInt *comp_u,
518 SInt *comp_v,
519 Int width,
520 Int width_prev,
521 Int prev_x_min,
522 Int prev_y_min,
523 Int prev_x_max,
524 Int prev_y_max,
525 Int rounding_control)
527 Int m,n;
529 Int x, y, ofx, ofy, lx;
530 Int xint, yint;
531 Int xh, yh;
532 Int index1,index2,index3,index4;
534 lx = width_prev/2;
536 x = x_curr>>1;
537 y = y_curr>>1;
539 xint = dx>>1;
540 xh = dx & 1;
541 yint = dy>>1;
542 yh = dy & 1;
544 if (!xh && !yh)
546 for (n = 0; n < 8; n++)
548 for (m = 0; m < 8; m++)
550 ofx = x + xint + m;
551 ofy = y + yint + n;
552 index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
553 prev_y_min,prev_x_max,prev_y_max);
554 comp_u[(y+n)*width/2+x+m]
555 = *(prev_u+index1);
556 comp_v[(y+n)*width/2+x+m]
557 = *(prev_v+index1);
561 else if (!xh && yh)
563 for (n = 0; n < 8; n++)
565 for (m = 0; m < 8; m++)
567 ofx = x + xint + m;
568 ofy = y + yint + n;
569 index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
570 prev_y_min,prev_x_max,prev_y_max);
571 index2 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
572 prev_y_min,prev_x_max,prev_y_max);
574 comp_u[(y+n)*width/2+x+m]
575 = (*(prev_u+index1) +
576 *(prev_u+index2) + 1- rounding_control)>>1;
578 comp_v[(y+n)*width/2+x+m]
579 = (*(prev_v+index1) +
580 *(prev_v+index2) + 1- rounding_control)>>1;
584 else if (xh && !yh)
586 for (n = 0; n < 8; n++)
588 for (m = 0; m < 8; m++)
590 ofx = x + xint + m;
591 ofy = y + yint + n;
592 index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
593 prev_y_min,prev_x_max,prev_y_max);
594 index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
595 prev_y_min,prev_x_max,prev_y_max);
597 comp_u[(y+n)*width/2+x+m]
598 = (*(prev_u+index1) +
599 *(prev_u+index2) + 1- rounding_control)>>1;
601 comp_v[(y+n)*width/2+x+m]
602 = (*(prev_v+index1) +
603 *(prev_v+index2) + 1- rounding_control)>>1;
607 else
608 { /* xh && yh */
609 for (n = 0; n < 8; n++)
611 for (m = 0; m < 8; m++)
613 ofx = x + xint + m;
614 ofy = y + yint + n;
615 index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,
616 prev_y_min,prev_x_max,prev_y_max);
617 index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,
618 prev_y_min,prev_x_max,prev_y_max);
619 index3 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,
620 prev_y_min,prev_x_max,prev_y_max);
621 index4 = unrestricted_MC_chro(ofx+xh,ofy+yh,lx,prev_x_min,
622 prev_y_min,prev_x_max,prev_y_max);
624 comp_u[(y+n)*width/2+x+m]
625 = (*(prev_u+index1)+
626 *(prev_u+index2)+
627 *(prev_u+index3)+
628 *(prev_u+index4)+
629 2- rounding_control)>>2;
631 comp_v[(y+n)*width/2+x+m]
632 = (*(prev_v+index1)+
633 *(prev_v+index2)+
634 *(prev_v+index3)+
635 *(prev_v+index4)+
636 2- rounding_control)>>2;
640 return;