[svn] / branches / release-1_0-branch / xvidcore / src / prediction / mbprediction.c Repository:
ViewVC logotype

Annotation of /branches/release-1_0-branch/xvidcore/src/prediction/mbprediction.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 677 - (view) (download)
Original Path: trunk/xvidcore/src/prediction/mbprediction.c

1 : edgomez 445 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Prediction functions -
5 :     *
6 :     * Copyright(C) 2001-2002 - Michael Militzer <isibaar@xvid.org>
7 : suxen_drol 499 * Copyright(C) 2001-2002 - Peter Ross <pross@xvid.org>
8 : edgomez 445 *
9 : edgomez 652 * This file is part of XviD, a free MPEG-4 video encoder/decoder
10 : edgomez 445 *
11 : edgomez 652 * 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 : edgomez 445 * the Free Software Foundation; either version 2 of the License, or
14 :     * (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 :     * 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 : edgomez 652 * Under section 8 of the GNU General Public License, the copyright
26 :     * holders of XVID explicitly forbid distribution in the following
27 :     * countries:
28 : edgomez 445 *
29 : edgomez 652 * - 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 :     *
54 : edgomez 677 * $Id: mbprediction.c,v 1.11 2002-11-26 23:44:11 edgomez Exp $
55 : edgomez 652 *
56 : edgomez 445 ****************************************************************************/
57 : Isibaar 3
58 :     #include "../encoder.h"
59 :     #include "mbprediction.h"
60 :     #include "../utils/mbfunctions.h"
61 :     #include "../bitstream/cbp.h"
62 :    
63 :    
64 :     #define ABS(X) (((X)>0)?(X):-(X))
65 :     #define DIV_DIV(A,B) ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )
66 :    
67 :    
68 : edgomez 445 /*****************************************************************************
69 :     * Local inlined function
70 :     ****************************************************************************/
71 :    
72 : edgomez 195 static int __inline
73 :     rescale(int predict_quant,
74 :     int current_quant,
75 :     int coeff)
76 : Isibaar 3 {
77 : edgomez 195 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
78 :     (current_quant)) : 0;
79 : Isibaar 3 }
80 :    
81 :    
82 : edgomez 445 /*****************************************************************************
83 :     * Local data
84 :     ****************************************************************************/
85 :    
86 : edgomez 195 static const int16_t default_acdc_values[15] = {
87 : Isibaar 3 1024,
88 : edgomez 78 0, 0, 0, 0, 0, 0, 0,
89 :     0, 0, 0, 0, 0, 0, 0
90 : Isibaar 3 };
91 :    
92 :    
93 : edgomez 445 /*****************************************************************************
94 :     * Functions
95 :     ****************************************************************************/
96 :    
97 :    
98 : Isibaar 3 /* get dc/ac prediction direction for a single block and place
99 :     predictor values into MB->pred_values[j][..]
100 :     */
101 :    
102 :    
103 : edgomez 195 void
104 :     predict_acdc(MACROBLOCK * pMBs,
105 :     uint32_t x,
106 :     uint32_t y,
107 :     uint32_t mb_width,
108 :     uint32_t block,
109 :     int16_t qcoeff[64],
110 :     uint32_t current_quant,
111 :     int32_t iDcScaler,
112 : suxen_drol 248 int16_t predictors[8],
113 : suxen_drol 252 const int bound)
114 : suxen_drol 248
115 : Isibaar 3 {
116 : suxen_drol 252 const int mbpos = (y * mb_width) + x;
117 : edgomez 78 int16_t *left, *top, *diag, *current;
118 : Isibaar 3
119 : edgomez 78 int32_t left_quant = current_quant;
120 :     int32_t top_quant = current_quant;
121 : Isibaar 3
122 : edgomez 78 const int16_t *pLeft = default_acdc_values;
123 :     const int16_t *pTop = default_acdc_values;
124 :     const int16_t *pDiag = default_acdc_values;
125 : Isibaar 3
126 : edgomez 677 uint32_t index = x + y * mb_width; /* current macroblock */
127 : edgomez 195 int *acpred_direction = &pMBs[index].acpred_directions[block];
128 : Isibaar 3 uint32_t i;
129 :    
130 :     left = top = diag = current = 0;
131 :    
132 : edgomez 677 /* grab left,top and diag macroblocks */
133 : Isibaar 3
134 : edgomez 677 /* left macroblock */
135 : Isibaar 3
136 : suxen_drol 248 if (x && mbpos >= bound + 1 &&
137 : edgomez 195 (pMBs[index - 1].mode == MODE_INTRA ||
138 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
139 : Isibaar 3
140 :     left = pMBs[index - 1].pred_values[0];
141 :     left_quant = pMBs[index - 1].quant;
142 : edgomez 677 /*DEBUGI("LEFT", *(left+MBPRED_SIZE)); */
143 : Isibaar 3 }
144 : edgomez 677 /* top macroblock */
145 : Isibaar 3
146 : suxen_drol 252 if (mbpos >= bound + (int)mb_width &&
147 : edgomez 195 (pMBs[index - mb_width].mode == MODE_INTRA ||
148 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
149 :    
150 : Isibaar 3 top = pMBs[index - mb_width].pred_values[0];
151 :     top_quant = pMBs[index - mb_width].quant;
152 : edgomez 78 }
153 : edgomez 677 /* diag macroblock */
154 : Isibaar 3
155 : suxen_drol 252 if (x && mbpos >= bound + (int)mb_width + 1 &&
156 : edgomez 195 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
157 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
158 :    
159 : Isibaar 3 diag = pMBs[index - 1 - mb_width].pred_values[0];
160 :     }
161 :    
162 : edgomez 78 current = pMBs[index].pred_values[0];
163 : Isibaar 3
164 : edgomez 677 /* now grab pLeft, pTop, pDiag _blocks_ */
165 : edgomez 195
166 : Isibaar 3 switch (block) {
167 : edgomez 195
168 :     case 0:
169 :     if (left)
170 : Isibaar 3 pLeft = left + MBPRED_SIZE;
171 : edgomez 195
172 :     if (top)
173 : Isibaar 3 pTop = top + (MBPRED_SIZE << 1);
174 : edgomez 195
175 :     if (diag)
176 : Isibaar 3 pDiag = diag + 3 * MBPRED_SIZE;
177 : edgomez 195
178 : Isibaar 3 break;
179 : edgomez 195
180 : Isibaar 3 case 1:
181 :     pLeft = current;
182 :     left_quant = current_quant;
183 : edgomez 195
184 :     if (top) {
185 : Isibaar 3 pTop = top + 3 * MBPRED_SIZE;
186 :     pDiag = top + (MBPRED_SIZE << 1);
187 :     }
188 :     break;
189 : edgomez 195
190 : Isibaar 3 case 2:
191 : edgomez 195 if (left) {
192 : Isibaar 3 pLeft = left + 3 * MBPRED_SIZE;
193 :     pDiag = left + MBPRED_SIZE;
194 :     }
195 : edgomez 195
196 : Isibaar 3 pTop = current;
197 :     top_quant = current_quant;
198 :    
199 :     break;
200 : edgomez 195
201 : Isibaar 3 case 3:
202 :     pLeft = current + (MBPRED_SIZE << 1);
203 :     left_quant = current_quant;
204 : edgomez 195
205 : Isibaar 3 pTop = current + MBPRED_SIZE;
206 :     top_quant = current_quant;
207 : edgomez 195
208 : Isibaar 3 pDiag = current;
209 : edgomez 195
210 : Isibaar 3 break;
211 : edgomez 195
212 : Isibaar 3 case 4:
213 : edgomez 195 if (left)
214 : Isibaar 3 pLeft = left + (MBPRED_SIZE << 2);
215 : edgomez 195 if (top)
216 : Isibaar 3 pTop = top + (MBPRED_SIZE << 2);
217 : edgomez 195 if (diag)
218 : Isibaar 3 pDiag = diag + (MBPRED_SIZE << 2);
219 :     break;
220 : edgomez 195
221 : Isibaar 3 case 5:
222 : edgomez 195 if (left)
223 : Isibaar 3 pLeft = left + 5 * MBPRED_SIZE;
224 : edgomez 195 if (top)
225 : Isibaar 3 pTop = top + 5 * MBPRED_SIZE;
226 : edgomez 195 if (diag)
227 : Isibaar 3 pDiag = diag + 5 * MBPRED_SIZE;
228 :     break;
229 :     }
230 :    
231 : edgomez 677 /* determine ac prediction direction & ac/dc predictor */
232 :     /* place rescaled ac/dc predictions into predictors[] for later use */
233 : Isibaar 3
234 : edgomez 195 if (ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) {
235 : edgomez 677 *acpred_direction = 1; /* vertical */
236 : Isibaar 3 predictors[0] = DIV_DIV(pTop[0], iDcScaler);
237 : edgomez 195 for (i = 1; i < 8; i++) {
238 : Isibaar 3 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
239 :     }
240 : edgomez 195 } else {
241 : edgomez 677 *acpred_direction = 2; /* horizontal */
242 : Isibaar 3 predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
243 : edgomez 195 for (i = 1; i < 8; i++) {
244 : Isibaar 3 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
245 :     }
246 :     }
247 :     }
248 :    
249 :    
250 :     /* decoder: add predictors to dct_codes[] and
251 :     store current coeffs to pred_values[] for future prediction
252 :     */
253 :    
254 :    
255 : edgomez 195 void
256 :     add_acdc(MACROBLOCK * pMB,
257 :     uint32_t block,
258 :     int16_t dct_codes[64],
259 :     uint32_t iDcScaler,
260 :     int16_t predictors[8])
261 : Isibaar 3 {
262 :     uint8_t acpred_direction = pMB->acpred_directions[block];
263 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
264 : Isibaar 3 uint32_t i;
265 :    
266 : suxen_drol 252 DPRINTF(DPRINTF_COEFF,"predictor[0] %i", predictors[0]);
267 :    
268 : edgomez 677 dct_codes[0] += predictors[0]; /* dc prediction */
269 : Isibaar 3 pCurrent[0] = dct_codes[0] * iDcScaler;
270 :    
271 : edgomez 195 if (acpred_direction == 1) {
272 :     for (i = 1; i < 8; i++) {
273 : Isibaar 3 int level = dct_codes[i] + predictors[i];
274 : edgomez 195
275 : suxen_drol 252 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i, predictors[i]);
276 :    
277 : Isibaar 3 dct_codes[i] = level;
278 :     pCurrent[i] = level;
279 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
280 : Isibaar 3 }
281 : edgomez 195 } else if (acpred_direction == 2) {
282 :     for (i = 1; i < 8; i++) {
283 :     int level = dct_codes[i * 8] + predictors[i];
284 : suxen_drol 252 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i*8, predictors[i]);
285 : edgomez 195
286 :     dct_codes[i * 8] = level;
287 :     pCurrent[i + 7] = level;
288 : Isibaar 3 pCurrent[i] = dct_codes[i];
289 :     }
290 : edgomez 195 } else {
291 :     for (i = 1; i < 8; i++) {
292 : Isibaar 3 pCurrent[i] = dct_codes[i];
293 : edgomez 195 pCurrent[i + 7] = dct_codes[i * 8];
294 : Isibaar 3 }
295 :     }
296 :     }
297 :    
298 :    
299 :    
300 : edgomez 677 /* ****************************************************************** */
301 :     /* ****************************************************************** */
302 : Isibaar 3
303 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
304 :    
305 : edgomez 78 todo: perform [-127,127] clamping after prediction
306 :     clamping must adjust the coeffs, so dequant is done correctly
307 : Isibaar 3
308 : edgomez 78 S1/S2 are used to determine if its worth predicting for AC
309 :     S1 = sum of all (qcoeff - prediction)
310 :     S2 = sum of all qcoeff
311 :     */
312 : Isibaar 3
313 : edgomez 195 uint32_t
314 :     calc_acdc(MACROBLOCK * pMB,
315 :     uint32_t block,
316 :     int16_t qcoeff[64],
317 :     uint32_t iDcScaler,
318 :     int16_t predictors[8])
319 : Isibaar 3 {
320 : edgomez 195 int16_t *pCurrent = pMB->pred_values[block];
321 : Isibaar 3 uint32_t i;
322 :     uint32_t S1 = 0, S2 = 0;
323 :    
324 :    
325 :     /* store current coeffs to pred_values[] for future prediction */
326 :    
327 :     pCurrent[0] = qcoeff[0] * iDcScaler;
328 : edgomez 195 for (i = 1; i < 8; i++) {
329 : Isibaar 3 pCurrent[i] = qcoeff[i];
330 :     pCurrent[i + 7] = qcoeff[i * 8];
331 : edgomez 78 }
332 : Isibaar 3
333 :     /* subtract predictors and store back in predictors[] */
334 :    
335 :     qcoeff[0] = qcoeff[0] - predictors[0];
336 :    
337 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
338 :     for (i = 1; i < 8; i++) {
339 : Isibaar 3 int16_t level;
340 :    
341 :     level = qcoeff[i];
342 :     S2 += ABS(level);
343 :     level -= predictors[i];
344 :     S1 += ABS(level);
345 :     predictors[i] = level;
346 :     }
347 : edgomez 677 } else /* acpred_direction == 2 */
348 : Isibaar 3 {
349 : edgomez 195 for (i = 1; i < 8; i++) {
350 : Isibaar 3 int16_t level;
351 :    
352 : edgomez 195 level = qcoeff[i * 8];
353 : Isibaar 3 S2 += ABS(level);
354 :     level -= predictors[i];
355 :     S1 += ABS(level);
356 :     predictors[i] = level;
357 :     }
358 :    
359 : edgomez 78 }
360 : Isibaar 3
361 : edgomez 195
362 : edgomez 78 return S2 - S1;
363 : Isibaar 3 }
364 :    
365 :    
366 :     /* apply predictors[] to qcoeff */
367 :    
368 : edgomez 195 void
369 :     apply_acdc(MACROBLOCK * pMB,
370 :     uint32_t block,
371 :     int16_t qcoeff[64],
372 :     int16_t predictors[8])
373 : Isibaar 3 {
374 :     uint32_t i;
375 :    
376 : edgomez 195 if (pMB->acpred_directions[block] == 1) {
377 :     for (i = 1; i < 8; i++) {
378 : Isibaar 3 qcoeff[i] = predictors[i];
379 :     }
380 : edgomez 195 } else {
381 :     for (i = 1; i < 8; i++) {
382 :     qcoeff[i * 8] = predictors[i];
383 : Isibaar 3 }
384 : edgomez 78 }
385 : Isibaar 3 }
386 :    
387 :    
388 : edgomez 195 void
389 :     MBPrediction(FRAMEINFO * frame,
390 :     uint32_t x,
391 :     uint32_t y,
392 :     uint32_t mb_width,
393 :     int16_t qcoeff[6 * 64])
394 : Isibaar 3 {
395 : edgomez 78
396 :     int32_t j;
397 : suxen_drol 136 int32_t iDcScaler, iQuant = frame->quant;
398 : Isibaar 3 int32_t S = 0;
399 :     int16_t predictors[6][8];
400 :    
401 : suxen_drol 136 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
402 : Isibaar 3
403 : edgomez 78 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
404 : edgomez 195
405 :     for (j = 0; j < 6; j++) {
406 : Isibaar 3 iDcScaler = get_dc_scaler(iQuant, (j < 4) ? 1 : 0);
407 :    
408 : edgomez 195 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
409 : suxen_drol 252 iQuant, iDcScaler, predictors[j], 0);
410 : edgomez 78
411 : edgomez 195 S += calc_acdc(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
412 : edgomez 78
413 : Isibaar 3 }
414 :    
415 : edgomez 677 if (S < 0) /* dont predict */
416 : edgomez 195 {
417 :     for (j = 0; j < 6; j++) {
418 : Isibaar 3 pMB->acpred_directions[j] = 0;
419 :     }
420 : edgomez 195 } else {
421 :     for (j = 0; j < 6; j++) {
422 :     apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
423 : Isibaar 3 }
424 :     }
425 :     pMB->cbp = calc_cbp(qcoeff);
426 :     }
427 : edgomez 78
428 : Isibaar 3 }

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