[svn] / trunk / xvidcore / src / prediction / mbprediction.h Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/prediction/mbprediction.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 254 - (view) (download)

1 : edgomez 149 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - MB prediction header file -
5 :     *
6 :     * This program is an implementation of a part of one or more MPEG-4
7 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
8 :     * to use this software module in hardware or software products are
9 :     * advised that its use may infringe existing patents or copyrights, and
10 :     * any such use would be at such party's own risk. The original
11 :     * developer of this software module and his/her company, and subsequent
12 :     * editors and their companies, will have no liability for use of this
13 :     * software or modifications or derivatives thereof.
14 :     *
15 :     * This program is free software; you can redistribute it and/or modify
16 :     * it under the terms of the GNU General Public License as published by
17 :     * the xvid_free Software Foundation; either version 2 of the License, or
18 :     * (at your option) any later version.
19 :     *
20 :     * This program is distributed in the hope that it will be useful,
21 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 :     * GNU General Public License for more details.
24 :     *
25 :     * You should have received a copy of the GNU General Public License
26 :     * along with this program; if not, write to the xvid_free Software
27 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 :     *
29 : suxen_drol 254 * $Id: mbprediction.h,v 1.12 2002-07-03 12:32:50 suxen_drol Exp $
30 : edgomez 149 *
31 :     *************************************************************************/
32 :    
33 : suxen_drol 248 /******************************************************************************
34 :     * *
35 :     * Revision history: *
36 :     * *
37 :     * 29.06.2002 get_pmvdata() bounding *
38 :     * *
39 :     ******************************************************************************/
40 :    
41 :    
42 : Isibaar 3 #ifndef _MBPREDICTION_H_
43 :     #define _MBPREDICTION_H_
44 :    
45 :     #include "../portab.h"
46 :     #include "../decoder.h"
47 :     #include "../global.h"
48 :    
49 :     #define MIN(X, Y) ((X)<(Y)?(X):(Y))
50 :     #define MAX(X, Y) ((X)>(Y)?(X):(Y))
51 :    
52 : edgomez 149 /* very large value */
53 : Isibaar 3 #define MV_MAX_ERROR (4096 * 256)
54 :    
55 :     #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
56 :    
57 : edgomez 195 void MBPrediction(FRAMEINFO * frame, /* <-- The parameter for ACDC and MV prediction */
58 : Isibaar 3
59 : edgomez 195 uint32_t x_pos, /* <-- The x position of the MB to be searched */
60 : Isibaar 3
61 : edgomez 195 uint32_t y_pos, /* <-- The y position of the MB to be searched */
62 : Isibaar 3
63 : edgomez 195 uint32_t x_dim, /* <-- Number of macroblocks in a row */
64 : Isibaar 3
65 : edgomez 195 int16_t * qcoeff); /* <-> The quantized DCT coefficients */
66 :    
67 :     void add_acdc(MACROBLOCK * pMB,
68 :     uint32_t block,
69 :     int16_t dct_codes[64],
70 :     uint32_t iDcScaler,
71 :     int16_t predictors[8]);
72 :    
73 :    
74 :     void predict_acdc(MACROBLOCK * pMBs,
75 :     uint32_t x,
76 :     uint32_t y,
77 :     uint32_t mb_width,
78 :     uint32_t block,
79 :     int16_t qcoeff[64],
80 :     uint32_t current_quant,
81 :     int32_t iDcScaler,
82 : suxen_drol 248 int16_t predictors[8],
83 : suxen_drol 252 const int bound);
84 : edgomez 195
85 : suxen_drol 248
86 : chl 139 /* get_pmvdata returns the median predictor and nothing else */
87 :    
88 : edgomez 195 static __inline VECTOR
89 :     get_pmv(const MACROBLOCK * const pMBs,
90 :     const uint32_t x,
91 :     const uint32_t y,
92 :     const uint32_t x_dim,
93 :     const uint32_t block)
94 : chl 139 {
95 :    
96 : edgomez 149 int xin1, xin2, xin3;
97 :     int yin1, yin2, yin3;
98 :     int vec1, vec2, vec3;
99 : edgomez 195 VECTOR lneigh, tneigh, trneigh; /* left neighbour, top neighbour, topright neighbour */
100 : edgomez 149 VECTOR median;
101 : chl 139
102 : edgomez 195 static VECTOR zeroMV = { 0, 0 };
103 : edgomez 149 uint32_t index = x + y * x_dim;
104 : chl 139
105 : edgomez 149 /* first row (special case) */
106 : edgomez 195 if (y == 0 && (block == 0 || block == 1)) {
107 :     if ((x == 0) && (block == 0)) // first column, first block
108 :     {
109 : chl 139 return zeroMV;
110 :     }
111 : edgomez 195 if (block == 1) // second block; has only a left neighbour
112 : chl 139 {
113 :     return pMBs[index].mvs[0];
114 : edgomez 195 } else { /* block==0, but x!=0, so again, there is a left neighbour */
115 :    
116 :     return pMBs[index - 1].mvs[1];
117 : chl 139 }
118 : edgomez 149 }
119 : chl 139
120 :     /*
121 : edgomez 149 * MODE_INTER, vm18 page 48
122 :     * MODE_INTER4V vm18 page 51
123 :     *
124 :     * (x,y-1) (x+1,y-1)
125 :     * [ | ] [ | ]
126 :     * [ 2 | 3 ] [ 2 | ]
127 :     *
128 :     * (x-1,y) (x,y) (x+1,y)
129 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
130 :     * [ | 3 ] [ 2 | 3 ] [ | ]
131 :     */
132 : chl 139
133 : edgomez 195 switch (block) {
134 : chl 139 case 0:
135 : edgomez 195 xin1 = x - 1;
136 :     yin1 = y;
137 :     vec1 = 1; /* left */
138 :     xin2 = x;
139 :     yin2 = y - 1;
140 :     vec2 = 2; /* top */
141 :     xin3 = x + 1;
142 :     yin3 = y - 1;
143 :     vec3 = 2; /* top right */
144 : chl 139 break;
145 :     case 1:
146 : edgomez 195 xin1 = x;
147 :     yin1 = y;
148 :     vec1 = 0;
149 :     xin2 = x;
150 :     yin2 = y - 1;
151 :     vec2 = 3;
152 :     xin3 = x + 1;
153 :     yin3 = y - 1;
154 :     vec3 = 2;
155 : edgomez 149 break;
156 : chl 139 case 2:
157 : edgomez 195 xin1 = x - 1;
158 :     yin1 = y;
159 :     vec1 = 3;
160 :     xin2 = x;
161 :     yin2 = y;
162 :     vec2 = 0;
163 :     xin3 = x;
164 :     yin3 = y;
165 :     vec3 = 1;
166 : edgomez 149 break;
167 : chl 139 default:
168 : edgomez 195 xin1 = x;
169 :     yin1 = y;
170 :     vec1 = 2;
171 :     xin2 = x;
172 :     yin2 = y;
173 :     vec2 = 0;
174 :     xin3 = x;
175 :     yin3 = y;
176 :     vec3 = 1;
177 : edgomez 149 }
178 : chl 139
179 :    
180 : edgomez 195 if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t) x_dim) {
181 :     lneigh = zeroMV;
182 :     } else {
183 :     lneigh = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
184 : chl 139 }
185 :    
186 : edgomez 195 if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t) x_dim) {
187 : chl 139 tneigh = zeroMV;
188 : edgomez 195 } else {
189 :     tneigh = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
190 : chl 139 }
191 :    
192 : edgomez 195 if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t) x_dim) {
193 : chl 139 trneigh = zeroMV;
194 : edgomez 195 } else {
195 : chl 139 trneigh = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
196 :     }
197 :    
198 : edgomez 149 /* median,minimum */
199 : edgomez 195
200 :     median.x =
201 :     MIN(MAX(lneigh.x, tneigh.x),
202 :     MIN(MAX(tneigh.x, trneigh.x), MAX(lneigh.x, trneigh.x)));
203 :     median.y =
204 :     MIN(MAX(lneigh.y, tneigh.y),
205 :     MIN(MAX(tneigh.y, trneigh.y), MAX(lneigh.y, trneigh.y)));
206 : chl 139 return median;
207 :     }
208 :    
209 :    
210 : Isibaar 3 /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD
211 :     instead of only Median MV */
212 :    
213 : edgomez 195 static __inline int
214 :     get_pmvdata(const MACROBLOCK * const pMBs,
215 :     const uint32_t x,
216 :     const uint32_t y,
217 :     const uint32_t x_dim,
218 :     const uint32_t block,
219 :     VECTOR * const pmv,
220 : suxen_drol 252 int32_t * const psad)
221 : Isibaar 3 {
222 :    
223 : edgomez 149 /*
224 :     * pmv are filled with:
225 :     * [0]: Median (or whatever is correct in a special case)
226 :     * [1]: left neighbour
227 :     * [2]: top neighbour
228 :     * [3]: topright neighbour
229 :     * psad are filled with:
230 :     * [0]: minimum of [1] to [3]
231 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
232 :     * [2]: top neighbour's SAD
233 :     * [3]: topright neighbour's SAD
234 :     */
235 : Isibaar 3
236 : edgomez 149 int xin1, xin2, xin3;
237 :     int yin1, yin2, yin3;
238 :     int vec1, vec2, vec3;
239 : Isibaar 3
240 : edgomez 149 uint32_t index = x + y * x_dim;
241 : edgomez 195 const VECTOR zeroMV = { 0, 0 };
242 : edgomez 149
243 : chl 166 // first row of blocks (special case)
244 : suxen_drol 252 if (y == 0 && (block == 0 || block == 1)) {
245 :     if ((x == 0) && (block == 0)) // first column, first block
246 : edgomez 195 {
247 : Isibaar 3 pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
248 : chl 166 psad[0] = 0;
249 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
250 : Isibaar 3 return 0;
251 :     }
252 : edgomez 195 if (block == 1) // second block; has only a left neighbour
253 : Isibaar 3 {
254 :     pmv[0] = pmv[1] = pMBs[index].mvs[0];
255 :     pmv[2] = pmv[3] = zeroMV;
256 :     psad[0] = psad[1] = pMBs[index].sad8[0];
257 : chl 166 psad[2] = psad[3] = MV_MAX_ERROR;
258 : Isibaar 3 return 0;
259 : edgomez 195 } else { /* block==0, but x!=0, so again, there is a left neighbour */
260 :    
261 :     pmv[0] = pmv[1] = pMBs[index - 1].mvs[1];
262 : Isibaar 3 pmv[2] = pmv[3] = zeroMV;
263 : edgomez 195 psad[0] = psad[1] = pMBs[index - 1].sad8[1];
264 : chl 166 psad[2] = psad[3] = MV_MAX_ERROR;
265 : Isibaar 3 return 0;
266 :     }
267 : edgomez 149 }
268 : Isibaar 3
269 :     /*
270 : edgomez 149 * MODE_INTER, vm18 page 48
271 :     * MODE_INTER4V vm18 page 51
272 :     *
273 :     * (x,y-1) (x+1,y-1)
274 :     * [ | ] [ | ]
275 :     * [ 2 | 3 ] [ 2 | ]
276 :     *
277 :     * (x-1,y) (x,y) (x+1,y)
278 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
279 :     * [ | 3 ] [ 2 | 3 ] [ | ]
280 :     */
281 : Isibaar 3
282 : edgomez 195 switch (block) {
283 : Isibaar 3 case 0:
284 : edgomez 195 xin1 = x - 1;
285 :     yin1 = y;
286 :     vec1 = 1; /* left */
287 :     xin2 = x;
288 :     yin2 = y - 1;
289 :     vec2 = 2; /* top */
290 :     xin3 = x + 1;
291 :     yin3 = y - 1;
292 :     vec3 = 2; /* top right */
293 : Isibaar 3 break;
294 :     case 1:
295 : edgomez 195 xin1 = x;
296 :     yin1 = y;
297 :     vec1 = 0;
298 :     xin2 = x;
299 :     yin2 = y - 1;
300 :     vec2 = 3;
301 :     xin3 = x + 1;
302 :     yin3 = y - 1;
303 :     vec3 = 2;
304 : edgomez 149 break;
305 : Isibaar 3 case 2:
306 : edgomez 195 xin1 = x - 1;
307 :     yin1 = y;
308 :     vec1 = 3;
309 :     xin2 = x;
310 :     yin2 = y;
311 :     vec2 = 0;
312 :     xin3 = x;
313 :     yin3 = y;
314 :     vec3 = 1;
315 : edgomez 149 break;
316 : Isibaar 3 default:
317 : edgomez 195 xin1 = x;
318 :     yin1 = y;
319 :     vec1 = 2;
320 :     xin2 = x;
321 :     yin2 = y;
322 :     vec2 = 0;
323 :     xin3 = x;
324 :     yin3 = y;
325 :     vec3 = 1;
326 : edgomez 149 }
327 : Isibaar 3
328 :    
329 : edgomez 195 if (xin1 < 0 || xin1 >= (int32_t) x_dim) {
330 : chl 165 pmv[1] = zeroMV;
331 : Isibaar 3 psad[1] = MV_MAX_ERROR;
332 : edgomez 195 } else {
333 :     pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
334 :     psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1];
335 : Isibaar 3 }
336 :    
337 : edgomez 195 if (xin2 < 0 || xin2 >= (int32_t) x_dim) {
338 : Isibaar 3 pmv[2] = zeroMV;
339 :     psad[2] = MV_MAX_ERROR;
340 : edgomez 195 } else {
341 :     pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
342 :     psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2];
343 : Isibaar 3 }
344 :    
345 : edgomez 195 if (xin3 < 0 || xin3 >= (int32_t) x_dim) {
346 : Isibaar 3 pmv[3] = zeroMV;
347 :     psad[3] = MV_MAX_ERROR;
348 : edgomez 195 } else {
349 : Isibaar 3 pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
350 : suxen_drol 254 psad[3] = pMBs[xin3 + yin3 * x_dim].sad8[vec3];
351 : Isibaar 3 }
352 :    
353 : edgomez 195 if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
354 :     pmv[0] = pmv[1];
355 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
356 : chl 165 return 1;
357 : Isibaar 3 }
358 :    
359 : edgomez 149 /* median,minimum */
360 :    
361 : edgomez 195 pmv[0].x =
362 :     MIN(MAX(pmv[1].x, pmv[2].x),
363 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
364 :     pmv[0].y =
365 :     MIN(MAX(pmv[1].y, pmv[2].y),
366 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
367 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
368 :    
369 : Isibaar 3 return 0;
370 :     }
371 :    
372 :    
373 : suxen_drol 254 /*
374 :     * MODE_INTER, vm18 page 48
375 :     * MODE_INTER4V vm18 page 51
376 :     *
377 :     * (x,y-1) (x+1,y-1)
378 :     * [ | ] [ | ]
379 :     * [ 2 | 3 ] [ 2 | ]
380 :     *
381 :     * (x-1,y) (x,y) (x+1,y)
382 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
383 :     * [ | 3 ] [ 2 | 3 ] [ | ]
384 :     */
385 : chl 139
386 : suxen_drol 254 static __inline VECTOR
387 :     get_pmv2(const MACROBLOCK * const mbs,
388 :     const int mb_width,
389 :     const int bound,
390 :     const int x,
391 :     const int y,
392 :     const int block)
393 :     {
394 :     static const VECTOR zeroMV = { 0, 0 };
395 :    
396 :     int lx, ly, lz; /* left */
397 :     int tx, ty, tz; /* top */
398 :     int rx, ry, rz; /* top-right */
399 :     int lpos, tpos, rpos;
400 :     int num_cand, last_cand;
401 :    
402 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
403 :    
404 :     switch (block) {
405 :     case 0:
406 :     lx = x - 1; ly = y; lz = 1;
407 :     tx = x; ty = y - 1; tz = 2;
408 :     rx = x + 1; ry = y - 1; rz = 2;
409 :     break;
410 :     case 1:
411 :     lx = x; ly = y; lz = 0;
412 :     tx = x; ty = y - 1; tz = 3;
413 :     rx = x + 1; ry = y - 1; rz = 2;
414 :     break;
415 :     case 2:
416 :     lx = x - 1; ly = y; lz = 3;
417 :     tx = x; ty = y; tz = 0;
418 :     rx = x; ry = y; rz = 1;
419 :     break;
420 :     default:
421 :     lx = x; ly = y; lz = 2;
422 :     tx = x; ty = y; tz = 0;
423 :     rx = x; ry = y; rz = 1;
424 :     }
425 :    
426 :     lpos = lx + ly * mb_width;
427 :     rpos = rx + ry * mb_width;
428 :     tpos = tx + ty * mb_width;
429 :     num_cand = 0;
430 :    
431 :     if (lpos >= bound && lx >= 0) {
432 :     num_cand++;
433 :     last_cand = 1;
434 :     pmv[1] = mbs[lpos].mvs[lz];
435 :     } else {
436 :     pmv[1] = zeroMV;
437 :     }
438 :    
439 :     if (tpos >= bound) {
440 :     num_cand++;
441 :     last_cand = 2;
442 :     pmv[2] = mbs[tpos].mvs[tz];
443 :     } else {
444 :     pmv[2] = zeroMV;
445 :     }
446 :    
447 :     if (rpos >= bound && rx < mb_width) {
448 :     num_cand++;
449 :     last_cand = 3;
450 :     pmv[3] = mbs[rpos].mvs[rz];
451 :     } else {
452 :     pmv[3] = zeroMV;
453 :     }
454 :    
455 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
456 :     if (num_cand != 1) {
457 :     /* set median */
458 :    
459 :     pmv[0].x =
460 :     MIN(MAX(pmv[1].x, pmv[2].x),
461 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
462 :     pmv[0].y =
463 :     MIN(MAX(pmv[1].y, pmv[2].y),
464 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
465 :     return pmv[0];
466 :     }
467 :    
468 :     return pmv[last_cand]; /* no point calculating median mv */
469 :     }
470 :    
471 :    
472 :    
473 :     /*
474 :     * pmv are filled with:
475 :     * [0]: Median (or whatever is correct in a special case)
476 :     * [1]: left neighbour
477 :     * [2]: top neighbour
478 :     * [3]: topright neighbour
479 :     * psad are filled with:
480 :     * [0]: minimum of [1] to [3]
481 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
482 :     * [2]: top neighbour's SAD
483 :     * [3]: topright neighbour's SAD
484 :     */
485 :     static __inline int
486 :     get_pmvdata2(const MACROBLOCK * const mbs,
487 :     const int mb_width,
488 :     const int bound,
489 :     const int x,
490 :     const int y,
491 :     const int block,
492 :     VECTOR * const pmv,
493 :     int32_t * const psad)
494 :     {
495 :     static const VECTOR zeroMV = { 0, 0 };
496 :    
497 :     int lx, ly, lz; /* left */
498 :     int tx, ty, tz; /* top */
499 :     int rx, ry, rz; /* top-right */
500 :     int lpos, tpos, rpos;
501 :     int num_cand, last_cand;
502 :    
503 :     switch (block) {
504 :     case 0:
505 :     lx = x - 1; ly = y; lz = 1;
506 :     tx = x; ty = y - 1; tz = 2;
507 :     rx = x + 1; ry = y - 1; rz = 2;
508 :     break;
509 :     case 1:
510 :     lx = x; ly = y; lz = 0;
511 :     tx = x; ty = y - 1; tz = 3;
512 :     rx = x + 1; ry = y - 1; rz = 2;
513 :     break;
514 :     case 2:
515 :     lx = x - 1; ly = y; lz = 3;
516 :     tx = x; ty = y; tz = 0;
517 :     rx = x; ry = y; rz = 1;
518 :     break;
519 :     default:
520 :     lx = x; ly = y; lz = 2;
521 :     tx = x; ty = y; tz = 0;
522 :     rx = x; ry = y; rz = 1;
523 :     }
524 :    
525 :     lpos = lx + ly * mb_width;
526 :     rpos = rx + ry * mb_width;
527 :     tpos = tx + ty * mb_width;
528 :     num_cand = 0;
529 :    
530 :     if (lpos >= bound && lx >= 0) {
531 :     num_cand++;
532 :     last_cand = 1;
533 :     pmv[1] = mbs[lpos].mvs[lz];
534 :     psad[1] = mbs[lpos].sad8[lz];
535 :     } else {
536 :     pmv[1] = zeroMV;
537 :     psad[1] = MV_MAX_ERROR;
538 :     }
539 :    
540 :     if (tpos >= bound) {
541 :     num_cand++;
542 :     last_cand = 2;
543 :     pmv[2]= mbs[tpos].mvs[tz];
544 :     psad[2] = mbs[tpos].sad8[tz];
545 :     } else {
546 :     pmv[2] = zeroMV;
547 :     psad[2] = MV_MAX_ERROR;
548 :     }
549 :    
550 :     if (rpos >= bound && rx < mb_width) {
551 :     num_cand++;
552 :     last_cand = 3;
553 :     pmv[3] = mbs[rpos].mvs[rz];
554 :     psad[3] = mbs[rpos].sad8[rz];
555 :     } else {
556 :     pmv[3] = zeroMV;
557 :     psad[3] = MV_MAX_ERROR;
558 :     }
559 :    
560 :     /* original pmvdata() compatibility hack */
561 :     if (x == 0 && y == 0 && block == 0)
562 :     {
563 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
564 :     psad[0] = 0;
565 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
566 :     return 0;
567 :     }
568 :    
569 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
570 :     if (num_cand == 1) {
571 :     pmv[0] = pmv[last_cand];
572 :     psad[0] = psad[last_cand];
573 :     // return MVequal(pmv[0], zeroMV); /* no point calculating median mv and minimum sad */
574 :    
575 :     /* original pmvdata() compatibility hack */
576 :     return y==0 && block <= 1 ? 0 : MVequal(pmv[0], zeroMV);
577 :     }
578 :    
579 :     if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
580 :     pmv[0] = pmv[1];
581 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
582 :     return 1;
583 :     /* compatibility patch */
584 :     //return y==0 && block <= 1 ? 0 : 1;
585 :     }
586 :    
587 :     /* set median, minimum */
588 :    
589 :     pmv[0].x =
590 :     MIN(MAX(pmv[1].x, pmv[2].x),
591 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
592 :     pmv[0].y =
593 :     MIN(MAX(pmv[1].y, pmv[2].y),
594 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
595 :    
596 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
597 :    
598 :     return 0;
599 :     }
600 :    
601 :    
602 : edgomez 195 #endif /* _MBPREDICTION_H_ */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4