[svn] / branches / dev-api-4 / xvidcore / src / prediction / mbprediction.h Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/prediction/mbprediction.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 286 - (view) (download)
Original Path: trunk/xvidcore/src/prediction/mbprediction.h

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 : chl 286 * $Id: mbprediction.h,v 1.13 2002-07-10 19:17:49 chl 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 286 #ifdef OLD_GETPMV
87 : chl 139 /* get_pmvdata returns the median predictor and nothing else */
88 :    
89 : edgomez 195 static __inline VECTOR
90 :     get_pmv(const MACROBLOCK * const pMBs,
91 :     const uint32_t x,
92 :     const uint32_t y,
93 :     const uint32_t x_dim,
94 :     const uint32_t block)
95 : chl 139 {
96 :    
97 : edgomez 149 int xin1, xin2, xin3;
98 :     int yin1, yin2, yin3;
99 :     int vec1, vec2, vec3;
100 : edgomez 195 VECTOR lneigh, tneigh, trneigh; /* left neighbour, top neighbour, topright neighbour */
101 : edgomez 149 VECTOR median;
102 : chl 139
103 : edgomez 195 static VECTOR zeroMV = { 0, 0 };
104 : edgomez 149 uint32_t index = x + y * x_dim;
105 : chl 139
106 : edgomez 149 /* first row (special case) */
107 : edgomez 195 if (y == 0 && (block == 0 || block == 1)) {
108 :     if ((x == 0) && (block == 0)) // first column, first block
109 :     {
110 : chl 139 return zeroMV;
111 :     }
112 : edgomez 195 if (block == 1) // second block; has only a left neighbour
113 : chl 139 {
114 :     return pMBs[index].mvs[0];
115 : edgomez 195 } else { /* block==0, but x!=0, so again, there is a left neighbour */
116 :    
117 :     return pMBs[index - 1].mvs[1];
118 : chl 139 }
119 : edgomez 149 }
120 : chl 139
121 :     /*
122 : edgomez 149 * MODE_INTER, vm18 page 48
123 :     * MODE_INTER4V vm18 page 51
124 :     *
125 :     * (x,y-1) (x+1,y-1)
126 :     * [ | ] [ | ]
127 :     * [ 2 | 3 ] [ 2 | ]
128 :     *
129 :     * (x-1,y) (x,y) (x+1,y)
130 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
131 :     * [ | 3 ] [ 2 | 3 ] [ | ]
132 :     */
133 : chl 139
134 : edgomez 195 switch (block) {
135 : chl 139 case 0:
136 : edgomez 195 xin1 = x - 1;
137 :     yin1 = y;
138 :     vec1 = 1; /* left */
139 :     xin2 = x;
140 :     yin2 = y - 1;
141 :     vec2 = 2; /* top */
142 :     xin3 = x + 1;
143 :     yin3 = y - 1;
144 :     vec3 = 2; /* top right */
145 : chl 139 break;
146 :     case 1:
147 : edgomez 195 xin1 = x;
148 :     yin1 = y;
149 :     vec1 = 0;
150 :     xin2 = x;
151 :     yin2 = y - 1;
152 :     vec2 = 3;
153 :     xin3 = x + 1;
154 :     yin3 = y - 1;
155 :     vec3 = 2;
156 : edgomez 149 break;
157 : chl 139 case 2:
158 : edgomez 195 xin1 = x - 1;
159 :     yin1 = y;
160 :     vec1 = 3;
161 :     xin2 = x;
162 :     yin2 = y;
163 :     vec2 = 0;
164 :     xin3 = x;
165 :     yin3 = y;
166 :     vec3 = 1;
167 : edgomez 149 break;
168 : chl 139 default:
169 : edgomez 195 xin1 = x;
170 :     yin1 = y;
171 :     vec1 = 2;
172 :     xin2 = x;
173 :     yin2 = y;
174 :     vec2 = 0;
175 :     xin3 = x;
176 :     yin3 = y;
177 :     vec3 = 1;
178 : edgomez 149 }
179 : chl 139
180 :    
181 : edgomez 195 if (xin1 < 0 || /* yin1 < 0 || */ xin1 >= (int32_t) x_dim) {
182 :     lneigh = zeroMV;
183 :     } else {
184 :     lneigh = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
185 : chl 139 }
186 :    
187 : edgomez 195 if (xin2 < 0 || /* yin2 < 0 || */ xin2 >= (int32_t) x_dim) {
188 : chl 139 tneigh = zeroMV;
189 : edgomez 195 } else {
190 :     tneigh = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
191 : chl 139 }
192 :    
193 : edgomez 195 if (xin3 < 0 || /* yin3 < 0 || */ xin3 >= (int32_t) x_dim) {
194 : chl 139 trneigh = zeroMV;
195 : edgomez 195 } else {
196 : chl 139 trneigh = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
197 :     }
198 :    
199 : edgomez 149 /* median,minimum */
200 : edgomez 195
201 :     median.x =
202 :     MIN(MAX(lneigh.x, tneigh.x),
203 :     MIN(MAX(tneigh.x, trneigh.x), MAX(lneigh.x, trneigh.x)));
204 :     median.y =
205 :     MIN(MAX(lneigh.y, tneigh.y),
206 :     MIN(MAX(tneigh.y, trneigh.y), MAX(lneigh.y, trneigh.y)));
207 : chl 139 return median;
208 :     }
209 :    
210 :    
211 : Isibaar 3 /* This is somehow a copy of get_pmv, but returning all MVs and Minimum SAD
212 :     instead of only Median MV */
213 :    
214 : edgomez 195 static __inline int
215 :     get_pmvdata(const MACROBLOCK * const pMBs,
216 :     const uint32_t x,
217 :     const uint32_t y,
218 :     const uint32_t x_dim,
219 :     const uint32_t block,
220 :     VECTOR * const pmv,
221 : suxen_drol 252 int32_t * const psad)
222 : Isibaar 3 {
223 :    
224 : edgomez 149 /*
225 :     * pmv are filled with:
226 :     * [0]: Median (or whatever is correct in a special case)
227 :     * [1]: left neighbour
228 :     * [2]: top neighbour
229 :     * [3]: topright neighbour
230 :     * psad are filled with:
231 :     * [0]: minimum of [1] to [3]
232 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
233 :     * [2]: top neighbour's SAD
234 :     * [3]: topright neighbour's SAD
235 :     */
236 : Isibaar 3
237 : edgomez 149 int xin1, xin2, xin3;
238 :     int yin1, yin2, yin3;
239 :     int vec1, vec2, vec3;
240 : Isibaar 3
241 : edgomez 149 uint32_t index = x + y * x_dim;
242 : edgomez 195 const VECTOR zeroMV = { 0, 0 };
243 : edgomez 149
244 : chl 166 // first row of blocks (special case)
245 : suxen_drol 252 if (y == 0 && (block == 0 || block == 1)) {
246 :     if ((x == 0) && (block == 0)) // first column, first block
247 : edgomez 195 {
248 : Isibaar 3 pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
249 : chl 166 psad[0] = 0;
250 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
251 : Isibaar 3 return 0;
252 :     }
253 : edgomez 195 if (block == 1) // second block; has only a left neighbour
254 : Isibaar 3 {
255 :     pmv[0] = pmv[1] = pMBs[index].mvs[0];
256 :     pmv[2] = pmv[3] = zeroMV;
257 :     psad[0] = psad[1] = pMBs[index].sad8[0];
258 : chl 166 psad[2] = psad[3] = MV_MAX_ERROR;
259 : Isibaar 3 return 0;
260 : edgomez 195 } else { /* block==0, but x!=0, so again, there is a left neighbour */
261 :    
262 :     pmv[0] = pmv[1] = pMBs[index - 1].mvs[1];
263 : Isibaar 3 pmv[2] = pmv[3] = zeroMV;
264 : edgomez 195 psad[0] = psad[1] = pMBs[index - 1].sad8[1];
265 : chl 166 psad[2] = psad[3] = MV_MAX_ERROR;
266 : Isibaar 3 return 0;
267 :     }
268 : edgomez 149 }
269 : Isibaar 3
270 :     /*
271 : edgomez 149 * MODE_INTER, vm18 page 48
272 :     * MODE_INTER4V vm18 page 51
273 :     *
274 :     * (x,y-1) (x+1,y-1)
275 :     * [ | ] [ | ]
276 :     * [ 2 | 3 ] [ 2 | ]
277 :     *
278 :     * (x-1,y) (x,y) (x+1,y)
279 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
280 :     * [ | 3 ] [ 2 | 3 ] [ | ]
281 :     */
282 : Isibaar 3
283 : edgomez 195 switch (block) {
284 : Isibaar 3 case 0:
285 : edgomez 195 xin1 = x - 1;
286 :     yin1 = y;
287 :     vec1 = 1; /* left */
288 :     xin2 = x;
289 :     yin2 = y - 1;
290 :     vec2 = 2; /* top */
291 :     xin3 = x + 1;
292 :     yin3 = y - 1;
293 :     vec3 = 2; /* top right */
294 : Isibaar 3 break;
295 :     case 1:
296 : edgomez 195 xin1 = x;
297 :     yin1 = y;
298 :     vec1 = 0;
299 :     xin2 = x;
300 :     yin2 = y - 1;
301 :     vec2 = 3;
302 :     xin3 = x + 1;
303 :     yin3 = y - 1;
304 :     vec3 = 2;
305 : edgomez 149 break;
306 : Isibaar 3 case 2:
307 : edgomez 195 xin1 = x - 1;
308 :     yin1 = y;
309 :     vec1 = 3;
310 :     xin2 = x;
311 :     yin2 = y;
312 :     vec2 = 0;
313 :     xin3 = x;
314 :     yin3 = y;
315 :     vec3 = 1;
316 : edgomez 149 break;
317 : Isibaar 3 default:
318 : edgomez 195 xin1 = x;
319 :     yin1 = y;
320 :     vec1 = 2;
321 :     xin2 = x;
322 :     yin2 = y;
323 :     vec2 = 0;
324 :     xin3 = x;
325 :     yin3 = y;
326 :     vec3 = 1;
327 : edgomez 149 }
328 : Isibaar 3
329 :    
330 : edgomez 195 if (xin1 < 0 || xin1 >= (int32_t) x_dim) {
331 : chl 165 pmv[1] = zeroMV;
332 : Isibaar 3 psad[1] = MV_MAX_ERROR;
333 : edgomez 195 } else {
334 :     pmv[1] = pMBs[xin1 + yin1 * x_dim].mvs[vec1];
335 :     psad[1] = pMBs[xin1 + yin1 * x_dim].sad8[vec1];
336 : Isibaar 3 }
337 :    
338 : edgomez 195 if (xin2 < 0 || xin2 >= (int32_t) x_dim) {
339 : Isibaar 3 pmv[2] = zeroMV;
340 :     psad[2] = MV_MAX_ERROR;
341 : edgomez 195 } else {
342 :     pmv[2] = pMBs[xin2 + yin2 * x_dim].mvs[vec2];
343 :     psad[2] = pMBs[xin2 + yin2 * x_dim].sad8[vec2];
344 : Isibaar 3 }
345 :    
346 : edgomez 195 if (xin3 < 0 || xin3 >= (int32_t) x_dim) {
347 : Isibaar 3 pmv[3] = zeroMV;
348 :     psad[3] = MV_MAX_ERROR;
349 : edgomez 195 } else {
350 : Isibaar 3 pmv[3] = pMBs[xin3 + yin3 * x_dim].mvs[vec3];
351 : suxen_drol 254 psad[3] = pMBs[xin3 + yin3 * x_dim].sad8[vec3];
352 : Isibaar 3 }
353 :    
354 : edgomez 195 if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
355 :     pmv[0] = pmv[1];
356 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
357 : chl 165 return 1;
358 : Isibaar 3 }
359 :    
360 : edgomez 149 /* median,minimum */
361 :    
362 : edgomez 195 pmv[0].x =
363 :     MIN(MAX(pmv[1].x, pmv[2].x),
364 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
365 :     pmv[0].y =
366 :     MIN(MAX(pmv[1].y, pmv[2].y),
367 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
368 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
369 :    
370 : Isibaar 3 return 0;
371 :     }
372 :    
373 : chl 286 #endif
374 : Isibaar 3
375 : suxen_drol 254 /*
376 :     * MODE_INTER, vm18 page 48
377 :     * MODE_INTER4V vm18 page 51
378 :     *
379 :     * (x,y-1) (x+1,y-1)
380 :     * [ | ] [ | ]
381 :     * [ 2 | 3 ] [ 2 | ]
382 :     *
383 :     * (x-1,y) (x,y) (x+1,y)
384 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
385 :     * [ | 3 ] [ 2 | 3 ] [ | ]
386 :     */
387 : chl 139
388 : suxen_drol 254 static __inline VECTOR
389 :     get_pmv2(const MACROBLOCK * const mbs,
390 :     const int mb_width,
391 :     const int bound,
392 :     const int x,
393 :     const int y,
394 :     const int block)
395 :     {
396 :     static const VECTOR zeroMV = { 0, 0 };
397 :    
398 :     int lx, ly, lz; /* left */
399 :     int tx, ty, tz; /* top */
400 :     int rx, ry, rz; /* top-right */
401 :     int lpos, tpos, rpos;
402 :     int num_cand, last_cand;
403 :    
404 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
405 :    
406 :     switch (block) {
407 :     case 0:
408 :     lx = x - 1; ly = y; lz = 1;
409 :     tx = x; ty = y - 1; tz = 2;
410 :     rx = x + 1; ry = y - 1; rz = 2;
411 :     break;
412 :     case 1:
413 :     lx = x; ly = y; lz = 0;
414 :     tx = x; ty = y - 1; tz = 3;
415 :     rx = x + 1; ry = y - 1; rz = 2;
416 :     break;
417 :     case 2:
418 :     lx = x - 1; ly = y; lz = 3;
419 :     tx = x; ty = y; tz = 0;
420 :     rx = x; ry = y; rz = 1;
421 :     break;
422 :     default:
423 :     lx = x; ly = y; lz = 2;
424 :     tx = x; ty = y; tz = 0;
425 :     rx = x; ry = y; rz = 1;
426 :     }
427 :    
428 :     lpos = lx + ly * mb_width;
429 :     rpos = rx + ry * mb_width;
430 :     tpos = tx + ty * mb_width;
431 :     num_cand = 0;
432 :    
433 :     if (lpos >= bound && lx >= 0) {
434 :     num_cand++;
435 :     last_cand = 1;
436 :     pmv[1] = mbs[lpos].mvs[lz];
437 :     } else {
438 :     pmv[1] = zeroMV;
439 :     }
440 :    
441 :     if (tpos >= bound) {
442 :     num_cand++;
443 :     last_cand = 2;
444 :     pmv[2] = mbs[tpos].mvs[tz];
445 :     } else {
446 :     pmv[2] = zeroMV;
447 :     }
448 :    
449 :     if (rpos >= bound && rx < mb_width) {
450 :     num_cand++;
451 :     last_cand = 3;
452 :     pmv[3] = mbs[rpos].mvs[rz];
453 :     } else {
454 :     pmv[3] = zeroMV;
455 :     }
456 :    
457 : chl 286 /* if only one valid candidate predictor, the invalid candiates are set to the canidate */
458 : suxen_drol 254 if (num_cand != 1) {
459 :     /* set median */
460 :    
461 :     pmv[0].x =
462 :     MIN(MAX(pmv[1].x, pmv[2].x),
463 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
464 :     pmv[0].y =
465 :     MIN(MAX(pmv[1].y, pmv[2].y),
466 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
467 :     return pmv[0];
468 :     }
469 :    
470 :     return pmv[last_cand]; /* no point calculating median mv */
471 :     }
472 :    
473 :    
474 :    
475 :     /*
476 :     * pmv are filled with:
477 :     * [0]: Median (or whatever is correct in a special case)
478 :     * [1]: left neighbour
479 :     * [2]: top neighbour
480 :     * [3]: topright neighbour
481 :     * psad are filled with:
482 :     * [0]: minimum of [1] to [3]
483 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
484 :     * [2]: top neighbour's SAD
485 :     * [3]: topright neighbour's SAD
486 :     */
487 : chl 286
488 : suxen_drol 254 static __inline int
489 :     get_pmvdata2(const MACROBLOCK * const mbs,
490 :     const int mb_width,
491 :     const int bound,
492 :     const int x,
493 :     const int y,
494 :     const int block,
495 :     VECTOR * const pmv,
496 :     int32_t * const psad)
497 :     {
498 :     static const VECTOR zeroMV = { 0, 0 };
499 :    
500 :     int lx, ly, lz; /* left */
501 :     int tx, ty, tz; /* top */
502 :     int rx, ry, rz; /* top-right */
503 :     int lpos, tpos, rpos;
504 :     int num_cand, last_cand;
505 :    
506 :     switch (block) {
507 :     case 0:
508 :     lx = x - 1; ly = y; lz = 1;
509 :     tx = x; ty = y - 1; tz = 2;
510 :     rx = x + 1; ry = y - 1; rz = 2;
511 :     break;
512 :     case 1:
513 :     lx = x; ly = y; lz = 0;
514 :     tx = x; ty = y - 1; tz = 3;
515 :     rx = x + 1; ry = y - 1; rz = 2;
516 :     break;
517 :     case 2:
518 :     lx = x - 1; ly = y; lz = 3;
519 :     tx = x; ty = y; tz = 0;
520 :     rx = x; ry = y; rz = 1;
521 :     break;
522 :     default:
523 :     lx = x; ly = y; lz = 2;
524 :     tx = x; ty = y; tz = 0;
525 :     rx = x; ry = y; rz = 1;
526 :     }
527 :    
528 :     lpos = lx + ly * mb_width;
529 :     rpos = rx + ry * mb_width;
530 :     tpos = tx + ty * mb_width;
531 :     num_cand = 0;
532 :    
533 :     if (lpos >= bound && lx >= 0) {
534 :     num_cand++;
535 :     last_cand = 1;
536 :     pmv[1] = mbs[lpos].mvs[lz];
537 :     psad[1] = mbs[lpos].sad8[lz];
538 :     } else {
539 :     pmv[1] = zeroMV;
540 :     psad[1] = MV_MAX_ERROR;
541 :     }
542 :    
543 :     if (tpos >= bound) {
544 :     num_cand++;
545 :     last_cand = 2;
546 :     pmv[2]= mbs[tpos].mvs[tz];
547 :     psad[2] = mbs[tpos].sad8[tz];
548 :     } else {
549 :     pmv[2] = zeroMV;
550 :     psad[2] = MV_MAX_ERROR;
551 :     }
552 :    
553 :     if (rpos >= bound && rx < mb_width) {
554 :     num_cand++;
555 :     last_cand = 3;
556 :     pmv[3] = mbs[rpos].mvs[rz];
557 :     psad[3] = mbs[rpos].sad8[rz];
558 :     } else {
559 :     pmv[3] = zeroMV;
560 :     psad[3] = MV_MAX_ERROR;
561 :     }
562 :    
563 :     /* original pmvdata() compatibility hack */
564 :     if (x == 0 && y == 0 && block == 0)
565 :     {
566 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
567 :     psad[0] = 0;
568 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
569 :     return 0;
570 :     }
571 :    
572 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
573 :     if (num_cand == 1) {
574 :     pmv[0] = pmv[last_cand];
575 :     psad[0] = psad[last_cand];
576 :     // return MVequal(pmv[0], zeroMV); /* no point calculating median mv and minimum sad */
577 :    
578 :     /* original pmvdata() compatibility hack */
579 :     return y==0 && block <= 1 ? 0 : MVequal(pmv[0], zeroMV);
580 :     }
581 :    
582 :     if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
583 :     pmv[0] = pmv[1];
584 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
585 :     return 1;
586 :     /* compatibility patch */
587 :     //return y==0 && block <= 1 ? 0 : 1;
588 :     }
589 :    
590 :     /* set median, minimum */
591 :    
592 :     pmv[0].x =
593 :     MIN(MAX(pmv[1].x, pmv[2].x),
594 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
595 :     pmv[0].y =
596 :     MIN(MAX(pmv[1].y, pmv[2].y),
597 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
598 :    
599 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
600 :    
601 :     return 0;
602 :     }
603 :    
604 : chl 286 /* copies of get_pmv and get_pmvdata for prediction from integer search */
605 : suxen_drol 254
606 : chl 286 static __inline VECTOR
607 :     get_ipmv(const MACROBLOCK * const mbs,
608 :     const int mb_width,
609 :     const int bound,
610 :     const int x,
611 :     const int y,
612 :     const int block)
613 :     {
614 :     static const VECTOR zeroMV = { 0, 0 };
615 :    
616 :     int lx, ly, lz; /* left */
617 :     int tx, ty, tz; /* top */
618 :     int rx, ry, rz; /* top-right */
619 :     int lpos, tpos, rpos;
620 :     int num_cand, last_cand;
621 :    
622 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
623 :    
624 :     switch (block) {
625 :     case 0:
626 :     lx = x - 1; ly = y; lz = 1;
627 :     tx = x; ty = y - 1; tz = 2;
628 :     rx = x + 1; ry = y - 1; rz = 2;
629 :     break;
630 :     case 1:
631 :     lx = x; ly = y; lz = 0;
632 :     tx = x; ty = y - 1; tz = 3;
633 :     rx = x + 1; ry = y - 1; rz = 2;
634 :     break;
635 :     case 2:
636 :     lx = x - 1; ly = y; lz = 3;
637 :     tx = x; ty = y; tz = 0;
638 :     rx = x; ry = y; rz = 1;
639 :     break;
640 :     default:
641 :     lx = x; ly = y; lz = 2;
642 :     tx = x; ty = y; tz = 0;
643 :     rx = x; ry = y; rz = 1;
644 :     }
645 :    
646 :     lpos = lx + ly * mb_width;
647 :     rpos = rx + ry * mb_width;
648 :     tpos = tx + ty * mb_width;
649 :     num_cand = 0;
650 :    
651 :     if (lpos >= bound && lx >= 0) {
652 :     num_cand++;
653 :     last_cand = 1;
654 :     pmv[1] = mbs[lpos].i_mvs[lz];
655 :     } else {
656 :     pmv[1] = zeroMV;
657 :     }
658 :    
659 :     if (tpos >= bound) {
660 :     num_cand++;
661 :     last_cand = 2;
662 :     pmv[2] = mbs[tpos].i_mvs[tz];
663 :     } else {
664 :     pmv[2] = zeroMV;
665 :     }
666 :    
667 :     if (rpos >= bound && rx < mb_width) {
668 :     num_cand++;
669 :     last_cand = 3;
670 :     pmv[3] = mbs[rpos].i_mvs[rz];
671 :     } else {
672 :     pmv[3] = zeroMV;
673 :     }
674 :    
675 :     /* if only one valid candidate predictor, the invalid candiates are set to the canidate */
676 :     if (num_cand != 1) {
677 :     /* set median */
678 :    
679 :     pmv[0].x =
680 :     MIN(MAX(pmv[1].x, pmv[2].x),
681 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
682 :     pmv[0].y =
683 :     MIN(MAX(pmv[1].y, pmv[2].y),
684 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
685 :     return pmv[0];
686 :     }
687 :    
688 :     return pmv[last_cand]; /* no point calculating median mv */
689 :     }
690 :    
691 :     static __inline int
692 :     get_ipmvdata(const MACROBLOCK * const mbs,
693 :     const int mb_width,
694 :     const int bound,
695 :     const int x,
696 :     const int y,
697 :     const int block,
698 :     VECTOR * const pmv,
699 :     int32_t * const psad)
700 :     {
701 :     static const VECTOR zeroMV = { 0, 0 };
702 :    
703 :     int lx, ly, lz; /* left */
704 :     int tx, ty, tz; /* top */
705 :     int rx, ry, rz; /* top-right */
706 :     int lpos, tpos, rpos;
707 :     int num_cand, last_cand;
708 :    
709 :     switch (block) {
710 :     case 0:
711 :     lx = x - 1; ly = y; lz = 1;
712 :     tx = x; ty = y - 1; tz = 2;
713 :     rx = x + 1; ry = y - 1; rz = 2;
714 :     break;
715 :     case 1:
716 :     lx = x; ly = y; lz = 0;
717 :     tx = x; ty = y - 1; tz = 3;
718 :     rx = x + 1; ry = y - 1; rz = 2;
719 :     break;
720 :     case 2:
721 :     lx = x - 1; ly = y; lz = 3;
722 :     tx = x; ty = y; tz = 0;
723 :     rx = x; ry = y; rz = 1;
724 :     break;
725 :     default:
726 :     lx = x; ly = y; lz = 2;
727 :     tx = x; ty = y; tz = 0;
728 :     rx = x; ry = y; rz = 1;
729 :     }
730 :    
731 :     lpos = lx + ly * mb_width;
732 :     rpos = rx + ry * mb_width;
733 :     tpos = tx + ty * mb_width;
734 :     num_cand = 0;
735 :    
736 :     if (lpos >= bound && lx >= 0) {
737 :     num_cand++;
738 :     last_cand = 1;
739 :     pmv[1] = mbs[lpos].i_mvs[lz];
740 :     psad[1] = mbs[lpos].i_sad8[lz];
741 :     } else {
742 :     pmv[1] = zeroMV;
743 :     psad[1] = MV_MAX_ERROR;
744 :     }
745 :    
746 :     if (tpos >= bound) {
747 :     num_cand++;
748 :     last_cand = 2;
749 :     pmv[2]= mbs[tpos].i_mvs[tz];
750 :     psad[2] = mbs[tpos].i_sad8[tz];
751 :     } else {
752 :     pmv[2] = zeroMV;
753 :     psad[2] = MV_MAX_ERROR;
754 :     }
755 :    
756 :     if (rpos >= bound && rx < mb_width) {
757 :     num_cand++;
758 :     last_cand = 3;
759 :     pmv[3] = mbs[rpos].i_mvs[rz];
760 :     psad[3] = mbs[rpos].i_sad8[rz];
761 :     } else {
762 :     pmv[3] = zeroMV;
763 :     psad[3] = MV_MAX_ERROR;
764 :     }
765 :    
766 :     /* original pmvdata() compatibility hack */
767 :     if (x == 0 && y == 0 && block == 0)
768 :     {
769 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
770 :     psad[0] = 0;
771 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
772 :     return 0;
773 :     }
774 :    
775 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
776 :     if (num_cand == 1) {
777 :     pmv[0] = pmv[last_cand];
778 :     psad[0] = psad[last_cand];
779 :     // return MVequal(pmv[0], zeroMV); /* no point calculating median mv and minimum sad */
780 :    
781 :     /* original pmvdata() compatibility hack */
782 :     return y==0 && block <= 1 ? 0 : MVequal(pmv[0], zeroMV);
783 :     }
784 :    
785 :     if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
786 :     pmv[0] = pmv[1];
787 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
788 :     return 1;
789 :     /* compatibility patch */
790 :     //return y==0 && block <= 1 ? 0 : 1;
791 :     }
792 :    
793 :     /* set median, minimum */
794 :    
795 :     pmv[0].x =
796 :     MIN(MAX(pmv[1].x, pmv[2].x),
797 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
798 :     pmv[0].y =
799 :     MIN(MAX(pmv[1].y, pmv[2].y),
800 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
801 :    
802 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
803 :    
804 :     return 0;
805 :     }
806 :    
807 :    
808 : edgomez 195 #endif /* _MBPREDICTION_H_ */

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