[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 605 - (view) (download)

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

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