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

Annotation of /xvidcore/src/decoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.46 - (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.42 * Copyright(C) 2002 MinChen <chenm001@163.com>
7 :     * 2002 Peter Ross <pross@xvid.org>
8 :     *
9 : edgomez 1.43 * This file is part of XviD, a free MPEG-4 video encoder/decoder
10 : edgomez 1.12 *
11 : edgomez 1.43 * 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 1.12 * the Free Software Foundation; either version 2 of the License, or
14 :     * (at your option) any later version.
15 :     *
16 :     * 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 :     *
21 :     * 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 1.1 *
25 : edgomez 1.43 * Under section 8 of the GNU General Public License, the copyright
26 :     * holders of XVID explicitly forbid distribution in the following
27 :     * countries:
28 :     *
29 :     * - Japan
30 :     * - United States of America
31 :     *
32 :     * 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 :     *
36 :     * 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 :     *
47 :     * 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 : edgomez 1.12 *
54 : edgomez 1.46 * $Id: decoder.c,v 1.45 2002/12/15 01:21:12 edgomez Exp $
55 : Isibaar 1.1 *
56 :     *************************************************************************/
57 :    
58 :     #include <stdlib.h>
59 : edgomez 1.12 #include <string.h>
60 : Isibaar 1.1
61 : chenm001 1.27 #ifdef BFRAMES_DEC_DEBUG
62 :     #define BFRAMES_DEC
63 :     #endif
64 :    
65 : Isibaar 1.1 #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 1.3 #include "utils/mem_align.h"
87 : Isibaar 1.1
88 : edgomez 1.19 int
89 :     decoder_create(XVID_DEC_PARAM * param)
90 : Isibaar 1.1 {
91 : edgomez 1.19 DECODER *dec;
92 : Isibaar 1.1
93 : Isibaar 1.4 dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
94 : edgomez 1.19 if (dec == NULL) {
95 : Isibaar 1.1 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 1.20 dec->low_delay = 0;
108 : edgomez 1.19
109 :     if (image_create(&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 :    
114 : edgomez 1.19 if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height)) {
115 : Isibaar 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
116 : Isibaar 1.3 xvid_free(dec);
117 : Isibaar 1.1 return XVID_ERR_MEMORY;
118 :     }
119 : edgomez 1.44 /* add by chenm001 <chenm001@163.com> */
120 :     /* for support B-frame to reference last 2 frame */
121 : edgomez 1.19 if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {
122 : chenm001 1.11 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 1.19 if (image_create(&dec->refn[2], dec->edged_width, dec->edged_height)) {
128 : chenm001 1.14 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 1.1
135 : edgomez 1.19 dec->mbs =
136 :     xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
137 :     CACHE_LINE);
138 :     if (dec->mbs == NULL) {
139 : Isibaar 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
140 : chenm001 1.14 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 :     xvid_free(dec);
144 :     return XVID_ERR_MEMORY;
145 :     }
146 : Isibaar 1.20
147 :     memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
148 :    
149 : edgomez 1.44 /* add by chenm001 <chenm001@163.com> */
150 :     /* for skip MB flag */
151 : edgomez 1.19 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 1.14 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 : Isibaar 1.3 xvid_free(dec);
161 : Isibaar 1.1 return XVID_ERR_MEMORY;
162 :     }
163 : Isibaar 1.20
164 :     memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
165 : Isibaar 1.1
166 :     init_timer();
167 :    
168 : edgomez 1.44 /* add by chenm001 <chenm001@163.com> */
169 :     /* for support B-frame to save reference frame's time */
170 : chenm001 1.14 dec->frames = -1;
171 :     dec->time = dec->time_base = dec->last_time_base = 0;
172 : edgomez 1.19
173 : Isibaar 1.1 return XVID_ERR_OK;
174 :     }
175 :    
176 :    
177 : edgomez 1.19 int
178 :     decoder_destroy(DECODER * dec)
179 : Isibaar 1.1 {
180 : chenm001 1.14 xvid_free(dec->last_mbs);
181 : Isibaar 1.3 xvid_free(dec->mbs);
182 : chenm001 1.11 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
183 : chenm001 1.14 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 1.1 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
186 : Isibaar 1.3 xvid_free(dec);
187 : Isibaar 1.1
188 :     write_timer();
189 :     return XVID_ERR_OK;
190 :     }
191 :    
192 :    
193 :    
194 : edgomez 1.19 static const int32_t dquant_table[4] = {
195 : Isibaar 1.1 -1, -2, 1, 2
196 :     };
197 :    
198 :    
199 : chenm001 1.14
200 :    
201 : edgomez 1.44 /* decode an intra macroblock */
202 : Isibaar 1.1
203 : edgomez 1.19 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 1.26 const uint32_t intra_dc_threshold,
213 :     const unsigned int bound)
214 : Isibaar 1.1 {
215 : edgomez 1.7
216 :     DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
217 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
218 : edgomez 1.7
219 : h 1.8 uint32_t stride = dec->edged_width;
220 :     uint32_t stride2 = stride / 2;
221 :     uint32_t next_block = stride * 8;
222 : h 1.5 uint32_t i;
223 :     uint32_t iQuant = pMB->quant;
224 :     uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
225 :    
226 : edgomez 1.7 pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
227 : h 1.8 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 : edgomez 1.7
230 : edgomez 1.44 memset(block, 0, 6 * 64 * sizeof(int16_t)); /* clear */
231 : h 1.5
232 : edgomez 1.19 for (i = 0; i < 6; i++) {
233 : h 1.5 uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
234 : Isibaar 1.1 int16_t predictors[8];
235 :     int start_coeff;
236 :    
237 :     start_timer();
238 : edgomez 1.19 predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, &block[i * 64],
239 : chenm001 1.26 iQuant, iDcScaler, predictors, bound);
240 : edgomez 1.19 if (!acpred_flag) {
241 : h 1.5 pMB->acpred_directions[i] = 0;
242 : Isibaar 1.1 }
243 :     stop_prediction_timer();
244 :    
245 : edgomez 1.19 if (quant < intra_dc_threshold) {
246 : Isibaar 1.1 int dc_size;
247 :     int dc_dif;
248 :    
249 : edgomez 1.19 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 1.1
252 : edgomez 1.19 if (dc_size > 8) {
253 : edgomez 1.44 BitstreamSkip(bs, 1); /* marker */
254 : Isibaar 1.1 }
255 : edgomez 1.19
256 :     block[i * 64 + 0] = dc_dif;
257 : Isibaar 1.1 start_coeff = 1;
258 : chenm001 1.26
259 :     DPRINTF(DPRINTF_COEFF,"block[0] %i", dc_dif);
260 : edgomez 1.19 } else {
261 : Isibaar 1.1 start_coeff = 0;
262 :     }
263 :    
264 :     start_timer();
265 : edgomez 1.44 if (cbp & (1 << (5 - i))) /* coded */
266 : Isibaar 1.1 {
267 : edgomez 1.19 get_intra_block(bs, &block[i * 64], pMB->acpred_directions[i],
268 :     start_coeff);
269 : Isibaar 1.1 }
270 :     stop_coding_timer();
271 :    
272 :     start_timer();
273 : edgomez 1.19 add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors);
274 : Isibaar 1.1 stop_prediction_timer();
275 :    
276 :     start_timer();
277 : edgomez 1.19 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 1.1 }
282 :     stop_iquant_timer();
283 :    
284 :     start_timer();
285 : edgomez 1.19 idct(&data[i * 64]);
286 : Isibaar 1.1 stop_idct_timer();
287 : h 1.5 }
288 : Isibaar 1.1
289 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
290 : h 1.8 next_block = stride;
291 :     stride *= 2;
292 : Isibaar 1.1 }
293 : h 1.5
294 :     start_timer();
295 : edgomez 1.19 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 1.5 stop_transfer_timer();
302 : Isibaar 1.1 }
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 1.19 { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };
312 : Isibaar 1.1
313 :    
314 : edgomez 1.44 /* decode an inter macroblock */
315 : Isibaar 1.1
316 : edgomez 1.19 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 1.1 {
327 : edgomez 1.7
328 : edgomez 1.19 DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
329 : edgomez 1.7 DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
330 : h 1.5
331 : h 1.8 uint32_t stride = dec->edged_width;
332 :     uint32_t stride2 = stride / 2;
333 :     uint32_t next_block = stride * 8;
334 : edgomez 1.7 uint32_t i;
335 :     uint32_t iQuant = pMB->quant;
336 : h 1.5 uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
337 : Isibaar 1.1 int uv_dx, uv_dy;
338 :    
339 : edgomez 1.7 pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
340 : h 1.8 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 1.5
343 : edgomez 1.19 if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
344 : h 1.5 uv_dx = pMB->mvs[0].x;
345 :     uv_dy = pMB->mvs[0].y;
346 : Isibaar 1.1
347 :     uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;
348 :     uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;
349 : edgomez 1.19 } else {
350 : Isibaar 1.1 int sum;
351 : Isibaar 1.34 sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
352 : edgomez 1.19
353 : Isibaar 1.34 uv_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
354 : Isibaar 1.1
355 : h 1.5 sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
356 : Isibaar 1.34
357 :     uv_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
358 : Isibaar 1.1 }
359 :    
360 :     start_timer();
361 : edgomez 1.46 interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,
362 :     pMB->mvs[0].x, pMB->mvs[0].y, stride, rounding);
363 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos,
364 :     pMB->mvs[1].x, pMB->mvs[1].y, stride, rounding);
365 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8,
366 :     pMB->mvs[2].x, pMB->mvs[2].y, stride, rounding);
367 :     interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8,
368 :     pMB->mvs[3].x, pMB->mvs[3].y, stride, rounding);
369 : edgomez 1.19 interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,
370 :     uv_dx, uv_dy, stride2, rounding);
371 :     interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,
372 :     uv_dx, uv_dy, stride2, rounding);
373 : Isibaar 1.1 stop_comp_timer();
374 :    
375 : edgomez 1.19 for (i = 0; i < 6; i++) {
376 : edgomez 1.44 if (cbp & (1 << (5 - i))) /* coded */
377 : Isibaar 1.1 {
378 : edgomez 1.44 memset(&block[i * 64], 0, 64 * sizeof(int16_t)); /* clear */
379 : Isibaar 1.1
380 :     start_timer();
381 : edgomez 1.19 get_inter_block(bs, &block[i * 64]);
382 : Isibaar 1.1 stop_coding_timer();
383 :    
384 :     start_timer();
385 : edgomez 1.19 if (dec->quant_type == 0) {
386 :     dequant_inter(&data[i * 64], &block[i * 64], iQuant);
387 :     } else {
388 :     dequant4_inter(&data[i * 64], &block[i * 64], iQuant);
389 : Isibaar 1.1 }
390 :     stop_iquant_timer();
391 :    
392 :     start_timer();
393 : edgomez 1.19 idct(&data[i * 64]);
394 : Isibaar 1.1 stop_idct_timer();
395 : h 1.5 }
396 :     }
397 : Isibaar 1.1
398 : edgomez 1.19 if (dec->interlacing && pMB->field_dct) {
399 : h 1.8 next_block = stride;
400 :     stride *= 2;
401 : Isibaar 1.1 }
402 : h 1.5
403 :     start_timer();
404 :     if (cbp & 32)
405 : edgomez 1.19 transfer_16to8add(pY_Cur, &data[0 * 64], stride);
406 : h 1.5 if (cbp & 16)
407 : edgomez 1.19 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);
408 : h 1.5 if (cbp & 8)
409 : edgomez 1.19 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);
410 : h 1.5 if (cbp & 4)
411 : edgomez 1.19 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);
412 : h 1.5 if (cbp & 2)
413 : edgomez 1.19 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
414 : h 1.5 if (cbp & 1)
415 : edgomez 1.19 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
416 : h 1.5 stop_transfer_timer();
417 : Isibaar 1.1 }
418 :    
419 :    
420 : edgomez 1.19 void
421 :     decoder_iframe(DECODER * dec,
422 :     Bitstream * bs,
423 :     int quant,
424 :     int intra_dc_threshold)
425 : Isibaar 1.1 {
426 : chenm001 1.26 uint32_t bound;
427 :     uint32_t x, y;
428 : chenm001 1.25
429 : chenm001 1.26 bound = 0;
430 : edgomez 1.7
431 : edgomez 1.19 for (y = 0; y < dec->mb_height; y++) {
432 :     for (x = 0; x < dec->mb_width; x++) {
433 : chenm001 1.26 MACROBLOCK *mb;
434 : Isibaar 1.1 uint32_t mcbpc;
435 :     uint32_t cbpc;
436 :     uint32_t acpred_flag;
437 :     uint32_t cbpy;
438 :     uint32_t cbp;
439 :    
440 : chenm001 1.26 while (BitstreamShowBits(bs, 9) == 1)
441 :     BitstreamSkip(bs, 9);
442 :    
443 :     if (check_resync_marker(bs, 0))
444 :     {
445 :     bound = read_video_packet_header(bs, 0, &quant);
446 :     x = bound % dec->mb_width;
447 :     y = bound / dec->mb_width;
448 :     }
449 :     mb = &dec->mbs[y * dec->mb_width + x];
450 :    
451 :     DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", x, y, BitstreamShowBits(bs, 32));
452 :    
453 : Isibaar 1.1 mcbpc = get_mcbpc_intra(bs);
454 :     mb->mode = mcbpc & 7;
455 :     cbpc = (mcbpc >> 4);
456 :    
457 :     acpred_flag = BitstreamGetBit(bs);
458 :    
459 :     cbpy = get_cbpy(bs, 1);
460 :     cbp = (cbpy << 2) | cbpc;
461 :    
462 : edgomez 1.19 if (mb->mode == MODE_INTRA_Q) {
463 :     quant += dquant_table[BitstreamGetBits(bs, 2)];
464 :     if (quant > 31) {
465 : Isibaar 1.1 quant = 31;
466 : edgomez 1.19 } else if (quant < 1) {
467 : Isibaar 1.1 quant = 1;
468 :     }
469 :     }
470 :     mb->quant = quant;
471 : chenm001 1.30 mb->mvs[0].x = mb->mvs[0].y =
472 :     mb->mvs[1].x = mb->mvs[1].y =
473 :     mb->mvs[2].x = mb->mvs[2].y =
474 :     mb->mvs[3].x = mb->mvs[3].y =0;
475 : h 1.5
476 : edgomez 1.19 if (dec->interlacing) {
477 : h 1.5 mb->field_dct = BitstreamGetBit(bs);
478 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "deci: field_dct: %d", mb->field_dct);
479 : h 1.5 }
480 : Isibaar 1.1
481 : edgomez 1.19 decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
482 : chenm001 1.26 intra_dc_threshold, bound);
483 : Isibaar 1.1 }
484 : albeu 1.32 if(dec->out_frm)
485 :     output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,0,y,dec->mb_width);
486 :    
487 : Isibaar 1.1 }
488 : edgomez 1.7
489 : Isibaar 1.1 }
490 :    
491 :    
492 : edgomez 1.19 void
493 :     get_motion_vector(DECODER * dec,
494 :     Bitstream * bs,
495 :     int x,
496 :     int y,
497 :     int k,
498 :     VECTOR * mv,
499 : chenm001 1.26 int fcode,
500 :     const int bound)
501 : Isibaar 1.1 {
502 : edgomez 1.7
503 : Isibaar 1.1 int scale_fac = 1 << (fcode - 1);
504 :     int high = (32 * scale_fac) - 1;
505 :     int low = ((-32) * scale_fac);
506 :     int range = (64 * scale_fac);
507 :    
508 : chenm001 1.26 VECTOR pmv;
509 : Isibaar 1.1 int mv_x, mv_y;
510 :    
511 : chenm001 1.26 pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);
512 : Isibaar 1.1
513 :     mv_x = get_mv(bs, fcode);
514 :     mv_y = get_mv(bs, fcode);
515 : edgomez 1.19
516 : chenm001 1.26 DPRINTF(DPRINTF_MV,"mv_diff (%i,%i) pred (%i,%i)", mv_x, mv_y, pmv.x, pmv.y);
517 :    
518 :     mv_x += pmv.x;
519 :     mv_y += pmv.y;
520 : Isibaar 1.1
521 : edgomez 1.19 if (mv_x < low) {
522 : Isibaar 1.1 mv_x += range;
523 : edgomez 1.19 } else if (mv_x > high) {
524 : Isibaar 1.1 mv_x -= range;
525 :     }
526 :    
527 : edgomez 1.19 if (mv_y < low) {
528 : Isibaar 1.1 mv_y += range;
529 : edgomez 1.19 } else if (mv_y > high) {
530 : Isibaar 1.1 mv_y -= range;
531 :     }
532 :    
533 :     mv->x = mv_x;
534 :     mv->y = mv_y;
535 :    
536 :     }
537 :    
538 :    
539 : edgomez 1.19 void
540 :     decoder_pframe(DECODER * dec,
541 :     Bitstream * bs,
542 :     int rounding,
543 :     int quant,
544 :     int fcode,
545 :     int intra_dc_threshold)
546 : Isibaar 1.1 {
547 : edgomez 1.7
548 : Isibaar 1.1 uint32_t x, y;
549 : chenm001 1.26 uint32_t bound;
550 : albeu 1.32 int cp_mb, st_mb;
551 : Isibaar 1.1
552 :     start_timer();
553 : edgomez 1.19 image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
554 : h 1.41 dec->width, dec->height);
555 : Isibaar 1.1 stop_edges_timer();
556 :    
557 : chenm001 1.26 bound = 0;
558 :    
559 : edgomez 1.19 for (y = 0; y < dec->mb_height; y++) {
560 : albeu 1.32 cp_mb = st_mb = 0;
561 : edgomez 1.19 for (x = 0; x < dec->mb_width; x++) {
562 : chenm001 1.26 MACROBLOCK *mb;
563 :    
564 : edgomez 1.44 /* skip stuffing */
565 : chenm001 1.26 while (BitstreamShowBits(bs, 10) == 1)
566 :     BitstreamSkip(bs, 10);
567 :    
568 :     if (check_resync_marker(bs, fcode - 1))
569 :     {
570 :     bound = read_video_packet_header(bs, fcode - 1, &quant);
571 :     x = bound % dec->mb_width;
572 :     y = bound / dec->mb_width;
573 :     }
574 :     mb = &dec->mbs[y * dec->mb_width + x];
575 :    
576 :     DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", x, y, BitstreamShowBits(bs, 32));
577 : suxen_drol 1.23
578 : edgomez 1.44 /*if (!(dec->mb_skip[y*dec->mb_width + x]=BitstreamGetBit(bs))) not_coded */
579 :     if (!(BitstreamGetBit(bs))) /* not_coded */
580 : Isibaar 1.1 {
581 :     uint32_t mcbpc;
582 :     uint32_t cbpc;
583 :     uint32_t acpred_flag;
584 :     uint32_t cbpy;
585 :     uint32_t cbp;
586 :     uint32_t intra;
587 :    
588 : albeu 1.32 cp_mb++;
589 : Isibaar 1.1 mcbpc = get_mcbpc_inter(bs);
590 :     mb->mode = mcbpc & 7;
591 :     cbpc = (mcbpc >> 4);
592 : chenm001 1.26
593 :     DPRINTF(DPRINTF_MB, "mode %i", mb->mode);
594 :     DPRINTF(DPRINTF_MB, "cbpc %i", cbpc);
595 : edgomez 1.2 acpred_flag = 0;
596 : Isibaar 1.1
597 :     intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);
598 : edgomez 1.19
599 :     if (intra) {
600 : Isibaar 1.1 acpred_flag = BitstreamGetBit(bs);
601 :     }
602 :    
603 : chenm001 1.26 cbpy = get_cbpy(bs, intra);
604 :     DPRINTF(DPRINTF_MB, "cbpy %i", cbpy);
605 : chenm001 1.25
606 : Isibaar 1.1 cbp = (cbpy << 2) | cbpc;
607 :    
608 : edgomez 1.19 if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {
609 : chenm001 1.26 int dquant = dquant_table[BitstreamGetBits(bs, 2)];
610 :     DPRINTF(DPRINTF_MB, "dquant %i", dquant);
611 :     quant += dquant;
612 : edgomez 1.19 if (quant > 31) {
613 : Isibaar 1.1 quant = 31;
614 : chenm001 1.26 } else if (quant < 1) {
615 : Isibaar 1.1 quant = 1;
616 :     }
617 : chenm001 1.26 DPRINTF(DPRINTF_MB, "quant %i", quant);
618 : Isibaar 1.1 }
619 :     mb->quant = quant;
620 : h 1.5
621 : edgomez 1.19 if (dec->interlacing) {
622 : h 1.37 if (cbp || intra) {
623 :     mb->field_dct = BitstreamGetBit(bs);
624 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "decp: field_dct: %d", mb->field_dct);
625 : h 1.37 }
626 : h 1.5
627 : edgomez 1.19 if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
628 : h 1.5 mb->field_pred = BitstreamGetBit(bs);
629 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "decp: field_pred: %d", mb->field_pred);
630 : h 1.5
631 : edgomez 1.19 if (mb->field_pred) {
632 : h 1.5 mb->field_for_top = BitstreamGetBit(bs);
633 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "decp: field_for_top: %d", mb->field_for_top);
634 : h 1.5 mb->field_for_bot = BitstreamGetBit(bs);
635 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "decp: field_for_bot: %d", mb->field_for_bot);
636 : h 1.5 }
637 :     }
638 :     }
639 :    
640 : edgomez 1.19 if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
641 :     if (dec->interlacing && mb->field_pred) {
642 :     get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],
643 : chenm001 1.26 fcode, bound);
644 : edgomez 1.19 get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1],
645 : chenm001 1.26 fcode, bound);
646 : edgomez 1.19 } else {
647 :     get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],
648 : chenm001 1.26 fcode, bound);
649 : edgomez 1.19 mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
650 :     mb->mvs[0].x;
651 :     mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
652 :     mb->mvs[0].y;
653 : h 1.5 }
654 : chl 1.35 } else if (mb->mode == MODE_INTER4V ) {
655 :    
656 : chenm001 1.26 get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);
657 :     get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode, bound);
658 :     get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode, bound);
659 :     get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode, bound);
660 : edgomez 1.44 } else /* MODE_INTRA, MODE_INTRA_Q */
661 : Isibaar 1.1 {
662 : edgomez 1.19 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =
663 :     0;
664 :     mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
665 :     0;
666 :     decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
667 : chenm001 1.26 intra_dc_threshold, bound);
668 : Isibaar 1.1 continue;
669 :     }
670 :    
671 : edgomez 1.19 decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant,
672 :     rounding);
673 : edgomez 1.44 } else /* not coded */
674 : Isibaar 1.1 {
675 : edgomez 1.39 DPRINTF(DPRINTF_DEBUG, "P-frame MB at (X,Y)=(%d,%d)", x, y);
676 :    
677 : chenm001 1.14 mb->mode = MODE_NOT_CODED;
678 : Isibaar 1.1 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
679 :     mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
680 : edgomez 1.19
681 : edgomez 1.44 /* copy macroblock directly from ref to cur */
682 : Isibaar 1.1
683 :     start_timer();
684 :    
685 : edgomez 1.19 transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +
686 :     (16 * x),
687 :     dec->refn[0].y + (16 * y) * dec->edged_width +
688 :     (16 * x), dec->edged_width);
689 :    
690 :     transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +
691 :     (16 * x + 8),
692 :     dec->refn[0].y + (16 * y) * dec->edged_width +
693 :     (16 * x + 8), dec->edged_width);
694 :    
695 :     transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +
696 :     (16 * x),
697 :     dec->refn[0].y + (16 * y +
698 :     8) * dec->edged_width +
699 :     (16 * x), dec->edged_width);
700 :    
701 :     transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +
702 :     (16 * x + 8),
703 :     dec->refn[0].y + (16 * y +
704 :     8) * dec->edged_width +
705 :     (16 * x + 8), dec->edged_width);
706 :    
707 :     transfer8x8_copy(dec->cur.u + (8 * y) * dec->edged_width / 2 +
708 :     (8 * x),
709 :     dec->refn[0].u +
710 :     (8 * y) * dec->edged_width / 2 + (8 * x),
711 :     dec->edged_width / 2);
712 :    
713 :     transfer8x8_copy(dec->cur.v + (8 * y) * dec->edged_width / 2 +
714 :     (8 * x),
715 :     dec->refn[0].v +
716 :     (8 * y) * dec->edged_width / 2 + (8 * x),
717 :     dec->edged_width / 2);
718 : Isibaar 1.1 stop_transfer_timer();
719 : albeu 1.32 if(dec->out_frm && cp_mb > 0) {
720 :     output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
721 :     cp_mb = 0;
722 :     }
723 :     st_mb = x+1;
724 : Isibaar 1.1 }
725 :     }
726 : albeu 1.32 if(dec->out_frm && cp_mb > 0)
727 :     output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
728 : Isibaar 1.1 }
729 :     }
730 :    
731 : edgomez 1.44 /* swap two MACROBLOCK array */
732 : edgomez 1.19 void
733 :     mb_swap(MACROBLOCK ** mb1,
734 :     MACROBLOCK ** mb2)
735 : chenm001 1.14 {
736 : edgomez 1.19 MACROBLOCK *temp = *mb1;
737 :    
738 :     *mb1 = *mb2;
739 :     *mb2 = temp;
740 : chenm001 1.14 }
741 :    
742 : edgomez 1.19 int
743 :     decoder_decode(DECODER * dec,
744 :     XVID_DEC_FRAME * frame)
745 : Isibaar 1.1 {
746 : edgomez 1.7
747 : Isibaar 1.1 Bitstream bs;
748 :     uint32_t rounding;
749 :     uint32_t quant;
750 : chenm001 1.14 uint32_t fcode_forward;
751 :     uint32_t fcode_backward;
752 : Isibaar 1.1 uint32_t intra_dc_threshold;
753 : chenm001 1.11 uint32_t vop_type;
754 : Isibaar 1.1
755 :     start_global_timer();
756 : albeu 1.32
757 :     dec->out_frm = (frame->colorspace == XVID_CSP_EXTERN) ? frame->image : NULL;
758 : edgomez 1.19
759 : Isibaar 1.1 BitstreamInit(&bs, frame->bitstream, frame->length);
760 :    
761 : edgomez 1.44 /* add by chenm001 <chenm001@163.com> */
762 :     /* for support B-frame to reference last 2 frame */
763 : Isibaar 1.18 dec->frames++;
764 : edgomez 1.19 vop_type =
765 :     BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward,
766 :     &fcode_backward, &intra_dc_threshold);
767 :    
768 : edgomez 1.44 dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0; /* init pred vector to 0 */
769 : edgomez 1.19
770 :     switch (vop_type) {
771 :     case P_VOP:
772 :     decoder_pframe(dec, &bs, rounding, quant, fcode_forward,
773 :     intra_dc_threshold);
774 : Isibaar 1.1 break;
775 :    
776 : edgomez 1.19 case I_VOP:
777 : Isibaar 1.1 decoder_iframe(dec, &bs, quant, intra_dc_threshold);
778 :     break;
779 : edgomez 1.19 case B_VOP:
780 : suxen_drol 1.21 image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
781 : Isibaar 1.1 break;
782 : edgomez 1.46 case N_VOP:
783 : edgomez 1.44 /* when low_delay==0, N_VOP's should interpolate between the past and future frames */
784 : suxen_drol 1.21 image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
785 : Isibaar 1.1 break;
786 :    
787 : edgomez 1.19 default:
788 : Isibaar 1.1 return XVID_ERR_FAIL;
789 :     }
790 :    
791 :     frame->length = BitstreamPos(&bs) / 8;
792 :    
793 : chenm001 1.27 image_output(&dec->cur, dec->width, dec->height, dec->edged_width,
794 : edgomez 1.19 frame->image, frame->stride, frame->colorspace);
795 : Isibaar 1.18
796 : edgomez 1.19 if (vop_type == I_VOP || vop_type == P_VOP) {
797 : chenm001 1.14 image_swap(&dec->refn[0], &dec->refn[1]);
798 :     image_swap(&dec->cur, &dec->refn[0]);
799 : chenm001 1.31
800 : edgomez 1.44 /* swap MACROBLOCK */
801 :     /* the Divx will not set the low_delay flage some times */
802 :     /* so follow code will wrong to not swap at that time */
803 :     /* this will broken bitstream! so I'm change it, */
804 :     /* But that is not the best way! can anyone tell me how */
805 :     /* to do another way? */
806 :     /* 18-07-2002 MinChen<chenm001@163.com> */
807 :     /*if (!dec->low_delay && vop_type == P_VOP) */
808 : chenm001 1.31 if (vop_type == P_VOP)
809 : chenm001 1.15 mb_swap(&dec->mbs, &dec->last_mbs);
810 : chenm001 1.14 }
811 :    
812 : Isibaar 1.1 emms();
813 :    
814 :     stop_global_timer();
815 :    
816 :     return XVID_ERR_OK;
817 :     }

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