[cvs] / xvidcore / src / decoder.c Repository:
ViewVC logotype

Annotation of /xvidcore/src/decoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.25 - (view) (download)

1 : Isibaar 1.1 /**************************************************************************
2 :     *
3 : edgomez 1.12 * XVID MPEG-4 VIDEO CODEC
4 :     * - Decoder main module -
5 : Isibaar 1.1 *
6 : edgomez 1.12 * This program is an implementation of a part of one or more MPEG-4
7 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
8 :     * to use this software module in hardware or software products are
9 :     * advised that its use may infringe existing patents or copyrights, and
10 :     * any such use would be at such party's own risk. The original
11 :     * developer of this software module and his/her company, and subsequent
12 :     * editors and their companies, will have no liability for use of this
13 :     * software or modifications or derivatives thereof.
14 :     *
15 :     * This program is free software; you can redistribute it and/or modify
16 :     * it under the terms of the GNU General Public License as published by
17 :     * the Free Software Foundation; either version 2 of the License, or
18 :     * (at your option) any later version.
19 :     *
20 :     * This program is distributed in the hope that it will be useful,
21 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 :     * GNU General Public License for more details.
24 :     *
25 :     * You should have received a copy of the GNU General Public License
26 :     * along with this program; if not, write to the Free Software
27 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 : Isibaar 1.1 *
29 :     *************************************************************************/
30 :    
31 :     /**************************************************************************
32 :     *
33 : edgomez 1.12 * History:
34 : Isibaar 1.1 *
35 : suxen_drol 1.21 * 22.06.2002 added primative N_VOP support
36 :     * #define BFRAMES_DEC now enables Minchenm's bframe decoder
37 : chenm001 1.17 * 08.05.2002 add low_delay support for B_VOP decode
38 :     * MinChen <chenm001@163.com>
39 :     * 05.05.2002 fix some B-frame decode problem
40 : chenm001 1.14 * 02.05.2002 add B-frame decode support(have some problem);
41 :     * MinChen <chenm001@163.com>
42 : chenm001 1.11 * 22.04.2002 add some B-frame decode support; chenm001 <chenm001@163.com>
43 : h 1.8 * 29.03.2002 interlacing fix - compensated block wasn't being used when
44 :     * reconstructing blocks, thus artifacts
45 :     * interlacing speedup - used transfers to re-interlace
46 :     * interlaced decoding should be as fast as progressive now
47 : h 1.5 * 26.03.2002 interlacing support - moved transfers outside decode loop
48 : edgomez 1.12 * 26.12.2001 decoder_mbinter: dequant/idct moved within if(coded) block
49 :     * 22.12.2001 lock based interpolation
50 :     * 01.12.2001 inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
51 :     *
52 : chenm001 1.25 * $Id: decoder.c,v 1.21 2002/06/22 07:23:09 suxen_drol Exp $
53 : Isibaar 1.1 *
54 :     *************************************************************************/
55 :    
56 :     #include <stdlib.h>
57 : edgomez 1.12 #include <string.h>
58 : Isibaar 1.1
59 :     #include "xvid.h"
60 :     #include "portab.h"
61 :    
62 :     #include "decoder.h"
63 :     #include "bitstream/bitstream.h"
64 :     #include "bitstream/mbcoding.h"
65 :    
66 :     #include "quant/quant_h263.h"
67 :     #include "quant/quant_mpeg4.h"
68 :     #include "dct/idct.h"
69 :     #include "dct/fdct.h"
70 :     #include "utils/mem_transfer.h"
71 :     #include "image/interpolate8x8.h"
72 :    
73 :     #include "bitstream/mbcoding.h"
74 :     #include "prediction/mbprediction.h"
75 :     #include "utils/timer.h"
76 :     #include "utils/emms.h"
77 :    
78 :     #include "image/image.h"
79 :     #include "image/colorspace.h"
80 : Isibaar 1.3 #include "utils/mem_align.h"
81 : Isibaar 1.1
82 : edgomez 1.19 int
83 :     decoder_create(XVID_DEC_PARAM * param)
84 : Isibaar 1.1 {
85 : edgomez 1.19 DECODER *dec;
86 : Isibaar 1.1
87 : Isibaar 1.4 dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
88 : edgomez 1.19 if (dec == NULL) {
89 : Isibaar 1.1 return XVID_ERR_MEMORY;
90 :     }
91 :     param->handle = dec;
92 :    
93 :     dec->width = param->width;
94 :     dec->height = param->height;
95 :    
96 :     dec->mb_width = (dec->width + 15) / 16;
97 :     dec->mb_height = (dec->height + 15) / 16;
98 :    
99 :     dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;
100 :     dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;
101 : Isibaar 1.20 dec->low_delay = 0;
102 : edgomez 1.19
103 :     if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) {
104 : Isibaar 1.3 xvid_free(dec);
105 : Isibaar 1.1 return XVID_ERR_MEMORY;
106 :     }
107 :    
108 : edgomez 1.19 if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height)) {
109 : Isibaar 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
110 : Isibaar 1.3 xvid_free(dec);
111 : Isibaar 1.1 return XVID_ERR_MEMORY;
112 :     }
113 : chenm001 1.11 // add by chenm001 <chenm001@163.com>
114 :     // for support B-frame to reference last 2 frame
115 : edgomez 1.19 if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {
116 : chenm001 1.11 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
117 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
118 :     xvid_free(dec);
119 :     return XVID_ERR_MEMORY;
120 :     }
121 : edgomez 1.19 if (image_create(&dec->refn[2], dec->edged_width, dec->edged_height)) {
122 : chenm001 1.14 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
123 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
124 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
125 :     xvid_free(dec);
126 :     return XVID_ERR_MEMORY;
127 :     }
128 : Isibaar 1.1
129 : edgomez 1.19 dec->mbs =
130 :     xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
131 :     CACHE_LINE);
132 :     if (dec->mbs == NULL) {
133 : Isibaar 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
134 : chenm001 1.14 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
135 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
136 :     image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
137 :     xvid_free(dec);
138 :     return XVID_ERR_MEMORY;
139 :     }
140 : Isibaar 1.20
141 :     memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
142 :    
143 : chenm001 1.14 // add by chenm001 <chenm001@163.com>
144 :     // for skip MB flag
145 : edgomez 1.19 dec->last_mbs =
146 :     xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
147 :     CACHE_LINE);
148 :     if (dec->last_mbs == NULL) {
149 : chenm001 1.14 xvid_free(dec->mbs);
150 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
151 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
152 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
153 :     image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
154 : Isibaar 1.3 xvid_free(dec);
155 : Isibaar 1.1 return XVID_ERR_MEMORY;
156 :     }
157 : Isibaar 1.20
158 :     memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
159 : Isibaar 1.1
160 :     init_timer();
161 :    
162 : chenm001 1.14 // add by chenm001 <chenm001@163.com>
163 :     // for support B-frame to save reference frame's time
164 :     dec->frames = -1;
165 :     dec->time = dec->time_base = dec->last_time_base = 0;
166 : edgomez 1.19
167 : Isibaar 1.1 return XVID_ERR_OK;
168 :     }
169 :    
170 :    
171 : chenm001 1.25
172 :     /* ****************************************************************
173 :     NIC 28.06.2002
174 :     riscritta la 'decoder_create' per cambiarne l'interfaccia e poterla
175 :     usare nella dll caricata dall'IM1 player
176 :     IM1_decoder_create(XVID_DEC_PARAM * param,XVID_DEC_FRAME * frame)
177 :     **************************************************************** */
178 :     //XVID_DEC_FRAME * frame
179 :    
180 :     int
181 :     IM1_decoder_create(XVID_DEC_PARAM * param,XVID_DEC_FRAME * frame)
182 :     {
183 :     DECODER *dec;
184 :     Bitstream bs;
185 :     uint32_t rounding;
186 :     uint32_t quant;
187 :     uint32_t fcode_forward;
188 :     uint32_t fcode_backward;
189 :     uint32_t intra_dc_threshold;
190 :    
191 :     dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
192 :     if (dec == NULL) {
193 :     return XVID_ERR_MEMORY;
194 :     }
195 :     param->handle = dec;
196 :    
197 :    
198 :     BitstreamInit(&bs, frame->bitstream, frame->length);//NIC
199 :    
200 :     //NIC
201 :     BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward,
202 :     &fcode_backward, &intra_dc_threshold);
203 :    
204 :    
205 :     param->width = dec->width; //NIC added
206 :     param->height = dec->height; //NIC added
207 :     //dec->width = param->width; //NIC commentate
208 :     //dec->height = param->height; //NIC commentate
209 :    
210 :     dec->mb_width = (dec->width + 15) / 16;
211 :     dec->mb_height = (dec->height + 15) / 16;
212 :    
213 :     dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;
214 :     dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;
215 :     dec->low_delay = 0;
216 :    
217 :     if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) {
218 :     xvid_free(dec);
219 :     return XVID_ERR_MEMORY;
220 :     }
221 :    
222 :     if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height)) {
223 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
224 :     xvid_free(dec);
225 :     return XVID_ERR_MEMORY;
226 :     }
227 :     // add by chenm001 <chenm001@163.com>
228 :     // for support B-frame to reference last 2 frame
229 :     if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {
230 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
231 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
232 :     xvid_free(dec);
233 :     return XVID_ERR_MEMORY;
234 :     }
235 :     if (image_create(&dec->refn[2], dec->edged_width, dec->edged_height)) {
236 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
237 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
238 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
239 :     xvid_free(dec);
240 :     return XVID_ERR_MEMORY;
241 :     }
242 :    
243 :     dec->mbs =
244 :     xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
245 :     CACHE_LINE);
246 :     if (dec->mbs == NULL) {
247 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
248 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
249 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
250 :     image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
251 :     xvid_free(dec);
252 :     return XVID_ERR_MEMORY;
253 :     }
254 :    
255 :     memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
256 :    
257 :     // add by chenm001 <chenm001@163.com>
258 :     // for skip MB flag
259 :     dec->last_mbs =
260 :     xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
261 :     CACHE_LINE);
262 :     if (dec->last_mbs == NULL) {
263 :     xvid_free(dec->mbs);
264 :     image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
265 :     image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
266 :     image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
267 :     image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
268 :     xvid_free(dec);
269 :     return XVID_ERR_MEMORY;
270 :     }
271 :    
272 :     memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
273 :    
274 :     init_timer();
275 :    
276 :     // add by chenm001 <chenm001@163.com>
277 :     // for support B-frame to save reference frame's time
278 :     dec->frames = -1;
279 :     dec->time = dec->time_base = dec->last_time_base = 0;
280 :    
281 :     return XVID_ERR_OK;
282 :     }
283 :     /* ****************************************************************
284 :     END NIC
285 :     **************************************************************** */
286 :    
287 : edgomez 1.19 int
288 :     decoder_destroy(DECODER * dec)
289 : Isibaar 1.1 {
290 : chenm001 1.14 xvid_free(dec->last_mbs);
291 : Isibaar 1.3 xvid_free(dec->mbs);
292 : chenm001 1.11 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
293 : chenm001 1.14 image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
294 :     image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
295 : Isibaar 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
296 : Isibaar 1.3 xvid_free(dec);
297 : Isibaar 1.1
298 :     write_timer();
299 :     return XVID_ERR_OK;
300 :     }
301 :    
302 :    
303 :    
304 : edgomez 1.19 static const int32_t dquant_table[4] = {
305 : Isibaar 1.1 -1, -2, 1, 2
306 :     };
307 :    
308 :    
309 : chenm001 1.14
310 :    
311 : Isibaar 1.1 // decode an intra macroblock
312 :    
313 : edgomez 1.19 void
314 :     decoder_mbintra(DECODER * dec,
315 :     MACROBLOCK * pMB,
316 :     const uint32_t x_pos,
317 :     const uint32_t y_pos,
318 :     const uint32_t acpred_flag,
319 :     const uint32_t cbp,
320 :     Bitstream * bs,
321 :     const uint32_t quant,
322 : chenm001 1.25 const uint32_t intra_dc_threshold)
323 : Isibaar 1.1 {
324 : edgomez 1.7
325 :     DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
326 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
327 : edgomez 1.7
328 : h 1.8 uint32_t stride = dec->edged_width;
329 :     uint32_t stride2 = stride / 2;
330 :     uint32_t next_block = stride * 8;
331 : h 1.5 uint32_t i;
332 :     uint32_t iQuant = pMB->quant;
333 :     uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
334 :    
335 : edgomez 1.7 pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
336 : h 1.8 pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
337 :     pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
338 : edgomez 1.7
339 : edgomez 1.19 memset(block, 0, 6 * 64 * sizeof(int16_t)); // clear
340 : h 1.5
341 : edgomez 1.19 for (i = 0; i < 6; i++) {
342 : h 1.5 uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
343 : Isibaar 1.1 int16_t predictors[8];
344 :     int start_coeff;
345 :    
346 :     start_timer();
347 : edgomez 1.19 predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, &block[i * 64],
348 : chenm001 1.25 iQuant, iDcScaler, predictors);
349 : edgomez 1.19 if (!acpred_flag) {
350 : h 1.5 pMB->acpred_directions[i] = 0;
351 : Isibaar 1.1 }
352 :     stop_prediction_timer();
353 :    
354 : edgomez 1.19 if (quant < intra_dc_threshold) {
355 : Isibaar 1.1 int dc_size;
356 :     int dc_dif;
357 :    
358 : edgomez 1.19 dc_size = i < 4 ? get_dc_size_lum(bs) : get_dc_size_chrom(bs);
359 :     dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0;
360 : Isibaar 1.1
361 : edgomez 1.19 if (dc_size > 8) {
362 :     BitstreamSkip(bs, 1); // marker
363 : Isibaar 1.1 }
364 : edgomez 1.19
365 :     block[i * 64 + 0] = dc_dif;
366 : Isibaar 1.1 start_coeff = 1;
367 : edgomez 1.19 } else {
368 : Isibaar 1.1 start_coeff = 0;
369 :     }
370 :    
371 :     start_timer();
372 : edgomez 1.19 if (cbp & (1 << (5 - i))) // coded
373 : Isibaar 1.1 {
374 : edgomez 1.19 get_intra_block(bs, &block[i * 64], pMB->acpred_directions[i],
375 :     start_coeff);
376 : Isibaar 1.1 }
377 :     stop_coding_timer();
378 :    
379 :     start_timer();
380 : edgomez 1.19 add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors);
381 : Isibaar 1.1 stop_prediction_timer();
382 :    
383 :     start_timer();
384 : edgomez 1.19 if (dec->quant_type == 0) {
385 :     dequant_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler);
386 :     } else {
387 :     dequant4_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler);
388 : Isibaar 1.1 }
389 :     stop_iquant_timer();
390 :    
391 :     start_timer();
392 : edgomez 1.19 idct(&data[i * 64]);
393 : Isibaar 1.1 stop_idct_timer();
394 : h 1.5 }
395 : Isibaar 1.1
396 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
397 : h 1.8 next_block = stride;
398 :     stride *= 2;
399 : Isibaar 1.1 }
400 : h 1.5
401 :     start_timer();
402 : edgomez 1.19 transfer_16to8copy(pY_Cur, &data[0 * 64], stride);
403 :     transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);
404 :     transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);
405 :     transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);
406 :     transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);
407 :     transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);
408 : h 1.5 stop_transfer_timer();
409 : Isibaar 1.1 }
410 :    
411 :    
412 :    
413 :    
414 :    
415 :     #define SIGN(X) (((X)>0)?1:-1)
416 :     #define ABS(X) (((X)>0)?(X):-(X))
417 :     static const uint32_t roundtab[16] =
418 : edgomez 1.19 { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };
419 : Isibaar 1.1
420 :    
421 :     // decode an inter macroblock
422 :    
423 : edgomez 1.19 void
424 :     decoder_mbinter(DECODER * dec,
425 :     const MACROBLOCK * pMB,
426 :     const uint32_t x_pos,
427 :     const uint32_t y_pos,
428 :     const uint32_t acpred_flag,
429 :     const uint32_t cbp,
430 :     Bitstream * bs,
431 :     const uint32_t quant,
432 :     const uint32_t rounding)
433 : Isibaar 1.1 {
434 : edgomez 1.7
435 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
436 : edgomez 1.7 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
437 : h 1.5
438 : h 1.8 uint32_t stride = dec->edged_width;
439 :     uint32_t stride2 = stride / 2;
440 :     uint32_t next_block = stride * 8;
441 : edgomez 1.7 uint32_t i;
442 :     uint32_t iQuant = pMB->quant;
443 : h 1.5 uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
444 : Isibaar 1.1 int uv_dx, uv_dy;
445 :    
446 : edgomez 1.7 pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
447 : h 1.8 pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
448 :     pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
449 : h 1.5
450 : edgomez 1.19 if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
451 : h 1.5 uv_dx = pMB->mvs[0].x;
452 :     uv_dy = pMB->mvs[0].y;
453 : Isibaar 1.1
454 :     uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
455 :     uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
456 : edgomez 1.19 } else {
457 : Isibaar 1.1 int sum;
458 : edgomez 1.19
459 : h 1.5 sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
460 : edgomez 1.19 uv_dx =
461 :     (sum ==
462 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
463 :     (ABS(sum) / 16) * 2));
464 : Isibaar 1.1
465 : h 1.5 sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
466 : edgomez 1.19 uv_dy =
467 :     (sum ==
468 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
469 :     (ABS(sum) / 16) * 2));
470 : Isibaar 1.1 }
471 :    
472 :     start_timer();
473 : edgomez 1.19 interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16 * x_pos, 16 * y_pos,
474 :     pMB->mvs[0].x, pMB->mvs[0].y, stride, rounding);
475 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16 * x_pos + 8,
476 :     16 * y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride,
477 :     rounding);
478 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16 * x_pos,
479 :     16 * y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride,
480 :     rounding);
481 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16 * x_pos + 8,
482 :     16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,
483 :     rounding);
484 :     interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,
485 :     uv_dx, uv_dy, stride2, rounding);
486 :     interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,
487 :     uv_dx, uv_dy, stride2, rounding);
488 : Isibaar 1.1 stop_comp_timer();
489 :    
490 : edgomez 1.19 for (i = 0; i < 6; i++) {
491 :     if (cbp & (1 << (5 - i))) // coded
492 : Isibaar 1.1 {
493 : edgomez 1.19 memset(&block[i * 64], 0, 64 * sizeof(int16_t)); // clear
494 : Isibaar 1.1
495 :     start_timer();
496 : edgomez 1.19 get_inter_block(bs, &block[i * 64]);
497 : Isibaar 1.1 stop_coding_timer();
498 :    
499 :     start_timer();
500 : edgomez 1.19 if (dec->quant_type == 0) {
501 :     dequant_inter(&data[i * 64], &block[i * 64], iQuant);
502 :     } else {
503 :     dequant4_inter(&data[i * 64], &block[i * 64], iQuant);
504 : Isibaar 1.1 }
505 :     stop_iquant_timer();
506 :    
507 :     start_timer();
508 : edgomez 1.19 idct(&data[i * 64]);
509 : Isibaar 1.1 stop_idct_timer();
510 : h 1.5 }
511 :     }
512 : Isibaar 1.1
513 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
514 : h 1.8 next_block = stride;
515 :     stride *= 2;
516 : Isibaar 1.1 }
517 : h 1.5
518 :     start_timer();
519 :     if (cbp & 32)
520 : edgomez 1.19 transfer_16to8add(pY_Cur, &data[0 * 64], stride);
521 : h 1.5 if (cbp & 16)
522 : edgomez 1.19 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);
523 : h 1.5 if (cbp & 8)
524 : edgomez 1.19 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);
525 : h 1.5 if (cbp & 4)
526 : edgomez 1.19 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);
527 : h 1.5 if (cbp & 2)
528 : edgomez 1.19 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
529 : h 1.5 if (cbp & 1)
530 : edgomez 1.19 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
531 : h 1.5 stop_transfer_timer();
532 : Isibaar 1.1 }
533 :    
534 :    
535 : edgomez 1.19 void
536 :     decoder_iframe(DECODER * dec,
537 :     Bitstream * bs,
538 :     int quant,
539 :     int intra_dc_threshold)
540 : Isibaar 1.1 {
541 : chenm001 1.25
542 : suxen_drol 1.22 uint32_t x, y;
543 : edgomez 1.7
544 : edgomez 1.19 for (y = 0; y < dec->mb_height; y++) {
545 :     for (x = 0; x < dec->mb_width; x++) {
546 : chenm001 1.25 MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
547 :    
548 : Isibaar 1.1 uint32_t mcbpc;
549 :     uint32_t cbpc;
550 :     uint32_t acpred_flag;
551 :     uint32_t cbpy;
552 :     uint32_t cbp;
553 :    
554 :     mcbpc = get_mcbpc_intra(bs);
555 :     mb->mode = mcbpc & 7;
556 :     cbpc = (mcbpc >> 4);
557 :    
558 :     acpred_flag = BitstreamGetBit(bs);
559 :    
560 : chenm001 1.25 if (mb->mode == MODE_STUFFING) {
561 :     DEBUG("-- STUFFING ?");
562 :     continue;
563 :     }
564 :    
565 : Isibaar 1.1 cbpy = get_cbpy(bs, 1);
566 :     cbp = (cbpy << 2) | cbpc;
567 :    
568 : edgomez 1.19 if (mb->mode == MODE_INTRA_Q) {
569 :     quant += dquant_table[BitstreamGetBits(bs, 2)];
570 :     if (quant > 31) {
571 : Isibaar 1.1 quant = 31;
572 : edgomez 1.19 } else if (quant < 1) {
573 : Isibaar 1.1 quant = 1;
574 :     }
575 :     }
576 :     mb->quant = quant;
577 : h 1.5
578 : edgomez 1.19 if (dec->interlacing) {
579 : h 1.5 mb->field_dct = BitstreamGetBit(bs);
580 :     DEBUG1("deci: field_dct: ", mb->field_dct);
581 :     }
582 : Isibaar 1.1
583 : edgomez 1.19 decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
584 : chenm001 1.25 intra_dc_threshold);
585 : Isibaar 1.1 }
586 :     }
587 : edgomez 1.7
588 : Isibaar 1.1 }
589 :    
590 :    
591 : edgomez 1.19 void
592 :     get_motion_vector(DECODER * dec,
593 :     Bitstream * bs,
594 :     int x,
595 :     int y,
596 :     int k,
597 :     VECTOR * mv,
598 : chenm001 1.25 int fcode)
599 : Isibaar 1.1 {
600 : edgomez 1.7
601 : Isibaar 1.1 int scale_fac = 1 << (fcode - 1);
602 :     int high = (32 * scale_fac) - 1;
603 :     int low = ((-32) * scale_fac);
604 :     int range = (64 * scale_fac);
605 :    
606 : chenm001 1.25 VECTOR pmv[4];
607 :     int32_t psad[4];
608 :    
609 : Isibaar 1.1 int mv_x, mv_y;
610 : chenm001 1.25 int pmv_x, pmv_y;
611 : Isibaar 1.1
612 : chenm001 1.25
613 :     get_pmvdata(dec->mbs, x, y, dec->mb_width, k, pmv, psad);
614 :    
615 :     pmv_x = pmv[0].x;
616 :     pmv_y = pmv[0].y;
617 : Isibaar 1.1
618 :     mv_x = get_mv(bs, fcode);
619 :     mv_y = get_mv(bs, fcode);
620 : edgomez 1.19
621 : chenm001 1.25 mv_x += pmv_x;
622 :     mv_y += pmv_y;
623 : Isibaar 1.1
624 : edgomez 1.19 if (mv_x < low) {
625 : Isibaar 1.1 mv_x += range;
626 : edgomez 1.19 } else if (mv_x > high) {
627 : Isibaar 1.1 mv_x -= range;
628 :     }
629 :    
630 : edgomez 1.19 if (mv_y < low) {
631 : Isibaar 1.1 mv_y += range;
632 : edgomez 1.19 } else if (mv_y > high) {
633 : Isibaar 1.1 mv_y -= range;
634 :     }
635 :    
636 :     mv->x = mv_x;
637 :     mv->y = mv_y;
638 :    
639 :     }
640 :    
641 :    
642 : edgomez 1.19 void
643 :     decoder_pframe(DECODER * dec,
644 :     Bitstream * bs,
645 :     int rounding,
646 :     int quant,
647 :     int fcode,
648 :     int intra_dc_threshold)
649 : Isibaar 1.1 {
650 : edgomez 1.7
651 : Isibaar 1.1 uint32_t x, y;
652 :    
653 :     start_timer();
654 : edgomez 1.19 image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
655 :     dec->width, dec->height, dec->interlacing);
656 : Isibaar 1.1 stop_edges_timer();
657 :    
658 : edgomez 1.19 for (y = 0; y < dec->mb_height; y++) {
659 :     for (x = 0; x < dec->mb_width; x++) {
660 : chenm001 1.25 MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
661 : suxen_drol 1.23
662 : edgomez 1.19 //if (!(dec->mb_skip[y*dec->mb_width + x]=BitstreamGetBit(bs))) // not_coded
663 :     if (!(BitstreamGetBit(bs))) // not_coded
664 : Isibaar 1.1 {
665 :     uint32_t mcbpc;
666 :     uint32_t cbpc;
667 :     uint32_t acpred_flag;
668 :     uint32_t cbpy;
669 :     uint32_t cbp;
670 :     uint32_t intra;
671 :    
672 :     mcbpc = get_mcbpc_inter(bs);
673 :     mb->mode = mcbpc & 7;
674 :     cbpc = (mcbpc >> 4);
675 : edgomez 1.2 acpred_flag = 0;
676 : Isibaar 1.1
677 :     intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);
678 : edgomez 1.19
679 :     if (intra) {
680 : Isibaar 1.1 acpred_flag = BitstreamGetBit(bs);
681 :     }
682 :    
683 : chenm001 1.25 if (mb->mode == MODE_STUFFING) {
684 :     DEBUG("-- STUFFING ?");
685 :     continue;
686 :     }
687 :    
688 : Isibaar 1.1 cbpy = get_cbpy(bs, intra);
689 :     cbp = (cbpy << 2) | cbpc;
690 :    
691 : edgomez 1.19 if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {
692 : chenm001 1.25 quant += dquant_table[BitstreamGetBits(bs, 2)];
693 : edgomez 1.19 if (quant > 31) {
694 : Isibaar 1.1 quant = 31;
695 : chenm001 1.25 } else if (mb->quant < 1) {
696 : Isibaar 1.1 quant = 1;
697 :     }
698 :     }
699 :     mb->quant = quant;
700 : h 1.5
701 : edgomez 1.19 if (dec->interlacing) {
702 : h 1.5 mb->field_dct = BitstreamGetBit(bs);
703 :     DEBUG1("decp: field_dct: ", mb->field_dct);
704 :    
705 : edgomez 1.19 if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
706 : h 1.5 mb->field_pred = BitstreamGetBit(bs);
707 :     DEBUG1("decp: field_pred: ", mb->field_pred);
708 :    
709 : edgomez 1.19 if (mb->field_pred) {
710 : h 1.5 mb->field_for_top = BitstreamGetBit(bs);
711 :     DEBUG1("decp: field_for_top: ", mb->field_for_top);
712 :     mb->field_for_bot = BitstreamGetBit(bs);
713 :     DEBUG1("decp: field_for_bot: ", mb->field_for_bot);
714 :     }
715 :     }
716 :     }
717 :    
718 : edgomez 1.19 if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
719 :     if (dec->interlacing && mb->field_pred) {
720 :     get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],
721 : chenm001 1.25 fcode);
722 : edgomez 1.19 get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1],
723 : chenm001 1.25 fcode);
724 : edgomez 1.19 } else {
725 :     get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],
726 : chenm001 1.25 fcode);
727 : edgomez 1.19 mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
728 :     mb->mvs[0].x;
729 :     mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
730 :     mb->mvs[0].y;
731 : h 1.5 }
732 : edgomez 1.19 } else if (mb->mode ==
733 :     MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */ ) {
734 : chenm001 1.25 get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
735 :     get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode);
736 :     get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode);
737 :     get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode);
738 : edgomez 1.19 } else // MODE_INTRA, MODE_INTRA_Q
739 : Isibaar 1.1 {
740 : edgomez 1.19 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
741 :     0;
742 :     mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
743 :     0;
744 :     decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
745 : chenm001 1.25 intra_dc_threshold);
746 : Isibaar 1.1 continue;
747 :     }
748 :    
749 : edgomez 1.19 decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant,
750 :     rounding);
751 :     } else // not coded
752 : Isibaar 1.1 {
753 : chenm001 1.15 //DEBUG2("P-frame MB at (X,Y)=",x,y);
754 : chenm001 1.14 mb->mode = MODE_NOT_CODED;
755 : Isibaar 1.1 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
756 :     mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
757 : edgomez 1.19
758 : Isibaar 1.1 // copy macroblock directly from ref to cur
759 :    
760 :     start_timer();
761 :    
762 : edgomez 1.19 transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +
763 :     (16 * x),
764 :     dec->refn[0].y + (16 * y) * dec->edged_width +
765 :     (16 * x), dec->edged_width);
766 :    
767 :     transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +
768 :     (16 * x + 8),
769 :     dec->refn[0].y + (16 * y) * dec->edged_width +
770 :     (16 * x + 8), dec->edged_width);
771 :    
772 :     transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +
773 :     (16 * x),
774 :     dec->refn[0].y + (16 * y +
775 :     8) * dec->edged_width +
776 :     (16 * x), dec->edged_width);
777 :    
778 :     transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +
779 :     (16 * x + 8),
780 :     dec->refn[0].y + (16 * y +
781 :     8) * dec->edged_width +
782 :     (16 * x + 8), dec->edged_width);
783 :    
784 :     transfer8x8_copy(dec->cur.u + (8 * y) * dec->edged_width / 2 +
785 :     (8 * x),
786 :     dec->refn[0].u +
787 :     (8 * y) * dec->edged_width / 2 + (8 * x),
788 :     dec->edged_width / 2);
789 :    
790 :     transfer8x8_copy(dec->cur.v + (8 * y) * dec->edged_width / 2 +
791 :     (8 * x),
792 :     dec->refn[0].v +
793 :     (8 * y) * dec->edged_width / 2 + (8 * x),
794 :     dec->edged_width / 2);
795 : Isibaar 1.1
796 :     stop_transfer_timer();
797 :     }
798 :     }
799 :     }
800 :     }
801 :    
802 : chenm001 1.14
803 :     // add by MinChen <chenm001@163.com>
804 :     // decode B-frame motion vector
805 : edgomez 1.19 void
806 :     get_b_motion_vector(DECODER * dec,
807 :     Bitstream * bs,
808 :     int x,
809 :     int y,
810 :     VECTOR * mv,
811 :     int fcode,
812 :     const VECTOR pmv)
813 : chenm001 1.14 {
814 :     int scale_fac = 1 << (fcode - 1);
815 :     int high = (32 * scale_fac) - 1;
816 :     int low = ((-32) * scale_fac);
817 :     int range = (64 * scale_fac);
818 :    
819 :     int mv_x, mv_y;
820 :     int pmv_x, pmv_y;
821 :    
822 :     pmv_x = pmv.x;
823 :     pmv_y = pmv.y;
824 :    
825 :     mv_x = get_mv(bs, fcode);
826 :     mv_y = get_mv(bs, fcode);
827 : edgomez 1.19
828 : chenm001 1.14 mv_x += pmv_x;
829 :     mv_y += pmv_y;
830 :    
831 : edgomez 1.19 if (mv_x < low) {
832 : chenm001 1.14 mv_x += range;
833 : edgomez 1.19 } else if (mv_x > high) {
834 : chenm001 1.14 mv_x -= range;
835 :     }
836 :    
837 : edgomez 1.19 if (mv_y < low) {
838 : chenm001 1.14 mv_y += range;
839 : edgomez 1.19 } else if (mv_y > high) {
840 : chenm001 1.14 mv_y -= range;
841 :     }
842 :    
843 :     mv->x = mv_x;
844 :     mv->y = mv_y;
845 :     }
846 :    
847 :    
848 :     // add by MinChen <chenm001@163.com>
849 :     // decode an B-frame forward & backward inter macroblock
850 : edgomez 1.19 void
851 :     decoder_bf_mbinter(DECODER * dec,
852 :     const MACROBLOCK * pMB,
853 :     const uint32_t x_pos,
854 :     const uint32_t y_pos,
855 :     const uint32_t cbp,
856 :     Bitstream * bs,
857 :     const uint32_t quant,
858 :     const uint8_t ref)
859 : chenm001 1.14 {
860 :    
861 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
862 : chenm001 1.14 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
863 :    
864 :     uint32_t stride = dec->edged_width;
865 :     uint32_t stride2 = stride / 2;
866 :     uint32_t next_block = stride * 8;
867 :     uint32_t i;
868 :     uint32_t iQuant = pMB->quant;
869 :     uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
870 :     int uv_dx, uv_dy;
871 :    
872 :     pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
873 :     pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
874 :     pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
875 :    
876 : edgomez 1.19 if (!(pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)) {
877 : chenm001 1.14 uv_dx = pMB->mvs[0].x;
878 :     uv_dy = pMB->mvs[0].y;
879 :    
880 :     uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
881 :     uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
882 : edgomez 1.19 } else {
883 : chenm001 1.14 int sum;
884 : edgomez 1.19
885 : chenm001 1.14 sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
886 : edgomez 1.19 uv_dx =
887 :     (sum ==
888 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
889 :     (ABS(sum) / 16) * 2));
890 : chenm001 1.14
891 :     sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
892 : edgomez 1.19 uv_dy =
893 :     (sum ==
894 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
895 :     (ABS(sum) / 16) * 2));
896 : chenm001 1.14 }
897 :    
898 :     start_timer();
899 : edgomez 1.19 interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos, 16 * y_pos,
900 :     pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
901 :     interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos + 8,
902 :     16 * y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
903 :     interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos,
904 :     16 * y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride,
905 :     0);
906 :     interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos + 8,
907 :     16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,
908 :     0);
909 :     interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,
910 :     uv_dx, uv_dy, stride2, 0);
911 :     interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,
912 :     uv_dx, uv_dy, stride2, 0);
913 : chenm001 1.14 stop_comp_timer();
914 :    
915 : edgomez 1.19 for (i = 0; i < 6; i++) {
916 :     if (cbp & (1 << (5 - i))) // coded
917 : chenm001 1.14 {
918 : edgomez 1.19 memset(&block[i * 64], 0, 64 * sizeof(int16_t)); // clear
919 : chenm001 1.14
920 :     start_timer();
921 : edgomez 1.19 get_inter_block(bs, &block[i * 64]);
922 : chenm001 1.14 stop_coding_timer();
923 :    
924 :     start_timer();
925 : edgomez 1.19 if (dec->quant_type == 0) {
926 :     dequant_inter(&data[i * 64], &block[i * 64], iQuant);
927 :     } else {
928 :     dequant4_inter(&data[i * 64], &block[i * 64], iQuant);
929 : chenm001 1.14 }
930 :     stop_iquant_timer();
931 :    
932 :     start_timer();
933 : edgomez 1.19 idct(&data[i * 64]);
934 : chenm001 1.14 stop_idct_timer();
935 :     }
936 :     }
937 :    
938 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
939 : chenm001 1.14 next_block = stride;
940 :     stride *= 2;
941 :     }
942 :    
943 :     start_timer();
944 :     if (cbp & 32)
945 : edgomez 1.19 transfer_16to8add(pY_Cur, &data[0 * 64], stride);
946 : chenm001 1.14 if (cbp & 16)
947 : edgomez 1.19 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);
948 : chenm001 1.14 if (cbp & 8)
949 : edgomez 1.19 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);
950 : chenm001 1.14 if (cbp & 4)
951 : edgomez 1.19 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);
952 : chenm001 1.14 if (cbp & 2)
953 : edgomez 1.19 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
954 : chenm001 1.14 if (cbp & 1)
955 : edgomez 1.19 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
956 : chenm001 1.14 stop_transfer_timer();
957 :     }
958 :    
959 :    
960 :     // add by MinChen <chenm001@163.com>
961 :     // decode an B-frame direct & inter macroblock
962 : edgomez 1.19 void
963 :     decoder_bf_interpolate_mbinter(DECODER * dec,
964 :     IMAGE forward,
965 :     IMAGE backward,
966 :     const MACROBLOCK * pMB,
967 :     const uint32_t x_pos,
968 :     const uint32_t y_pos,
969 :     const uint32_t cbp,
970 :     Bitstream * bs)
971 : chenm001 1.14 {
972 :    
973 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
974 : chenm001 1.14 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
975 :    
976 : edgomez 1.19 uint32_t stride = dec->edged_width;
977 :     uint32_t stride2 = stride / 2;
978 :     uint32_t next_block = stride * 8;
979 :     uint32_t iQuant = pMB->quant;
980 :     int uv_dx, uv_dy;
981 :     int b_uv_dx, b_uv_dy;
982 :     uint32_t i;
983 :     uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
984 : chenm001 1.15
985 :     pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
986 :     pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
987 :     pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
988 : chenm001 1.14
989 : edgomez 1.19 if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)) {
990 : chenm001 1.14 uv_dx = pMB->mvs[0].x;
991 :     uv_dy = pMB->mvs[0].y;
992 :    
993 :     uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
994 :     uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
995 :    
996 :     b_uv_dx = pMB->b_mvs[0].x;
997 :     b_uv_dy = pMB->b_mvs[0].y;
998 :    
999 :     b_uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
1000 :     b_uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
1001 : edgomez 1.19 } else {
1002 : chenm001 1.14 int sum;
1003 : edgomez 1.19
1004 : chenm001 1.14 sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1005 : edgomez 1.19 uv_dx =
1006 :     (sum ==
1007 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
1008 :     (ABS(sum) / 16) * 2));
1009 : chenm001 1.14
1010 :     sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1011 : edgomez 1.19 uv_dy =
1012 :     (sum ==
1013 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
1014 :     (ABS(sum) / 16) * 2));
1015 :    
1016 :     sum =
1017 :     pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x +
1018 :     pMB->b_mvs[3].x;
1019 :     b_uv_dx =
1020 :     (sum ==
1021 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
1022 :     (ABS(sum) / 16) * 2));
1023 :    
1024 :     sum =
1025 :     pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y +
1026 :     pMB->b_mvs[3].y;
1027 :     b_uv_dy =
1028 :     (sum ==
1029 :     0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +
1030 :     (ABS(sum) / 16) * 2));
1031 :     }
1032 : chenm001 1.14
1033 :    
1034 :     start_timer();
1035 : edgomez 1.19 interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos,
1036 :     pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1037 :     interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos,
1038 :     pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
1039 :     interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8,
1040 :     pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
1041 :     interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8,
1042 :     16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,
1043 :     0);
1044 :     interpolate8x8_switch(dec->cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx,
1045 :     uv_dy, stride2, 0);
1046 :     interpolate8x8_switch(dec->cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx,
1047 :     uv_dy, stride2, 0);
1048 :    
1049 :    
1050 :     interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos, 16 * y_pos,
1051 :     pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1052 :     interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,
1053 :     16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride,
1054 :     0);
1055 :     interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos,
1056 :     16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y,
1057 :     stride, 0);
1058 :     interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,
1059 :     16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y,
1060 :     stride, 0);
1061 :     interpolate8x8_switch(dec->refn[2].u, backward.u, 8 * x_pos, 8 * y_pos,
1062 :     b_uv_dx, b_uv_dy, stride2, 0);
1063 :     interpolate8x8_switch(dec->refn[2].v, backward.v, 8 * x_pos, 8 * y_pos,
1064 :     b_uv_dx, b_uv_dy, stride2, 0);
1065 :    
1066 :     interpolate8x8_c(dec->cur.y, dec->refn[2].y, 16 * x_pos, 16 * y_pos,
1067 :     stride);
1068 :     interpolate8x8_c(dec->cur.y, dec->refn[2].y, 16 * x_pos + 8, 16 * y_pos,
1069 :     stride);
1070 :     interpolate8x8_c(dec->cur.y, dec->refn[2].y, 16 * x_pos, 16 * y_pos + 8,
1071 :     stride);
1072 :     interpolate8x8_c(dec->cur.y, dec->refn[2].y, 16 * x_pos + 8,
1073 :     16 * y_pos + 8, stride);
1074 :     interpolate8x8_c(dec->cur.u, dec->refn[2].u, 8 * x_pos, 8 * y_pos,
1075 :     stride2);
1076 :     interpolate8x8_c(dec->cur.v, dec->refn[2].v, 8 * x_pos, 8 * y_pos,
1077 :     stride2);
1078 : chenm001 1.14
1079 :     stop_comp_timer();
1080 : edgomez 1.19
1081 :     for (i = 0; i < 6; i++) {
1082 :     if (cbp & (1 << (5 - i))) // coded
1083 : chenm001 1.15 {
1084 : edgomez 1.19 memset(&block[i * 64], 0, 64 * sizeof(int16_t)); // clear
1085 : chenm001 1.14
1086 : chenm001 1.15 start_timer();
1087 : edgomez 1.19 get_inter_block(bs, &block[i * 64]);
1088 : chenm001 1.15 stop_coding_timer();
1089 :    
1090 :     start_timer();
1091 : edgomez 1.19 if (dec->quant_type == 0) {
1092 :     dequant_inter(&data[i * 64], &block[i * 64], iQuant);
1093 :     } else {
1094 :     dequant4_inter(&data[i * 64], &block[i * 64], iQuant);
1095 : chenm001 1.15 }
1096 :     stop_iquant_timer();
1097 :    
1098 :     start_timer();
1099 : edgomez 1.19 idct(&data[i * 64]);
1100 : chenm001 1.15 stop_idct_timer();
1101 :     }
1102 :     }
1103 :    
1104 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
1105 : chenm001 1.15 next_block = stride;
1106 :     stride *= 2;
1107 :     }
1108 :    
1109 :     start_timer();
1110 :     if (cbp & 32)
1111 : edgomez 1.19 transfer_16to8add(pY_Cur, &data[0 * 64], stride);
1112 : chenm001 1.15 if (cbp & 16)
1113 : edgomez 1.19 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);
1114 : chenm001 1.15 if (cbp & 8)
1115 : edgomez 1.19 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);
1116 : chenm001 1.15 if (cbp & 4)
1117 : edgomez 1.19 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);
1118 : chenm001 1.15 if (cbp & 2)
1119 : edgomez 1.19 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
1120 : chenm001 1.15 if (cbp & 1)
1121 : edgomez 1.19 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
1122 : chenm001 1.15 stop_transfer_timer();
1123 : chenm001 1.14 }
1124 :    
1125 :    
1126 :     // add by MinChen <chenm001@163.com>
1127 :     // for decode B-frame dbquant
1128 : edgomez 1.19 int32_t __inline
1129 :     get_dbquant(Bitstream * bs)
1130 : chenm001 1.14 {
1131 : edgomez 1.19 if (!BitstreamGetBit(bs)) // '0'
1132 :     return (0);
1133 : chenm001 1.14 else if (!BitstreamGetBit(bs)) // '10'
1134 : edgomez 1.19 return (-2);
1135 : chenm001 1.14 else
1136 : edgomez 1.19 return (2); // '11'
1137 : chenm001 1.14 }
1138 :    
1139 :     // add by MinChen <chenm001@163.com>
1140 :     // for decode B-frame mb_type
1141 :     // bit ret_value
1142 :     // 1 0
1143 :     // 01 1
1144 :     // 001 2
1145 :     // 0001 3
1146 : edgomez 1.19 int32_t __inline
1147 :     get_mbtype(Bitstream * bs)
1148 : chenm001 1.14 {
1149 : chenm001 1.15 int32_t mb_type;
1150 : edgomez 1.19
1151 :     for (mb_type = 0; mb_type <= 3; mb_type++) {
1152 :     if (BitstreamGetBit(bs))
1153 : chenm001 1.15 break;
1154 :     }
1155 :    
1156 : edgomez 1.19 if (mb_type <= 3)
1157 :     return (mb_type);
1158 : chenm001 1.14 else
1159 : edgomez 1.19 return (-1);
1160 : chenm001 1.14 }
1161 :    
1162 : edgomez 1.19 void
1163 :     decoder_bframe(DECODER * dec,
1164 :     Bitstream * bs,
1165 :     int quant,
1166 :     int fcode_forward,
1167 :     int fcode_backward)
1168 : chenm001 1.14 {
1169 :    
1170 : edgomez 1.19 uint32_t x, y;
1171 :     VECTOR mv, zeromv;
1172 : chenm001 1.14
1173 :     start_timer();
1174 : edgomez 1.19 image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
1175 :     dec->width, dec->height, dec->interlacing);
1176 : chenm001 1.14 //image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);
1177 :     stop_edges_timer();
1178 :    
1179 : chenm001 1.15
1180 : edgomez 1.19 for (y = 0; y < dec->mb_height; y++) {
1181 : chenm001 1.15 // Initialize Pred Motion Vector
1182 :     dec->p_fmv.x = dec->p_fmv.y = dec->p_bmv.x = dec->p_bmv.y = 0;
1183 : edgomez 1.19 for (x = 0; x < dec->mb_width; x++) {
1184 :     MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
1185 :     MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];
1186 : chenm001 1.14
1187 : edgomez 1.19 mb->mvs[0].x = mb->mvs[0].y = zeromv.x = zeromv.y = mv.x = mv.y =
1188 :     0;
1189 : chenm001 1.15
1190 : chenm001 1.14 // the last P_VOP is skip macroblock ?
1191 : edgomez 1.19 if (last_mb->mode == MODE_NOT_CODED) {
1192 : chenm001 1.15 //DEBUG2("Skip MB in B-frame at (X,Y)=!",x,y);
1193 :     mb->mb_type = MODE_FORWARD;
1194 :     mb->cbp = 0;
1195 :     mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;
1196 :     mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;
1197 :     mb->quant = 8;
1198 : chenm001 1.14
1199 : chenm001 1.15 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, quant, 1);
1200 : chenm001 1.14 continue;
1201 :     }
1202 : chenm001 1.15 //t=BitstreamShowBits(bs,32);
1203 :    
1204 : edgomez 1.19 if (!BitstreamGetBit(bs)) { // modb=='0'
1205 :     const uint8_t modb2 = BitstreamGetBit(bs);
1206 : chenm001 1.14
1207 :     mb->mb_type = get_mbtype(bs);
1208 : edgomez 1.19
1209 :     if (!modb2) { // modb=='00'
1210 :     mb->cbp = BitstreamGetBits(bs, 6);
1211 : chenm001 1.14 } else {
1212 :     mb->cbp = 0;
1213 :     }
1214 : edgomez 1.19 if (mb->mb_type && mb->cbp) {
1215 : chenm001 1.14 quant += get_dbquant(bs);
1216 :    
1217 : edgomez 1.19 if (quant > 31) {
1218 : chenm001 1.14 quant = 31;
1219 : chenm001 1.25 } else if (mb->quant < 1) {
1220 : chenm001 1.14 quant = 1;
1221 :     }
1222 : chenm001 1.15 } else {
1223 :     quant = 8;
1224 : chenm001 1.14 }
1225 :     mb->quant = quant;
1226 :     } else {
1227 :     mb->mb_type = MODE_DIRECT_NONE_MV;
1228 : edgomez 1.19 mb->cbp = 0;
1229 : chenm001 1.14 }
1230 :    
1231 : chenm001 1.15 mb->mode = MODE_INTER;
1232 : chenm001 1.14 //DEBUG1("Switch bm_type=",mb->mb_type);
1233 :    
1234 : edgomez 1.19 switch (mb->mb_type) {
1235 : chenm001 1.14 case MODE_DIRECT:
1236 :     get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], 1, zeromv);
1237 :    
1238 :     case MODE_DIRECT_NONE_MV:
1239 : edgomez 1.19 { // Because this file is a C file not C++ so I use '{' to define var
1240 :     const int64_t TRB = dec->time_pp - dec->time_bp, TRD =
1241 :     dec->time_pp;
1242 : chenm001 1.14 int i;
1243 : edgomez 1.19
1244 :     for (i = 0; i < 4; i++) {
1245 :     mb->mvs[i].x =
1246 :     (int32_t) ((TRB * last_mb->mvs[i].x) / TRD +
1247 :     mb->mvs[0].x);
1248 :     mb->b_mvs[i].x =
1249 :     (int32_t) ((mb->mvs[0].x ==
1250 :     0) ? ((TRB -
1251 :     TRD) * last_mb->mvs[i].x) /
1252 :     TRD : mb->mvs[i].x - last_mb->mvs[i].x);
1253 :     mb->mvs[i].y =
1254 :     (int32_t) ((TRB * last_mb->mvs[i].y) / TRD +
1255 :     mb->mvs[0].y);
1256 :     mb->b_mvs[i].y =
1257 :     (int32_t) ((mb->mvs[0].y ==
1258 :     0) ? ((TRB -
1259 :     TRD) * last_mb->mvs[i].y) /
1260 :     TRD : mb->mvs[i].y - last_mb->mvs[i].y);
1261 : chenm001 1.14 }
1262 :     //DEBUG("B-frame Direct!\n");
1263 :     }
1264 :     mb->mode = MODE_INTER4V;
1265 : edgomez 1.19 decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],
1266 :     mb, x, y, mb->cbp, bs);
1267 : chenm001 1.14 break;
1268 :    
1269 :     case MODE_INTERPOLATE:
1270 : edgomez 1.19 get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_forward,
1271 :     dec->p_fmv);
1272 :     dec->p_fmv.x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
1273 :     mb->mvs[0].x;
1274 :     dec->p_fmv.y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
1275 :     mb->mvs[0].y;
1276 :    
1277 :     get_b_motion_vector(dec, bs, x, y, &mb->b_mvs[0],
1278 :     fcode_backward, dec->p_bmv);
1279 :     dec->p_bmv.x = mb->b_mvs[1].x = mb->b_mvs[2].x =
1280 :     mb->b_mvs[3].x = mb->b_mvs[0].x;
1281 :     dec->p_bmv.y = mb->b_mvs[1].y = mb->b_mvs[2].y =
1282 :     mb->b_mvs[3].y = mb->b_mvs[0].y;
1283 : chenm001 1.14
1284 : edgomez 1.19 decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],
1285 :     mb, x, y, mb->cbp, bs);
1286 : chenm001 1.14 //DEBUG("B-frame Bidir!\n");
1287 :     break;
1288 :    
1289 :     case MODE_BACKWARD:
1290 : edgomez 1.19 get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_backward,
1291 :     dec->p_bmv);
1292 :     dec->p_bmv.x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
1293 :     mb->mvs[0].x;
1294 :     dec->p_bmv.y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
1295 :     mb->mvs[0].y;
1296 : chenm001 1.15
1297 : chenm001 1.14 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, quant, 0);
1298 :     //DEBUG("B-frame Backward!\n");
1299 :     break;
1300 :    
1301 :     case MODE_FORWARD:
1302 : edgomez 1.19 get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_forward,
1303 :     dec->p_fmv);
1304 :     dec->p_fmv.x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
1305 :     mb->mvs[0].x;
1306 :     dec->p_fmv.y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
1307 :     mb->mvs[0].y;
1308 : chenm001 1.15
1309 : chenm001 1.14 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, quant, 1);
1310 : chenm001 1.15 //DEBUG("B-frame Forward!\n");
1311 : chenm001 1.14 break;
1312 :    
1313 :     default:
1314 : edgomez 1.19 DEBUG1("Not support B-frame mb_type =", mb->mb_type);
1315 : chenm001 1.14 }
1316 :    
1317 : edgomez 1.19 } // end of FOR
1318 : chenm001 1.14 }
1319 :     }
1320 :    
1321 :     // swap two MACROBLOCK array
1322 : edgomez 1.19 void
1323 :     mb_swap(MACROBLOCK ** mb1,
1324 :     MACROBLOCK ** mb2)
1325 : chenm001 1.14 {
1326 : edgomez 1.19 MACROBLOCK *temp = *mb1;
1327 :    
1328 :     *mb1 = *mb2;
1329 :     *mb2 = temp;
1330 : chenm001 1.14 }
1331 :    
1332 : edgomez 1.19 int
1333 :     decoder_decode(DECODER * dec,
1334 :     XVID_DEC_FRAME * frame)
1335 : Isibaar 1.1 {
1336 : edgomez 1.7
1337 : Isibaar 1.1 Bitstream bs;
1338 :     uint32_t rounding;
1339 :     uint32_t quant;
1340 : chenm001 1.14 uint32_t fcode_forward;
1341 :     uint32_t fcode_backward;
1342 : Isibaar 1.1 uint32_t intra_dc_threshold;
1343 : chenm001 1.11 uint32_t vop_type;
1344 : Isibaar 1.1
1345 :     start_global_timer();
1346 : edgomez 1.19
1347 : Isibaar 1.1 BitstreamInit(&bs, frame->bitstream, frame->length);
1348 :    
1349 : chenm001 1.11 // add by chenm001 <chenm001@163.com>
1350 :     // for support B-frame to reference last 2 frame
1351 : Isibaar 1.18 dec->frames++;
1352 : edgomez 1.19 vop_type =
1353 :     BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward,
1354 :     &fcode_backward, &intra_dc_threshold);
1355 :    
1356 :     dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0; // init pred vector to 0
1357 :    
1358 :     switch (vop_type) {
1359 :     case P_VOP:
1360 :     decoder_pframe(dec, &bs, rounding, quant, fcode_forward,
1361 :     intra_dc_threshold);
1362 : chenm001 1.25 printf("P_VOP Time=%ld\n",dec->time);
1363 : edgomez 1.19 DEBUG1("P_VOP Time=", dec->time);
1364 : Isibaar 1.1 break;
1365 :    
1366 : edgomez 1.19 case I_VOP:
1367 : Isibaar 1.1 decoder_iframe(dec, &bs, quant, intra_dc_threshold);
1368 : chenm001 1.25 printf("I_VOP Time=%ld\n",dec->time);
1369 : edgomez 1.19 DEBUG1("I_VOP Time=", dec->time);
1370 : Isibaar 1.1 break;
1371 :    
1372 : edgomez 1.19 case B_VOP:
1373 : suxen_drol 1.21 #ifdef BFRAMES_DEC
1374 : edgomez 1.19 if (dec->time_pp > dec->time_bp) {
1375 : chenm001 1.25 printf("I_VOP Time=%ld\n",dec->time);
1376 : edgomez 1.19 DEBUG1("B_VOP Time=", dec->time);
1377 : chenm001 1.14 decoder_bframe(dec, &bs, quant, fcode_forward, fcode_backward);
1378 :     } else {
1379 :     DEBUG("broken B-frame!");
1380 :     }
1381 : suxen_drol 1.21 #else
1382 : chenm001 1.25 printf("Che minchia ne so\n");
1383 : suxen_drol 1.21 image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
1384 : Isibaar 1.18 #endif
1385 : Isibaar 1.1 break;
1386 : edgomez 1.19
1387 :     case N_VOP: // vop not coded
1388 : suxen_drol 1.21 // when low_delay==0, N_VOP's should interpolate between the past and future frames
1389 :     image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
1390 : chenm001 1.25 printf("N_VOP vop not coded\n");
1391 : Isibaar 1.1 break;
1392 :    
1393 : edgomez 1.19 default:
1394 : Isibaar 1.1 return XVID_ERR_FAIL;
1395 :     }
1396 :    
1397 :     frame->length = BitstreamPos(&bs) / 8;
1398 :    
1399 : suxen_drol 1.21 #ifdef BFRAMES_DEC
1400 : chenm001 1.17 // test if no B_VOP
1401 : edgomez 1.19 if (dec->low_delay) {
1402 : Isibaar 1.18 #endif
1403 : edgomez 1.19 image_output(&dec->cur, dec->width, dec->height, dec->edged_width,
1404 :     frame->image, frame->stride, frame->colorspace);
1405 : suxen_drol 1.21 #ifdef BFRAMES_DEC
1406 : chenm001 1.17 } else {
1407 : edgomez 1.19 if (dec->frames >= 1) {
1408 : chenm001 1.17 start_timer();
1409 : edgomez 1.19 if ((vop_type == I_VOP || vop_type == P_VOP)) {
1410 :     image_output(&dec->refn[0], dec->width, dec->height,
1411 :     dec->edged_width, frame->image, frame->stride,
1412 :     frame->colorspace);
1413 : chenm001 1.17 } else if (vop_type == B_VOP) {
1414 : edgomez 1.19 image_output(&dec->cur, dec->width, dec->height,
1415 :     dec->edged_width, frame->image, frame->stride,
1416 :     frame->colorspace);
1417 : chenm001 1.17 }
1418 :     stop_conv_timer();
1419 : chenm001 1.14 }
1420 :     }
1421 : Isibaar 1.18 #endif
1422 :    
1423 : edgomez 1.19 if (vop_type == I_VOP || vop_type == P_VOP) {
1424 : chenm001 1.14 image_swap(&dec->refn[0], &dec->refn[1]);
1425 :     image_swap(&dec->cur, &dec->refn[0]);
1426 :     // swap MACROBLOCK
1427 : edgomez 1.19 if (dec->low_delay && vop_type == P_VOP)
1428 : chenm001 1.15 mb_swap(&dec->mbs, &dec->last_mbs);
1429 : chenm001 1.14 }
1430 :    
1431 : Isibaar 1.1 emms();
1432 :    
1433 :     stop_global_timer();
1434 :    
1435 :     return XVID_ERR_OK;
1436 :     }

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