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

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

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