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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.18 - (view) (download)

1 : edgomez 1.14 /*****************************************************************************
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 : suxen_drol 1.18 * $Id: mbprediction.c,v 1.17 2005/09/13 12:12:15 suxen_drol Exp $
24 : edgomez 1.14 *
25 :     ****************************************************************************/
26 :    
27 :     #include <stdlib.h>
28 : Isibaar 1.1
29 : edgomez 1.13 #include "../global.h"
30 : Isibaar 1.1 #include "../encoder.h"
31 :     #include "mbprediction.h"
32 :     #include "../utils/mbfunctions.h"
33 :     #include "../bitstream/cbp.h"
34 : edgomez 1.13 #include "../bitstream/mbcoding.h"
35 :     #include "../bitstream/zigzag.h"
36 : Isibaar 1.1
37 :    
38 : edgomez 1.4 static int __inline
39 :     rescale(int predict_quant,
40 :     int current_quant,
41 :     int coeff)
42 : Isibaar 1.1 {
43 : edgomez 1.4 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
44 :     (current_quant)) : 0;
45 : Isibaar 1.1 }
46 :    
47 :    
48 : edgomez 1.4 static const int16_t default_acdc_values[15] = {
49 : Isibaar 1.1 1024,
50 : edgomez 1.2 0, 0, 0, 0, 0, 0, 0,
51 :     0, 0, 0, 0, 0, 0, 0
52 : Isibaar 1.1 };
53 : edgomez 1.8
54 :    
55 : Isibaar 1.1 /* get dc/ac prediction direction for a single block and place
56 :     predictor values into MB->pred_values[j][..]
57 :     */
58 :    
59 :    
60 : edgomez 1.4 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 1.5 int16_t predictors[8],
70 : edgomez 1.16 const int bound)
71 : suxen_drol 1.5
72 : Isibaar 1.1 {
73 : suxen_drol 1.6 const int mbpos = (y * mb_width) + x;
74 : edgomez 1.2 int16_t *left, *top, *diag, *current;
75 : Isibaar 1.1
76 : edgomez 1.2 int32_t left_quant = current_quant;
77 :     int32_t top_quant = current_quant;
78 : Isibaar 1.1
79 : edgomez 1.2 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 1.1
83 : edgomez 1.14 uint32_t index = x + y * mb_width; /* current macroblock */
84 : edgomez 1.4 int *acpred_direction = &pMBs[index].acpred_directions[block];
85 : Isibaar 1.1 uint32_t i;
86 :    
87 : suxen_drol 1.18 left = top = diag = current = NULL;
88 : Isibaar 1.1
89 : edgomez 1.14 /* grab left,top and diag macroblocks */
90 : Isibaar 1.1
91 : edgomez 1.14 /* left macroblock */
92 : Isibaar 1.1
93 : suxen_drol 1.5 if (x && mbpos >= bound + 1 &&
94 : edgomez 1.4 (pMBs[index - 1].mode == MODE_INTRA ||
95 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
96 : Isibaar 1.1
97 : suxen_drol 1.18 left = (int16_t*)pMBs[index - 1].pred_values[0];
98 : Isibaar 1.1 left_quant = pMBs[index - 1].quant;
99 :     }
100 : edgomez 1.14 /* top macroblock */
101 : edgomez 1.4
102 : suxen_drol 1.6 if (mbpos >= bound + (int)mb_width &&
103 : edgomez 1.4 (pMBs[index - mb_width].mode == MODE_INTRA ||
104 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
105 : Isibaar 1.1
106 : suxen_drol 1.18 top = (int16_t*)pMBs[index - mb_width].pred_values[0];
107 : Isibaar 1.1 top_quant = pMBs[index - mb_width].quant;
108 : edgomez 1.2 }
109 : edgomez 1.14 /* diag macroblock */
110 : edgomez 1.4
111 : suxen_drol 1.6 if (x && mbpos >= bound + (int)mb_width + 1 &&
112 : edgomez 1.4 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
113 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
114 : Isibaar 1.1
115 : suxen_drol 1.18 diag = (int16_t*)pMBs[index - 1 - mb_width].pred_values[0];
116 : Isibaar 1.1 }
117 :    
118 : suxen_drol 1.18 current = (int16_t*)pMBs[index].pred_values[0];
119 : Isibaar 1.1
120 : edgomez 1.14 /* now grab pLeft, pTop, pDiag _blocks_ */
121 : edgomez 1.4
122 : Isibaar 1.1 switch (block) {
123 : edgomez 1.4
124 :     case 0:
125 :     if (left)
126 : Isibaar 1.1 pLeft = left + MBPRED_SIZE;
127 : edgomez 1.4
128 :     if (top)
129 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 1);
130 : edgomez 1.4
131 :     if (diag)
132 : Isibaar 1.1 pDiag = diag + 3 * MBPRED_SIZE;
133 : edgomez 1.4
134 : Isibaar 1.1 break;
135 : edgomez 1.4
136 : Isibaar 1.1 case 1:
137 :     pLeft = current;
138 :     left_quant = current_quant;
139 : edgomez 1.4
140 :     if (top) {
141 : Isibaar 1.1 pTop = top + 3 * MBPRED_SIZE;
142 :     pDiag = top + (MBPRED_SIZE << 1);
143 :     }
144 :     break;
145 : edgomez 1.4
146 : Isibaar 1.1 case 2:
147 : edgomez 1.4 if (left) {
148 : Isibaar 1.1 pLeft = left + 3 * MBPRED_SIZE;
149 :     pDiag = left + MBPRED_SIZE;
150 :     }
151 : edgomez 1.4
152 : Isibaar 1.1 pTop = current;
153 :     top_quant = current_quant;
154 :    
155 :     break;
156 : edgomez 1.4
157 : Isibaar 1.1 case 3:
158 :     pLeft = current + (MBPRED_SIZE << 1);
159 :     left_quant = current_quant;
160 : edgomez 1.4
161 : Isibaar 1.1 pTop = current + MBPRED_SIZE;
162 :     top_quant = current_quant;
163 : edgomez 1.4
164 : Isibaar 1.1 pDiag = current;
165 : edgomez 1.4
166 : Isibaar 1.1 break;
167 : edgomez 1.4
168 : Isibaar 1.1 case 4:
169 : edgomez 1.4 if (left)
170 : Isibaar 1.1 pLeft = left + (MBPRED_SIZE << 2);
171 : edgomez 1.4 if (top)
172 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 2);
173 : edgomez 1.4 if (diag)
174 : Isibaar 1.1 pDiag = diag + (MBPRED_SIZE << 2);
175 :     break;
176 : edgomez 1.4
177 : Isibaar 1.1 case 5:
178 : edgomez 1.4 if (left)
179 : Isibaar 1.1 pLeft = left + 5 * MBPRED_SIZE;
180 : edgomez 1.4 if (top)
181 : Isibaar 1.1 pTop = top + 5 * MBPRED_SIZE;
182 : edgomez 1.4 if (diag)
183 : Isibaar 1.1 pDiag = diag + 5 * MBPRED_SIZE;
184 :     break;
185 :     }
186 :    
187 : edgomez 1.15 /* determine ac prediction direction & ac/dc predictor place rescaled ac/dc
188 :     * predictions into predictors[] for later use */
189 : edgomez 1.14 if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) {
190 :     *acpred_direction = 1; /* vertical */
191 : edgomez 1.13 predictors[0] = DIV_DIV(pTop[0], iDcScaler);
192 : edgomez 1.4 for (i = 1; i < 8; i++) {
193 : Isibaar 1.1 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
194 :     }
195 : edgomez 1.4 } else {
196 : edgomez 1.14 *acpred_direction = 2; /* horizontal */
197 : edgomez 1.13 predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
198 : edgomez 1.4 for (i = 1; i < 8; i++) {
199 : Isibaar 1.1 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
200 :     }
201 :     }
202 :     }
203 :    
204 :    
205 :     /* decoder: add predictors to dct_codes[] and
206 : edgomez 1.14 store current coeffs to pred_values[] for future prediction
207 : Isibaar 1.1 */
208 :    
209 : edgomez 1.16 /* Up to this version, no DC clipping was performed, so we try to be backward
210 :     * compatible to avoid artifacts */
211 :     #define BS_VERSION_BUGGY_DC_CLIPPING 34
212 : Isibaar 1.1
213 : edgomez 1.4 void
214 :     add_acdc(MACROBLOCK * pMB,
215 :     uint32_t block,
216 :     int16_t dct_codes[64],
217 :     uint32_t iDcScaler,
218 : edgomez 1.16 int16_t predictors[8],
219 :     const int bsversion)
220 : Isibaar 1.1 {
221 :     uint8_t acpred_direction = pMB->acpred_directions[block];
222 : suxen_drol 1.18 int16_t *pCurrent = (int16_t*)pMB->pred_values[block];
223 : Isibaar 1.1 uint32_t i;
224 :    
225 : edgomez 1.14 DPRINTF(XVID_DEBUG_COEFF,"predictor[0] %i\n", predictors[0]);
226 : suxen_drol 1.6
227 : edgomez 1.14 dct_codes[0] += predictors[0]; /* dc prediction */
228 : edgomez 1.16 pCurrent[0] = dct_codes[0]*iDcScaler;
229 :     if (!bsversion || bsversion > BS_VERSION_BUGGY_DC_CLIPPING) {
230 :     pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
231 :     }
232 : Isibaar 1.1
233 : edgomez 1.4 if (acpred_direction == 1) {
234 :     for (i = 1; i < 8; i++) {
235 : Isibaar 1.1 int level = dct_codes[i] + predictors[i];
236 : edgomez 1.4
237 : edgomez 1.14 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i, predictors[i]);
238 : suxen_drol 1.6
239 : Isibaar 1.1 dct_codes[i] = level;
240 :     pCurrent[i] = level;
241 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
242 : Isibaar 1.1 }
243 : edgomez 1.4 } else if (acpred_direction == 2) {
244 :     for (i = 1; i < 8; i++) {
245 :     int level = dct_codes[i * 8] + predictors[i];
246 : edgomez 1.14 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i*8, predictors[i]);
247 : edgomez 1.4
248 :     dct_codes[i * 8] = level;
249 :     pCurrent[i + 7] = level;
250 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
251 :     }
252 : edgomez 1.4 } else {
253 :     for (i = 1; i < 8; i++) {
254 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
255 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
256 : Isibaar 1.1 }
257 :     }
258 :     }
259 :    
260 :    
261 :    
262 : edgomez 1.14 /*****************************************************************************
263 :     ****************************************************************************/
264 : Isibaar 1.1
265 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
266 :    
267 : edgomez 1.13 returns sum of coeefficients *saved* if prediction is enabled
268 :    
269 : edgomez 1.2 S1 = sum of all (qcoeff - prediction)
270 :     S2 = sum of all qcoeff
271 :     */
272 : Isibaar 1.1
273 : suxen_drol 1.18 static int
274 : edgomez 1.13 calc_acdc_coeff(MACROBLOCK * pMB,
275 : edgomez 1.4 uint32_t block,
276 :     int16_t qcoeff[64],
277 :     uint32_t iDcScaler,
278 :     int16_t predictors[8])
279 : Isibaar 1.1 {
280 : suxen_drol 1.18 int16_t *pCurrent = (int16_t*)pMB->pred_values[block];
281 : Isibaar 1.1 uint32_t i;
282 : edgomez 1.13 int S1 = 0, S2 = 0;
283 : Isibaar 1.1
284 :    
285 :     /* store current coeffs to pred_values[] for future prediction */
286 :    
287 : edgomez 1.13 pCurrent[0] = qcoeff[0] * iDcScaler;
288 : edgomez 1.16 pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
289 : edgomez 1.4 for (i = 1; i < 8; i++) {
290 : Isibaar 1.1 pCurrent[i] = qcoeff[i];
291 :     pCurrent[i + 7] = qcoeff[i * 8];
292 : edgomez 1.2 }
293 : Isibaar 1.1
294 :     /* subtract predictors and store back in predictors[] */
295 :    
296 :     qcoeff[0] = qcoeff[0] - predictors[0];
297 :    
298 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
299 :     for (i = 1; i < 8; i++) {
300 : Isibaar 1.1 int16_t level;
301 :    
302 :     level = qcoeff[i];
303 : edgomez 1.14 S2 += abs(level);
304 : Isibaar 1.1 level -= predictors[i];
305 : edgomez 1.14 S1 += abs(level);
306 : Isibaar 1.1 predictors[i] = level;
307 :     }
308 : edgomez 1.14 } else /* acpred_direction == 2 */
309 : Isibaar 1.1 {
310 : edgomez 1.4 for (i = 1; i < 8; i++) {
311 : Isibaar 1.1 int16_t level;
312 :    
313 : edgomez 1.4 level = qcoeff[i * 8];
314 : edgomez 1.14 S2 += abs(level);
315 : Isibaar 1.1 level -= predictors[i];
316 : edgomez 1.14 S1 += abs(level);
317 : Isibaar 1.1 predictors[i] = level;
318 :     }
319 :    
320 : edgomez 1.2 }
321 : Isibaar 1.1
322 : edgomez 1.4
323 : edgomez 1.2 return S2 - S1;
324 : Isibaar 1.1 }
325 :    
326 :    
327 : edgomez 1.13
328 :     /* returns the bits *saved* if prediction is enabled */
329 :    
330 : suxen_drol 1.18 static int
331 : edgomez 1.13 calc_acdc_bits(MACROBLOCK * pMB,
332 :     uint32_t block,
333 :     int16_t qcoeff[64],
334 :     uint32_t iDcScaler,
335 :     int16_t predictors[8])
336 :     {
337 :     const int direction = pMB->acpred_directions[block];
338 : suxen_drol 1.18 int16_t *pCurrent = (int16_t*)pMB->pred_values[block];
339 : edgomez 1.13 int16_t tmp[8];
340 :     unsigned int i;
341 :     int Z1, Z2;
342 :    
343 :     /* store current coeffs to pred_values[] for future prediction */
344 :     pCurrent[0] = qcoeff[0] * iDcScaler;
345 : edgomez 1.16 pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
346 : edgomez 1.13 for (i = 1; i < 8; i++) {
347 :     pCurrent[i] = qcoeff[i];
348 :     pCurrent[i + 7] = qcoeff[i * 8];
349 :     }
350 :    
351 :    
352 :     /* dc prediction */
353 :     qcoeff[0] = qcoeff[0] - predictors[0];
354 :    
355 :     /* calc cost before ac prediction */
356 :     Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]);
357 :    
358 :     /* apply ac prediction & calc cost*/
359 :     if (direction == 1) {
360 :     for (i = 1; i < 8; i++) {
361 :     tmp[i] = qcoeff[i];
362 :     qcoeff[i] -= predictors[i];
363 :     predictors[i] = qcoeff[i];
364 :     }
365 : edgomez 1.14 }else{ /* acpred_direction == 2 */
366 : edgomez 1.13 for (i = 1; i < 8; i++) {
367 :     tmp[i] = qcoeff[i*8];
368 :     qcoeff[i*8] -= predictors[i];
369 :     predictors[i] = qcoeff[i*8];
370 :     }
371 :     }
372 :    
373 :     Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]);
374 :    
375 :     /* undo prediction */
376 :     if (direction == 1) {
377 : edgomez 1.14 for (i = 1; i < 8; i++)
378 : edgomez 1.13 qcoeff[i] = tmp[i];
379 : edgomez 1.14 }else{ /* acpred_direction == 2 */
380 :     for (i = 1; i < 8; i++)
381 : edgomez 1.13 qcoeff[i*8] = tmp[i];
382 :     }
383 :    
384 :     return Z2-Z1;
385 :     }
386 :    
387 : Isibaar 1.1 /* apply predictors[] to qcoeff */
388 :    
389 : suxen_drol 1.18 static void
390 : edgomez 1.4 apply_acdc(MACROBLOCK * pMB,
391 :     uint32_t block,
392 :     int16_t qcoeff[64],
393 :     int16_t predictors[8])
394 : Isibaar 1.1 {
395 : edgomez 1.13 unsigned int i;
396 : Isibaar 1.1
397 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
398 : edgomez 1.14 for (i = 1; i < 8; i++)
399 : Isibaar 1.1 qcoeff[i] = predictors[i];
400 : edgomez 1.4 } else {
401 : edgomez 1.14 for (i = 1; i < 8; i++)
402 : edgomez 1.4 qcoeff[i * 8] = predictors[i];
403 : edgomez 1.2 }
404 : Isibaar 1.1 }
405 :    
406 :    
407 : edgomez 1.4 void
408 :     MBPrediction(FRAMEINFO * frame,
409 :     uint32_t x,
410 :     uint32_t y,
411 :     uint32_t mb_width,
412 :     int16_t qcoeff[6 * 64])
413 : Isibaar 1.1 {
414 : edgomez 1.2
415 :     int32_t j;
416 : edgomez 1.14 int32_t iDcScaler, iQuant;
417 : edgomez 1.13 int S = 0;
418 : Isibaar 1.1 int16_t predictors[6][8];
419 :    
420 : suxen_drol 1.3 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
421 : edgomez 1.14 iQuant = pMB->quant;
422 : Isibaar 1.1
423 : edgomez 1.2 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
424 : edgomez 1.4
425 :     for (j = 0; j < 6; j++) {
426 : edgomez 1.13 iDcScaler = get_dc_scaler(iQuant, j<4);
427 : Isibaar 1.1
428 : edgomez 1.4 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
429 : edgomez 1.16 iQuant, iDcScaler, predictors[j], 0);
430 : edgomez 1.4
431 : edgomez 1.14 if ((frame->vop_flags & XVID_VOP_HQACPRED))
432 : edgomez 1.13 S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
433 :     else
434 :     S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
435 : edgomez 1.2
436 : Isibaar 1.1 }
437 :    
438 : edgomez 1.14 if (S<=0) { /* dont predict */
439 : edgomez 1.13 for (j = 0; j < 6; j++)
440 : Isibaar 1.1 pMB->acpred_directions[j] = 0;
441 : edgomez 1.13 }else{
442 : edgomez 1.14 for (j = 0; j < 6; j++)
443 : edgomez 1.4 apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
444 : Isibaar 1.1 }
445 : edgomez 1.14
446 : Isibaar 1.1 pMB->cbp = calc_cbp(qcoeff);
447 :     }
448 : edgomez 1.14 }
449 :    
450 :     static const VECTOR zeroMV = { 0, 0 };
451 :    
452 :     VECTOR
453 :     get_pmv2(const MACROBLOCK * const mbs,
454 :     const int mb_width,
455 :     const int bound,
456 :     const int x,
457 :     const int y,
458 :     const int block)
459 :     {
460 :     int lx, ly, lz; /* left */
461 :     int tx, ty, tz; /* top */
462 :     int rx, ry, rz; /* top-right */
463 :     int lpos, tpos, rpos;
464 :     int num_cand = 0, last_cand = 1;
465 :    
466 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
467 :    
468 :     switch (block) {
469 :     case 0:
470 :     lx = x - 1; ly = y; lz = 1;
471 :     tx = x; ty = y - 1; tz = 2;
472 :     rx = x + 1; ry = y - 1; rz = 2;
473 :     break;
474 :     case 1:
475 :     lx = x; ly = y; lz = 0;
476 :     tx = x; ty = y - 1; tz = 3;
477 :     rx = x + 1; ry = y - 1; rz = 2;
478 :     break;
479 :     case 2:
480 :     lx = x - 1; ly = y; lz = 3;
481 :     tx = x; ty = y; tz = 0;
482 :     rx = x; ry = y; rz = 1;
483 :     break;
484 :     default:
485 :     lx = x; ly = y; lz = 2;
486 :     tx = x; ty = y; tz = 0;
487 :     rx = x; ry = y; rz = 1;
488 :     }
489 :    
490 :     lpos = lx + ly * mb_width;
491 :     rpos = rx + ry * mb_width;
492 :     tpos = tx + ty * mb_width;
493 :    
494 :     if (lpos >= bound && lx >= 0) {
495 :     num_cand++;
496 :     pmv[1] = mbs[lpos].mvs[lz];
497 :     } else pmv[1] = zeroMV;
498 :    
499 :     if (tpos >= bound) {
500 :     num_cand++;
501 :     last_cand = 2;
502 :     pmv[2] = mbs[tpos].mvs[tz];
503 :     } else pmv[2] = zeroMV;
504 :    
505 :     if (rpos >= bound && rx < mb_width) {
506 :     num_cand++;
507 :     last_cand = 3;
508 :     pmv[3] = mbs[rpos].mvs[rz];
509 :     } else pmv[3] = zeroMV;
510 :    
511 :     /* If there're more than one candidate, we return the median vector */
512 :    
513 :     if (num_cand > 1) {
514 :     /* set median */
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 :     return pmv[0];
522 :     }
523 :    
524 :     return pmv[last_cand]; /* no point calculating median mv */
525 :     }
526 :    
527 : suxen_drol 1.17 VECTOR get_pmv2_interlaced(const MACROBLOCK * const mbs,
528 :     const int mb_width,
529 :     const int bound,
530 :     const int x,
531 :     const int y,
532 :     const int block)
533 :     {
534 :     int lx, ly, lz; /* left */
535 :     int tx, ty, tz; /* top */
536 :     int rx, ry, rz; /* top-right */
537 :     int lpos, tpos, rpos;
538 :     int num_cand = 0, last_cand = 1;
539 :    
540 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
541 :    
542 :     lx=x-1; ly=y; lz=1;
543 :     tx=x; ty=y-1; tz=2;
544 :     rx=x+1; ry=y-1; rz=2;
545 :    
546 :     lpos=lx+ly*mb_width;
547 :     rpos=rx+ry*mb_width;
548 :     tpos=tx+ty*mb_width;
549 :    
550 :     if(lx>=0 && lpos>=bound)
551 :     {
552 :     num_cand++;
553 :     if(mbs[lpos].field_pred)
554 :     pmv[1] = mbs[lpos].mvs_avg;
555 :     else
556 :     pmv[1] = mbs[lpos].mvs[lz];
557 :     }
558 :     else
559 :     {
560 :     pmv[1] = zeroMV;
561 :     }
562 :    
563 :     if(tpos>=bound)
564 :     {
565 :     num_cand++;
566 :     last_cand=2;
567 :     if(mbs[tpos].field_pred)
568 :     pmv[2] = mbs[tpos].mvs_avg;
569 :     else
570 :     pmv[2] = mbs[tpos].mvs[tz];
571 :     }
572 :     else
573 :     {
574 :     pmv[2] = zeroMV;
575 :     }
576 :    
577 :     if(rx<mb_width && rpos>=bound)
578 :     {
579 :     num_cand++;
580 :     last_cand = 3;
581 :     if(mbs[rpos].field_pred)
582 :     pmv[3] = mbs[rpos].mvs_avg;
583 :     else
584 :     pmv[3] = mbs[rpos].mvs[rz];
585 :     }
586 :     else
587 :     {
588 :     pmv[3] = zeroMV;
589 :     }
590 :    
591 :     /* If there're more than one candidate, we return the median vector */
592 :     if(num_cand>1)
593 :     {
594 :     /* set median */
595 :     pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x),
596 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
597 :     pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y),
598 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
599 :    
600 :     return pmv[0];
601 :     }
602 :    
603 :     return pmv[last_cand]; /* no point calculating median mv */
604 :     }
605 :    
606 : edgomez 1.14 VECTOR
607 :     get_qpmv2(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 :     int lx, ly, lz; /* left */
615 :     int tx, ty, tz; /* top */
616 :     int rx, ry, rz; /* top-right */
617 :     int lpos, tpos, rpos;
618 :     int num_cand = 0, last_cand = 1;
619 :    
620 :     VECTOR pmv[4]; /* left neighbour, top neighbour, top-right neighbour */
621 :    
622 :     switch (block) {
623 :     case 0:
624 :     lx = x - 1; ly = y; lz = 1;
625 :     tx = x; ty = y - 1; tz = 2;
626 :     rx = x + 1; ry = y - 1; rz = 2;
627 :     break;
628 :     case 1:
629 :     lx = x; ly = y; lz = 0;
630 :     tx = x; ty = y - 1; tz = 3;
631 :     rx = x + 1; ry = y - 1; rz = 2;
632 :     break;
633 :     case 2:
634 :     lx = x - 1; ly = y; lz = 3;
635 :     tx = x; ty = y; tz = 0;
636 :     rx = x; ry = y; rz = 1;
637 :     break;
638 :     default:
639 :     lx = x; ly = y; lz = 2;
640 :     tx = x; ty = y; tz = 0;
641 :     rx = x; ry = y; rz = 1;
642 :     }
643 :    
644 :     lpos = lx + ly * mb_width;
645 :     rpos = rx + ry * mb_width;
646 :     tpos = tx + ty * mb_width;
647 :    
648 :     if (lpos >= bound && lx >= 0) {
649 :     num_cand++;
650 :     pmv[1] = mbs[lpos].qmvs[lz];
651 :     } else pmv[1] = zeroMV;
652 :    
653 :     if (tpos >= bound) {
654 :     num_cand++;
655 :     last_cand = 2;
656 :     pmv[2] = mbs[tpos].qmvs[tz];
657 :     } else pmv[2] = zeroMV;
658 :    
659 :     if (rpos >= bound && rx < mb_width) {
660 :     num_cand++;
661 :     last_cand = 3;
662 :     pmv[3] = mbs[rpos].qmvs[rz];
663 :     } else pmv[3] = zeroMV;
664 :    
665 :     /* If there're more than one candidate, we return the median vector */
666 :    
667 :     if (num_cand > 1) {
668 :     /* set median */
669 :     pmv[0].x =
670 :     MIN(MAX(pmv[1].x, pmv[2].x),
671 :     MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
672 :     pmv[0].y =
673 :     MIN(MAX(pmv[1].y, pmv[2].y),
674 :     MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
675 :     return pmv[0];
676 :     }
677 : edgomez 1.2
678 : edgomez 1.14 return pmv[last_cand]; /* no point calculating median mv */
679 : suxen_drol 1.6 }

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