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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1142 - (view) (download)

1 : edgomez 1142 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Prediction module -
5 :     *
6 :     * Copyright (C) 2001-2003 Michael Militzer <isibaar@xvid.org>
7 :     * 2001-2003 Peter Ross <pross@xvid.org>
8 :     *
9 :     * This program is free software ; you can redistribute it and/or modify
10 :     * it under the terms of the GNU General Public License as published by
11 :     * the Free Software Foundation ; either version 2 of the License, or
12 :     * (at your option) any later version.
13 :     *
14 :     * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 :     *
19 :     * You should have received a copy of the GNU General Public License
20 :     * along with this program ; if not, write to the Free Software
21 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     *
23 :     * $Id: mbprediction.c,v 1.13.2.8 2003-09-10 22:19:00 edgomez Exp $
24 :     *
25 :     ****************************************************************************/
26 : Isibaar 3
27 : edgomez 982 #include <stdlib.h>
28 :    
29 : edgomez 851 #include "../global.h"
30 : Isibaar 3 #include "../encoder.h"
31 :     #include "mbprediction.h"
32 :     #include "../utils/mbfunctions.h"
33 :     #include "../bitstream/cbp.h"
34 : edgomez 851 #include "../bitstream/mbcoding.h"
35 :     #include "../bitstream/zigzag.h"
36 : Isibaar 3
37 :    
38 : edgomez 195 static int __inline
39 :     rescale(int predict_quant,
40 :     int current_quant,
41 :     int coeff)
42 : Isibaar 3 {
43 : edgomez 195 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
44 :     (current_quant)) : 0;
45 : Isibaar 3 }
46 :    
47 :    
48 : edgomez 195 static const int16_t default_acdc_values[15] = {
49 : Isibaar 3 1024,
50 : edgomez 78 0, 0, 0, 0, 0, 0, 0,
51 :     0, 0, 0, 0, 0, 0, 0
52 : Isibaar 3 };
53 :    
54 :    
55 :     /* get dc/ac prediction direction for a single block and place
56 :     predictor values into MB->pred_values[j][..]
57 :     */
58 :    
59 :    
60 : edgomez 195 void
61 :     predict_acdc(MACROBLOCK * pMBs,
62 :     uint32_t x,
63 :     uint32_t y,
64 :     uint32_t mb_width,
65 :     uint32_t block,
66 :     int16_t qcoeff[64],
67 :     uint32_t current_quant,
68 :     int32_t iDcScaler,
69 : suxen_drol 248 int16_t predictors[8],
70 : suxen_drol 252 const int bound)
71 : suxen_drol 248
72 : Isibaar 3 {
73 : suxen_drol 252 const int mbpos = (y * mb_width) + x;
74 : edgomez 78 int16_t *left, *top, *diag, *current;
75 : Isibaar 3
76 : edgomez 78 int32_t left_quant = current_quant;
77 :     int32_t top_quant = current_quant;
78 : Isibaar 3
79 : edgomez 78 const int16_t *pLeft = default_acdc_values;
80 :     const int16_t *pTop = default_acdc_values;
81 :     const int16_t *pDiag = default_acdc_values;
82 : Isibaar 3
83 : edgomez 1053 uint32_t index = x + y * mb_width; /* current macroblock */
84 : edgomez 195 int *acpred_direction = &pMBs[index].acpred_directions[block];
85 : Isibaar 3 uint32_t i;
86 :    
87 :     left = top = diag = current = 0;
88 :    
89 : edgomez 1053 /* grab left,top and diag macroblocks */
90 : Isibaar 3
91 : edgomez 1053 /* left macroblock */
92 : Isibaar 3
93 : suxen_drol 248 if (x && mbpos >= bound + 1 &&
94 : edgomez 195 (pMBs[index - 1].mode == MODE_INTRA ||
95 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
96 : Isibaar 3
97 :     left = pMBs[index - 1].pred_values[0];
98 :     left_quant = pMBs[index - 1].quant;
99 :     }
100 : edgomez 1053 /* top macroblock */
101 : Isibaar 3
102 : suxen_drol 252 if (mbpos >= bound + (int)mb_width &&
103 : edgomez 195 (pMBs[index - mb_width].mode == MODE_INTRA ||
104 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
105 :    
106 : Isibaar 3 top = pMBs[index - mb_width].pred_values[0];
107 :     top_quant = pMBs[index - mb_width].quant;
108 : edgomez 78 }
109 : edgomez 1053 /* diag macroblock */
110 : Isibaar 3
111 : suxen_drol 252 if (x && mbpos >= bound + (int)mb_width + 1 &&
112 : edgomez 195 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
113 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
114 :    
115 : Isibaar 3 diag = pMBs[index - 1 - mb_width].pred_values[0];
116 :     }
117 :    
118 : edgomez 78 current = pMBs[index].pred_values[0];
119 : Isibaar 3
120 : edgomez 1053 /* now grab pLeft, pTop, pDiag _blocks_ */
121 : edgomez 195
122 : Isibaar 3 switch (block) {
123 : edgomez 195
124 :     case 0:
125 :     if (left)
126 : Isibaar 3 pLeft = left + MBPRED_SIZE;
127 : edgomez 195
128 :     if (top)
129 : Isibaar 3 pTop = top + (MBPRED_SIZE << 1);
130 : edgomez 195
131 :     if (diag)
132 : Isibaar 3 pDiag = diag + 3 * MBPRED_SIZE;
133 : edgomez 195
134 : Isibaar 3 break;
135 : edgomez 195
136 : Isibaar 3 case 1:
137 :     pLeft = current;
138 :     left_quant = current_quant;
139 : edgomez 195
140 :     if (top) {
141 : Isibaar 3 pTop = top + 3 * MBPRED_SIZE;
142 :     pDiag = top + (MBPRED_SIZE << 1);
143 :     }
144 :     break;
145 : edgomez 195
146 : Isibaar 3 case 2:
147 : edgomez 195 if (left) {
148 : Isibaar 3 pLeft = left + 3 * MBPRED_SIZE;
149 :     pDiag = left + MBPRED_SIZE;
150 :     }
151 : edgomez 195
152 : Isibaar 3 pTop = current;
153 :     top_quant = current_quant;
154 :    
155 :     break;
156 : edgomez 195
157 : Isibaar 3 case 3:
158 :     pLeft = current + (MBPRED_SIZE << 1);
159 :     left_quant = current_quant;
160 : edgomez 195
161 : Isibaar 3 pTop = current + MBPRED_SIZE;
162 :     top_quant = current_quant;
163 : edgomez 195
164 : Isibaar 3 pDiag = current;
165 : edgomez 195
166 : Isibaar 3 break;
167 : edgomez 195
168 : Isibaar 3 case 4:
169 : edgomez 195 if (left)
170 : Isibaar 3 pLeft = left + (MBPRED_SIZE << 2);
171 : edgomez 195 if (top)
172 : Isibaar 3 pTop = top + (MBPRED_SIZE << 2);
173 : edgomez 195 if (diag)
174 : Isibaar 3 pDiag = diag + (MBPRED_SIZE << 2);
175 :     break;
176 : edgomez 195
177 : Isibaar 3 case 5:
178 : edgomez 195 if (left)
179 : Isibaar 3 pLeft = left + 5 * MBPRED_SIZE;
180 : edgomez 195 if (top)
181 : Isibaar 3 pTop = top + 5 * MBPRED_SIZE;
182 : edgomez 195 if (diag)
183 : Isibaar 3 pDiag = diag + 5 * MBPRED_SIZE;
184 :     break;
185 :     }
186 :    
187 : edgomez 1053 /*
188 :     * determine ac prediction direction & ac/dc predictor place rescaled ac/dc
189 :     * predictions into predictors[] for later use
190 :     */
191 : Isibaar 3
192 : edgomez 982 if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) {
193 : edgomez 1053 *acpred_direction = 1; /* vertical */
194 : edgomez 851 predictors[0] = DIV_DIV(pTop[0], iDcScaler);
195 : edgomez 195 for (i = 1; i < 8; i++) {
196 : Isibaar 3 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
197 :     }
198 : edgomez 195 } else {
199 : edgomez 1053 *acpred_direction = 2; /* horizontal */
200 : edgomez 851 predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
201 : edgomez 195 for (i = 1; i < 8; i++) {
202 : Isibaar 3 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
203 :     }
204 :     }
205 :     }
206 :    
207 :    
208 :     /* decoder: add predictors to dct_codes[] and
209 :     store current coeffs to pred_values[] for future prediction
210 :     */
211 :    
212 :    
213 : edgomez 195 void
214 :     add_acdc(MACROBLOCK * pMB,
215 :     uint32_t block,
216 :     int16_t dct_codes[64],
217 :     uint32_t iDcScaler,
218 :     int16_t predictors[8])
219 : Isibaar 3 {
220 :     uint8_t acpred_direction = pMB->acpred_directions[block];
221 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
222 : Isibaar 3 uint32_t i;
223 :    
224 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[0] %i\n", predictors[0]);
225 : suxen_drol 252
226 : edgomez 1053 dct_codes[0] += predictors[0]; /* dc prediction */
227 : edgomez 851 pCurrent[0] = dct_codes[0] * iDcScaler;
228 : Isibaar 3
229 : edgomez 195 if (acpred_direction == 1) {
230 :     for (i = 1; i < 8; i++) {
231 : Isibaar 3 int level = dct_codes[i] + predictors[i];
232 : edgomez 195
233 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i, predictors[i]);
234 : suxen_drol 252
235 : Isibaar 3 dct_codes[i] = level;
236 :     pCurrent[i] = level;
237 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
238 : Isibaar 3 }
239 : edgomez 195 } else if (acpred_direction == 2) {
240 :     for (i = 1; i < 8; i++) {
241 :     int level = dct_codes[i * 8] + predictors[i];
242 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i*8, predictors[i]);
243 : edgomez 195
244 :     dct_codes[i * 8] = level;
245 :     pCurrent[i + 7] = level;
246 : Isibaar 3 pCurrent[i] = dct_codes[i];
247 :     }
248 : edgomez 195 } else {
249 :     for (i = 1; i < 8; i++) {
250 : Isibaar 3 pCurrent[i] = dct_codes[i];
251 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
252 : Isibaar 3 }
253 :     }
254 :     }
255 :    
256 :    
257 :    
258 : edgomez 1053 /*****************************************************************************
259 :     ****************************************************************************/
260 : Isibaar 3
261 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
262 :    
263 : edgomez 851 returns sum of coeefficients *saved* if prediction is enabled
264 :    
265 : edgomez 78 S1 = sum of all (qcoeff - prediction)
266 :     S2 = sum of all qcoeff
267 :     */
268 : Isibaar 3
269 : edgomez 851 int
270 :     calc_acdc_coeff(MACROBLOCK * pMB,
271 : edgomez 195 uint32_t block,
272 :     int16_t qcoeff[64],
273 :     uint32_t iDcScaler,
274 :     int16_t predictors[8])
275 : Isibaar 3 {
276 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
277 : Isibaar 3 uint32_t i;
278 : edgomez 851 int S1 = 0, S2 = 0;
279 : Isibaar 3
280 :    
281 :     /* store current coeffs to pred_values[] for future prediction */
282 :    
283 : edgomez 851 pCurrent[0] = qcoeff[0] * iDcScaler;
284 : edgomez 195 for (i = 1; i < 8; i++) {
285 : Isibaar 3 pCurrent[i] = qcoeff[i];
286 :     pCurrent[i + 7] = qcoeff[i * 8];
287 : edgomez 78 }
288 : Isibaar 3
289 :     /* subtract predictors and store back in predictors[] */
290 :    
291 :     qcoeff[0] = qcoeff[0] - predictors[0];
292 :    
293 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
294 :     for (i = 1; i < 8; i++) {
295 : Isibaar 3 int16_t level;
296 :    
297 :     level = qcoeff[i];
298 : edgomez 982 S2 += abs(level);
299 : Isibaar 3 level -= predictors[i];
300 : edgomez 982 S1 += abs(level);
301 : Isibaar 3 predictors[i] = level;
302 :     }
303 : edgomez 1053 } else /* acpred_direction == 2 */
304 : Isibaar 3 {
305 : edgomez 195 for (i = 1; i < 8; i++) {
306 : Isibaar 3 int16_t level;
307 :    
308 : edgomez 195 level = qcoeff[i * 8];
309 : edgomez 982 S2 += abs(level);
310 : Isibaar 3 level -= predictors[i];
311 : edgomez 982 S1 += abs(level);
312 : Isibaar 3 predictors[i] = level;
313 :     }
314 :    
315 : edgomez 78 }
316 : Isibaar 3
317 : edgomez 195
318 : edgomez 78 return S2 - S1;
319 : Isibaar 3 }
320 :    
321 :    
322 : edgomez 851
323 :     /* returns the bits *saved* if prediction is enabled */
324 :    
325 :     int
326 :     calc_acdc_bits(MACROBLOCK * pMB,
327 :     uint32_t block,
328 :     int16_t qcoeff[64],
329 :     uint32_t iDcScaler,
330 :     int16_t predictors[8])
331 :     {
332 :     const int direction = pMB->acpred_directions[block];
333 :     int16_t *pCurrent = pMB->pred_values[block];
334 :     int16_t tmp[8];
335 :     unsigned int i;
336 :     int Z1, Z2;
337 :    
338 :     /* store current coeffs to pred_values[] for future prediction */
339 :     pCurrent[0] = qcoeff[0] * iDcScaler;
340 :     for (i = 1; i < 8; i++) {
341 :     pCurrent[i] = qcoeff[i];
342 :     pCurrent[i + 7] = qcoeff[i * 8];
343 :     }
344 :    
345 :    
346 :     /* dc prediction */
347 :     qcoeff[0] = qcoeff[0] - predictors[0];
348 :    
349 :     /* calc cost before ac prediction */
350 :     #ifdef BIGLUT
351 :     Z2 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[0], 1);
352 :     #else
353 :     Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]);
354 :     #endif
355 :    
356 :     /* apply ac prediction & calc cost*/
357 :     if (direction == 1) {
358 :     for (i = 1; i < 8; i++) {
359 :     tmp[i] = qcoeff[i];
360 :     qcoeff[i] -= predictors[i];
361 :     predictors[i] = qcoeff[i];
362 :     }
363 : edgomez 1053 }else{ /* acpred_direction == 2 */
364 : edgomez 851 for (i = 1; i < 8; i++) {
365 :     tmp[i] = qcoeff[i*8];
366 :     qcoeff[i*8] -= predictors[i];
367 :     predictors[i] = qcoeff[i*8];
368 :     }
369 :     }
370 :    
371 :     #ifdef BIGLUT
372 :     Z1 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[direction], 1);
373 :     #else
374 :     Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]);
375 :     #endif
376 :    
377 :     /* undo prediction */
378 :     if (direction == 1) {
379 :     for (i = 1; i < 8; i++)
380 :     qcoeff[i] = tmp[i];
381 : edgomez 1053 }else{ /* acpred_direction == 2 */
382 : edgomez 851 for (i = 1; i < 8; i++)
383 :     qcoeff[i*8] = tmp[i];
384 :     }
385 :    
386 :     return Z2-Z1;
387 :     }
388 :    
389 : Isibaar 3 /* apply predictors[] to qcoeff */
390 :    
391 : edgomez 195 void
392 :     apply_acdc(MACROBLOCK * pMB,
393 :     uint32_t block,
394 :     int16_t qcoeff[64],
395 :     int16_t predictors[8])
396 : Isibaar 3 {
397 : edgomez 851 unsigned int i;
398 : Isibaar 3
399 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
400 : edgomez 851 for (i = 1; i < 8; i++)
401 : Isibaar 3 qcoeff[i] = predictors[i];
402 : edgomez 195 } else {
403 : edgomez 851 for (i = 1; i < 8; i++)
404 : edgomez 195 qcoeff[i * 8] = predictors[i];
405 : edgomez 78 }
406 : Isibaar 3 }
407 :    
408 :    
409 : edgomez 195 void
410 :     MBPrediction(FRAMEINFO * frame,
411 :     uint32_t x,
412 :     uint32_t y,
413 :     uint32_t mb_width,
414 :     int16_t qcoeff[6 * 64])
415 : Isibaar 3 {
416 : edgomez 78
417 :     int32_t j;
418 : suxen_drol 926 int32_t iDcScaler, iQuant;
419 : edgomez 851 int S = 0;
420 : Isibaar 3 int16_t predictors[6][8];
421 :    
422 : suxen_drol 136 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
423 : suxen_drol 926 iQuant = pMB->quant;
424 : Isibaar 3
425 : edgomez 78 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
426 : edgomez 195
427 :     for (j = 0; j < 6; j++) {
428 : edgomez 851 iDcScaler = get_dc_scaler(iQuant, j<4);
429 : Isibaar 3
430 : edgomez 195 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
431 : suxen_drol 252 iQuant, iDcScaler, predictors[j], 0);
432 : edgomez 78
433 : edgomez 949 if ((frame->vop_flags & XVID_VOP_HQACPRED))
434 : edgomez 851 S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
435 :     else
436 :     S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
437 : edgomez 78
438 : Isibaar 3 }
439 :    
440 : edgomez 1053 if (S<=0) { /* dont predict */
441 : edgomez 851 for (j = 0; j < 6; j++)
442 : Isibaar 3 pMB->acpred_directions[j] = 0;
443 : edgomez 851 }else{
444 :     for (j = 0; j < 6; j++)
445 : edgomez 195 apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
446 : Isibaar 3 }
447 : edgomez 851
448 : Isibaar 3 pMB->cbp = calc_cbp(qcoeff);
449 :     }
450 : edgomez 1142 }
451 : edgomez 78
452 : edgomez 1142 static const VECTOR zeroMV = { 0, 0 };
453 :    
454 :     VECTOR
455 :     get_pmv2(const MACROBLOCK * const mbs,
456 :     const int mb_width,
457 :     const int bound,
458 :     const int x,
459 :     const int y,
460 :     const int block)
461 :     {
462 :     int lx, ly, lz; /* left */
463 :     int tx, ty, tz; /* top */
464 :     int rx, ry, rz; /* top-right */
465 :     int lpos, tpos, rpos;
466 :     int num_cand = 0, last_cand = 1;
467 :    
468 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
469 :    
470 :     switch (block) {
471 :     case 0:
472 :     lx = x - 1; ly = y; lz = 1;
473 :     tx = x; ty = y - 1; tz = 2;
474 :     rx = x + 1; ry = y - 1; rz = 2;
475 :     break;
476 :     case 1:
477 :     lx = x; ly = y; lz = 0;
478 :     tx = x; ty = y - 1; tz = 3;
479 :     rx = x + 1; ry = y - 1; rz = 2;
480 :     break;
481 :     case 2:
482 :     lx = x - 1; ly = y; lz = 3;
483 :     tx = x; ty = y; tz = 0;
484 :     rx = x; ry = y; rz = 1;
485 :     break;
486 :     default:
487 :     lx = x; ly = y; lz = 2;
488 :     tx = x; ty = y; tz = 0;
489 :     rx = x; ry = y; rz = 1;
490 :     }
491 :    
492 :     lpos = lx + ly * mb_width;
493 :     rpos = rx + ry * mb_width;
494 :     tpos = tx + ty * mb_width;
495 :    
496 :     if (lpos >= bound && lx >= 0) {
497 :     num_cand++;
498 :     pmv[1] = mbs[lpos].mvs[lz];
499 :     } else pmv[1] = zeroMV;
500 :    
501 :     if (tpos >= bound) {
502 :     num_cand++;
503 :     last_cand = 2;
504 :     pmv[2] = mbs[tpos].mvs[tz];
505 :     } else pmv[2] = zeroMV;
506 :    
507 :     if (rpos >= bound && rx < mb_width) {
508 :     num_cand++;
509 :     last_cand = 3;
510 :     pmv[3] = mbs[rpos].mvs[rz];
511 :     } else pmv[3] = zeroMV;
512 :    
513 :     /* If there're more than one candidate, we return the median vector */
514 :    
515 :     if (num_cand > 1) {
516 :     /* set median */
517 :     pmv[0].x =
518 :     MIN(MAX(pmv[1].x, pmv[2].x),
519 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
520 :     pmv[0].y =
521 :     MIN(MAX(pmv[1].y, pmv[2].y),
522 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
523 :     return pmv[0];
524 :     }
525 :    
526 :     return pmv[last_cand]; /* no point calculating median mv */
527 : Isibaar 3 }
528 : edgomez 1142
529 :     VECTOR
530 :     get_qpmv2(const MACROBLOCK * const mbs,
531 :     const int mb_width,
532 :     const int bound,
533 :     const int x,
534 :     const int y,
535 :     const int block)
536 :     {
537 :     int lx, ly, lz; /* left */
538 :     int tx, ty, tz; /* top */
539 :     int rx, ry, rz; /* top-right */
540 :     int lpos, tpos, rpos;
541 :     int num_cand = 0, last_cand = 1;
542 :    
543 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
544 :    
545 :     switch (block) {
546 :     case 0:
547 :     lx = x - 1; ly = y; lz = 1;
548 :     tx = x; ty = y - 1; tz = 2;
549 :     rx = x + 1; ry = y - 1; rz = 2;
550 :     break;
551 :     case 1:
552 :     lx = x; ly = y; lz = 0;
553 :     tx = x; ty = y - 1; tz = 3;
554 :     rx = x + 1; ry = y - 1; rz = 2;
555 :     break;
556 :     case 2:
557 :     lx = x - 1; ly = y; lz = 3;
558 :     tx = x; ty = y; tz = 0;
559 :     rx = x; ry = y; rz = 1;
560 :     break;
561 :     default:
562 :     lx = x; ly = y; lz = 2;
563 :     tx = x; ty = y; tz = 0;
564 :     rx = x; ry = y; rz = 1;
565 :     }
566 :    
567 :     lpos = lx + ly * mb_width;
568 :     rpos = rx + ry * mb_width;
569 :     tpos = tx + ty * mb_width;
570 :    
571 :     if (lpos >= bound && lx >= 0) {
572 :     num_cand++;
573 :     pmv[1] = mbs[lpos].qmvs[lz];
574 :     } else pmv[1] = zeroMV;
575 :    
576 :     if (tpos >= bound) {
577 :     num_cand++;
578 :     last_cand = 2;
579 :     pmv[2] = mbs[tpos].qmvs[tz];
580 :     } else pmv[2] = zeroMV;
581 :    
582 :     if (rpos >= bound && rx < mb_width) {
583 :     num_cand++;
584 :     last_cand = 3;
585 :     pmv[3] = mbs[rpos].qmvs[rz];
586 :     } else pmv[3] = zeroMV;
587 :    
588 :     /* If there're more than one candidate, we return the median vector */
589 :    
590 :     if (num_cand > 1) {
591 :     /* set median */
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 :     return pmv[0];
599 :     }
600 :    
601 :     return pmv[last_cand]; /* no point calculating median mv */
602 :     }

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