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

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

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