[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 248 - (view) (download)
Original Path: trunk/xvidcore/src/prediction/mbprediction.c

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

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