[svn] / branches / dev-api-4 / xvidcore / src / utils / mbtransquant.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/utils/mbtransquant.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (view) (download)
Original Path: trunk/xvidcore/src/utils/mbtransquant.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 :     * mbtransquant.c *
33 :     * *
34 :     * Copyright (C) 2001 - Peter Ross <pross@cs.rmit.edu.au> *
35 :     * Copyright (C) 2001 - Michael Militzer <isibaar@xvid.org> *
36 :     * *
37 :     * For more information visit the XviD homepage: http://www.xvid.org *
38 :     * *
39 :     ******************************************************************************/
40 :    
41 :     /******************************************************************************
42 :     * *
43 :     * Revision history: *
44 :     * *
45 : h 69 * 26.03.2002 interlacing support - moved transfers outside loops
46 : Isibaar 3 * 22.12.2001 get_dc_scaler() moved to common.h
47 :     * 19.11.2001 introduced coefficient thresholding (Isibaar) *
48 :     * 17.11.2001 initial version *
49 :     * *
50 :     ******************************************************************************/
51 :    
52 :     #include "../portab.h"
53 :     #include "mbfunctions.h"
54 :    
55 :     #include "../global.h"
56 :     #include "mem_transfer.h"
57 :     #include "timer.h"
58 :     #include "../dct/fdct.h"
59 :     #include "../dct/idct.h"
60 :     #include "../quant/quant_mpeg4.h"
61 :     #include "../quant/quant_h263.h"
62 :     #include "../encoder.h"
63 :    
64 :     #define MIN(X, Y) ((X)<(Y)?(X):(Y))
65 :     #define MAX(X, Y) ((X)>(Y)?(X):(Y))
66 :    
67 :     #define TOOSMALL_LIMIT 1 /* skip blocks having a coefficient sum below this value */
68 :    
69 :     /* this isnt pretty, but its better than 20 ifdefs */
70 :    
71 :     void MBTransQuantIntra(const MBParam *pParam,
72 : h 69 MACROBLOCK * pMB,
73 : Isibaar 3 const uint32_t x_pos,
74 :     const uint32_t y_pos,
75 :     int16_t data[][64],
76 :     int16_t qcoeff[][64],
77 :     IMAGE * const pCurrent)
78 :    
79 :     {
80 :     const uint32_t stride = pParam->edged_width;
81 :     uint32_t i;
82 :     uint32_t iQuant = pParam->quant;
83 :     uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
84 :    
85 :     pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);
86 :     pU_Cur = pCurrent->u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
87 :     pV_Cur = pCurrent->v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
88 : h 69
89 :     start_timer();
90 :     transfer_8to16copy(data[0], pY_Cur, stride);
91 :     transfer_8to16copy(data[1], pY_Cur + 8, stride);
92 :     transfer_8to16copy(data[2], pY_Cur + 8 * stride, stride);
93 :     transfer_8to16copy(data[3], pY_Cur + 8 * stride + 8, stride);
94 :     transfer_8to16copy(data[4], pU_Cur, stride / 2);
95 :     transfer_8to16copy(data[5], pV_Cur, stride / 2);
96 :     stop_transfer_timer();
97 :    
98 :     start_timer();
99 :     pMB->field_dct = 0;
100 :     if (pParam->global_flags & XVID_INTERLACING)
101 :     {
102 :     pMB->field_dct = MBDecideFieldDCT(data);
103 :     }
104 :     stop_interlacing_timer();
105 :    
106 :     for(i = 0; i < 6; i++)
107 :     {
108 : Isibaar 3 uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
109 :    
110 :     start_timer();
111 :     fdct(data[i]);
112 :     stop_dct_timer();
113 :    
114 :     if (pParam->quant_type == H263_QUANT)
115 :     {
116 :     start_timer();
117 :     quant_intra(qcoeff[i], data[i], iQuant, iDcScaler);
118 :     stop_quant_timer();
119 :    
120 :     start_timer();
121 :     dequant_intra(data[i], qcoeff[i], iQuant, iDcScaler);
122 :     stop_iquant_timer();
123 :     }
124 :     else
125 :     {
126 :     start_timer();
127 :     quant4_intra(qcoeff[i], data[i], iQuant, iDcScaler);
128 :     stop_quant_timer();
129 :    
130 :     start_timer();
131 :     dequant4_intra(data[i], qcoeff[i], iQuant, iDcScaler);
132 :     stop_iquant_timer();
133 :     }
134 :    
135 :     start_timer();
136 :     idct(data[i]);
137 :     stop_idct_timer();
138 : h 69 }
139 : Isibaar 3
140 : h 69 start_timer();
141 :     if (pMB->field_dct)
142 :     {
143 :     MBFieldToFrame(data);
144 :     }
145 :     stop_interlacing_timer();
146 :    
147 :     start_timer();
148 :     transfer_16to8copy(pY_Cur, data[0], stride);
149 :     transfer_16to8copy(pY_Cur + 8, data[1], stride);
150 :     transfer_16to8copy(pY_Cur + 8 * stride, data[2], stride);
151 :     transfer_16to8copy(pY_Cur + 8 + 8 * stride, data[3], stride);
152 :     transfer_16to8copy(pU_Cur, data[4], stride / 2);
153 :     transfer_16to8copy(pV_Cur, data[5], stride / 2);
154 :     stop_transfer_timer();
155 : Isibaar 3 }
156 :    
157 :    
158 :     uint8_t MBTransQuantInter(const MBParam *pParam,
159 : h 69 MACROBLOCK * pMB,
160 : Isibaar 3 const uint32_t x_pos, const uint32_t y_pos,
161 :     int16_t data[][64],
162 :     int16_t qcoeff[][64],
163 :     IMAGE * const pCurrent)
164 :    
165 :     {
166 :     const uint32_t stride = pParam->edged_width;
167 : h 69 uint32_t i;
168 :     uint32_t iQuant = pParam->quant;
169 : Isibaar 3 uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
170 :     uint8_t cbp = 0;
171 :     uint32_t sum;
172 :    
173 :     pY_Cur = pCurrent->y + (y_pos << 4) * stride + (x_pos << 4);
174 :     pU_Cur = pCurrent->u + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
175 :     pV_Cur = pCurrent->v + (y_pos << 3) * (stride >> 1) + (x_pos << 3);
176 :    
177 : h 69 start_timer();
178 :     pMB->field_dct = 0;
179 :     if (pParam->global_flags & XVID_INTERLACING)
180 :     {
181 :     pMB->field_dct = MBDecideFieldDCT(data);
182 :     }
183 :     stop_interlacing_timer();
184 :    
185 :     for(i = 0; i < 6; i++)
186 :     {
187 : Isibaar 3 /*
188 :     no need to transfer 8->16-bit
189 :     (this is performed already in motion compensation)
190 :     */
191 :     start_timer();
192 :     fdct(data[i]);
193 :     stop_dct_timer();
194 :    
195 :     if (pParam->quant_type == 0)
196 :     {
197 :     start_timer();
198 :     sum = quant_inter(qcoeff[i], data[i], iQuant);
199 :     stop_quant_timer();
200 :     }
201 :     else
202 :     {
203 :     start_timer();
204 :     sum = quant4_inter(qcoeff[i], data[i], iQuant);
205 :     stop_quant_timer();
206 :     }
207 :    
208 :     if(sum >= TOOSMALL_LIMIT) { // skip block ?
209 :    
210 :     if (pParam->quant_type == H263_QUANT)
211 :     {
212 :     start_timer();
213 :     dequant_inter(data[i], qcoeff[i], iQuant);
214 :     stop_iquant_timer();
215 :     }
216 :     else
217 :     {
218 :     start_timer();
219 :     dequant4_inter(data[i], qcoeff[i], iQuant);
220 :     stop_iquant_timer();
221 :     }
222 :    
223 :     cbp |= 1 << (5 - i);
224 :    
225 :     start_timer();
226 :     idct(data[i]);
227 :     stop_idct_timer();
228 :     }
229 :     }
230 : h 69
231 :     start_timer();
232 :     if (pMB->field_dct)
233 :     {
234 :     MBFieldToFrame(data);
235 :     }
236 :     stop_interlacing_timer();
237 :    
238 :     start_timer();
239 :     if (cbp & 32)
240 :     transfer_16to8add(pY_Cur, data[0], stride);
241 :     if (cbp & 16)
242 :     transfer_16to8add(pY_Cur + 8, data[1], stride);
243 :     if (cbp & 8)
244 :     transfer_16to8add(pY_Cur + 8 * stride, data[2], stride);
245 :     if (cbp & 4)
246 :     transfer_16to8add(pY_Cur + 8 + 8 * stride, data[3], stride);
247 :     if (cbp & 2)
248 :     transfer_16to8add(pU_Cur, data[4], stride / 2);
249 :     if (cbp & 1)
250 :     transfer_16to8add(pV_Cur, data[5], stride / 2);
251 :     stop_transfer_timer();
252 :    
253 : Isibaar 3 return cbp;
254 :     }
255 : h 69
256 :    
257 :     /* if sum(diff between field lines) < sum(diff between frame lines), use field dct */
258 :    
259 :     #define ABS(X) (X)<0 ? -(X) : (X)
260 :    
261 :     uint32_t MBDecideFieldDCT(int16_t data[][64])
262 :     {
263 :     const uint8_t blocks[] = {0, 0, 0, 0, 2, 2, 2, 2};
264 :     const uint8_t lines[] = {0, 16, 32, 48, 0, 16, 32, 48};
265 :    
266 :     int frame = 0, field = 0;
267 :     int i, j;
268 :    
269 :     for (i=0 ; i<7 ; ++i)
270 :     {
271 :     for (j=0 ; j<8 ; ++j)
272 :     {
273 :     frame += ABS(data[0][(i+1)*8 + j] - data[0][i*8 + j]);
274 :     frame += ABS(data[1][(i+1)*8 + j] - data[1][i*8 + j]);
275 :     frame += ABS(data[2][(i+1)*8 + j] - data[2][i*8 + j]);
276 :     frame += ABS(data[3][(i+1)*8 + j] - data[3][i*8 + j]);
277 :    
278 :     field += ABS(data[blocks[i+1]][lines[i+1] + j] - data[blocks[i]][lines[i] + j]);
279 :     field += ABS(data[blocks[i+1]][lines[i+1] + 8 + j] - data[blocks[i]][lines[i] + 8 + j]);
280 :     field += ABS(data[blocks[i+1]+1][lines[i+1] + j] - data[blocks[i]+1][lines[i] + j]);
281 :     field += ABS(data[blocks[i+1]+1][lines[i+1] + 8 + j] - data[blocks[i]+1][lines[i] + 8 + j]);
282 :     }
283 :     }
284 :    
285 :     if (frame > field)
286 :     {
287 :     MBFrameToField(data);
288 :     }
289 :    
290 :     return (frame > field);
291 :     }
292 :    
293 :    
294 :     /* deinterlace Y blocks vertically */
295 :    
296 :     #define MOVLINE(X,Y) memcpy(X, Y, sizeof(tmp))
297 :     #define LINE(X,Y) &data[X][Y*8]
298 :    
299 :     void MBFrameToField(int16_t data[][64])
300 :     {
301 :     int16_t tmp[8];
302 :    
303 :     /* left blocks */
304 :    
305 :     // 1=2, 2=4, 4=8, 8=1
306 :     MOVLINE(tmp, LINE(0,1));
307 :     MOVLINE(LINE(0,1), LINE(0,2));
308 :     MOVLINE(LINE(0,2), LINE(0,4));
309 :     MOVLINE(LINE(0,4), LINE(2,0));
310 :     MOVLINE(LINE(2,0), tmp);
311 :    
312 :     // 3=6, 6=12, 12=9, 9=3
313 :     MOVLINE(tmp, LINE(0,3));
314 :     MOVLINE(LINE(0,3), LINE(0,6));
315 :     MOVLINE(LINE(0,6), LINE(2,4));
316 :     MOVLINE(LINE(2,4), LINE(2,1));
317 :     MOVLINE(LINE(2,1), tmp);
318 :    
319 :     // 5=10, 10=5
320 :     MOVLINE(tmp, LINE(0,5));
321 :     MOVLINE(LINE(0,5), LINE(2,2));
322 :     MOVLINE(LINE(2,2), tmp);
323 :    
324 :     // 7=14, 14=13, 13=11, 11=7
325 :     MOVLINE(tmp, LINE(0,7));
326 :     MOVLINE(LINE(0,7), LINE(2,6));
327 :     MOVLINE(LINE(2,6), LINE(2,5));
328 :     MOVLINE(LINE(2,5), LINE(2,3));
329 :     MOVLINE(LINE(2,3), tmp);
330 :    
331 :     /* right blocks */
332 :    
333 :     // 1=2, 2=4, 4=8, 8=1
334 :     MOVLINE(tmp, LINE(1,1));
335 :     MOVLINE(LINE(1,1), LINE(1,2));
336 :     MOVLINE(LINE(1,2), LINE(1,4));
337 :     MOVLINE(LINE(1,4), LINE(3,0));
338 :     MOVLINE(LINE(3,0), tmp);
339 :    
340 :     // 3=6, 6=12, 12=9, 9=3
341 :     MOVLINE(tmp, LINE(1,3));
342 :     MOVLINE(LINE(1,3), LINE(1,6));
343 :     MOVLINE(LINE(1,6), LINE(3,4));
344 :     MOVLINE(LINE(3,4), LINE(3,1));
345 :     MOVLINE(LINE(3,1), tmp);
346 :    
347 :     // 5=10, 10=5
348 :     MOVLINE(tmp, LINE(1,5));
349 :     MOVLINE(LINE(1,5), LINE(3,2));
350 :     MOVLINE(LINE(3,2), tmp);
351 :    
352 :     // 7=14, 14=13, 13=11, 11=7
353 :     MOVLINE(tmp, LINE(1,7));
354 :     MOVLINE(LINE(1,7), LINE(3,6));
355 :     MOVLINE(LINE(3,6), LINE(3,5));
356 :     MOVLINE(LINE(3,5), LINE(3,3));
357 :     MOVLINE(LINE(3,3), tmp);
358 :     }
359 :    
360 :    
361 :     /* interlace Y blocks vertically */
362 :    
363 :     void MBFieldToFrame(int16_t data[][64])
364 :     {
365 :     uint16_t tmp[8];
366 :    
367 :     /* left blocks */
368 :    
369 :     // 1=8, 8=4, 4=2, 2=1
370 :     MOVLINE(tmp, LINE(0,1));
371 :     MOVLINE(LINE(0,1), LINE(2,0));
372 :     MOVLINE(LINE(2,0), LINE(0,4));
373 :     MOVLINE(LINE(0,4), LINE(0,2));
374 :     MOVLINE(LINE(0,2), tmp);
375 :    
376 :     // 3=9, 9=12, 12=6, 6=3
377 :     MOVLINE(tmp, LINE(0,3));
378 :     MOVLINE(LINE(0,3), LINE(2,1));
379 :     MOVLINE(LINE(2,1), LINE(2,4));
380 :     MOVLINE(LINE(2,4), LINE(0,6));
381 :     MOVLINE(LINE(0,6), tmp);
382 :    
383 :     // 5=10, 10=5
384 :     MOVLINE(tmp, LINE(0,5));
385 :     MOVLINE(LINE(0,5), LINE(2,2));
386 :     MOVLINE(LINE(2,2), tmp);
387 :    
388 :     // 7=11, 11=13, 13=14, 14=7
389 :     MOVLINE(tmp, LINE(0,7));
390 :     MOVLINE(LINE(0,7), LINE(2,3));
391 :     MOVLINE(LINE(2,3), LINE(2,5));
392 :     MOVLINE(LINE(2,5), LINE(2,6));
393 :     MOVLINE(LINE(2,6), tmp);
394 :    
395 :     /* right blocks */
396 :    
397 :     // 1=8, 8=4, 4=2, 2=1
398 :     MOVLINE(tmp, LINE(1,1));
399 :     MOVLINE(LINE(1,1), LINE(3,0));
400 :     MOVLINE(LINE(3,0), LINE(1,4));
401 :     MOVLINE(LINE(1,4), LINE(1,2));
402 :     MOVLINE(LINE(1,2), tmp);
403 :    
404 :     // 3=9, 9=12, 12=6, 6=3
405 :     MOVLINE(tmp, LINE(1,3));
406 :     MOVLINE(LINE(1,3), LINE(3,1));
407 :     MOVLINE(LINE(3,1), LINE(3,4));
408 :     MOVLINE(LINE(3,4), LINE(1,6));
409 :     MOVLINE(LINE(1,6), tmp);
410 :    
411 :     // 5=10, 10=5
412 :     MOVLINE(tmp, LINE(1,5));
413 :     MOVLINE(LINE(1,5), LINE(3,2));
414 :     MOVLINE(LINE(3,2), tmp);
415 :    
416 :     // 7=11, 11=13, 13=14, 14=7
417 :     MOVLINE(tmp, LINE(1,7));
418 :     MOVLINE(LINE(1,7), LINE(3,3));
419 :     MOVLINE(LINE(3,3), LINE(3,5));
420 :     MOVLINE(LINE(3,5), LINE(3,6));
421 :     MOVLINE(LINE(3,6), tmp);
422 :     }

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