r1009: Move the dependencies to newer package names
[cinelerra_cv/mob.git] / quicktime / encore50 / mot_util.c
blob6b08f268e05bce27f36bbab36189a82775a2cbfc
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_util.c
28 * Copyright (C) 2001 Project Mayo
30 * Adam Li
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some utility functions to for motion estimation and */
37 /* compensation. */
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 "mom_structs.h"
42 #include "vm_common_defs.h"
44 #include "mot_util.h"
46 /* ------------------------------------------------------------------------- */
48 /* Macro to compute the MB absolute error difference of the inside the shape */
50 //static Int P_diff;
51 #define DIFF1(v1,v2,idx) (P_diff = (v1[idx]-v2[idx]), ABS(P_diff))
53 /***********************************************************CommentBegin******
55 * -- InterpolateImage -- Interpolates a complete (SInt)image
57 * Purpose :
58 * Interpolates a complete (SInt) image for easier half pel prediction
60 ***********************************************************CommentEnd********/
62 Void
63 InterpolateImage(
64 Image *input_image, /* <-- image to interpolate (SInt) */
65 Image *output_image, /* --> interpolated image (SInt) */
66 Int rounding_control
69 SInt *ii, *oo;
70 UInt i, j;
71 UInt width, height;
73 width = input_image->x;
74 height = input_image->y;
75 ii = (SInt*)GetImageData(output_image);
76 oo = (SInt*)GetImageData(input_image);
78 /* main image */
79 for (j = 0; j < height-1; j++)
81 for (i = 0; i < width-1; i++)
83 *(ii + (i<<1)) = *(oo + i);
84 *(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1- rounding_control)>>1;
85 *(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1-
86 rounding_control)>>1;
87 *(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) +
88 *(oo+i+width) + *(oo+i+1+width) + 2-
89 rounding_control)>>2;
91 /* last pels on each line */
92 *(ii+ (width<<1) - 2) = *(oo + width - 1);
93 *(ii+ (width<<1) - 1) = *(oo + width - 1);
94 *(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1-
95 rounding_control)>>1;
96 *(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1-
97 rounding_control)>>1;
98 ii += (width<<2);
99 oo += width;
102 /* last lines */
103 for (i = 0; i < width-1; i++)
105 *(ii+ (i<<1)) = *(oo + i);
106 *(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1- rounding_control)>>1;
107 *(ii+ (width<<1)+ (i<<1)) = *(oo + i);
108 *(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1-
109 rounding_control)>>1;
112 /* bottom right corner pels */
113 *(ii + (width<<1) - 2) = *(oo + width -1);
114 *(ii + (width<<1) - 1) = *(oo + width -1);
115 *(ii + (width<<2) - 2) = *(oo + width -1);
116 *(ii + (width<<2) - 1) = *(oo + width -1);
118 return;
122 /***********************************************************CommentBegin******
124 * -- GetMotionImages --
126 * Purpose :
127 * Translate the MVs data from the resulting separated four
128 * (Float) Images (16x16/8x8, X,Y) of the motion estimation process
129 * into two Images, which contain the 16x16 and 8x8 MVs
130 * values acording to the modes (MBM_INTRA, MBM_INTER16,
131 * MBM_INTER8). It also
132 * makes a copy of imode16 (SInt-Image of modes).
134 * Return values :
135 * 1 on success, -1 on error
137 ***********************************************************CommentEnd********/
140 GetMotionImages(
141 Image *imv16_w, /* <-- 16x16 horiz. MV Float-Image (MxN) (cuad.) */
142 Image *imv16_h, /* <-- 16x16 verti. MV Float-Image (MxN) (cuad.) */
143 Image *imv8_w, /* <-- 8x8 horizontal MV Float-Image (MxN) */
144 Image *imv8_h, /* <-- 8x8 vertical MV Float-Image (MxN) */
145 Image *imode16, /* <-- SInt-Image of modes (M/2xN/2) */
146 Image **mv_x, /* --> horizontal MV Float-Image (MxN) */
147 Image **mv_y, /* --> vertical MV Float-Image (MxN) */
148 Image **mode /* --> SInt-Image of modes (M/2xN/2) */
152 Int i, j;
153 Int width, height, base;
154 Float val_x, val_y;
155 Float *data_x, *data_y,
156 *mv16_w, *mv16_h,
157 *mv8_w, *mv8_h;
158 SInt *mode16, *data_mode;
159 SInt modo;
161 width = imode16->x; height = imode16->y;
163 (*mode)=AllocImage(width,height,SHORT_TYPE);
164 (*mv_x)=AllocImage(width*2,height*2,FLOAT_TYPE);
165 (*mv_y)=AllocImage(width*2,height*2,FLOAT_TYPE);
166 data_x = (Float*)GetImageData((*mv_x));
167 data_y = (Float*)GetImageData((*mv_y));
168 data_mode = (SInt*)GetImageData((*mode));
169 mode16=(SInt*)GetImageData(imode16);
170 mv16_w=(Float*)GetImageData(imv16_w);
171 mv16_h=(Float*)GetImageData(imv16_h);
172 mv8_w=(Float*)GetImageData(imv8_w);
173 mv8_h=(Float*)GetImageData(imv8_h);
175 for(j=0;j<height;j++)
177 for(i=0;i< width;i++)
179 modo=data_mode[j*width+i]=mode16[j*width+i];
180 if ( modo==MBM_INTRA) /*INTRA*/
182 base=2*j*2*width+2*i;
183 data_x[base]=0.0; data_x[base+1]=0.0;
184 data_y[base]=0.0; data_y[base+1]=0.0;
185 base+=width*2;
186 data_x[base]=0.0; data_x[base+1]=0.0;
187 data_y[base]=0.0; data_y[base+1]=0.0;
189 else if(modo==MBM_INTER16) /*INTER 16*/
191 base=2*j*2*width+2*i;
192 val_x=mv16_w[base];val_y=mv16_h[base];
194 data_x[base]=val_x; data_x[base+1]=val_x;
195 data_y[base]=val_y; data_y[base+1]=val_y;
196 base+=width*2;
197 data_x[base]=val_x; data_x[base+1]=val_x;
198 data_y[base]=val_y; data_y[base+1]=val_y;
200 else if (modo==MBM_INTER8) /*INTER4*8*/
202 base=2*j*2*width+2*i;
204 data_x[base] = mv8_w[base];
205 data_y[base] = mv8_h[base];
206 data_x[base+1] = mv8_w[base+1];
207 data_y[base+1] = mv8_h[base+1];
208 base+=width*2;
209 data_x[base] = mv8_w[base];
210 data_y[base] = mv8_h[base];
211 data_x[base+1] = mv8_w[base+1];
212 data_y[base+1] = mv8_h[base+1];
214 } /* end for*/
215 } /* end for*/
217 return(1);
221 /***********************************************************CommentBegin******
223 * -- ChooseMode -- chooses coding mode INTRA/INTER dependig on the SAD values
225 * Purpose :
226 * chooses coding mode INTRA/INTER dependig on the SAD values
228 * Return values :
229 * 1 for INTER, 0 for INTRA
231 ***********************************************************CommentEnd********/
234 ChooseMode(
235 SInt *curr, /* <-- current Y values (not extended) */
236 Int x_pos, /* <-- upper-left MB corner hor. coor. */
237 Int y_pos, /* <-- upper-left MB corner ver. coor. */
238 Int min_SAD, /* <-- min SAD (from integer pel search) */
239 UInt width /* <-- current Y picture width */
242 Int i, j;
243 Int MB_mean = 0, A = 0;
244 Int y_off;
246 for (j = 0; j < MB_SIZE; j++)
248 y_off = (y_pos + j) * width;
249 for (i = 0; i < MB_SIZE; i++)
251 MB_mean += *(curr + x_pos + i + y_off);
255 MB_mean /= 256;
257 for (j = 0; j < MB_SIZE; j++)
259 y_off = (y_pos + j) * width;
260 for (i = 0; i < MB_SIZE; i++)
262 A += abs( *(curr + x_pos + i + y_off) - MB_mean );
266 if (A < (min_SAD - 2*256))
267 return 0;
268 else
269 return 1;
273 /***********************************************************CommentBegin******
275 * -- SAD_Macroblock -- obtains the SAD for a Macroblock
277 * Purpose :
278 * obtains the SAD for a Macroblock
280 * Return values :
281 * sad of the MB
283 ***********************************************************CommentEnd********/
286 SAD_Macroblock(
287 SInt *ii, /* <-- Pointer to the upper-left pel of first MB */
288 SInt *act_block, /* <-- Id, second MB (width=16) */
289 UInt h_length, /* <-- Width of first area */
290 Int Min_FRAME /* <-- Minimum prediction error so far */
293 /* Int i;
294 Int sad = 0;
295 SInt *kk;
296 register Int P_diff;
298 kk = act_block;
299 i = 16;
300 while (i--)
302 sad += (DIFF1(ii,kk,0)+DIFF1(ii,kk,1)
303 +DIFF1(ii,kk,2)+DIFF1(ii,kk,3)
304 +DIFF1(ii,kk,4)+DIFF1(ii,kk,5)
305 +DIFF1(ii,kk,6)+DIFF1(ii,kk,7)
306 +DIFF1(ii,kk,8)+DIFF1(ii,kk,9)
307 +DIFF1(ii,kk,10)+DIFF1(ii,kk,11)
308 +DIFF1(ii,kk,12)+DIFF1(ii,kk,13)
309 +DIFF1(ii,kk,14)+DIFF1(ii,kk,15)
312 ii += h_length;
313 kk += 16;
314 if (sad > Min_FRAME)
315 return MV_MAX_ERROR;
318 return sad;
320 int i, j;
321 int sad = 0;
322 SInt *p1 = ii, *p2 = act_block;
324 i = 16;
325 while (i--) {
326 j = 16;
327 while (j --)
328 sad += abs((int)*(p1++) - (int)*(p2++));
329 if (sad > Min_FRAME)
330 return MV_MAX_ERROR;
331 p1 += h_length - 16;
334 return sad;
338 /***********************************************************CommentBegin******
340 * -- SAD_Block -- obtains the SAD for a Block
342 * Purpose :
343 * obtains the SAD for a Block
345 * Return values :
346 * sad of the Block
348 ***********************************************************CommentEnd********/
351 SAD_Block(
352 SInt *ii, /* <-- First area */
353 SInt *act_block, /* <-- Id. second MB (width=16) */
354 UInt h_length, /* <-- Width of first area */
355 Int min_sofar /* <-- Minimum prediction error so far */
358 /* Int i;
359 Int sad = 0;
360 SInt *kk;
361 register Int P_diff;
363 kk = act_block;
364 i = 8;
365 while (i--)
367 sad += (DIFF1(ii,kk,0)+DIFF1(ii,kk,1)
368 +DIFF1(ii,kk,2)+DIFF1(ii,kk,3)
369 +DIFF1(ii,kk,4)+DIFF1(ii,kk,5)
370 +DIFF1(ii,kk,6)+DIFF1(ii,kk,7)
373 ii += h_length;
374 kk += 16;
375 if (sad > min_sofar)
376 return INT_MAX;
379 return sad;
381 int i, j;
382 int sad = 0;
383 SInt *p1 = ii, *p2 = act_block;
385 i = 8;
386 while (i--) {
387 j = 8;
388 while (j --)
389 sad += abs((int)*(p1++) - (int)*(p2++));
390 if (sad > min_sofar)
391 return INT_MAX;
392 p1 += h_length - 8;
393 p2 += 16 - 8;
396 return sad;
401 /***********************************************************CommentBegin******
403 * -- LoadArea -- fills array with a image-data
405 * Purpose :
406 * fills array with a image-data
408 * Return values :
409 * Pointer to the filled array
411 ***********************************************************CommentEnd********/
413 Void
414 LoadArea(
415 SInt *im, /* <-- pointer to image */
416 Int x, /* <-- horizontal pos */
417 Int y, /* <-- vertical pos */
418 Int x_size, /* <-- width of array */
419 Int y_size, /* <-- height of array */
420 Int lx, /* <-- width of the image data */
421 SInt *block /* <-> pointer to the array */
424 SInt *in;
425 SInt *out;
426 Int i = x_size;
427 Int j = y_size;
429 in = im + (y*lx) + x;
430 out = block;
432 while (j--)
434 while (i--)
435 *out++ = *in++;
436 i = x_size;
437 in += lx - x_size;
440 return;
444 /***********************************************************CommentBegin******
446 * -- SetArea -- fills a image-data with an array
448 * Purpose :
449 * fills a image-data with an array
451 ***********************************************************CommentEnd********/
453 Void
454 SetArea(
455 SInt *block, /* <-- pointer to array */
456 Int x, /* <-- horizontal pos in image */
457 Int y, /* <-- vertical pos in image */
458 Int x_size, /* <-- width of array */
459 Int y_size, /* <-- height of array */
460 Int lx, /* <-- width of the image data */
461 SInt *im /* --> pointer to image */
464 SInt *in;
465 SInt *out;
466 Int i = x_size;
467 Int j = y_size;
469 in = block;
470 out = im + (y*lx) + x;
472 while (j--)
474 while (i--)
475 *out++ = *in++;
476 i = x_size;
477 out += lx - x_size;