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

Annotation of /trunk/xvidcore/src/decoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 648 - (view) (download)

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

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