[svn] / trunk / xvidcore / src / prediction / mbprediction.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/prediction/mbprediction.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 195 - (view) (download)

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

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