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

1 : edgomez 851 /******************************************************************************
2 :     * *
3 :     * This file is part of XviD, a free MPEG-4 video encoder/decoder *
4 :     * *
5 :     * XviD is an implementation of a part of one or more MPEG-4 Video tools *
6 :     * as specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 :     * software module in hardware or software products are advised that its *
8 :     * use may infringe existing patents or copyrights, and any such use *
9 :     * would be at such party's own risk. The original developer of this *
10 :     * software module and his/her company, and subsequent editors and their *
11 :     * companies, will have no liability for use of this software or *
12 :     * modifications or derivatives thereof. *
13 :     * *
14 :     * XviD is free software; you can redistribute it and/or modify it *
15 :     * under the terms of the GNU General Public License as published by *
16 :     * the Free Software Foundation; either version 2 of the License, or *
17 :     * (at your option) any later version. *
18 :     * *
19 :     * XviD is distributed in the hope that it will be useful, but *
20 :     * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 :     * GNU General Public License for more details. *
23 :     * *
24 :     * You should have received a copy of the GNU General Public License *
25 :     * along with this program; if not, write to the Free Software *
26 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
27 :     * *
28 :     ******************************************************************************/
29 : Isibaar 3
30 : edgomez 851 /******************************************************************************
31 :     * *
32 :     * mbprediction.c *
33 :     * *
34 :     * Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org> *
35 :     * Copyright (C) 2001 - Peter Ross <pross@cs.rmit.edu.au> *
36 :     * *
37 :     * For more information visit the XviD homepage: http://www.xvid.org *
38 :     * *
39 :     ******************************************************************************/
40 :    
41 :     /******************************************************************************
42 :     * *
43 :     * Revision history: *
44 :     * *
45 :     * 29.06.2002 predict_acdc() bounding *
46 :     * 12.12.2001 improved calc_acdc_prediction; removed need for memcpy *
47 :     * 15.12.2001 moved pmv displacement to motion estimation *
48 :     * 30.11.2001 mmx cbp support *
49 :     * 17.11.2001 initial version *
50 :     * *
51 :     ******************************************************************************/
52 :    
53 : edgomez 982 #include <stdlib.h>
54 :    
55 : edgomez 851 #include "../global.h"
56 : Isibaar 3 #include "../encoder.h"
57 :     #include "mbprediction.h"
58 :     #include "../utils/mbfunctions.h"
59 :     #include "../bitstream/cbp.h"
60 : edgomez 851 #include "../bitstream/mbcoding.h"
61 :     #include "../bitstream/zigzag.h"
62 : Isibaar 3
63 :    
64 : edgomez 195 static int __inline
65 :     rescale(int predict_quant,
66 :     int current_quant,
67 :     int coeff)
68 : Isibaar 3 {
69 : edgomez 195 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
70 :     (current_quant)) : 0;
71 : Isibaar 3 }
72 :    
73 :    
74 : edgomez 195 static const int16_t default_acdc_values[15] = {
75 : Isibaar 3 1024,
76 : edgomez 78 0, 0, 0, 0, 0, 0, 0,
77 :     0, 0, 0, 0, 0, 0, 0
78 : Isibaar 3 };
79 :    
80 :    
81 :     /* get dc/ac prediction direction for a single block and place
82 :     predictor values into MB->pred_values[j][..]
83 :     */
84 :    
85 :    
86 : edgomez 195 void
87 :     predict_acdc(MACROBLOCK * pMBs,
88 :     uint32_t x,
89 :     uint32_t y,
90 :     uint32_t mb_width,
91 :     uint32_t block,
92 :     int16_t qcoeff[64],
93 :     uint32_t current_quant,
94 :     int32_t iDcScaler,
95 : suxen_drol 248 int16_t predictors[8],
96 : suxen_drol 252 const int bound)
97 : suxen_drol 248
98 : Isibaar 3 {
99 : suxen_drol 252 const int mbpos = (y * mb_width) + x;
100 : edgomez 78 int16_t *left, *top, *diag, *current;
101 : Isibaar 3
102 : edgomez 78 int32_t left_quant = current_quant;
103 :     int32_t top_quant = current_quant;
104 : Isibaar 3
105 : edgomez 78 const int16_t *pLeft = default_acdc_values;
106 :     const int16_t *pTop = default_acdc_values;
107 :     const int16_t *pDiag = default_acdc_values;
108 : Isibaar 3
109 : edgomez 1053 uint32_t index = x + y * mb_width; /* current macroblock */
110 : edgomez 195 int *acpred_direction = &pMBs[index].acpred_directions[block];
111 : Isibaar 3 uint32_t i;
112 :    
113 :     left = top = diag = current = 0;
114 :    
115 : edgomez 1053 /* grab left,top and diag macroblocks */
116 : Isibaar 3
117 : edgomez 1053 /* left macroblock */
118 : Isibaar 3
119 : suxen_drol 248 if (x && mbpos >= bound + 1 &&
120 : edgomez 195 (pMBs[index - 1].mode == MODE_INTRA ||
121 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
122 : Isibaar 3
123 :     left = pMBs[index - 1].pred_values[0];
124 :     left_quant = pMBs[index - 1].quant;
125 :     }
126 : edgomez 1053 /* top macroblock */
127 : Isibaar 3
128 : suxen_drol 252 if (mbpos >= bound + (int)mb_width &&
129 : edgomez 195 (pMBs[index - mb_width].mode == MODE_INTRA ||
130 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
131 :    
132 : Isibaar 3 top = pMBs[index - mb_width].pred_values[0];
133 :     top_quant = pMBs[index - mb_width].quant;
134 : edgomez 78 }
135 : edgomez 1053 /* diag macroblock */
136 : Isibaar 3
137 : suxen_drol 252 if (x && mbpos >= bound + (int)mb_width + 1 &&
138 : edgomez 195 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
139 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
140 :    
141 : Isibaar 3 diag = pMBs[index - 1 - mb_width].pred_values[0];
142 :     }
143 :    
144 : edgomez 78 current = pMBs[index].pred_values[0];
145 : Isibaar 3
146 : edgomez 1053 /* now grab pLeft, pTop, pDiag _blocks_ */
147 : edgomez 195
148 : Isibaar 3 switch (block) {
149 : edgomez 195
150 :     case 0:
151 :     if (left)
152 : Isibaar 3 pLeft = left + MBPRED_SIZE;
153 : edgomez 195
154 :     if (top)
155 : Isibaar 3 pTop = top + (MBPRED_SIZE << 1);
156 : edgomez 195
157 :     if (diag)
158 : Isibaar 3 pDiag = diag + 3 * MBPRED_SIZE;
159 : edgomez 195
160 : Isibaar 3 break;
161 : edgomez 195
162 : Isibaar 3 case 1:
163 :     pLeft = current;
164 :     left_quant = current_quant;
165 : edgomez 195
166 :     if (top) {
167 : Isibaar 3 pTop = top + 3 * MBPRED_SIZE;
168 :     pDiag = top + (MBPRED_SIZE << 1);
169 :     }
170 :     break;
171 : edgomez 195
172 : Isibaar 3 case 2:
173 : edgomez 195 if (left) {
174 : Isibaar 3 pLeft = left + 3 * MBPRED_SIZE;
175 :     pDiag = left + MBPRED_SIZE;
176 :     }
177 : edgomez 195
178 : Isibaar 3 pTop = current;
179 :     top_quant = current_quant;
180 :    
181 :     break;
182 : edgomez 195
183 : Isibaar 3 case 3:
184 :     pLeft = current + (MBPRED_SIZE << 1);
185 :     left_quant = current_quant;
186 : edgomez 195
187 : Isibaar 3 pTop = current + MBPRED_SIZE;
188 :     top_quant = current_quant;
189 : edgomez 195
190 : Isibaar 3 pDiag = current;
191 : edgomez 195
192 : Isibaar 3 break;
193 : edgomez 195
194 : Isibaar 3 case 4:
195 : edgomez 195 if (left)
196 : Isibaar 3 pLeft = left + (MBPRED_SIZE << 2);
197 : edgomez 195 if (top)
198 : Isibaar 3 pTop = top + (MBPRED_SIZE << 2);
199 : edgomez 195 if (diag)
200 : Isibaar 3 pDiag = diag + (MBPRED_SIZE << 2);
201 :     break;
202 : edgomez 195
203 : Isibaar 3 case 5:
204 : edgomez 195 if (left)
205 : Isibaar 3 pLeft = left + 5 * MBPRED_SIZE;
206 : edgomez 195 if (top)
207 : Isibaar 3 pTop = top + 5 * MBPRED_SIZE;
208 : edgomez 195 if (diag)
209 : Isibaar 3 pDiag = diag + 5 * MBPRED_SIZE;
210 :     break;
211 :     }
212 :    
213 : edgomez 1053 /*
214 :     * determine ac prediction direction & ac/dc predictor place rescaled ac/dc
215 :     * predictions into predictors[] for later use
216 :     */
217 : Isibaar 3
218 : edgomez 982 if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) {
219 : edgomez 1053 *acpred_direction = 1; /* vertical */
220 : edgomez 851 predictors[0] = DIV_DIV(pTop[0], iDcScaler);
221 : edgomez 195 for (i = 1; i < 8; i++) {
222 : Isibaar 3 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
223 :     }
224 : edgomez 195 } else {
225 : edgomez 1053 *acpred_direction = 2; /* horizontal */
226 : edgomez 851 predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
227 : edgomez 195 for (i = 1; i < 8; i++) {
228 : Isibaar 3 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
229 :     }
230 :     }
231 :     }
232 :    
233 :    
234 :     /* decoder: add predictors to dct_codes[] and
235 :     store current coeffs to pred_values[] for future prediction
236 :     */
237 :    
238 :    
239 : edgomez 195 void
240 :     add_acdc(MACROBLOCK * pMB,
241 :     uint32_t block,
242 :     int16_t dct_codes[64],
243 :     uint32_t iDcScaler,
244 :     int16_t predictors[8])
245 : Isibaar 3 {
246 :     uint8_t acpred_direction = pMB->acpred_directions[block];
247 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
248 : Isibaar 3 uint32_t i;
249 :    
250 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[0] %i\n", predictors[0]);
251 : suxen_drol 252
252 : edgomez 1053 dct_codes[0] += predictors[0]; /* dc prediction */
253 : edgomez 851 pCurrent[0] = dct_codes[0] * iDcScaler;
254 : Isibaar 3
255 : edgomez 195 if (acpred_direction == 1) {
256 :     for (i = 1; i < 8; i++) {
257 : Isibaar 3 int level = dct_codes[i] + predictors[i];
258 : edgomez 195
259 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i, predictors[i]);
260 : suxen_drol 252
261 : Isibaar 3 dct_codes[i] = level;
262 :     pCurrent[i] = level;
263 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
264 : Isibaar 3 }
265 : edgomez 195 } else if (acpred_direction == 2) {
266 :     for (i = 1; i < 8; i++) {
267 :     int level = dct_codes[i * 8] + predictors[i];
268 : edgomez 1038 DPRINTF(XVID_DEBUG_COEFF,"predictor[%i] %i\n",i*8, predictors[i]);
269 : edgomez 195
270 :     dct_codes[i * 8] = level;
271 :     pCurrent[i + 7] = level;
272 : Isibaar 3 pCurrent[i] = dct_codes[i];
273 :     }
274 : edgomez 195 } else {
275 :     for (i = 1; i < 8; i++) {
276 : Isibaar 3 pCurrent[i] = dct_codes[i];
277 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
278 : Isibaar 3 }
279 :     }
280 :     }
281 :    
282 :    
283 :    
284 : edgomez 1053 /*****************************************************************************
285 :     ****************************************************************************/
286 : Isibaar 3
287 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
288 :    
289 : edgomez 851 returns sum of coeefficients *saved* if prediction is enabled
290 :    
291 : edgomez 78 S1 = sum of all (qcoeff - prediction)
292 :     S2 = sum of all qcoeff
293 :     */
294 : Isibaar 3
295 : edgomez 851 int
296 :     calc_acdc_coeff(MACROBLOCK * pMB,
297 : edgomez 195 uint32_t block,
298 :     int16_t qcoeff[64],
299 :     uint32_t iDcScaler,
300 :     int16_t predictors[8])
301 : Isibaar 3 {
302 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
303 : Isibaar 3 uint32_t i;
304 : edgomez 851 int S1 = 0, S2 = 0;
305 : Isibaar 3
306 :    
307 :     /* store current coeffs to pred_values[] for future prediction */
308 :    
309 : edgomez 851 pCurrent[0] = qcoeff[0] * iDcScaler;
310 : edgomez 195 for (i = 1; i < 8; i++) {
311 : Isibaar 3 pCurrent[i] = qcoeff[i];
312 :     pCurrent[i + 7] = qcoeff[i * 8];
313 : edgomez 78 }
314 : Isibaar 3
315 :     /* subtract predictors and store back in predictors[] */
316 :    
317 :     qcoeff[0] = qcoeff[0] - predictors[0];
318 :    
319 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
320 :     for (i = 1; i < 8; i++) {
321 : Isibaar 3 int16_t level;
322 :    
323 :     level = qcoeff[i];
324 : edgomez 982 S2 += abs(level);
325 : Isibaar 3 level -= predictors[i];
326 : edgomez 982 S1 += abs(level);
327 : Isibaar 3 predictors[i] = level;
328 :     }
329 : edgomez 1053 } else /* acpred_direction == 2 */
330 : Isibaar 3 {
331 : edgomez 195 for (i = 1; i < 8; i++) {
332 : Isibaar 3 int16_t level;
333 :    
334 : edgomez 195 level = qcoeff[i * 8];
335 : edgomez 982 S2 += abs(level);
336 : Isibaar 3 level -= predictors[i];
337 : edgomez 982 S1 += abs(level);
338 : Isibaar 3 predictors[i] = level;
339 :     }
340 :    
341 : edgomez 78 }
342 : Isibaar 3
343 : edgomez 195
344 : edgomez 78 return S2 - S1;
345 : Isibaar 3 }
346 :    
347 :    
348 : edgomez 851
349 :     /* returns the bits *saved* if prediction is enabled */
350 :    
351 :     int
352 :     calc_acdc_bits(MACROBLOCK * pMB,
353 :     uint32_t block,
354 :     int16_t qcoeff[64],
355 :     uint32_t iDcScaler,
356 :     int16_t predictors[8])
357 :     {
358 :     const int direction = pMB->acpred_directions[block];
359 :     int16_t *pCurrent = pMB->pred_values[block];
360 :     int16_t tmp[8];
361 :     unsigned int i;
362 :     int Z1, Z2;
363 :    
364 :     /* store current coeffs to pred_values[] for future prediction */
365 :     pCurrent[0] = qcoeff[0] * iDcScaler;
366 :     for (i = 1; i < 8; i++) {
367 :     pCurrent[i] = qcoeff[i];
368 :     pCurrent[i + 7] = qcoeff[i * 8];
369 :     }
370 :    
371 :    
372 :     /* dc prediction */
373 :     qcoeff[0] = qcoeff[0] - predictors[0];
374 :    
375 :     /* calc cost before ac prediction */
376 :     #ifdef BIGLUT
377 :     Z2 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[0], 1);
378 :     #else
379 :     Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]);
380 :     #endif
381 :    
382 :     /* apply ac prediction & calc cost*/
383 :     if (direction == 1) {
384 :     for (i = 1; i < 8; i++) {
385 :     tmp[i] = qcoeff[i];
386 :     qcoeff[i] -= predictors[i];
387 :     predictors[i] = qcoeff[i];
388 :     }
389 : edgomez 1053 }else{ /* acpred_direction == 2 */
390 : edgomez 851 for (i = 1; i < 8; i++) {
391 :     tmp[i] = qcoeff[i*8];
392 :     qcoeff[i*8] -= predictors[i];
393 :     predictors[i] = qcoeff[i*8];
394 :     }
395 :     }
396 :    
397 :     #ifdef BIGLUT
398 :     Z1 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[direction], 1);
399 :     #else
400 :     Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]);
401 :     #endif
402 :    
403 :     /* undo prediction */
404 :     if (direction == 1) {
405 :     for (i = 1; i < 8; i++)
406 :     qcoeff[i] = tmp[i];
407 : edgomez 1053 }else{ /* acpred_direction == 2 */
408 : edgomez 851 for (i = 1; i < 8; i++)
409 :     qcoeff[i*8] = tmp[i];
410 :     }
411 :    
412 :     return Z2-Z1;
413 :     }
414 :    
415 : Isibaar 3 /* apply predictors[] to qcoeff */
416 :    
417 : edgomez 195 void
418 :     apply_acdc(MACROBLOCK * pMB,
419 :     uint32_t block,
420 :     int16_t qcoeff[64],
421 :     int16_t predictors[8])
422 : Isibaar 3 {
423 : edgomez 851 unsigned int i;
424 : Isibaar 3
425 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
426 : edgomez 851 for (i = 1; i < 8; i++)
427 : Isibaar 3 qcoeff[i] = predictors[i];
428 : edgomez 195 } else {
429 : edgomez 851 for (i = 1; i < 8; i++)
430 : edgomez 195 qcoeff[i * 8] = predictors[i];
431 : edgomez 78 }
432 : Isibaar 3 }
433 :    
434 :    
435 : edgomez 195 void
436 :     MBPrediction(FRAMEINFO * frame,
437 :     uint32_t x,
438 :     uint32_t y,
439 :     uint32_t mb_width,
440 :     int16_t qcoeff[6 * 64])
441 : Isibaar 3 {
442 : edgomez 78
443 :     int32_t j;
444 : suxen_drol 926 int32_t iDcScaler, iQuant;
445 : edgomez 851 int S = 0;
446 : Isibaar 3 int16_t predictors[6][8];
447 :    
448 : suxen_drol 136 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
449 : suxen_drol 926 iQuant = pMB->quant;
450 : Isibaar 3
451 : edgomez 78 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
452 : edgomez 195
453 :     for (j = 0; j < 6; j++) {
454 : edgomez 851 iDcScaler = get_dc_scaler(iQuant, j<4);
455 : Isibaar 3
456 : edgomez 195 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
457 : suxen_drol 252 iQuant, iDcScaler, predictors[j], 0);
458 : edgomez 78
459 : edgomez 949 if ((frame->vop_flags & XVID_VOP_HQACPRED))
460 : edgomez 851 S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
461 :     else
462 :     S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
463 : edgomez 78
464 : Isibaar 3 }
465 :    
466 : edgomez 1053 if (S<=0) { /* dont predict */
467 : edgomez 851 for (j = 0; j < 6; j++)
468 : Isibaar 3 pMB->acpred_directions[j] = 0;
469 : edgomez 851 }else{
470 :     for (j = 0; j < 6; j++)
471 : edgomez 195 apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
472 : Isibaar 3 }
473 : edgomez 851
474 : Isibaar 3 pMB->cbp = calc_cbp(qcoeff);
475 :     }
476 : edgomez 78
477 : Isibaar 3 }

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