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

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

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