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

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