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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (view) (download)

1 : edgomez 1.5 /**************************************************************************
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 : edgomez 1.15 * $Id: mbprediction.h,v 1.14 2002/09/07 13:43:00 edgomez Exp $
30 : edgomez 1.5 *
31 :     *************************************************************************/
32 :    
33 : Isibaar 1.1 #ifndef _MBPREDICTION_H_
34 :     #define _MBPREDICTION_H_
35 :    
36 :     #include "../portab.h"
37 :     #include "../decoder.h"
38 :     #include "../global.h"
39 :    
40 :     #define MIN(X, Y) ((X)<(Y)?(X):(Y))
41 :     #define MAX(X, Y) ((X)>(Y)?(X):(Y))
42 :    
43 : edgomez 1.5 /* very large value */
44 : Isibaar 1.1 #define MV_MAX_ERROR (4096 * 256)
45 :    
46 :     #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
47 :    
48 : edgomez 1.14 /*****************************************************************************
49 :     * Prototypes
50 :     ****************************************************************************/
51 :    
52 : edgomez 1.9 void MBPrediction(FRAMEINFO * frame, /* <-- The parameter for ACDC and MV prediction */
53 :    
54 :     uint32_t x_pos, /* <-- The x position of the MB to be searched */
55 :    
56 :     uint32_t y_pos, /* <-- The y position of the MB to be searched */
57 :    
58 :     uint32_t x_dim, /* <-- Number of macroblocks in a row */
59 :    
60 :     int16_t * qcoeff); /* <-> The quantized DCT coefficients */
61 :    
62 :     void add_acdc(MACROBLOCK * pMB,
63 :     uint32_t block,
64 :     int16_t dct_codes[64],
65 :     uint32_t iDcScaler,
66 :     int16_t predictors[8]);
67 :    
68 :    
69 :     void predict_acdc(MACROBLOCK * pMBs,
70 :     uint32_t x,
71 :     uint32_t y,
72 :     uint32_t mb_width,
73 :     uint32_t block,
74 :     int16_t qcoeff[64],
75 :     uint32_t current_quant,
76 :     int32_t iDcScaler,
77 : suxen_drol 1.10 int16_t predictors[8],
78 : suxen_drol 1.11 const int bound);
79 : suxen_drol 1.10
80 : Isibaar 1.1
81 : edgomez 1.14 /*****************************************************************************
82 :     * Inlined functions
83 :     ****************************************************************************/
84 :    
85 :     /*
86 :     * MODE_INTER, vm18 page 48
87 :     * MODE_INTER4V vm18 page 51
88 :     *
89 :     * (x,y-1) (x+1,y-1)
90 :     * [ | ] [ | ]
91 :     * [ 2 | 3 ] [ 2 | ]
92 :     *
93 :     * (x-1,y) (x,y) (x+1,y)
94 :     * [ | 1 ] [ 0 | 1 ] [ 0 | ]
95 :     * [ | 3 ] [ 2 | 3 ] [ | ]
96 :     */
97 : suxen_drol 1.12
98 :     static __inline VECTOR
99 :     get_pmv2(const MACROBLOCK * const mbs,
100 :     const int mb_width,
101 :     const int bound,
102 :     const int x,
103 :     const int y,
104 :     const int block)
105 :     {
106 :     static const VECTOR zeroMV = { 0, 0 };
107 :    
108 :     int lx, ly, lz; /* left */
109 :     int tx, ty, tz; /* top */
110 :     int rx, ry, rz; /* top-right */
111 :     int lpos, tpos, rpos;
112 :     int num_cand, last_cand;
113 :    
114 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
115 :    
116 :     switch (block) {
117 :     case 0:
118 :     lx = x - 1; ly = y; lz = 1;
119 :     tx = x; ty = y - 1; tz = 2;
120 :     rx = x + 1; ry = y - 1; rz = 2;
121 :     break;
122 :     case 1:
123 :     lx = x; ly = y; lz = 0;
124 :     tx = x; ty = y - 1; tz = 3;
125 :     rx = x + 1; ry = y - 1; rz = 2;
126 :     break;
127 :     case 2:
128 :     lx = x - 1; ly = y; lz = 3;
129 :     tx = x; ty = y; tz = 0;
130 :     rx = x; ry = y; rz = 1;
131 :     break;
132 :     default:
133 :     lx = x; ly = y; lz = 2;
134 :     tx = x; ty = y; tz = 0;
135 :     rx = x; ry = y; rz = 1;
136 :     }
137 :    
138 :     lpos = lx + ly * mb_width;
139 :     rpos = rx + ry * mb_width;
140 :     tpos = tx + ty * mb_width;
141 : edgomez 1.15 last_cand = num_cand = 0;
142 : suxen_drol 1.12
143 :     if (lpos >= bound && lx >= 0) {
144 :     num_cand++;
145 :     last_cand = 1;
146 :     pmv[1] = mbs[lpos].mvs[lz];
147 :     } else {
148 :     pmv[1] = zeroMV;
149 :     }
150 :    
151 :     if (tpos >= bound) {
152 :     num_cand++;
153 :     last_cand = 2;
154 :     pmv[2] = mbs[tpos].mvs[tz];
155 :     } else {
156 :     pmv[2] = zeroMV;
157 :     }
158 :    
159 :     if (rpos >= bound && rx < mb_width) {
160 :     num_cand++;
161 :     last_cand = 3;
162 :     pmv[3] = mbs[rpos].mvs[rz];
163 :     } else {
164 :     pmv[3] = zeroMV;
165 :     }
166 :    
167 : edgomez 1.15 /*
168 :     * If there're more than one candidate, we return the median vector
169 :     * edgomez : the special case "no candidates" is handled the same way
170 :     * because all vectors are set to zero. So the median vector
171 :     * is {0,0}, and this is exactly the vector we must return
172 :     * according to the mpeg4 specs.
173 :     */
174 :    
175 : suxen_drol 1.12 if (num_cand != 1) {
176 :     /* set median */
177 :    
178 :     pmv[0].x =
179 :     MIN(MAX(pmv[1].x, pmv[2].x),
180 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
181 :     pmv[0].y =
182 :     MIN(MAX(pmv[1].y, pmv[2].y),
183 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
184 :     return pmv[0];
185 :     }
186 :    
187 :     return pmv[last_cand]; /* no point calculating median mv */
188 :     }
189 :    
190 :    
191 :    
192 : edgomez 1.14 /*
193 :     * pmv are filled with:
194 :     * [0]: Median (or whatever is correct in a special case)
195 :     * [1]: left neighbour
196 :     * [2]: top neighbour
197 :     * [3]: topright neighbour
198 :     * psad are filled with:
199 :     * [0]: minimum of [1] to [3]
200 :     * [1]: left neighbour's SAD (NB:[1] to [3] are actually not needed)
201 :     * [2]: top neighbour's SAD
202 :     * [3]: topright neighbour's SAD
203 :     */
204 : chl 1.13
205 : suxen_drol 1.12 static __inline int
206 :     get_pmvdata2(const MACROBLOCK * const mbs,
207 :     const int mb_width,
208 :     const int bound,
209 :     const int x,
210 :     const int y,
211 :     const int block,
212 :     VECTOR * const pmv,
213 :     int32_t * const psad)
214 :     {
215 :     static const VECTOR zeroMV = { 0, 0 };
216 :    
217 :     int lx, ly, lz; /* left */
218 :     int tx, ty, tz; /* top */
219 :     int rx, ry, rz; /* top-right */
220 :     int lpos, tpos, rpos;
221 :     int num_cand, last_cand;
222 :    
223 :     switch (block) {
224 :     case 0:
225 :     lx = x - 1; ly = y; lz = 1;
226 :     tx = x; ty = y - 1; tz = 2;
227 :     rx = x + 1; ry = y - 1; rz = 2;
228 :     break;
229 :     case 1:
230 :     lx = x; ly = y; lz = 0;
231 :     tx = x; ty = y - 1; tz = 3;
232 :     rx = x + 1; ry = y - 1; rz = 2;
233 :     break;
234 :     case 2:
235 :     lx = x - 1; ly = y; lz = 3;
236 :     tx = x; ty = y; tz = 0;
237 :     rx = x; ry = y; rz = 1;
238 :     break;
239 :     default:
240 :     lx = x; ly = y; lz = 2;
241 :     tx = x; ty = y; tz = 0;
242 :     rx = x; ry = y; rz = 1;
243 :     }
244 :    
245 :     lpos = lx + ly * mb_width;
246 :     rpos = rx + ry * mb_width;
247 :     tpos = tx + ty * mb_width;
248 : edgomez 1.15 last_cand = num_cand = 0;
249 : suxen_drol 1.12
250 :     if (lpos >= bound && lx >= 0) {
251 :     num_cand++;
252 :     last_cand = 1;
253 :     pmv[1] = mbs[lpos].mvs[lz];
254 :     psad[1] = mbs[lpos].sad8[lz];
255 :     } else {
256 :     pmv[1] = zeroMV;
257 :     psad[1] = MV_MAX_ERROR;
258 :     }
259 :    
260 :     if (tpos >= bound) {
261 :     num_cand++;
262 :     last_cand = 2;
263 :     pmv[2]= mbs[tpos].mvs[tz];
264 :     psad[2] = mbs[tpos].sad8[tz];
265 :     } else {
266 :     pmv[2] = zeroMV;
267 :     psad[2] = MV_MAX_ERROR;
268 :     }
269 :    
270 :     if (rpos >= bound && rx < mb_width) {
271 :     num_cand++;
272 :     last_cand = 3;
273 :     pmv[3] = mbs[rpos].mvs[rz];
274 :     psad[3] = mbs[rpos].sad8[rz];
275 : chl 1.13 } else {
276 :     pmv[3] = zeroMV;
277 :     psad[3] = MV_MAX_ERROR;
278 :     }
279 :    
280 :     /* original pmvdata() compatibility hack */
281 :     if (x == 0 && y == 0 && block == 0)
282 :     {
283 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
284 :     psad[0] = 0;
285 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
286 :     return 0;
287 :     }
288 :    
289 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
290 :     if (num_cand == 1) {
291 :     pmv[0] = pmv[last_cand];
292 :     psad[0] = psad[last_cand];
293 :     // return MVequal(pmv[0], zeroMV); /* no point calculating median mv and minimum sad */
294 :    
295 :     /* original pmvdata() compatibility hack */
296 :     return y==0 && block <= 1 ? 0 : MVequal(pmv[0], zeroMV);
297 :     }
298 :    
299 :     if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
300 :     pmv[0] = pmv[1];
301 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
302 :     return 1;
303 :     /* compatibility patch */
304 :     //return y==0 && block <= 1 ? 0 : 1;
305 :     }
306 :    
307 :     /* set median, minimum */
308 :    
309 :     pmv[0].x =
310 :     MIN(MAX(pmv[1].x, pmv[2].x),
311 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
312 :     pmv[0].y =
313 :     MIN(MAX(pmv[1].y, pmv[2].y),
314 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
315 :    
316 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
317 :    
318 :     return 0;
319 :     }
320 :    
321 :     /* copies of get_pmv and get_pmvdata for prediction from integer search */
322 :    
323 :     static __inline VECTOR
324 :     get_ipmv(const MACROBLOCK * const mbs,
325 :     const int mb_width,
326 :     const int bound,
327 :     const int x,
328 :     const int y,
329 :     const int block)
330 :     {
331 :     static const VECTOR zeroMV = { 0, 0 };
332 :    
333 :     int lx, ly, lz; /* left */
334 :     int tx, ty, tz; /* top */
335 :     int rx, ry, rz; /* top-right */
336 :     int lpos, tpos, rpos;
337 :     int num_cand, last_cand;
338 :    
339 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
340 :    
341 :     switch (block) {
342 :     case 0:
343 :     lx = x - 1; ly = y; lz = 1;
344 :     tx = x; ty = y - 1; tz = 2;
345 :     rx = x + 1; ry = y - 1; rz = 2;
346 :     break;
347 :     case 1:
348 :     lx = x; ly = y; lz = 0;
349 :     tx = x; ty = y - 1; tz = 3;
350 :     rx = x + 1; ry = y - 1; rz = 2;
351 :     break;
352 :     case 2:
353 :     lx = x - 1; ly = y; lz = 3;
354 :     tx = x; ty = y; tz = 0;
355 :     rx = x; ry = y; rz = 1;
356 :     break;
357 :     default:
358 :     lx = x; ly = y; lz = 2;
359 :     tx = x; ty = y; tz = 0;
360 :     rx = x; ry = y; rz = 1;
361 :     }
362 :    
363 :     lpos = lx + ly * mb_width;
364 :     rpos = rx + ry * mb_width;
365 :     tpos = tx + ty * mb_width;
366 : edgomez 1.15 last_cand = num_cand = 0;
367 : chl 1.13
368 :     if (lpos >= bound && lx >= 0) {
369 :     num_cand++;
370 :     last_cand = 1;
371 :     pmv[1] = mbs[lpos].i_mvs[lz];
372 :     } else {
373 :     pmv[1] = zeroMV;
374 :     }
375 :    
376 :     if (tpos >= bound) {
377 :     num_cand++;
378 :     last_cand = 2;
379 :     pmv[2] = mbs[tpos].i_mvs[tz];
380 :     } else {
381 :     pmv[2] = zeroMV;
382 :     }
383 :    
384 :     if (rpos >= bound && rx < mb_width) {
385 :     num_cand++;
386 :     last_cand = 3;
387 :     pmv[3] = mbs[rpos].i_mvs[rz];
388 :     } else {
389 :     pmv[3] = zeroMV;
390 :     }
391 :    
392 :     /* if only one valid candidate predictor, the invalid candiates are set to the canidate */
393 :     if (num_cand != 1) {
394 :     /* set median */
395 :    
396 :     pmv[0].x =
397 :     MIN(MAX(pmv[1].x, pmv[2].x),
398 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
399 :     pmv[0].y =
400 :     MIN(MAX(pmv[1].y, pmv[2].y),
401 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
402 :     return pmv[0];
403 :     }
404 :    
405 :     return pmv[last_cand]; /* no point calculating median mv */
406 :     }
407 :    
408 :     static __inline int
409 :     get_ipmvdata(const MACROBLOCK * const mbs,
410 :     const int mb_width,
411 :     const int bound,
412 :     const int x,
413 :     const int y,
414 :     const int block,
415 :     VECTOR * const pmv,
416 :     int32_t * const psad)
417 :     {
418 :     static const VECTOR zeroMV = { 0, 0 };
419 :    
420 :     int lx, ly, lz; /* left */
421 :     int tx, ty, tz; /* top */
422 :     int rx, ry, rz; /* top-right */
423 :     int lpos, tpos, rpos;
424 :     int num_cand, last_cand;
425 :    
426 :     switch (block) {
427 :     case 0:
428 :     lx = x - 1; ly = y; lz = 1;
429 :     tx = x; ty = y - 1; tz = 2;
430 :     rx = x + 1; ry = y - 1; rz = 2;
431 :     break;
432 :     case 1:
433 :     lx = x; ly = y; lz = 0;
434 :     tx = x; ty = y - 1; tz = 3;
435 :     rx = x + 1; ry = y - 1; rz = 2;
436 :     break;
437 :     case 2:
438 :     lx = x - 1; ly = y; lz = 3;
439 :     tx = x; ty = y; tz = 0;
440 :     rx = x; ry = y; rz = 1;
441 :     break;
442 :     default:
443 :     lx = x; ly = y; lz = 2;
444 :     tx = x; ty = y; tz = 0;
445 :     rx = x; ry = y; rz = 1;
446 :     }
447 :    
448 :     lpos = lx + ly * mb_width;
449 :     rpos = rx + ry * mb_width;
450 :     tpos = tx + ty * mb_width;
451 : edgomez 1.15 last_cand = num_cand = 0;
452 : chl 1.13
453 :     if (lpos >= bound && lx >= 0) {
454 :     num_cand++;
455 :     last_cand = 1;
456 :     pmv[1] = mbs[lpos].i_mvs[lz];
457 :     psad[1] = mbs[lpos].i_sad8[lz];
458 :     } else {
459 :     pmv[1] = zeroMV;
460 :     psad[1] = MV_MAX_ERROR;
461 :     }
462 :    
463 :     if (tpos >= bound) {
464 :     num_cand++;
465 :     last_cand = 2;
466 :     pmv[2]= mbs[tpos].i_mvs[tz];
467 :     psad[2] = mbs[tpos].i_sad8[tz];
468 :     } else {
469 :     pmv[2] = zeroMV;
470 :     psad[2] = MV_MAX_ERROR;
471 :     }
472 :    
473 :     if (rpos >= bound && rx < mb_width) {
474 :     num_cand++;
475 :     last_cand = 3;
476 :     pmv[3] = mbs[rpos].i_mvs[rz];
477 :     psad[3] = mbs[rpos].i_sad8[rz];
478 : suxen_drol 1.12 } else {
479 :     pmv[3] = zeroMV;
480 :     psad[3] = MV_MAX_ERROR;
481 :     }
482 :    
483 :     /* original pmvdata() compatibility hack */
484 :     if (x == 0 && y == 0 && block == 0)
485 :     {
486 :     pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
487 :     psad[0] = 0;
488 :     psad[1] = psad[2] = psad[3] = MV_MAX_ERROR;
489 :     return 0;
490 :     }
491 :    
492 :     /* if only one valid candidate preictor, the invalid candiates are set to the canidate */
493 :     if (num_cand == 1) {
494 :     pmv[0] = pmv[last_cand];
495 :     psad[0] = psad[last_cand];
496 :     // return MVequal(pmv[0], zeroMV); /* no point calculating median mv and minimum sad */
497 :    
498 :     /* original pmvdata() compatibility hack */
499 :     return y==0 && block <= 1 ? 0 : MVequal(pmv[0], zeroMV);
500 :     }
501 :    
502 :     if ((MVequal(pmv[1], pmv[2])) && (MVequal(pmv[1], pmv[3]))) {
503 :     pmv[0] = pmv[1];
504 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
505 :     return 1;
506 :     /* compatibility patch */
507 :     //return y==0 && block <= 1 ? 0 : 1;
508 :     }
509 :    
510 :     /* set median, minimum */
511 :    
512 :     pmv[0].x =
513 :     MIN(MAX(pmv[1].x, pmv[2].x),
514 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
515 :     pmv[0].y =
516 :     MIN(MAX(pmv[1].y, pmv[2].y),
517 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
518 :    
519 :     psad[0] = MIN(MIN(psad[1], psad[2]), psad[3]);
520 :    
521 :     return 0;
522 :     }
523 : Isibaar 1.1
524 :    
525 : edgomez 1.9 #endif /* _MBPREDICTION_H_ */

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