[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.8 - (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 :     * Copyright(C) 2001-2002 - Peter Ross <pross@cs.rmit.edu.au>
8 :     *
9 :     * This program is an implementation of a part of one or more MPEG-4
10 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
11 :     * to use this software module in hardware or software products are
12 :     * advised that its use may infringe existing patents or copyrights, and
13 :     * any such use would be at such party's own risk. The original
14 :     * developer of this software module and his/her company, and subsequent
15 :     * editors and their companies, will have no liability for use of this
16 :     * software or modifications or derivatives thereof.
17 :     *
18 :     * This program is free software; you can redistribute it and/or modify
19 :     * it under the terms of the GNU General Public License as published by
20 :     * the Free Software Foundation; either version 2 of the License, or
21 :     * (at your option) any later version.
22 :     *
23 :     * This program is distributed in the hope that it will be useful,
24 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 :     * GNU General Public License for more details.
27 :     *
28 :     * You should have received a copy of the GNU General Public License
29 :     * along with this program; if not, write to the Free Software
30 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 :     *
32 :     * $Id$
33 :     *
34 :     ****************************************************************************/
35 : Isibaar 1.1
36 :     #include "../encoder.h"
37 :     #include "mbprediction.h"
38 :     #include "../utils/mbfunctions.h"
39 :     #include "../bitstream/cbp.h"
40 :    
41 :    
42 :     #define ABS(X) (((X)>0)?(X):-(X))
43 :     #define DIV_DIV(A,B) ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )
44 :    
45 :    
46 : edgomez 1.8 /*****************************************************************************
47 :     * Local inlined function
48 :     ****************************************************************************/
49 :    
50 : edgomez 1.4 static int __inline
51 :     rescale(int predict_quant,
52 :     int current_quant,
53 :     int coeff)
54 : Isibaar 1.1 {
55 : edgomez 1.4 return (coeff != 0) ? DIV_DIV((coeff) * (predict_quant),
56 :     (current_quant)) : 0;
57 : Isibaar 1.1 }
58 :    
59 :    
60 : edgomez 1.8 /*****************************************************************************
61 :     * Local data
62 :     ****************************************************************************/
63 :    
64 : edgomez 1.4 static const int16_t default_acdc_values[15] = {
65 : Isibaar 1.1 1024,
66 : edgomez 1.2 0, 0, 0, 0, 0, 0, 0,
67 :     0, 0, 0, 0, 0, 0, 0
68 : Isibaar 1.1 };
69 : edgomez 1.8
70 :    
71 :     /*****************************************************************************
72 :     * Functions
73 :     ****************************************************************************/
74 : Isibaar 1.1
75 :    
76 :     /* get dc/ac prediction direction for a single block and place
77 :     predictor values into MB->pred_values[j][..]
78 :     */
79 :    
80 :    
81 : edgomez 1.4 void
82 :     predict_acdc(MACROBLOCK * pMBs,
83 :     uint32_t x,
84 :     uint32_t y,
85 :     uint32_t mb_width,
86 :     uint32_t block,
87 :     int16_t qcoeff[64],
88 :     uint32_t current_quant,
89 :     int32_t iDcScaler,
90 : suxen_drol 1.5 int16_t predictors[8],
91 : suxen_drol 1.6 const int bound)
92 : suxen_drol 1.5
93 : Isibaar 1.1 {
94 : suxen_drol 1.6 const int mbpos = (y * mb_width) + x;
95 : edgomez 1.2 int16_t *left, *top, *diag, *current;
96 : Isibaar 1.1
97 : edgomez 1.2 int32_t left_quant = current_quant;
98 :     int32_t top_quant = current_quant;
99 : Isibaar 1.1
100 : edgomez 1.2 const int16_t *pLeft = default_acdc_values;
101 :     const int16_t *pTop = default_acdc_values;
102 :     const int16_t *pDiag = default_acdc_values;
103 : Isibaar 1.1
104 : edgomez 1.4 uint32_t index = x + y * mb_width; // current macroblock
105 :     int *acpred_direction = &pMBs[index].acpred_directions[block];
106 : Isibaar 1.1 uint32_t i;
107 :    
108 :     left = top = diag = current = 0;
109 :    
110 :     // grab left,top and diag macroblocks
111 :    
112 :     // left macroblock
113 :    
114 : suxen_drol 1.5 if (x && mbpos >= bound + 1 &&
115 : edgomez 1.4 (pMBs[index - 1].mode == MODE_INTRA ||
116 :     pMBs[index - 1].mode == MODE_INTRA_Q)) {
117 : Isibaar 1.1
118 :     left = pMBs[index - 1].pred_values[0];
119 :     left_quant = pMBs[index - 1].quant;
120 :     //DEBUGI("LEFT", *(left+MBPRED_SIZE));
121 :     }
122 :     // top macroblock
123 : edgomez 1.4
124 : suxen_drol 1.6 if (mbpos >= bound + (int)mb_width &&
125 : edgomez 1.4 (pMBs[index - mb_width].mode == MODE_INTRA ||
126 :     pMBs[index - mb_width].mode == MODE_INTRA_Q)) {
127 : Isibaar 1.1
128 :     top = pMBs[index - mb_width].pred_values[0];
129 :     top_quant = pMBs[index - mb_width].quant;
130 : edgomez 1.2 }
131 : Isibaar 1.1 // diag macroblock
132 : edgomez 1.4
133 : suxen_drol 1.6 if (x && mbpos >= bound + (int)mb_width + 1 &&
134 : edgomez 1.4 (pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
135 :     pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) {
136 : Isibaar 1.1
137 :     diag = pMBs[index - 1 - mb_width].pred_values[0];
138 :     }
139 :    
140 : edgomez 1.2 current = pMBs[index].pred_values[0];
141 : Isibaar 1.1
142 :     // now grab pLeft, pTop, pDiag _blocks_
143 : edgomez 1.4
144 : Isibaar 1.1 switch (block) {
145 : edgomez 1.4
146 :     case 0:
147 :     if (left)
148 : Isibaar 1.1 pLeft = left + MBPRED_SIZE;
149 : edgomez 1.4
150 :     if (top)
151 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 1);
152 : edgomez 1.4
153 :     if (diag)
154 : Isibaar 1.1 pDiag = diag + 3 * MBPRED_SIZE;
155 : edgomez 1.4
156 : Isibaar 1.1 break;
157 : edgomez 1.4
158 : Isibaar 1.1 case 1:
159 :     pLeft = current;
160 :     left_quant = current_quant;
161 : edgomez 1.4
162 :     if (top) {
163 : Isibaar 1.1 pTop = top + 3 * MBPRED_SIZE;
164 :     pDiag = top + (MBPRED_SIZE << 1);
165 :     }
166 :     break;
167 : edgomez 1.4
168 : Isibaar 1.1 case 2:
169 : edgomez 1.4 if (left) {
170 : Isibaar 1.1 pLeft = left + 3 * MBPRED_SIZE;
171 :     pDiag = left + MBPRED_SIZE;
172 :     }
173 : edgomez 1.4
174 : Isibaar 1.1 pTop = current;
175 :     top_quant = current_quant;
176 :    
177 :     break;
178 : edgomez 1.4
179 : Isibaar 1.1 case 3:
180 :     pLeft = current + (MBPRED_SIZE << 1);
181 :     left_quant = current_quant;
182 : edgomez 1.4
183 : Isibaar 1.1 pTop = current + MBPRED_SIZE;
184 :     top_quant = current_quant;
185 : edgomez 1.4
186 : Isibaar 1.1 pDiag = current;
187 : edgomez 1.4
188 : Isibaar 1.1 break;
189 : edgomez 1.4
190 : Isibaar 1.1 case 4:
191 : edgomez 1.4 if (left)
192 : Isibaar 1.1 pLeft = left + (MBPRED_SIZE << 2);
193 : edgomez 1.4 if (top)
194 : Isibaar 1.1 pTop = top + (MBPRED_SIZE << 2);
195 : edgomez 1.4 if (diag)
196 : Isibaar 1.1 pDiag = diag + (MBPRED_SIZE << 2);
197 :     break;
198 : edgomez 1.4
199 : Isibaar 1.1 case 5:
200 : edgomez 1.4 if (left)
201 : Isibaar 1.1 pLeft = left + 5 * MBPRED_SIZE;
202 : edgomez 1.4 if (top)
203 : Isibaar 1.1 pTop = top + 5 * MBPRED_SIZE;
204 : edgomez 1.4 if (diag)
205 : Isibaar 1.1 pDiag = diag + 5 * MBPRED_SIZE;
206 :     break;
207 :     }
208 :    
209 : edgomez 1.4 // determine ac prediction direction & ac/dc predictor
210 :     // place rescaled ac/dc predictions into predictors[] for later use
211 : Isibaar 1.1
212 : edgomez 1.4 if (ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) {
213 :     *acpred_direction = 1; // vertical
214 : Isibaar 1.1 predictors[0] = DIV_DIV(pTop[0], iDcScaler);
215 : edgomez 1.4 for (i = 1; i < 8; i++) {
216 : Isibaar 1.1 predictors[i] = rescale(top_quant, current_quant, pTop[i]);
217 :     }
218 : edgomez 1.4 } else {
219 :     *acpred_direction = 2; // horizontal
220 : Isibaar 1.1 predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
221 : edgomez 1.4 for (i = 1; i < 8; i++) {
222 : Isibaar 1.1 predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
223 :     }
224 :     }
225 :     }
226 :    
227 :    
228 :     /* decoder: add predictors to dct_codes[] and
229 :     store current coeffs to pred_values[] for future prediction
230 :     */
231 :    
232 :    
233 : edgomez 1.4 void
234 :     add_acdc(MACROBLOCK * pMB,
235 :     uint32_t block,
236 :     int16_t dct_codes[64],
237 :     uint32_t iDcScaler,
238 :     int16_t predictors[8])
239 : Isibaar 1.1 {
240 :     uint8_t acpred_direction = pMB->acpred_directions[block];
241 : edgomez 1.4 int16_t *pCurrent = pMB->pred_values[block];
242 : Isibaar 1.1 uint32_t i;
243 :    
244 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[0] %i", predictors[0]);
245 :    
246 : Isibaar 1.1 dct_codes[0] += predictors[0]; // dc prediction
247 :     pCurrent[0] = dct_codes[0] * iDcScaler;
248 :    
249 : edgomez 1.4 if (acpred_direction == 1) {
250 :     for (i = 1; i < 8; i++) {
251 : Isibaar 1.1 int level = dct_codes[i] + predictors[i];
252 : edgomez 1.4
253 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i, predictors[i]);
254 :    
255 : Isibaar 1.1 dct_codes[i] = level;
256 :     pCurrent[i] = level;
257 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
258 : Isibaar 1.1 }
259 : edgomez 1.4 } else if (acpred_direction == 2) {
260 :     for (i = 1; i < 8; i++) {
261 :     int level = dct_codes[i * 8] + predictors[i];
262 : suxen_drol 1.6 DPRINTF(DPRINTF_COEFF,"predictor[%i] %i",i*8, predictors[i]);
263 : edgomez 1.4
264 :     dct_codes[i * 8] = level;
265 :     pCurrent[i + 7] = level;
266 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
267 :     }
268 : edgomez 1.4 } else {
269 :     for (i = 1; i < 8; i++) {
270 : Isibaar 1.1 pCurrent[i] = dct_codes[i];
271 : edgomez 1.4 pCurrent[i + 7] = dct_codes[i * 8];
272 : Isibaar 1.1 }
273 :     }
274 :     }
275 :    
276 :    
277 :    
278 :     // ******************************************************************
279 :     // ******************************************************************
280 :    
281 :     /* encoder: subtract predictors from qcoeff[] and calculate S1/S2
282 :    
283 : edgomez 1.2 todo: perform [-127,127] clamping after prediction
284 :     clamping must adjust the coeffs, so dequant is done correctly
285 : Isibaar 1.1
286 : edgomez 1.2 S1/S2 are used to determine if its worth predicting for AC
287 :     S1 = sum of all (qcoeff - prediction)
288 :     S2 = sum of all qcoeff
289 :     */
290 : Isibaar 1.1
291 : edgomez 1.4 uint32_t
292 :     calc_acdc(MACROBLOCK * pMB,
293 :     uint32_t block,
294 :     int16_t qcoeff[64],
295 :     uint32_t iDcScaler,
296 :     int16_t predictors[8])
297 : Isibaar 1.1 {
298 : edgomez 1.4 int16_t *pCurrent = pMB->pred_values[block];
299 : Isibaar 1.1 uint32_t i;
300 :     uint32_t S1 = 0, S2 = 0;
301 :    
302 :    
303 :     /* store current coeffs to pred_values[] for future prediction */
304 :    
305 :     pCurrent[0] = qcoeff[0] * iDcScaler;
306 : edgomez 1.4 for (i = 1; i < 8; i++) {
307 : Isibaar 1.1 pCurrent[i] = qcoeff[i];
308 :     pCurrent[i + 7] = qcoeff[i * 8];
309 : edgomez 1.2 }
310 : Isibaar 1.1
311 :     /* subtract predictors and store back in predictors[] */
312 :    
313 :     qcoeff[0] = qcoeff[0] - predictors[0];
314 :    
315 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
316 :     for (i = 1; i < 8; i++) {
317 : Isibaar 1.1 int16_t level;
318 :    
319 :     level = qcoeff[i];
320 :     S2 += ABS(level);
321 :     level -= predictors[i];
322 :     S1 += ABS(level);
323 :     predictors[i] = level;
324 :     }
325 : edgomez 1.4 } else // acpred_direction == 2
326 : Isibaar 1.1 {
327 : edgomez 1.4 for (i = 1; i < 8; i++) {
328 : Isibaar 1.1 int16_t level;
329 :    
330 : edgomez 1.4 level = qcoeff[i * 8];
331 : Isibaar 1.1 S2 += ABS(level);
332 :     level -= predictors[i];
333 :     S1 += ABS(level);
334 :     predictors[i] = level;
335 :     }
336 :    
337 : edgomez 1.2 }
338 : Isibaar 1.1
339 : edgomez 1.4
340 : edgomez 1.2 return S2 - S1;
341 : Isibaar 1.1 }
342 :    
343 :    
344 :     /* apply predictors[] to qcoeff */
345 :    
346 : edgomez 1.4 void
347 :     apply_acdc(MACROBLOCK * pMB,
348 :     uint32_t block,
349 :     int16_t qcoeff[64],
350 :     int16_t predictors[8])
351 : Isibaar 1.1 {
352 :     uint32_t i;
353 :    
354 : edgomez 1.4 if (pMB->acpred_directions[block] == 1) {
355 :     for (i = 1; i < 8; i++) {
356 : Isibaar 1.1 qcoeff[i] = predictors[i];
357 :     }
358 : edgomez 1.4 } else {
359 :     for (i = 1; i < 8; i++) {
360 :     qcoeff[i * 8] = predictors[i];
361 : Isibaar 1.1 }
362 : edgomez 1.2 }
363 : Isibaar 1.1 }
364 :    
365 :    
366 : edgomez 1.4 void
367 :     MBPrediction(FRAMEINFO * frame,
368 :     uint32_t x,
369 :     uint32_t y,
370 :     uint32_t mb_width,
371 :     int16_t qcoeff[6 * 64])
372 : Isibaar 1.1 {
373 : edgomez 1.2
374 :     int32_t j;
375 : suxen_drol 1.3 int32_t iDcScaler, iQuant = frame->quant;
376 : Isibaar 1.1 int32_t S = 0;
377 :     int16_t predictors[6][8];
378 :    
379 : suxen_drol 1.3 MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
380 : Isibaar 1.1
381 : edgomez 1.2 if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {
382 : edgomez 1.4
383 :     for (j = 0; j < 6; j++) {
384 : Isibaar 1.1 iDcScaler = get_dc_scaler(iQuant, (j < 4) ? 1 : 0);
385 :    
386 : edgomez 1.4 predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
387 : suxen_drol 1.6 iQuant, iDcScaler, predictors[j], 0);
388 : edgomez 1.4
389 :     S += calc_acdc(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
390 : edgomez 1.2
391 : Isibaar 1.1 }
392 :    
393 : edgomez 1.4 if (S < 0) // dont predict
394 :     {
395 :     for (j = 0; j < 6; j++) {
396 : Isibaar 1.1 pMB->acpred_directions[j] = 0;
397 :     }
398 : edgomez 1.4 } else {
399 :     for (j = 0; j < 6; j++) {
400 :     apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
401 : Isibaar 1.1 }
402 :     }
403 :     pMB->cbp = calc_cbp(qcoeff);
404 :     }
405 : edgomez 1.2
406 : suxen_drol 1.6 }

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