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

1 : edgomez 1.13 /******************************************************************************
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 :    
30 :     /******************************************************************************
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 : Isibaar 1.1
53 : edgomez 1.13.2.4 #include <stdlib.h>
54 :    
55 : edgomez 1.13 #include "../global.h"
56 : Isibaar 1.1 #include "../encoder.h"
57 :     #include "mbprediction.h"
58 :     #include "../utils/mbfunctions.h"
59 :     #include "../bitstream/cbp.h"
60 : edgomez 1.13 #include "../bitstream/mbcoding.h"
61 :     #include "../bitstream/zigzag.h"
62 : Isibaar 1.1
63 :    
64 : edgomez 1.4 static int __inline
65 :     rescale(int predict_quant,
66 :     int current_quant,
67 :     int coeff)
68 : Isibaar 1.1 {
69 : edgomez 1.4 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
70 :     (current_quant)) : 0;
71 : Isibaar 1.1 }
72 :    
73 :    
74 : edgomez 1.4 static const int16_t default_acdc_values[15] = {
75 : Isibaar 1.1 1024,
76 : edgomez 1.2 0, 0, 0, 0, 0, 0, 0,
77 :     0, 0, 0, 0, 0, 0, 0
78 : Isibaar 1.1 };
79 : edgomez 1.8
80 :    
81 : Isibaar 1.1 /* get dc/ac prediction direction for a single block and place
82 :     predictor values into MB->pred_values[j][..]
83 :     */
84 :    
85 :    
86 : edgomez 1.4 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 1.5 int16_t predictors[8],
96 : suxen_drol 1.6 const int bound)
97 : suxen_drol 1.5
98 : Isibaar 1.1 {
99 : suxen_drol 1.6 const int mbpos = (y * mb_width) + x;
100 : edgomez 1.2 int16_t *left, *top, *diag, *current;
101 : Isibaar 1.1
102 : edgomez 1.2 int32_t left_quant = current_quant;
103 :     int32_t top_quant = current_quant;
104 : Isibaar 1.1
105 : edgomez 1.2 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 1.1
109 : edgomez 1.13 uint32_t index = x + y * mb_width; // current macroblock
110 : edgomez 1.4 int *acpred_direction = &pMBs[index].acpred_directions[block];
111 : Isibaar 1.1 uint32_t i;
112 :    
113 :     left = top = diag = current = 0;
114 :    
115 : edgomez 1.13 // grab left,top and diag macroblocks
116 : Isibaar 1.1
117 : edgomez 1.13 // left macroblock
118 : Isibaar 1.1
119 : suxen_drol 1.5 if (x && mbpos >= bound + 1 &&
120 : edgomez 1.4 (pMBs[index - 1].mode == MODE_INTRA ||
121 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
122 : Isibaar 1.1
123 :     left = pMBs[index - 1].pred_values[0];
124 :     left_quant = pMBs[index - 1].quant;
125 : edgomez 1.13 //DEBUGI("LEFT", *(left+MBPRED_SIZE));
126 : Isibaar 1.1 }
127 : edgomez 1.13 // top macroblock
128 : edgomez 1.4
129 : suxen_drol 1.6 if (mbpos >= bound + (int)mb_width &&
130 : edgomez 1.4 (pMBs[index - mb_width].mode == MODE_INTRA ||
131 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
132 : Isibaar 1.1
133 :     top = pMBs[index - mb_width].pred_values[0];
134 :     top_quant = pMBs[index - mb_width].quant;
135 : edgomez 1.2 }
136 : edgomez 1.13 // diag macroblock
137 : edgomez 1.4
138 : suxen_drol 1.6 if (x && mbpos >= bound + (int)mb_width + 1 &&
139 : edgomez 1.4 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
140 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
141 : Isibaar 1.1
142 :     diag = pMBs[index - 1 - mb_width].pred_values[0];
143 :     }
144 :    
145 : edgomez 1.2 current = pMBs[index].pred_values[0];
146 : Isibaar 1.1
147 : edgomez 1.13 // now grab pLeft, pTop, pDiag _blocks_
148 : edgomez 1.4
149 : Isibaar 1.1 switch (block) {
150 : edgomez 1.4
151 :     case 0:
152 :     if (left)
153 : Isibaar 1.1 pLeft = left + MBPRED_SIZE;
154 : edgomez 1.4
155 :     if (top)
156 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 1);
157 : edgomez 1.4
158 :     if (diag)
159 : Isibaar 1.1 pDiag = diag + 3 * MBPRED_SIZE;
160 : edgomez 1.4
161 : Isibaar 1.1 break;
162 : edgomez 1.4
163 : Isibaar 1.1 case 1:
164 :     pLeft = current;
165 :     left_quant = current_quant;
166 : edgomez 1.4
167 :     if (top) {
168 : Isibaar 1.1 pTop = top + 3 * MBPRED_SIZE;
169 :     pDiag = top + (MBPRED_SIZE << 1);
170 :     }
171 :     break;
172 : edgomez 1.4
173 : Isibaar 1.1 case 2:
174 : edgomez 1.4 if (left) {
175 : Isibaar 1.1 pLeft = left + 3 * MBPRED_SIZE;
176 :     pDiag = left + MBPRED_SIZE;
177 :     }
178 : edgomez 1.4
179 : Isibaar 1.1 pTop = current;
180 :     top_quant = current_quant;
181 :    
182 :     break;
183 : edgomez 1.4
184 : Isibaar 1.1 case 3:
185 :     pLeft = current + (MBPRED_SIZE << 1);
186 :     left_quant = current_quant;
187 : edgomez 1.4
188 : Isibaar 1.1 pTop = current + MBPRED_SIZE;
189 :     top_quant = current_quant;
190 : edgomez 1.4
191 : Isibaar 1.1 pDiag = current;
192 : edgomez 1.4
193 : Isibaar 1.1 break;
194 : edgomez 1.4
195 : Isibaar 1.1 case 4:
196 : edgomez 1.4 if (left)
197 : Isibaar 1.1 pLeft = left + (MBPRED_SIZE << 2);
198 : edgomez 1.4 if (top)
199 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 2);
200 : edgomez 1.4 if (diag)
201 : Isibaar 1.1 pDiag = diag + (MBPRED_SIZE << 2);
202 :     break;
203 : edgomez 1.4
204 : Isibaar 1.1 case 5:
205 : edgomez 1.4 if (left)
206 : Isibaar 1.1 pLeft = left + 5 * MBPRED_SIZE;
207 : edgomez 1.4 if (top)
208 : Isibaar 1.1 pTop = top + 5 * MBPRED_SIZE;
209 : edgomez 1.4 if (diag)
210 : Isibaar 1.1 pDiag = diag + 5 * MBPRED_SIZE;
211 :     break;
212 :     }
213 :    
214 : edgomez 1.13 // determine ac prediction direction & ac/dc predictor
215 :     // place rescaled ac/dc predictions into predictors[] for later use
216 : Isibaar 1.1
217 : edgomez 1.13.2.4 if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) {
218 : edgomez 1.13 *acpred_direction = 1; // vertical
219 :     predictors[0] = DIV_DIV(pTop[0], iDcScaler);
220 : edgomez 1.4 for (i = 1; i < 8; i++) {
221 : Isibaar 1.1 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
222 :     }
223 : edgomez 1.4 } else {
224 : edgomez 1.13 *acpred_direction = 2; // horizontal
225 :     predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
226 : edgomez 1.4 for (i = 1; i < 8; i++) {
227 : Isibaar 1.1 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
228 :     }
229 :     }
230 :     }
231 :    
232 :    
233 :     /* decoder: add predictors to dct_codes[] and
234 :     store current coeffs to pred_values[] for future prediction
235 :     */
236 :    
237 :    
238 : edgomez 1.4 void
239 :     add_acdc(MACROBLOCK * pMB,
240 :     uint32_t block,
241 :     int16_t dct_codes[64],
242 :     uint32_t iDcScaler,
243 :     int16_t predictors[8])
244 : Isibaar 1.1 {
245 :     uint8_t acpred_direction = pMB->acpred_directions[block];
246 : edgomez 1.4 int16_t *pCurrent = pMB->pred_values[block];
247 : Isibaar 1.1 uint32_t i;
248 :    
249 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[0] %i", predictors[0]);
250 :    
251 : edgomez 1.13 dct_codes[0] += predictors[0]; // dc prediction
252 :     pCurrent[0] = dct_codes[0] * iDcScaler;
253 : Isibaar 1.1
254 : edgomez 1.4 if (acpred_direction == 1) {
255 :     for (i = 1; i < 8; i++) {
256 : Isibaar 1.1 int level = dct_codes[i] + predictors[i];
257 : edgomez 1.4
258 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i, predictors[i]);
259 :    
260 : Isibaar 1.1 dct_codes[i] = level;
261 :     pCurrent[i] = level;
262 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
263 : Isibaar 1.1 }
264 : edgomez 1.4 } else if (acpred_direction == 2) {
265 :     for (i = 1; i < 8; i++) {
266 :     int level = dct_codes[i * 8] + predictors[i];
267 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i*8, predictors[i]);
268 : edgomez 1.4
269 :     dct_codes[i * 8] = level;
270 :     pCurrent[i + 7] = level;
271 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
272 :     }
273 : edgomez 1.4 } else {
274 :     for (i = 1; i < 8; i++) {
275 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
276 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
277 : Isibaar 1.1 }
278 :     }
279 :     }
280 :    
281 :    
282 :    
283 : edgomez 1.13 // ******************************************************************
284 :     // ******************************************************************
285 : Isibaar 1.1
286 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
287 :    
288 : edgomez 1.13 returns sum of coeefficients *saved* if prediction is enabled
289 :    
290 : edgomez 1.2 S1 = sum of all (qcoeff - prediction)
291 :     S2 = sum of all qcoeff
292 :     */
293 : Isibaar 1.1
294 : edgomez 1.13 int
295 :     calc_acdc_coeff(MACROBLOCK * pMB,
296 : edgomez 1.4 uint32_t block,
297 :     int16_t qcoeff[64],
298 :     uint32_t iDcScaler,
299 :     int16_t predictors[8])
300 : Isibaar 1.1 {
301 : edgomez 1.4 int16_t *pCurrent = pMB->pred_values[block];
302 : Isibaar 1.1 uint32_t i;
303 : edgomez 1.13 int S1 = 0, S2 = 0;
304 : Isibaar 1.1
305 :    
306 :     /* store current coeffs to pred_values[] for future prediction */
307 :    
308 : edgomez 1.13 pCurrent[0] = qcoeff[0] * iDcScaler;
309 : edgomez 1.4 for (i = 1; i < 8; i++) {
310 : Isibaar 1.1 pCurrent[i] = qcoeff[i];
311 :     pCurrent[i + 7] = qcoeff[i * 8];
312 : edgomez 1.2 }
313 : Isibaar 1.1
314 :     /* subtract predictors and store back in predictors[] */
315 :    
316 :     qcoeff[0] = qcoeff[0] - predictors[0];
317 :    
318 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
319 :     for (i = 1; i < 8; i++) {
320 : Isibaar 1.1 int16_t level;
321 :    
322 :     level = qcoeff[i];
323 : edgomez 1.13.2.4 S2 += abs(level);
324 : Isibaar 1.1 level -= predictors[i];
325 : edgomez 1.13.2.4 S1 += abs(level);
326 : Isibaar 1.1 predictors[i] = level;
327 :     }
328 : edgomez 1.13 } else // acpred_direction == 2
329 : Isibaar 1.1 {
330 : edgomez 1.4 for (i = 1; i < 8; i++) {
331 : Isibaar 1.1 int16_t level;
332 :    
333 : edgomez 1.4 level = qcoeff[i * 8];
334 : edgomez 1.13.2.4 S2 += abs(level);
335 : Isibaar 1.1 level -= predictors[i];
336 : edgomez 1.13.2.4 S1 += abs(level);
337 : Isibaar 1.1 predictors[i] = level;
338 :     }
339 :    
340 : edgomez 1.2 }
341 : Isibaar 1.1
342 : edgomez 1.4
343 : edgomez 1.2 return S2 - S1;
344 : Isibaar 1.1 }
345 :    
346 :    
347 : edgomez 1.13
348 :     /* returns the bits *saved* if prediction is enabled */
349 :    
350 :     int
351 :     calc_acdc_bits(MACROBLOCK * pMB,
352 :     uint32_t block,
353 :     int16_t qcoeff[64],
354 :     uint32_t iDcScaler,
355 :     int16_t predictors[8])
356 :     {
357 :     const int direction = pMB->acpred_directions[block];
358 :     int16_t *pCurrent = pMB->pred_values[block];
359 :     int16_t tmp[8];
360 :     unsigned int i;
361 :     int Z1, Z2;
362 :    
363 :     /* store current coeffs to pred_values[] for future prediction */
364 :     pCurrent[0] = qcoeff[0] * iDcScaler;
365 :     for (i = 1; i < 8; i++) {
366 :     pCurrent[i] = qcoeff[i];
367 :     pCurrent[i + 7] = qcoeff[i * 8];
368 :     }
369 :    
370 :    
371 :     /* dc prediction */
372 :     qcoeff[0] = qcoeff[0] - predictors[0];
373 :    
374 :     /* calc cost before ac prediction */
375 :     #ifdef BIGLUT
376 :     Z2 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[0], 1);
377 :     #else
378 :     Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]);
379 :     #endif
380 :    
381 :     /* apply ac prediction & calc cost*/
382 :     if (direction == 1) {
383 :     for (i = 1; i < 8; i++) {
384 :     tmp[i] = qcoeff[i];
385 :     qcoeff[i] -= predictors[i];
386 :     predictors[i] = qcoeff[i];
387 :     }
388 :     }else{ // acpred_direction == 2
389 :     for (i = 1; i < 8; i++) {
390 :     tmp[i] = qcoeff[i*8];
391 :     qcoeff[i*8] -= predictors[i];
392 :     predictors[i] = qcoeff[i*8];
393 :     }
394 :     }
395 :    
396 :     #ifdef BIGLUT
397 :     Z1 = CodeCoeff_CalcBits(qcoeff, intra_table, scan_tables[direction], 1);
398 :     #else
399 :     Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]);
400 :     #endif
401 :    
402 :     /* undo prediction */
403 :     if (direction == 1) {
404 :     for (i = 1; i < 8; i++)
405 :     qcoeff[i] = tmp[i];
406 :     }else{ // acpred_direction == 2
407 :     for (i = 1; i < 8; i++)
408 :     qcoeff[i*8] = tmp[i];
409 :     }
410 :    
411 :     return Z2-Z1;
412 :     }
413 :    
414 : Isibaar 1.1 /* apply predictors[] to qcoeff */
415 :    
416 : edgomez 1.4 void
417 :     apply_acdc(MACROBLOCK * pMB,
418 :     uint32_t block,
419 :     int16_t qcoeff[64],
420 :     int16_t predictors[8])
421 : Isibaar 1.1 {
422 : edgomez 1.13 unsigned int i;
423 : Isibaar 1.1
424 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
425 : edgomez 1.13 for (i = 1; i < 8; i++)
426 : Isibaar 1.1 qcoeff[i] = predictors[i];
427 : edgomez 1.4 } else {
428 : edgomez 1.13 for (i = 1; i < 8; i++)
429 : edgomez 1.4 qcoeff[i * 8] = predictors[i];
430 : edgomez 1.2 }
431 : Isibaar 1.1 }
432 :    
433 :    
434 : edgomez 1.4 void
435 :     MBPrediction(FRAMEINFO * frame,
436 :     uint32_t x,
437 :     uint32_t y,
438 :     uint32_t mb_width,
439 :     int16_t qcoeff[6 * 64])
440 : Isibaar 1.1 {
441 : edgomez 1.2
442 :     int32_t j;
443 : suxen_drol 1.13.2.2 int32_t iDcScaler, iQuant;
444 : edgomez 1.13 int S = 0;
445 : Isibaar 1.1 int16_t predictors[6][8];
446 :    
447 : suxen_drol 1.3 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
448 : suxen_drol 1.13.2.2 iQuant = pMB->quant;
449 : Isibaar 1.1
450 : edgomez 1.2 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
451 : edgomez 1.4
452 :     for (j = 0; j < 6; j++) {
453 : edgomez 1.13 iDcScaler = get_dc_scaler(iQuant, j<4);
454 : Isibaar 1.1
455 : edgomez 1.4 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
456 : suxen_drol 1.6 iQuant, iDcScaler, predictors[j], 0);
457 : edgomez 1.4
458 : edgomez 1.13.2.3 if ((frame->vop_flags & XVID_VOP_HQACPRED))
459 : edgomez 1.13 S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
460 :     else
461 :     S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
462 : edgomez 1.2
463 : Isibaar 1.1 }
464 :    
465 : edgomez 1.13 if (S<=0) { // dont predict
466 :     for (j = 0; j < 6; j++)
467 : Isibaar 1.1 pMB->acpred_directions[j] = 0;
468 : edgomez 1.13 }else{
469 :     for (j = 0; j < 6; j++)
470 : edgomez 1.4 apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
471 : Isibaar 1.1 }
472 : edgomez 1.13
473 : Isibaar 1.1 pMB->cbp = calc_cbp(qcoeff);
474 :     }
475 : edgomez 1.2
476 : suxen_drol 1.6 }

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