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

Diff of /xvidcore/src/decoder.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.37.2.13, Wed Nov 20 19:52:45 2002 UTC revision 1.75.2.1, Fri Dec 30 14:26:46 2005 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  -  Decoder main module  -   *  - Decoder Module -
5   *   *
6   *  This program is an implementation of a part of one or more MPEG-4   *  Copyright(C) 2002      MinChen <chenm001@163.com>
7   *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending   *               2002-2004 Peter Ross <pross@xvid.org>
  *  to use this software module in hardware or software products are  
  *  advised that its use may infringe existing patents or copyrights, and  
  *  any such use would be at such party's own risk.  The original  
  *  developer of this software module and his/her company, and subsequent  
  *  editors and their companies, will have no liability for use of this  
  *  software or modifications or derivatives thereof.  
8   *   *
9   *  This program is free software; you can redistribute it and/or modify   *  This program is free software; you can redistribute it and/or modify
10   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
# Line 26  Line 20 
20   *  along with this program; if not, write to the Free Software   *  along with this program; if not, write to the Free Software
21   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   *   *
  *************************************************************************/  
   
 /**************************************************************************  
  *  
  *  History:  
  *  
  *  15.07.2002  fix a bug in B-frame decode at DIRECT mode  
  *              MinChen <chenm001@163.com>  
  *  10.07.2002  added BFRAMES_DEC_DEBUG support  
  *              Fix a little bug for low_delay flage  
  *              MinChen <chenm001@163.com>  
  *  28.06.2002  added basic resync support to iframe/pframe_decode()  
  *  22.06.2002  added primative N_VOP support  
  *                              #define BFRAMES_DEC now enables Minchen's bframe decoder  
  *  08.05.2002  add low_delay support for B_VOP decode  
  *              MinChen <chenm001@163.com>  
  *  05.05.2002  fix some B-frame decode problem  
  *  02.05.2002  add B-frame decode support(have some problem);  
  *              MinChen <chenm001@163.com>  
  *  22.04.2002  add some B-frame decode support;  chenm001 <chenm001@163.com>  
  *  29.03.2002  interlacing fix - compensated block wasn't being used when  
  *              reconstructing blocks, thus artifacts  
  *              interlacing speedup - used transfers to re-interlace  
  *              interlaced decoding should be as fast as progressive now  
  *  26.03.2002  interlacing support - moved transfers outside decode loop  
  *  26.12.2001  decoder_mbinter: dequant/idct moved within if(coded) block  
  *  22.12.2001  lock based interpolation  
  *  01.12.2001  inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
  *  
23   *  $Id$   *  $Id$
24   *   *
25   *************************************************************************/   ****************************************************************************/
26    
27    #include <stdio.h>
28  #include <stdlib.h>  #include <stdlib.h>
29  #include <string.h>  #include <string.h>
30    
# Line 68  Line 34 
34    
35  #include "xvid.h"  #include "xvid.h"
36  #include "portab.h"  #include "portab.h"
37    #include "global.h"
38    
39  #include "decoder.h"  #include "decoder.h"
40  #include "bitstream/bitstream.h"  #include "bitstream/bitstream.h"
41  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
42    
43  #include "quant/quant_h263.h"  #include "quant/quant.h"
44  #include "quant/quant_mpeg4.h"  #include "quant/quant_matrix.h"
45  #include "dct/idct.h"  #include "dct/idct.h"
46  #include "dct/fdct.h"  #include "dct/fdct.h"
47  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
48  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
49    #include "image/font.h"
50    #include "image/qpel.h"
51    
52  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
53  #include "prediction/mbprediction.h"  #include "prediction/mbprediction.h"
54  #include "utils/timer.h"  #include "utils/timer.h"
55  #include "utils/emms.h"  #include "utils/emms.h"
56  #include "motion/motion.h"  #include "motion/motion.h"
57    #include "motion/gmc.h"
58    
59  #include "image/image.h"  #include "image/image.h"
60  #include "image/colorspace.h"  #include "image/colorspace.h"
61    #include "image/postprocessing.h"
62  #include "utils/mem_align.h"  #include "utils/mem_align.h"
63    
64  int  #define DIV2ROUND(n)  (((n)>>1)|((n)&1))
65    #define DIV2(n)       ((n)>>1)
66    #define DIVUVMOV(n) (((n) >> 1) + roundtab_79[(n) & 0x3]) //
67    
68    static int
69  decoder_resize(DECODER * dec)  decoder_resize(DECODER * dec)
70  {  {
71          /* free existing */          /* free existing */
72            image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
73          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
74          image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);          image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
75          image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);          image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
76          image_destroy(&dec->refh, dec->edged_width, dec->edged_height);          image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);
77          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);  
78            image_destroy(&dec->gmc, dec->edged_width, dec->edged_height);
79    
80      image_null(&dec->cur);
81      image_null(&dec->refn[0]);
82      image_null(&dec->refn[1]);
83      image_null(&dec->tmp);
84      image_null(&dec->qtmp);
85      image_null(&dec->gmc);
86    
87    
         if (dec->last_mbs)  
88                  xvid_free(dec->last_mbs);                  xvid_free(dec->last_mbs);
         if (dec->mbs)  
89                  xvid_free(dec->mbs);                  xvid_free(dec->mbs);
90      xvid_free(dec->qscale);
91      dec->last_mbs = NULL;
92      dec->mbs = NULL;
93      dec->qscale = NULL;
94    
95          /* realloc */          /* realloc */
   
96          dec->mb_width = (dec->width + 15) / 16;          dec->mb_width = (dec->width + 15) / 16;
97          dec->mb_height = (dec->height + 15) / 16;          dec->mb_height = (dec->height + 15) / 16;
98    
99          dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;          dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;
100          dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;          dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;
101    
102          if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) {          if (   image_create(&dec->cur, dec->edged_width, dec->edged_height)
103                  xvid_free(dec);              || image_create(&dec->refn[0], dec->edged_width, dec->edged_height)
104                  return XVID_ERR_MEMORY;              || image_create(&dec->refn[1], dec->edged_width, dec->edged_height)         /* Support B-frame to reference last 2 frame */
105          }              || image_create(&dec->tmp, dec->edged_width, dec->edged_height)
106                || image_create(&dec->qtmp, dec->edged_width, dec->edged_height)
107          if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height)) {        || image_create(&dec->gmc, dec->edged_width, dec->edged_height) )
108                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);      goto memory_error;
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
   
         // add by chenm001 <chenm001@163.com>  
         // for support B-frame to reference last 2 frame  
         if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {  
                 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
         if (image_create(&dec->refn[2], dec->edged_width, dec->edged_height)) {  
                 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
   
         if (image_create(&dec->refh, dec->edged_width, dec->edged_height)) {  
                 image_destroy(&dec->cur, dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
109    
110          dec->mbs =          dec->mbs =
111                  xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,                  xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
112                                          CACHE_LINE);                                          CACHE_LINE);
113          if (dec->mbs == NULL) {          if (dec->mbs == NULL)
114                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);            goto memory_error;
                 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->refh, dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
115          memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);          memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
116    
117          // add by chenm001 <chenm001@163.com>          /* For skip MB flag */
         // for skip MB flag  
118          dec->last_mbs =          dec->last_mbs =
119                  xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,                  xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
120                                          CACHE_LINE);                                          CACHE_LINE);
121          if (dec->last_mbs == NULL) {          if (dec->last_mbs == NULL)
122              goto memory_error;
123            memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
124    
125            /* nothing happens if that fails */
126            dec->qscale =
127                    xvid_malloc(sizeof(int) * dec->mb_width * dec->mb_height, CACHE_LINE);
128    
129            if (dec->qscale)
130                    memset(dec->qscale, 0, sizeof(int) * dec->mb_width * dec->mb_height);
131    
132            return 0;
133    
134    memory_error:
135            /* Most structures were deallocated / nullifieded, so it should be safe */
136            /* decoder_destroy(dec) minus the write_timer */
137                  xvid_free(dec->mbs);                  xvid_free(dec->mbs);
138                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);                  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
139                  image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);                  image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
140                  image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);                  image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
141                  image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);    image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
142                  image_destroy(&dec->refh, dec->edged_width, dec->edged_height);    image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);
143    
144                  xvid_free(dec);                  xvid_free(dec);
145                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
146          }          }
147    
         memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);  
   
         return XVID_ERR_OK;  
 }  
   
148    
149  int  int
150  decoder_create(XVID_DEC_PARAM * param)  decoder_create(xvid_dec_create_t * create)
151  {  {
152          DECODER *dec;          DECODER *dec;
153    
154      if (XVID_VERSION_MAJOR(create->version) != 1) /* v1.x.x */
155        return XVID_ERR_VERSION;
156    
157          dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);          dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
158          if (dec == NULL) {          if (dec == NULL) {
159                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
160          }          }
161    
162          memset(dec, 0, sizeof(DECODER));          memset(dec, 0, sizeof(DECODER));
163    
164          param->handle = dec;    dec->mpeg_quant_matrices = xvid_malloc(sizeof(uint16_t) * 64 * 8, CACHE_LINE);
165      if (dec->mpeg_quant_matrices == NULL) {
166        xvid_free(dec);
167        return XVID_ERR_MEMORY;
168      }
169    
170      create->handle = dec;
171    
172          dec->width = param->width;    dec->width = create->width;
173          dec->height = param->height;    dec->height = create->height;
174    
175          image_null(&dec->cur);          image_null(&dec->cur);
176          image_null(&dec->refn[0]);          image_null(&dec->refn[0]);
177          image_null(&dec->refn[1]);          image_null(&dec->refn[1]);
178          image_null(&dec->refn[2]);    image_null(&dec->tmp);
179          image_null(&dec->refh);    image_null(&dec->qtmp);
180    
181      /* image based GMC */
182      image_null(&dec->gmc);
183    
184          dec->mbs = NULL;          dec->mbs = NULL;
185          dec->last_mbs = NULL;          dec->last_mbs = NULL;
186      dec->qscale = NULL;
187    
188          init_timer();          init_timer();
189      init_postproc(&dec->postproc);
190      init_mpeg_matrix(dec->mpeg_quant_matrices);
191    
192          // add by chenm001 <chenm001@163.com>    /* For B-frame support (used to save reference frame's time */
193          // for support B-frame to save reference frame's time    dec->frames = 0;
         dec->frames = -1;  
194          dec->time = dec->time_base = dec->last_time_base = 0;          dec->time = dec->time_base = dec->last_time_base = 0;
195          dec->low_delay = 0;          dec->low_delay = 0;
196      dec->packed_mode = 0;
197      dec->time_inc_resolution = 1; /* until VOL header says otherwise */
198    
199      dec->bs_version = 0xffff; /* Initialize to very high value -> assume bugfree stream */
200    
201          dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);          dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);
202    
203          if (dec->fixed_dimensions)          if (dec->fixed_dimensions)
204                  return decoder_resize(dec);                  return decoder_resize(dec);
205          else          else
206                  return XVID_ERR_OK;      return 0;
207  }  }
208    
209    
# Line 233  Line 212 
212  {  {
213          xvid_free(dec->last_mbs);          xvid_free(dec->last_mbs);
214          xvid_free(dec->mbs);          xvid_free(dec->mbs);
215      xvid_free(dec->qscale);
216    
217      /* image based GMC */
218      image_destroy(&dec->gmc, dec->edged_width, dec->edged_height);
219    
220          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
221          image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);          image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
222          image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);    image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
223          image_destroy(&dec->refh, dec->edged_width, dec->edged_height);    image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);
224          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
225      xvid_free(dec->mpeg_quant_matrices);
226          xvid_free(dec);          xvid_free(dec);
227    
228          write_timer();          write_timer();
229          return XVID_ERR_OK;    return 0;
230  }  }
231    
   
   
232  static const int32_t dquant_table[4] = {  static const int32_t dquant_table[4] = {
233          -1, -2, 1, 2          -1, -2, 1, 2
234  };  };
235    
236    /* decode an intra macroblock */
237    static void
   
 // decode an intra macroblock  
   
 void  
238  decoder_mbintra(DECODER * dec,  decoder_mbintra(DECODER * dec,
239                                  MACROBLOCK * pMB,                                  MACROBLOCK * pMB,
240                                  const uint32_t x_pos,                                  const uint32_t x_pos,
# Line 282  Line 261 
261          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
262          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
263    
264          memset(block, 0, 6 * 64 * sizeof(int16_t));     // clear    memset(block, 0, 6 * 64 * sizeof(int16_t)); /* clear */
265    
266          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
267                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);                  uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
# Line 305  Line 284 
284                          dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0;                          dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0;
285    
286                          if (dc_size > 8) {                          if (dc_size > 8) {
287                                  BitstreamSkip(bs, 1);   // marker          BitstreamSkip(bs, 1); /* marker */
288                          }                          }
289    
290                          block[i * 64 + 0] = dc_dif;                          block[i * 64 + 0] = dc_dif;
291                          start_coeff = 1;                          start_coeff = 1;
292    
293                          DPRINTF(DPRINTF_COEFF,"block[0] %i", dc_dif);        DPRINTF(XVID_DEBUG_COEFF,"block[0] %i\n", dc_dif);
294                  } else {                  } else {
295                          start_coeff = 0;                          start_coeff = 0;
296                  }                  }
297    
298                  start_timer();                  start_timer();
299                  if (cbp & (1 << (5 - i)))       // coded      if (cbp & (1 << (5 - i))) /* coded */
300                  {                  {
301                          int direction = dec->alternate_vertical_scan ?                          int direction = dec->alternate_vertical_scan ?
302                                  2 : pMB->acpred_directions[i];                                  2 : pMB->acpred_directions[i];
# Line 327  Line 306 
306                  stop_coding_timer();                  stop_coding_timer();
307    
308                  start_timer();                  start_timer();
309                  add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors);      add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors, dec->bs_version);
310                  stop_prediction_timer();                  stop_prediction_timer();
311    
312                  start_timer();                  start_timer();
313                  if (dec->quant_type == 0) {                  if (dec->quant_type == 0) {
314                          dequant_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler);        dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
315                  } else {                  } else {
316                          dequant4_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler);        dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
317                  }                  }
318                  stop_iquant_timer();                  stop_iquant_timer();
319    
320                  start_timer();                  start_timer();
321                  idct(&data[i * 64]);      idct((short * const)&data[i * 64]);
322                  stop_idct_timer();                  stop_idct_timer();
323    
324          }          }
325    
326          if (dec->interlacing && pMB->field_dct) {          if (dec->interlacing && pMB->field_dct) {
# Line 358  Line 338 
338          stop_transfer_timer();          stop_transfer_timer();
339  }  }
340    
341    static void
342    decoder_mb_decode(DECODER * dec,
343            const uint32_t cbp,
344            Bitstream * bs,
345            uint8_t * pY_Cur,
346            uint8_t * pU_Cur,
347            uint8_t * pV_Cur,
348            const MACROBLOCK * pMB)
349    {
350      DECLARE_ALIGNED_MATRIX(data, 1, 64, int16_t, CACHE_LINE);
351    
352      int stride = dec->edged_width;
353      int i;
354      const uint32_t iQuant = pMB->quant;
355      const int direction = dec->alternate_vertical_scan ? 2 : 0;
356      typedef void (*get_inter_block_function_t)(
357          Bitstream * bs,
358          int16_t * block,
359          int direction,
360          const int quant,
361          const uint16_t *matrix);
362      typedef void (*add_residual_function_t)(
363          uint8_t *predicted_block,
364          const int16_t *residual,
365          int stride);
366    
367      const get_inter_block_function_t get_inter_block = (dec->quant_type == 0)
368        ? (get_inter_block_function_t)get_inter_block_h263
369        : (get_inter_block_function_t)get_inter_block_mpeg;
370    
371      uint8_t *dst[6];
372      int strides[6];
373    
374    
375      if (dec->interlacing && pMB->field_dct) {
376        dst[0] = pY_Cur;
377        dst[1] = pY_Cur + 8;
378        dst[2] = pY_Cur + stride;
379        dst[3] = dst[2] + 8;
380        dst[4] = pU_Cur;
381        dst[5] = pV_Cur;
382        strides[0] = strides[1] = strides[2] = strides[3] = stride*2;
383        strides[4] = stride/2;
384        strides[5] = stride/2;
385      } else {
386        dst[0] = pY_Cur;
387        dst[1] = pY_Cur + 8;
388        dst[2] = pY_Cur + 8*stride;
389        dst[3] = dst[2] + 8;
390        dst[4] = pU_Cur;
391        dst[5] = pV_Cur;
392        strides[0] = strides[1] = strides[2] = strides[3] = stride;
393        strides[4] = stride/2;
394        strides[5] = stride/2;
395      }
396    
397      for (i = 0; i < 6; i++) {
398        /* Process only coded blocks */
399        if (cbp & (1 << (5 - i))) {
400    
401          /* Clear the block */
402          memset(&data[0], 0, 64*sizeof(int16_t));
403    
404          /* Decode coeffs and dequantize on the fly */
405          start_timer();
406          get_inter_block(bs, &data[0], direction, iQuant, get_inter_matrix(dec->mpeg_quant_matrices));
407          stop_coding_timer();
408    
409          /* iDCT */
410          start_timer();
411          idct((short * const)&data[0]);
412          stop_idct_timer();
413    
414  #define SIGN(X) (((X)>0)?1:-1)        /* Add this residual to the predicted block */
415  #define ABS(X) (((X)>0)?(X):-(X))        start_timer();
416          transfer_16to8add(dst[i], &data[0], strides[i]);
417          stop_transfer_timer();
418        }
419      }
420    }
421    
422  // decode an inter macroblock  static void __inline
423    validate_vector(VECTOR * mv, unsigned int x_pos, unsigned int y_pos, const DECODER * dec)
424    {
425      /* clip a vector to valid range
426         prevents crashes if bitstream is broken
427      */
428      int shift = 5 + dec->quarterpel;
429      int xborder_high = (int)(dec->mb_width - x_pos) << shift;
430      int xborder_low = (-(int)x_pos-1) << shift;
431      int yborder_high = (int)(dec->mb_height - y_pos) << shift;
432      int yborder_low = (-(int)y_pos-1) << shift;
433    
434    #define CHECK_MV(mv) \
435      do { \
436      if ((mv).x > xborder_high) { \
437        DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", (mv).x, xborder_high, x_pos, y_pos); \
438        (mv).x = xborder_high; \
439      } else if ((mv).x < xborder_low) { \
440        DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", (mv).x, xborder_low, x_pos, y_pos); \
441        (mv).x = xborder_low; \
442      } \
443      if ((mv).y > yborder_high) { \
444        DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", (mv).y, yborder_high, x_pos, y_pos); \
445        (mv).y = yborder_high; \
446      } else if ((mv).y < yborder_low) { \
447        DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", (mv).y, yborder_low, x_pos, y_pos); \
448        (mv).y = yborder_low; \
449      } \
450      } while (0)
451    
452      CHECK_MV(mv[0]);
453      CHECK_MV(mv[1]);
454      CHECK_MV(mv[2]);
455      CHECK_MV(mv[3]);
456    }
457    
458    /* Up to this version, chroma rounding was wrong with qpel.
459     * So we try to be backward compatible to avoid artifacts */
460    #define BS_VERSION_BUGGY_CHROMA_ROUNDING 1
461    
462  void  /* decode an inter macroblock */
463    static void
464  decoder_mbinter(DECODER * dec,  decoder_mbinter(DECODER * dec,
465                                  const MACROBLOCK * pMB,                                  const MACROBLOCK * pMB,
466                                  const uint32_t x_pos,                                  const uint32_t x_pos,
467                                  const uint32_t y_pos,                                  const uint32_t y_pos,
                                 const uint32_t acpred_flag,  
468                                  const uint32_t cbp,                                  const uint32_t cbp,
469                                  Bitstream * bs,                                  Bitstream * bs,
470                                  const uint32_t quant,          const uint32_t rounding,
471                                  const uint32_t rounding)          const int ref,
472                    const int bvop)
473  {  {
   
         DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);  
         DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);  
   
474          uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
475          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
         uint32_t next_block = stride * 8;  
476          uint32_t i;          uint32_t i;
477          uint32_t iQuant = pMB->quant;  
478          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
479    
480          int uv_dx, uv_dy;          int uv_dx, uv_dy;
481      VECTOR mv[4]; /* local copy of mvs */
482    
483          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
484          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
485          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
486      for (i = 0; i < 4; i++)
487        mv[i] = pMB->mvs[i];
488    
489          if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {    validate_vector(mv, x_pos, y_pos, dec);
                 uv_dx = pMB->mvs[0].x;  
                 uv_dy = pMB->mvs[0].y;  
490    
491                  if (dec->quarterpel)    start_timer();
492                  {  
493      if ((pMB->mode != MODE_INTER4V) || (bvop)) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
494    
495        uv_dx = mv[0].x;
496        uv_dy = mv[0].y;
497        if (dec->quarterpel) {
498                            if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
499                                    uv_dx = (uv_dx>>1) | (uv_dx&1);
500                                    uv_dy = (uv_dy>>1) | (uv_dy&1);
501                            }
502                            else {
503                          uv_dx /= 2;                          uv_dx /= 2;
504                          uv_dy /= 2;                          uv_dy /= 2;
505                  }                  }
506        }
507                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
508                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
509    
510                  start_timer();      if (dec->quarterpel)
511          interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->qtmp.y, dec->qtmp.y + 64,
512                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
513                          mv[0].x, mv[0].y, stride, rounding);
514        else
515          interpolate16x16_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos, 16*y_pos,
516                      mv[0].x, mv[0].y, stride, rounding);
517    
518      } else {  /* MODE_INTER4V */
519    
520                  if(dec->quarterpel) {                  if(dec->quarterpel) {
521                          interpolate16x16_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
522                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,                                  int z;
523                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                                  uv_dx = 0; uv_dy = 0;
524                                    for (z = 0; z < 4; z++) {
525                                      uv_dx += ((mv[z].x>>1) | (mv[z].x&1));
526                                      uv_dy += ((mv[z].y>>1) | (mv[z].y&1));
527                                    }
528                  }                  }
529                  else {                  else {
530            uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);
531            uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);
532          }
533        } else {
534          uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x;
535          uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y;
536        }
537    
538        uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];
539        uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];
540    
541        if (dec->quarterpel) {
542          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,
543                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
544                      mv[0].x, mv[0].y, stride, rounding);
545          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,
546                      dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
547                      mv[1].x, mv[1].y, stride, rounding);
548          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,
549                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
550                      mv[2].x, mv[2].y, stride, rounding);
551          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,
552                      dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
553                      mv[3].x, mv[3].y, stride, rounding);
554        } else {
555                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,
556                                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                  mv[0].x, mv[0].y, stride, rounding);
557                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos,                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos,
558                                                                pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);                  mv[1].x, mv[1].y, stride, rounding);
559                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8,                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8,
560                                                                    pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);                  mv[2].x, mv[2].y, stride, rounding);
561                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8,                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8,
562                                                                    pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);                  mv[3].x, mv[3].y, stride, rounding);
563        }
564                  }                  }
565    
566                  interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,    /* chroma */
567      interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,
568                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
569                  interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,    interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,
570                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
571    
572                  stop_comp_timer();                  stop_comp_timer();
573    
574          } else {    if (cbp)
575                  int sum;      decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
576    }
577    
578                  if(dec->quarterpel)  /* decode an inter macroblock in field mode */
579                          sum = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);  static void
580                  else  decoder_mbinter_field(DECODER * dec,
581                          sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;          const MACROBLOCK * pMB,
582            const uint32_t x_pos,
583            const uint32_t y_pos,
584            const uint32_t cbp,
585            Bitstream * bs,
586            const uint32_t rounding,
587            const int ref,
588                    const int bvop)
589    {
590      uint32_t stride = dec->edged_width;
591      uint32_t stride2 = stride / 2;
592    
593      uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
594    
595                  uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];    int uvtop_dx, uvtop_dy;
596      int uvbot_dx, uvbot_dy;
597      VECTOR mv[4]; /* local copy of mvs */
598    
599                  if(dec->quarterpel)    /* Get pointer to memory areas */
600                          sum = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);    pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
601                  else    pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
602                          sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;    pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
603    
604                  uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];    mv[0] = pMB->mvs[0];
605      mv[1] = pMB->mvs[1];
606      memset(&mv[2],0,2*sizeof(VECTOR));
607    
608      validate_vector(mv, x_pos, y_pos, dec);
609    
610                  start_timer();                  start_timer();
611                  if(dec->quarterpel) {  
612                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,    if((pMB->mode!=MODE_INTER4V) || (bvop))   /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
613                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos,    {
614                                                                            pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);      /* Prepare top field vector */
615                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,      uvtop_dx = DIV2ROUND(mv[0].x);
616                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,      uvtop_dy = DIV2ROUND(mv[0].y);
617                                                                            pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);  
618                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,      /* Prepare bottom field vector */
619                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,      uvbot_dx = DIV2ROUND(mv[1].x);
620                                                                            pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);      uvbot_dy = DIV2ROUND(mv[1].y);
621                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,  
622                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,      if(dec->quarterpel)
623                                                                            pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);      {
624          /* NOT supported */
625                  }                  }
626                  else {      else
627                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,      {
628                                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);        /* Interpolate top field left part(we use double stride for every 2nd line) */
629                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos,        interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
630                                                                    pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);                              16*x_pos,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
631                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8,        /* top field right part */
632                                                                    pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);        interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
633                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8,                              16*x_pos+8,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
634                                                                    pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);  
635          /* Interpolate bottom field left part(we use double stride for every 2nd line) */
636          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
637                                16*x_pos,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
638          /* Bottom field right part */
639          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
640                                16*x_pos+8,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
641    
642          /* Interpolate field1 U */
643          interpolate8x4_switch(dec->cur.u,dec->refn[ref].u+pMB->field_for_top*stride2,
644                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
645    
646          /* Interpolate field1 V */
647          interpolate8x4_switch(dec->cur.v,dec->refn[ref].v+pMB->field_for_top*stride2,
648                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
649    
650          /* Interpolate field2 U */
651          interpolate8x4_switch(dec->cur.u+stride2,dec->refn[ref].u+pMB->field_for_bot*stride2,
652                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
653    
654          /* Interpolate field2 V */
655          interpolate8x4_switch(dec->cur.v+stride2,dec->refn[ref].v+pMB->field_for_bot*stride2,
656                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
657        }
658      }
659      else
660      {
661        /* We don't expect 4 motion vectors in interlaced mode */
662                  }                  }
663    
                 interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,  
                                                           uv_dx, uv_dy, stride2, rounding);  
                 interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,  
                                                           uv_dx, uv_dy, stride2, rounding);  
664                  stop_comp_timer();                  stop_comp_timer();
         }  
665    
666          for (i = 0; i < 6; i++) {    /* Must add error correction? */
667                  int direction = dec->alternate_vertical_scan ? 2 : 0;    if(cbp)
668       decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
669    }
670    
671                  if (cbp & (1 << (5 - i)))       // coded  static void
672    decoder_mbgmc(DECODER * dec,
673            MACROBLOCK * const pMB,
674            const uint32_t x_pos,
675            const uint32_t y_pos,
676            const uint32_t fcode,
677            const uint32_t cbp,
678            Bitstream * bs,
679            const uint32_t rounding)
680                  {                  {
681                          memset(&block[i * 64], 0, 64 * sizeof(int16_t));        // clear    const uint32_t stride = dec->edged_width;
682      const uint32_t stride2 = stride / 2;
683    
684                          start_timer();    uint8_t *const pY_Cur=dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
685                          get_inter_block(bs, &block[i * 64], direction);    uint8_t *const pU_Cur=dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
686                          stop_coding_timer();    uint8_t *const pV_Cur=dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
687    
688                          start_timer();    NEW_GMC_DATA * gmc_data = &dec->new_gmc_data;
689                          if (dec->quant_type == 0) {  
690                                  dequant_inter(&data[i * 64], &block[i * 64], iQuant);    pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;
                         } else {  
                                 dequant4_inter(&data[i * 64], &block[i * 64], iQuant);  
                         }  
                         stop_iquant_timer();  
691    
692                          start_timer();                          start_timer();
                         idct(&data[i * 64]);  
                         stop_idct_timer();  
                 }  
         }  
693    
694          if (dec->interlacing && pMB->field_dct) {  /* this is where the calculations are done */
695                  next_block = stride;  
696                  stride *= 2;    gmc_data->predict_16x16(gmc_data,
697          }        dec->cur.y + y_pos*16*stride + x_pos*16, dec->refn[0].y,
698          stride, stride, x_pos, y_pos, rounding);
699    
700      gmc_data->predict_8x8(gmc_data,
701          dec->cur.u + y_pos*8*stride2 + x_pos*8, dec->refn[0].u,
702          dec->cur.v + y_pos*8*stride2 + x_pos*8, dec->refn[0].v,
703          stride2, stride2, x_pos, y_pos, rounding);
704    
705      gmc_data->get_average_mv(gmc_data, &pMB->amv, x_pos, y_pos, dec->quarterpel);
706    
707      pMB->amv.x = gmc_sanitize(pMB->amv.x, dec->quarterpel, fcode);
708      pMB->amv.y = gmc_sanitize(pMB->amv.y, dec->quarterpel, fcode);
709    
710      pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;
711    
         start_timer();  
         if (cbp & 32)  
                 transfer_16to8add(pY_Cur, &data[0 * 64], stride);  
         if (cbp & 16)  
                 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);  
         if (cbp & 8)  
                 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);  
         if (cbp & 4)  
                 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);  
         if (cbp & 2)  
                 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);  
         if (cbp & 1)  
                 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);  
712          stop_transfer_timer();          stop_transfer_timer();
713    
714      if (cbp)
715        decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
716    
717  }  }
718    
719    
720  void  static void
721  decoder_iframe(DECODER * dec,  decoder_iframe(DECODER * dec,
722                             Bitstream * bs,                             Bitstream * bs,
                            int reduced_resolution,  
723                             int quant,                             int quant,
724                             int intra_dc_threshold)                             int intra_dc_threshold)
725  {  {
726          uint32_t bound;          uint32_t bound;
727          uint32_t x, y;          uint32_t x, y;
728          int mb_width = dec->mb_width;    const uint32_t mb_width = dec->mb_width;
729          int mb_height = dec->mb_height;    const uint32_t mb_height = dec->mb_height;
   
         if (reduced_resolution)  
         {  
                 mb_width /= 2;  
                 mb_height /= 2;  
         }  
730    
731          bound = 0;          bound = 0;
732    
# Line 563  Line 746 
746                          {                          {
747                                  bound = read_video_packet_header(bs, dec, 0,                                  bound = read_video_packet_header(bs, dec, 0,
748                                                          &quant, NULL, NULL, &intra_dc_threshold);                                                          &quant, NULL, NULL, &intra_dc_threshold);
749                                  x = bound % dec->mb_width;          x = bound % mb_width;
750                                  y = bound / dec->mb_width;          y = bound / mb_width;
751                          }                          }
752                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
753    
754                          DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", x, y, BitstreamShowBits(bs, 32));        DPRINTF(XVID_DEBUG_MB, "macroblock (%i,%i) %08x\n", x, y, BitstreamShowBits(bs, 32));
755    
756                          mcbpc = get_mcbpc_intra(bs);                          mcbpc = get_mcbpc_intra(bs);
757                          mb->mode = mcbpc & 7;                          mb->mode = mcbpc & 7;
# Line 595  Line 778 
778    
779                          if (dec->interlacing) {                          if (dec->interlacing) {
780                                  mb->field_dct = BitstreamGetBit(bs);                                  mb->field_dct = BitstreamGetBit(bs);
781                                  DEBUG1("deci: field_dct: ", mb->field_dct);          DPRINTF(XVID_DEBUG_MB,"deci: field_dct: %i\n", mb->field_dct);
782                          }                          }
783    
784                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
# Line 603  Line 786 
786    
787                  }                  }
788                  if(dec->out_frm)                  if(dec->out_frm)
789                    output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,0,y,dec->mb_width);        output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,0,y,mb_width);
790          }          }
791    
792  }  }
793    
794    
795  void  static void
796  get_motion_vector(DECODER * dec,  get_motion_vector(DECODER * dec,
797                                    Bitstream * bs,                                    Bitstream * bs,
798                                    int x,                                    int x,
799                                    int y,                                    int y,
800                                    int k,                                    int k,
801                                    VECTOR * mv,          VECTOR * ret_mv,
802                                    int fcode,                                    int fcode,
803                                    const int bound)                                    const int bound)
804  {  {
805    
806          int scale_fac = 1 << (fcode - 1);    const int scale_fac = 1 << (fcode - 1);
807          int high = (32 * scale_fac) - 1;    const int high = (32 * scale_fac) - 1;
808          int low = ((-32) * scale_fac);    const int low = ((-32) * scale_fac);
809          int range = (64 * scale_fac);    const int range = (64 * scale_fac);
810    
811          VECTOR pmv;    const VECTOR pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);
812          int mv_x, mv_y;    VECTOR mv;
   
         pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);  
813    
814          mv_x = get_mv(bs, fcode);    mv.x = get_mv(bs, fcode);
815          mv_y = get_mv(bs, fcode);    mv.y = get_mv(bs, fcode);
816    
817          DPRINTF(DPRINTF_MV,"mv_diff (%i,%i) pred (%i,%i)", mv_x, mv_y, pmv.x, pmv.y);    DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", mv.x, mv.y, pmv.x, pmv.y, mv.x+pmv.x, mv.y+pmv.y);
818    
819          mv_x += pmv.x;    mv.x += pmv.x;
820          mv_y += pmv.y;    mv.y += pmv.y;
821    
822          if (mv_x < low) {    if (mv.x < low) {
823                  mv_x += range;      mv.x += range;
824          } else if (mv_x > high) {    } else if (mv.x > high) {
825                  mv_x -= range;      mv.x -= range;
826          }          }
827    
828          if (mv_y < low) {    if (mv.y < low) {
829                  mv_y += range;      mv.y += range;
830          } else if (mv_y > high) {    } else if (mv.y > high) {
831                  mv_y -= range;      mv.y -= range;
832          }          }
833    
834          mv->x = mv_x;    ret_mv->x = mv.x;
835          mv->y = mv_y;    ret_mv->y = mv.y;
836  }  }
837    
838    /* We use this when decoder runs interlaced -> different prediction */
839    
840    static void get_motion_vector_interlaced(DECODER * dec,
841            Bitstream * bs,
842            int x,
843            int y,
844            int k,
845            MACROBLOCK *pMB,
846            int fcode,
847            const int bound)
848    {
849      const int scale_fac = 1 << (fcode - 1);
850      const int high = (32 * scale_fac) - 1;
851      const int low = ((-32) * scale_fac);
852      const int range = (64 * scale_fac);
853    
854      /* Get interlaced prediction */
855      const VECTOR pmv=get_pmv2_interlaced(dec->mbs,dec->mb_width,bound,x,y,k);
856      VECTOR mv,mvf1,mvf2;
857    
858      if(!pMB->field_pred)
859      {
860        mv.x = get_mv(bs,fcode);
861        mv.y = get_mv(bs,fcode);
862    
863        mv.x += pmv.x;
864        mv.y += pmv.y;
865    
866        if(mv.x<low) {
867          mv.x += range;
868        } else if (mv.x>high) {
869          mv.x-=range;
870        }
871    
872        if (mv.y < low) {
873          mv.y += range;
874        } else if (mv.y > high) {
875          mv.y -= range;
876        }
877    
878  static __inline int gmc_sanitize(int value, int quarterpel, int fcode)      pMB->mvs[0]=pMB->mvs[1]=pMB->mvs[2]=pMB->mvs[3]=mv;
879      }
880      else
881  {  {
882          int length = 1 << (fcode+4);      mvf1.x = get_mv(bs, fcode);
883        mvf1.y = get_mv(bs, fcode);
884    
885        mvf1.x += pmv.x;
886        mvf1.y = 2*(mvf1.y+pmv.y/2); /* It's multiple of 2 */
887    
888        if (mvf1.x < low) {
889          mvf1.x += range;
890        } else if (mvf1.x > high) {
891          mvf1.x -= range;
892        }
893    
894        if (mvf1.y < low) {
895          mvf1.y += range;
896        } else if (mvf1.y > high) {
897          mvf1.y -= range;
898        }
899    
900        mvf2.x = get_mv(bs, fcode);
901        mvf2.y = get_mv(bs, fcode);
902    
903          if (quarterpel) value *= 2;      mvf2.x += pmv.x;
904        mvf2.y = 2*(mvf2.y+pmv.y/2); /* It's multiple of 2 */
905    
906        if (mvf2.x < low) {
907          mvf2.x += range;
908        } else if (mvf2.x > high) {
909          mvf2.x -= range;
910        }
911    
912          if (value < -length)      if (mvf2.y < low) {
913                  return -length;        mvf2.y += range;
914          else if (value >= length)      } else if (mvf2.y > high) {
915                  return length-1;        mvf2.y -= range;
         else return value;  
916  }  }
917    
918        pMB->mvs[0]=mvf1;
919        pMB->mvs[1]=mvf2;
920        pMB->mvs[2].x=pMB->mvs[3].x=0;
921        pMB->mvs[2].y=pMB->mvs[3].y=0;
922    
923  /* for P_VOP set gmc_mv to NULL */      /* Calculate average for as it is field predicted */
924  void      pMB->mvs_avg.x=DIV2ROUND(pMB->mvs[0].x+pMB->mvs[1].x);
925        pMB->mvs_avg.y=DIV2ROUND(pMB->mvs[0].y+pMB->mvs[1].y);
926      }
927    }
928    
929    /* for P_VOP set gmc_warp to NULL */
930    static void
931  decoder_pframe(DECODER * dec,  decoder_pframe(DECODER * dec,
932                             Bitstream * bs,                             Bitstream * bs,
933                             int rounding,                             int rounding,
                            int reduced_resolution,  
934                             int quant,                             int quant,
935                             int fcode,                             int fcode,
936                             int intra_dc_threshold,                             int intra_dc_threshold,
937                             VECTOR * gmc_mv)          const WARPPOINTS *const gmc_warp)
938  {  {
   
939          uint32_t x, y;          uint32_t x, y;
940          uint32_t bound;          uint32_t bound;
941          int cp_mb, st_mb;          int cp_mb, st_mb;
942      const uint32_t mb_width = dec->mb_width;
943      const uint32_t mb_height = dec->mb_height;
944    
945      if (!dec->is_edged[0]) {
946          start_timer();          start_timer();
947          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
948                                     dec->width, dec->height);              dec->width, dec->height, dec->bs_version);
949        dec->is_edged[0] = 1;
950          stop_edges_timer();          stop_edges_timer();
951      }
952    
953      if (gmc_warp) {
954        /* accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16 */
955        generate_GMCparameters( dec->sprite_warping_points,
956            dec->sprite_warping_accuracy, gmc_warp,
957            dec->width, dec->height, &dec->new_gmc_data);
958    
959        /* image warping is done block-based in decoder_mbgmc(), now */
960      }
961    
962          bound = 0;          bound = 0;
963    
964          for (y = 0; y < dec->mb_height; y++) {    for (y = 0; y < mb_height; y++) {
965                  cp_mb = st_mb = 0;                  cp_mb = st_mb = 0;
966                  for (x = 0; x < dec->mb_width; x++) {      for (x = 0; x < mb_width; x++) {
967                          MACROBLOCK *mb;                          MACROBLOCK *mb;
968    
969                          // skip stuffing        /* skip stuffing */
970                          while (BitstreamShowBits(bs, 10) == 1)                          while (BitstreamShowBits(bs, 10) == 1)
971                                  BitstreamSkip(bs, 10);                                  BitstreamSkip(bs, 10);
972    
973                          if (check_resync_marker(bs, fcode - 1))        if (check_resync_marker(bs, fcode - 1)) {
                         {  
974                                  bound = read_video_packet_header(bs, dec, fcode - 1,                                  bound = read_video_packet_header(bs, dec, fcode - 1,
975                                          &quant, &fcode, NULL, &intra_dc_threshold);                                          &quant, &fcode, NULL, &intra_dc_threshold);
976                                  x = bound % dec->mb_width;          x = bound % mb_width;
977                                  y = bound / dec->mb_width;          y = bound / mb_width;
978                          }                          }
979                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
980    
981                          DPRINTF(DPRINTF_MB, "macroblock (%i,%i) %08x", x, y, BitstreamShowBits(bs, 32));        DPRINTF(XVID_DEBUG_MB, "macroblock (%i,%i) %08x\n", x, y, BitstreamShowBits(bs, 32));
982    
983                          //if (!(dec->mb_skip[y*dec->mb_width + x]=BitstreamGetBit(bs)))         // not_coded        if (!(BitstreamGetBit(bs))) { /* block _is_ coded */
984                          if (!(BitstreamGetBit(bs)))     // not_coded          uint32_t mcbpc, cbpc, cbpy, cbp;
985                          {          uint32_t intra, acpred_flag = 0;
986                                  uint32_t mcbpc;          int mcsel = 0;    /* mcsel: '0'=local motion, '1'=GMC */
                                 uint32_t cbpc;  
                                 uint32_t acpred_flag;  
                                 uint32_t cbpy;  
                                 uint32_t cbp;  
                                 uint32_t intra;  
                                 int mcsel = 0;          // mcsel: '0'=local motion, '1'=GMC  
987    
988                                  cp_mb++;                                  cp_mb++;
989                                  mcbpc = get_mcbpc_inter(bs);                                  mcbpc = get_mcbpc_inter(bs);
990                                  mb->mode = mcbpc & 7;                                  mb->mode = mcbpc & 7;
991                                  cbpc = (mcbpc >> 4);                                  cbpc = (mcbpc >> 4);
992    
993                                  DPRINTF(DPRINTF_MB, "mode %i", mb->mode);          DPRINTF(XVID_DEBUG_MB, "mode %i\n", mb->mode);
994                                  DPRINTF(DPRINTF_MB, "cbpc %i", cbpc);          DPRINTF(XVID_DEBUG_MB, "cbpc %i\n", cbpc);
                                 acpred_flag = 0;  
995    
996                                  intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);                                  intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);
997    
998                                  if (intra) {          if (gmc_warp && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q))
                                         acpred_flag = BitstreamGetBit(bs);  
                                 }  
   
                                 if (gmc_mv && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q))  
                                 {  
999                                          mcsel = BitstreamGetBit(bs);                                          mcsel = BitstreamGetBit(bs);
1000                                  }          else if (intra)
1001              acpred_flag = BitstreamGetBit(bs);
1002    
1003                                  cbpy = get_cbpy(bs, intra);                                  cbpy = get_cbpy(bs, intra);
1004                                  DPRINTF(DPRINTF_MB, "cbpy %i", cbpy);          DPRINTF(XVID_DEBUG_MB, "cbpy %i mcsel %i \n", cbpy,mcsel);
1005    
1006                                  cbp = (cbpy << 2) | cbpc;                                  cbp = (cbpy << 2) | cbpc;
1007    
1008                                  if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {                                  if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q) {
1009                                          int dquant = dquant_table[BitstreamGetBits(bs, 2)];                                          int dquant = dquant_table[BitstreamGetBits(bs, 2)];
1010                                          DPRINTF(DPRINTF_MB, "dquant %i", dquant);            DPRINTF(XVID_DEBUG_MB, "dquant %i\n", dquant);
1011                                          quant += dquant;                                          quant += dquant;
1012                                          if (quant > 31) {                                          if (quant > 31) {
1013                                                  quant = 31;                                                  quant = 31;
1014                                          } else if (quant < 1) {                                          } else if (quant < 1) {
1015                                                  quant = 1;                                                  quant = 1;
1016                                          }                                          }
1017                                          DPRINTF(DPRINTF_MB, "quant %i", quant);            DPRINTF(XVID_DEBUG_MB, "quant %i\n", quant);
1018                                  }                                  }
1019                                  mb->quant = quant;                                  mb->quant = quant;
1020    
1021            mb->field_pred=0;
1022                                  if (dec->interlacing) {                                  if (dec->interlacing) {
1023                                          if (cbp || intra) {                                          if (cbp || intra) {
1024                                                  mb->field_dct = BitstreamGetBit(bs);                                                  mb->field_dct = BitstreamGetBit(bs);
1025                                                  DEBUG1("decp: field_dct: ", mb->field_dct);              DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct);
1026                                          }                                          }
1027    
1028                                          if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {            if ((mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) && !mcsel) {
1029                                                  mb->field_pred = BitstreamGetBit(bs);                                                  mb->field_pred = BitstreamGetBit(bs);
1030                                                  DEBUG1("decp: field_pred: ", mb->field_pred);              DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred);
1031    
1032                                                  if (mb->field_pred) {                                                  if (mb->field_pred) {
1033                                                          mb->field_for_top = BitstreamGetBit(bs);                                                          mb->field_for_top = BitstreamGetBit(bs);
1034                                                          DEBUG1("decp: field_for_top: ", mb->field_for_top);                DPRINTF(XVID_DEBUG_MB,"decp: field_for_top: %i\n", mb->field_for_top);
1035                                                          mb->field_for_bot = BitstreamGetBit(bs);                                                          mb->field_for_bot = BitstreamGetBit(bs);
1036                                                          DEBUG1("decp: field_for_bot: ", mb->field_for_bot);                DPRINTF(XVID_DEBUG_MB,"decp: field_for_bot: %i\n", mb->field_for_bot);
1037                                                  }                                                  }
1038                                          }                                          }
1039                                  }                                  }
1040    
1041                                  if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {          if (mcsel) {
1042              decoder_mbgmc(dec, mb, x, y, fcode, cbp, bs, rounding);
1043              continue;
1044    
1045                                          if (mcsel)          } else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
                                         {  
                                                 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = gmc_sanitize(gmc_mv[0].x, dec->quarterpel, fcode);  
                                                 mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = gmc_sanitize(gmc_mv[0].y, dec->quarterpel, fcode);  
1046    
1047                                          } else if (dec->interlacing && mb->field_pred) {            if(dec->interlacing) {
1048                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],              /* Get motion vectors interlaced, field_pred is handled there */
1049                                                                                    fcode, bound);              get_motion_vector_interlaced(dec, bs, x, y, 0, mb, fcode, bound);
                                                 get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1],  
                                                                                   fcode, bound);  
1050                                          } else {                                          } else {
1051                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],              get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);
1052                                                                                    fcode, bound);              mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];
                                                 mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =  
                                                         mb->mvs[0].x;  
                                                 mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =  
                                                         mb->mvs[0].y;  
1053                                          }                                          }
1054                                  } else if (mb->mode == MODE_INTER4V ) {                                  } else if (mb->mode == MODE_INTER4V ) {
1055              /* interlaced missing here */
1056                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);                                          get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);
1057                                          get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode, bound);                                          get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode, bound);
1058                                          get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode, bound);                                          get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode, bound);
1059                                          get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode, bound);                                          get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode, bound);
1060                                  } else                  // MODE_INTRA, MODE_INTRA_Q          } else { /* MODE_INTRA, MODE_INTRA_Q */
1061                                  {            mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
1062                                          mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x =            mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
                                                 0;  
                                         mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =  
                                                 0;  
1063                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
1064                                                                          intra_dc_threshold, bound);                                                                          intra_dc_threshold, bound);
1065                                          continue;                                          continue;
1066                                  }                                  }
1067    
1068                                  decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant,          /* See how to decode */
1069                                                                  rounding);          if(!mb->field_pred)
1070             decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1071            else
1072             decoder_mbinter_field(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1073    
1074          } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */
1075            mb->mode = MODE_NOT_CODED_GMC;
1076            mb->quant = quant;
1077            decoder_mbgmc(dec, mb, x, y, fcode, 0x00, bs, rounding);
1078    
1079            if(dec->out_frm && cp_mb > 0) {
1080              output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
1081              cp_mb = 0;
1082                          }                          }
1083                          else if (gmc_mv)        /* not coded S_VOP macroblock */          st_mb = x+1;
1084                          {        } else { /* not coded P_VOP macroblock */
                                 mb->mode = MODE_NOT_CODED;  
                                 mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = gmc_sanitize(gmc_mv[0].x, dec->quarterpel, fcode);  
                                 mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = gmc_sanitize(gmc_mv[0].y, dec->quarterpel, fcode);  
                                 decoder_mbinter(dec, mb, x, y, 0, 0, bs, quant, rounding);  
                         }  
                         else    /* not coded P_VOP macroblock */  
                         {  
1085                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
1086            mb->quant = quant;
1087    
1088                                  mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;                                  mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
1089                                  mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;                                  mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
1090                                  // copy macroblock directly from ref to cur          mb->field_pred=0; /* (!) */
1091    
1092                                  start_timer();          decoder_mbinter(dec, mb, x, y, 0, bs,
1093                                    rounding, 0, 0);
                                 transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +  
                                                                  (16 * x),  
                                                                  dec->refn[0].y + (16 * y) * dec->edged_width +  
                                                                  (16 * x), dec->edged_width);  
   
                                 transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +  
                                                                  (16 * x + 8),  
                                                                  dec->refn[0].y + (16 * y) * dec->edged_width +  
                                                                  (16 * x + 8), dec->edged_width);  
   
                                 transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +  
                                                                  (16 * x),  
                                                                  dec->refn[0].y + (16 * y +  
                                                                                                    8) * dec->edged_width +  
                                                                  (16 * x), dec->edged_width);  
   
                                 transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +  
                                                                  (16 * x + 8),  
                                                                  dec->refn[0].y + (16 * y +  
                                                                                                    8) * dec->edged_width +  
                                                                  (16 * x + 8), dec->edged_width);  
   
                                 transfer8x8_copy(dec->cur.u + (8 * y) * dec->edged_width / 2 +  
                                                                  (8 * x),  
                                                                  dec->refn[0].u +  
                                                                  (8 * y) * dec->edged_width / 2 + (8 * x),  
                                                                  dec->edged_width / 2);  
   
                                 transfer8x8_copy(dec->cur.v + (8 * y) * dec->edged_width / 2 +  
                                                                  (8 * x),  
                                                                  dec->refn[0].v +  
                                                                  (8 * y) * dec->edged_width / 2 + (8 * x),  
                                                                  dec->edged_width / 2);  
   
                                 stop_transfer_timer();  
1094    
1095                                  if(dec->out_frm && cp_mb > 0) {                                  if(dec->out_frm && cp_mb > 0) {
1096                                    output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);                                    output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
# Line 881  Line 1099 
1099                                  st_mb = x+1;                                  st_mb = x+1;
1100                          }                          }
1101                  }                  }
1102    
1103                  if(dec->out_frm && cp_mb > 0)                  if(dec->out_frm && cp_mb > 0)
1104                    output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);                    output_slice(&dec->cur, dec->edged_width,dec->width,dec->out_frm,st_mb,y,cp_mb);
1105          }          }
1106  }  }
1107    
1108    
1109  // add by MinChen <chenm001@163.com>  /* decode B-frame motion vector */
1110  // decode B-frame motion vector  static void
1111  void  get_b_motion_vector(Bitstream * bs,
 get_b_motion_vector(DECODER * dec,  
                                         Bitstream * bs,  
                                         int x,  
                                         int y,  
1112                                          VECTOR * mv,                                          VECTOR * mv,
1113                                          int fcode,                                          int fcode,
1114                                          const VECTOR pmv)            const VECTOR pmv,
1115  {            const DECODER * const dec,
1116          int scale_fac = 1 << (fcode - 1);            const int x, const int y)
1117          int high = (32 * scale_fac) - 1;  {
1118          int low = ((-32) * scale_fac);    const int scale_fac = 1 << (fcode - 1);
1119          int range = (64 * scale_fac);    const int high = (32 * scale_fac) - 1;
1120      const int low = ((-32) * scale_fac);
1121      const int range = (64 * scale_fac);
1122    
1123          int mv_x, mv_y;    int mv_x = get_mv(bs, fcode);
1124          int pmv_x, pmv_y;    int mv_y = get_mv(bs, fcode);
1125    
1126          pmv_x = pmv.x;    mv_x += pmv.x;
1127          pmv_y = pmv.y;    mv_y += pmv.y;
   
         mv_x = get_mv(bs, fcode);  
         mv_y = get_mv(bs, fcode);  
   
         mv_x += pmv_x;  
         mv_y += pmv_y;  
1128    
1129          if (mv_x < low) {    if (mv_x < low)
1130                  mv_x += range;                  mv_x += range;
1131          } else if (mv_x > high) {    else if (mv_x > high)
1132                  mv_x -= range;                  mv_x -= range;
         }  
1133    
1134          if (mv_y < low) {    if (mv_y < low)
1135                  mv_y += range;                  mv_y += range;
1136          } else if (mv_y > high) {    else if (mv_y > high)
1137                  mv_y -= range;                  mv_y -= range;
         }  
1138    
1139          mv->x = mv_x;          mv->x = mv_x;
1140          mv->y = mv_y;          mv->y = mv_y;
1141  }  }
1142    
1143    /* decode an B-frame direct & interpolate macroblock */
1144  // add by MinChen <chenm001@163.com>  static void
 // decode an B-frame forward & backward inter macroblock  
 void  
 decoder_bf_mbinter(DECODER * dec,  
                                    const MACROBLOCK * pMB,  
                                    const uint32_t x_pos,  
                                    const uint32_t y_pos,  
                                    const uint32_t cbp,  
                                    Bitstream * bs,  
                                    const uint32_t quant,  
                                    const uint8_t ref)  
 {  
   
         DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);  
         DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);  
   
         uint32_t stride = dec->edged_width;  
         uint32_t stride2 = stride / 2;  
         uint32_t next_block = stride * 8;  
         uint32_t i;  
         uint32_t iQuant = pMB->quant;  
         uint8_t *pY_Cur, *pU_Cur, *pV_Cur;  
         int uv_dx, uv_dy;  
   
         pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);  
         pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);  
         pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);  
   
   
         if (!(pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)) {  
                 uv_dx = pMB->mvs[0].x;  
                 uv_dy = pMB->mvs[0].y;  
   
                 if (dec->quarterpel)  
                 {  
                         uv_dx /= 2;  
                         uv_dy /= 2;  
                 }  
   
                 uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];  
                 uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];  
         } else {  
                 int sum;  
   
                 if(dec->quarterpel)  
                         sum = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);  
                 else  
                         sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;  
   
                 uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];  
   
                 if(dec->quarterpel)  
                         sum = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);  
                 else  
                         sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;  
   
                 uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];  
         }  
   
         start_timer();  
         if(dec->quarterpel) {  
                 interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->refh.y, dec->refh.y + 64,  
                                                                     dec->refh.y + 128, 16*x_pos, 16*y_pos,  
                                                                     pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);  
         }  
         else {  
                 interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos, 16*y_pos,  
                                                           pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);  
                 interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos + 8, 16*y_pos,  
                                                       pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);  
                 interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos, 16*y_pos + 8,  
                                                           pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);  
                 interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos + 8, 16*y_pos + 8,  
                                                           pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);  
         }  
   
         interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,  
                                                   uv_dx, uv_dy, stride2, 0);  
         interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,  
                                                   uv_dx, uv_dy, stride2, 0);  
         stop_comp_timer();  
   
         for (i = 0; i < 6; i++) {  
                 int direction = dec->alternate_vertical_scan ? 2 : 0;  
   
                 if (cbp & (1 << (5 - i)))       // coded  
                 {  
                         memset(&block[i * 64], 0, 64 * sizeof(int16_t));        // clear  
   
                         start_timer();  
                         get_inter_block(bs, &block[i * 64], direction);  
                         stop_coding_timer();  
   
                         start_timer();  
                         if (dec->quant_type == 0) {  
                                 dequant_inter(&data[i * 64], &block[i * 64], iQuant);  
                         } else {  
                                 dequant4_inter(&data[i * 64], &block[i * 64], iQuant);  
                         }  
                         stop_iquant_timer();  
   
                         start_timer();  
                         idct(&data[i * 64]);  
                         stop_idct_timer();  
                 }  
         }  
   
         if (dec->interlacing && pMB->field_dct) {  
                 next_block = stride;  
                 stride *= 2;  
         }  
   
         start_timer();  
         if (cbp & 32)  
                 transfer_16to8add(pY_Cur, &data[0 * 64], stride);  
         if (cbp & 16)  
                 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);  
         if (cbp & 8)  
                 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);  
         if (cbp & 4)  
                 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);  
         if (cbp & 2)  
                 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);  
         if (cbp & 1)  
                 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);  
         stop_transfer_timer();  
 }  
   
 // add by MinChen <chenm001@163.com>  
 // decode an B-frame direct &  inter macroblock  
 void  
1145  decoder_bf_interpolate_mbinter(DECODER * dec,  decoder_bf_interpolate_mbinter(DECODER * dec,
1146                                                             IMAGE forward,                                                             IMAGE forward,
1147                                                             IMAGE backward,                                                             IMAGE backward,
1148                                                             const MACROBLOCK * pMB,                  MACROBLOCK * pMB,
1149                                                             const uint32_t x_pos,                                                             const uint32_t x_pos,
1150                                                             const uint32_t y_pos,                                                             const uint32_t y_pos,
1151                                                             Bitstream * bs)                  Bitstream * bs,
1152                    const int direct)
1153  {  {
   
         DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);  
         DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);  
   
1154          uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
1155          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
         uint32_t next_block = stride * 8;  
         uint32_t iQuant = pMB->quant;  
1156          int uv_dx, uv_dy;          int uv_dx, uv_dy;
1157          int b_uv_dx, b_uv_dy;          int b_uv_dx, b_uv_dy;
         uint32_t i;  
1158          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
1159      const uint32_t cbp = pMB->cbp;      const uint32_t cbp = pMB->cbp;
1160    
# Line 1089  Line 1162 
1162          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
1163          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
1164    
1165      validate_vector(pMB->mvs, x_pos, y_pos, dec);
1166      validate_vector(pMB->b_mvs, x_pos, y_pos, dec);
1167    
1168          if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)) {    if (!direct) {
1169                  uv_dx = pMB->mvs[0].x;                  uv_dx = pMB->mvs[0].x;
1170                  uv_dy = pMB->mvs[0].y;                  uv_dy = pMB->mvs[0].y;
   
1171                  b_uv_dx = pMB->b_mvs[0].x;                  b_uv_dx = pMB->b_mvs[0].x;
1172                  b_uv_dy = pMB->b_mvs[0].y;                  b_uv_dy = pMB->b_mvs[0].y;
1173    
1174                  if (dec->quarterpel)      if (dec->quarterpel) {
1175                  {                          if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
1176                                    uv_dx = (uv_dx>>1) | (uv_dx&1);
1177                                    uv_dy = (uv_dy>>1) | (uv_dy&1);
1178                                    b_uv_dx = (b_uv_dx>>1) | (b_uv_dx&1);
1179                                    b_uv_dy = (b_uv_dy>>1) | (b_uv_dy&1);
1180                            }
1181                            else {
1182                          uv_dx /= 2;                          uv_dx /= 2;
1183                          uv_dy /= 2;                          uv_dy /= 2;
   
1184                          b_uv_dx /= 2;                          b_uv_dx /= 2;
1185                          b_uv_dy /= 2;                          b_uv_dy /= 2;
1186                  }                  }
1187        }
1188    
1189                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
1190                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
   
1191                  b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];                  b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];
1192                  b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];                  b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];
         } else {  
                 int sum;  
1193    
1194                  if(dec->quarterpel)    } else {
1195                          sum = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);            if (dec->quarterpel) { /* for qpel the /2 shall be done before summation. We've done it right in the encoder in the past. */
1196                  else                                                           /* TODO: figure out if we ever did it wrong on the encoder side. If yes, add some workaround */
1197                          sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;                  if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
1198                            int z;
1199                  uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];                          uv_dx = 0; uv_dy = 0;
1200                            b_uv_dx = 0; b_uv_dy = 0;
1201                  if(dec->quarterpel)                          for (z = 0; z < 4; z++) {
1202                          sum = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);                            uv_dx += ((pMB->mvs[z].x>>1) | (pMB->mvs[z].x&1));
1203                  else                            uv_dy += ((pMB->mvs[z].y>>1) | (pMB->mvs[z].y&1));
1204                          sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                            b_uv_dx += ((pMB->b_mvs[z].x>>1) | (pMB->b_mvs[z].x&1));
1205                              b_uv_dy += ((pMB->b_mvs[z].y>>1) | (pMB->b_mvs[z].y&1));
1206                  uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];                          }
1207                    }
1208                    else {
1209                  if(dec->quarterpel)                          uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
1210                          sum = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2);                          uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
1211                  else                          b_uv_dx = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2);
1212                          sum = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;                          b_uv_dy = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2);
1213                    }
1214                  b_uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];          } else {
1215          uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1216                  if(dec->quarterpel)        uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1217                          sum = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2);        b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;
1218                  else        b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
                         sum = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;  
   
                 b_uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];  
1219          }          }
1220    
1221        uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];
1222        uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];
1223        b_uv_dx = (b_uv_dx >> 3) + roundtab_76[b_uv_dx & 0xf];
1224        b_uv_dy = (b_uv_dy >> 3) + roundtab_76[b_uv_dy & 0xf];
1225      }
1226    
1227          start_timer();          start_timer();
1228          if(dec->quarterpel) {          if(dec->quarterpel) {
1229                  if((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q))      if(!direct) {
1230                          interpolate16x16_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,        interpolate16x16_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
1231                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
1232                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1233                  else {      } else {
1234                          interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
1235                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
1236                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1237                          interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
1238                                                                              dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,                      dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
1239                                                                              pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);                                                                              pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
1240                          interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
1241                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,                      dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
1242                                                                              pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);                                                                              pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
1243                          interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->qtmp.y, dec->qtmp.y + 64,
1244                                                                              dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,                      dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
1245                                                                              pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);                                                                              pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
1246                  }                  }
1247          }    } else {
         else {  
1248                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos,                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos,
1249                                                            pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);                                                            pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1250                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos,                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos,
1251                                                            pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);                                                            pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
1252                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8,                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8,
1253                                                            pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);                                                            pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
1254                  interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8,      interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos + 8,
1255                                                            16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,                pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
                                                           0);  
1256          }          }
1257    
1258          interpolate8x8_switch(dec->cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx,          interpolate8x8_switch(dec->cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx,
# Line 1185  Line 1262 
1262    
1263    
1264          if(dec->quarterpel) {          if(dec->quarterpel) {
1265                  if((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q))      if(!direct) {
1266                          interpolate16x16_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,        interpolate16x16_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1267                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,            dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
1268                                                                              pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                                              pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1269                  else {      } else {
1270                          interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1271                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,            dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
1272                                                                              pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                                              pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1273                          interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1274                                                                              dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,            dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
1275                                                                              pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);                                                                              pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
1276                          interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1277                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,            dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
1278                                                                              pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);                                                                              pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
1279                          interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1280                                                                              dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,            dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
1281                                                                              pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);                                                                              pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
1282                  }                  }
1283          }    } else {
1284          else {      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos, 16 * y_pos,
                 interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos, 16 * y_pos,  
1285                                                            pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                            pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1286                  interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
1287                                                            16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride,          16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
1288                                                            0);      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos,
1289                  interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos,          16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
1290                                                            16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
1291                                                            stride, 0);          16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
                 interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,  
                                                           16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y,  
                                                           stride, 0);  
1292          }          }
1293    
1294          interpolate8x8_switch(dec->refn[2].u, backward.u, 8 * x_pos, 8 * y_pos,    interpolate8x8_add_switch(dec->cur.u, backward.u, 8 * x_pos, 8 * y_pos,
1295                                                    b_uv_dx, b_uv_dy, stride2, 0);                                                    b_uv_dx, b_uv_dy, stride2, 0);
1296          interpolate8x8_switch(dec->refn[2].v, backward.v, 8 * x_pos, 8 * y_pos,    interpolate8x8_add_switch(dec->cur.v, backward.v, 8 * x_pos, 8 * y_pos,
1297                                                    b_uv_dx, b_uv_dy, stride2, 0);                                                    b_uv_dx, b_uv_dy, stride2, 0);
1298    
         interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 stride, 0, 8);  
   
         interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,  
                                                 dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,  
                                                 dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos + 8,  
                                                 stride, 0, 8);  
   
         interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,  
                                                 dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,  
                                                 dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos,  
                                                 stride, 0, 8);  
   
         interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,  
                                                 dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,  
                                                 dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,  
                                                 stride, 0, 8);  
   
         interpolate8x8_avg2(dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->refn[2].u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 stride2, 0, 8);  
   
         interpolate8x8_avg2(dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->refn[2].v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 stride2, 0, 8);  
   
1299          stop_comp_timer();          stop_comp_timer();
1300    
1301          for (i = 0; i < 6; i++) {    if (cbp)
1302                  int direction = dec->alternate_vertical_scan ? 2 : 0;      decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
   
                 if (cbp & (1 << (5 - i)))       // coded  
                 {  
                         memset(&block[i * 64], 0, 64 * sizeof(int16_t));        // clear  
   
                         start_timer();  
                         get_inter_block(bs, &block[i * 64], direction);  
                         stop_coding_timer();  
   
                         start_timer();  
                         if (dec->quant_type == 0) {  
                                 dequant_inter(&data[i * 64], &block[i * 64], iQuant);  
                         } else {  
                                 dequant4_inter(&data[i * 64], &block[i * 64], iQuant);  
                         }  
                         stop_iquant_timer();  
   
                         start_timer();  
                         idct(&data[i * 64]);  
                         stop_idct_timer();  
                 }  
1303          }          }
1304    
1305          if (dec->interlacing && pMB->field_dct) {  /* for decode B-frame dbquant */
1306                  next_block = stride;  static __inline int32_t
                 stride *= 2;  
         }  
   
         start_timer();  
         if (cbp & 32)  
                 transfer_16to8add(pY_Cur, &data[0 * 64], stride);  
         if (cbp & 16)  
                 transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);  
         if (cbp & 8)  
                 transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);  
         if (cbp & 4)  
                 transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);  
         if (cbp & 2)  
                 transfer_16to8add(pU_Cur, &data[4 * 64], stride2);  
         if (cbp & 1)  
                 transfer_16to8add(pV_Cur, &data[5 * 64], stride2);  
         stop_transfer_timer();  
 }  
   
   
 // add by MinChen <chenm001@163.com>  
 // for decode B-frame dbquant  
 int32_t __inline  
1307  get_dbquant(Bitstream * bs)  get_dbquant(Bitstream * bs)
1308  {  {
1309          if (!BitstreamGetBit(bs))       // '0'    if (!BitstreamGetBit(bs))   /*  '0' */
1310                  return (0);                  return (0);
1311          else if (!BitstreamGetBit(bs))  // '10'    else if (!BitstreamGetBit(bs))  /* '10' */
1312                  return (-2);                  return (-2);
1313          else    else              /* '11' */
1314                  return (2);                             // '11'      return (2);
1315  }  }
1316    
1317  // add by MinChen <chenm001@163.com>  /*
1318  // for decode B-frame mb_type   * decode B-frame mb_type
1319  // bit   ret_value   * bit    ret_value
1320  // 1        0   * 1    0
1321  // 01       1   * 01   1
1322  // 001      2   * 001    2
1323  // 0001     3   * 0001   3
1324  int32_t __inline   */
1325    static int32_t __inline
1326  get_mbtype(Bitstream * bs)  get_mbtype(Bitstream * bs)
1327  {  {
1328          int32_t mb_type;          int32_t mb_type;
1329    
1330          for (mb_type = 0; mb_type <= 3; mb_type++) {    for (mb_type = 0; mb_type <= 3; mb_type++)
1331                  if (BitstreamGetBit(bs))                  if (BitstreamGetBit(bs))
                         break;  
         }  
   
         if (mb_type <= 3)  
1332                  return (mb_type);                  return (mb_type);
1333          else  
1334                  return (-1);    return -1;
1335  }  }
1336    
1337  void  static void
1338  decoder_bframe(DECODER * dec,  decoder_bframe(DECODER * dec,
1339                             Bitstream * bs,                             Bitstream * bs,
1340                             int quant,                             int quant,
# Line 1348  Line 1344 
1344          uint32_t x, y;          uint32_t x, y;
1345          VECTOR mv;          VECTOR mv;
1346          const VECTOR zeromv = {0,0};          const VECTOR zeromv = {0,0};
1347  #ifdef BFRAMES_DEC_DEBUG    int i;
         FILE *fp;  
         static char first=0;  
 #define BFRAME_DEBUG    if (!first && fp){ \  
                 fprintf(fp,"Y=%3d   X=%3d   MB=%2d   CBP=%02X\n",y,x,mb->mb_type,mb->cbp); \  
         }  
 #endif  
1348    
1349      if (!dec->is_edged[0]) {
1350          start_timer();          start_timer();
1351          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
1352                                     dec->width, dec->height);              dec->width, dec->height, dec->bs_version);
1353          image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height,      dec->is_edged[0] = 1;
                                    dec->width, dec->height);  
1354          stop_edges_timer();          stop_edges_timer();
1355      }
1356    
1357  #ifdef BFRAMES_DEC_DEBUG    if (!dec->is_edged[1]) {
1358          if (!first){      start_timer();
1359                  fp=fopen("C:\\XVIDDBG.TXT","w");      image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height,
1360                dec->width, dec->height, dec->bs_version);
1361        dec->is_edged[1] = 1;
1362        stop_edges_timer();
1363          }          }
 #endif  
1364    
1365          for (y = 0; y < dec->mb_height; y++) {          for (y = 0; y < dec->mb_height; y++) {
1366                  // Initialize Pred Motion Vector      /* Initialize Pred Motion Vector */
1367                  dec->p_fmv = dec->p_bmv = zeromv;                  dec->p_fmv = dec->p_bmv = zeromv;
1368                  for (x = 0; x < dec->mb_width; x++) {                  for (x = 0; x < dec->mb_width; x++) {
1369                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
1370                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];
1371          const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;
1372          int intra_dc_threshold; /* fake variable */
1373    
1374          if (check_resync_marker(bs, fcode_max  - 1)) {
1375            int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,
1376                               &fcode_forward, &fcode_backward, &intra_dc_threshold);
1377            x = bound % dec->mb_width;
1378            y = bound / dec->mb_width;
1379            /* reset predicted macroblocks */
1380            dec->p_fmv = dec->p_bmv = zeromv;
1381          }
1382    
1383                          mv =                          mv =
1384                          mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] =                          mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] =
1385                          mb->mvs[0] = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = zeromv;                          mb->mvs[0] = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = zeromv;
1386          mb->quant = quant;
1387    
1388          /*
1389           * skip if the co-located P_VOP macroblock is not coded
1390           * if not codec in co-located S_VOP macroblock is _not_
1391           * automatically skipped
1392           */
1393    
                         // the last P_VOP is skip macroblock ?  
1394                          if (last_mb->mode == MODE_NOT_CODED) {                          if (last_mb->mode == MODE_NOT_CODED) {
                                 //DEBUG2("Skip MB in B-frame at (X,Y)=!",x,y);  
1395                                  mb->cbp = 0;                                  mb->cbp = 0;
1396  #ifdef BFRAMES_DEC_DEBUG          mb->mode = MODE_FORWARD;
1397                                  mb->mb_type = MODE_NOT_CODED;          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
         BFRAME_DEBUG  
 #endif  
                                 mb->mb_type = MODE_FORWARD;  
                                 mb->quant = last_mb->quant;  
                                 //mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;  
                                 //mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;  
   
                                 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, mb->quant, 1);  
1398                                  continue;                                  continue;
1399                          }                          }
1400    
1401                          if (!BitstreamGetBit(bs)) {     // modb=='0'        if (!BitstreamGetBit(bs)) { /* modb=='0' */
1402                                  const uint8_t modb2 = BitstreamGetBit(bs);                                  const uint8_t modb2 = BitstreamGetBit(bs);
1403    
1404                                  mb->mb_type = get_mbtype(bs);          mb->mode = get_mbtype(bs);
1405    
1406                                  if (!modb2) {   // modb=='00'          if (!modb2)   /* modb=='00' */
1407                                          mb->cbp = BitstreamGetBits(bs, 6);                                          mb->cbp = BitstreamGetBits(bs, 6);
1408                                  } else {          else
1409                                          mb->cbp = 0;                                          mb->cbp = 0;
                                 }  
                                 if (mb->mb_type && mb->cbp) {  
                                         quant += get_dbquant(bs);  
1410    
1411                                          if (quant > 31) {          if (mb->mode && mb->cbp) {
1412              quant += get_dbquant(bs);
1413              if (quant > 31)
1414                                                  quant = 31;                                                  quant = 31;
1415                                          } else if (quant < 1) {            else if (quant < 1)
1416                                                  quant = 1;                                                  quant = 1;
1417                                          }                                          }
1418            mb->quant = quant;
1419    
1420            if (dec->interlacing) {
1421              if (mb->cbp) {
1422                mb->field_dct = BitstreamGetBit(bs);
1423                DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct);
1424                                  }                                  }
1425    
1426              if (mb->mode) {
1427                mb->field_pred = BitstreamGetBit(bs);
1428                DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred);
1429    
1430                if (mb->field_pred) {
1431                  mb->field_for_top = BitstreamGetBit(bs);
1432                  DPRINTF(XVID_DEBUG_MB,"decp: field_for_top: %i\n", mb->field_for_top);
1433                  mb->field_for_bot = BitstreamGetBit(bs);
1434                  DPRINTF(XVID_DEBUG_MB,"decp: field_for_bot: %i\n", mb->field_for_bot);
1435                }
1436              }
1437            }
1438    
1439                          } else {                          } else {
1440                                  mb->mb_type = MODE_DIRECT_NONE_MV;          mb->mode = MODE_DIRECT_NONE_MV;
1441                                  mb->cbp = 0;                                  mb->cbp = 0;
1442                          }                          }
1443    
1444                          mb->quant = quant;        switch (mb->mode) {
                         mb->mode = MODE_INTER4V;  
                         //DEBUG1("Switch bm_type=",mb->mb_type);  
   
 #ifdef BFRAMES_DEC_DEBUG  
         BFRAME_DEBUG  
 #endif  
   
                         switch (mb->mb_type) {  
1445                          case MODE_DIRECT:                          case MODE_DIRECT:
1446                                  get_b_motion_vector(dec, bs, x, y, &mv, 1, zeromv);          get_b_motion_vector(bs, &mv, 1, zeromv, dec, x, y);
1447    
1448                          case MODE_DIRECT_NONE_MV:                          case MODE_DIRECT_NONE_MV:
                                 {  
                                         const int64_t TRB = dec->time_pp - dec->time_bp, TRD = dec->time_pp;  
                                         int i;  
   
1449                                          for (i = 0; i < 4; i++) {                                          for (i = 0; i < 4; i++) {
1450                                                  mb->mvs[i].x = (int32_t) ((TRB * last_mb->mvs[i].x)            mb->mvs[i].x = last_mb->mvs[i].x*dec->time_bp/dec->time_pp + mv.x;
1451                                                                        / TRD + mv.x);            mb->mvs[i].y = last_mb->mvs[i].y*dec->time_bp/dec->time_pp + mv.y;
1452                                                  mb->b_mvs[i].x = (int32_t) ((mv.x == 0)  
1453                                                                                  ? ((TRB - TRD) * last_mb->mvs[i].x)            mb->b_mvs[i].x = (mv.x)
1454                                                                                    / TRD              ?  mb->mvs[i].x - last_mb->mvs[i].x
1455                                                                                  : mb->mvs[i].x - last_mb->mvs[i].x);              : last_mb->mvs[i].x*(dec->time_bp - dec->time_pp)/dec->time_pp;
1456                                                  mb->mvs[i].y = (int32_t) ((TRB * last_mb->mvs[i].y)            mb->b_mvs[i].y = (mv.y)
1457                                                                        / TRD + mv.y);              ? mb->mvs[i].y - last_mb->mvs[i].y
1458                                                  mb->b_mvs[i].y = (int32_t) ((mv.y == 0)              : last_mb->mvs[i].y*(dec->time_bp - dec->time_pp)/dec->time_pp;
                                                                                 ? ((TRB - TRD) * last_mb->mvs[i].y)  
                                                                                   / TRD  
                                                                             : mb->mvs[i].y - last_mb->mvs[i].y);  
                                         }  
                                         //DEBUG("B-frame Direct!\n");  
1459                                  }                                  }
1460    
1461                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],
1462                                                                                             mb, x, y, bs);                          mb, x, y, bs, 1);
1463                                  break;                                  break;
1464    
1465                          case MODE_INTERPOLATE:                          case MODE_INTERPOLATE:
1466                                  get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_forward,          get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);
                                                                         dec->p_fmv);  
1467                                  dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];                                  dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];
1468    
1469                                  get_b_motion_vector(dec, bs, x, y, &mb->b_mvs[0],          get_b_motion_vector(bs, &mb->b_mvs[0], fcode_backward, dec->p_bmv, dec, x, y);
1470                                                                          fcode_backward, dec->p_bmv);          dec->p_bmv = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] = mb->b_mvs[0];
                                 dec->p_bmv = mb->b_mvs[1] = mb->b_mvs[2] =  
                                         mb->b_mvs[3] = mb->b_mvs[0];  
1471    
1472                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],
1473                                                                                             mb, x, y, bs);                        mb, x, y, bs, 0);
                                 //DEBUG("B-frame Bidir!\n");  
1474                                  break;                                  break;
1475    
1476                          case MODE_BACKWARD:                          case MODE_BACKWARD:
1477                                  get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_backward,          get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);
                                                                         dec->p_bmv);  
1478                                  dec->p_bmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];                                  dec->p_bmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];
1479    
1480                                  mb->mode = MODE_INTER;          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 1);
                                 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, quant, 0);  
                                 //DEBUG("B-frame Backward!\n");  
1481                                  break;                                  break;
1482    
1483                          case MODE_FORWARD:                          case MODE_FORWARD:
1484                                  get_b_motion_vector(dec, bs, x, y, &mb->mvs[0], fcode_forward,          get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);
                                                                         dec->p_fmv);  
1485                                  dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];                                  dec->p_fmv = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] =     mb->mvs[0];
1486    
1487                                  mb->mode = MODE_INTER;          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
                                 decoder_bf_mbinter(dec, mb, x, y, mb->cbp, bs, quant, 1);  
                                 //DEBUG("B-frame Forward!\n");  
1488                                  break;                                  break;
1489    
1490                          default:                          default:
1491                                  DEBUG1("Not support B-frame mb_type =", mb->mb_type);          DPRINTF(XVID_DEBUG_ERROR,"Not supported B-frame mb_type = %i\n", mb->mode);
1492                          }                          }
1493        } /* End of for */
                 }                                               // end of FOR  
1494          }          }
 #ifdef BFRAMES_DEC_DEBUG  
         if (!first){  
                 first=1;  
                 if (fp)  
                         fclose(fp);  
         }  
 #endif  
1495  }  }
1496    
1497  // swap two MACROBLOCK array  /* perform post processing if necessary, and output the image */
1498  void  static void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,
1499  mb_swap(MACROBLOCK ** mb1,            xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,
1500                  MACROBLOCK ** mb2)            int coding_type, int quant)
1501  {  {
1502          MACROBLOCK *temp = *mb1;    const int brightness = XVID_VERSION_MINOR(frame->version) >= 1 ? frame->brightness : 0;
1503    
1504          *mb1 = *mb2;    if (dec->cartoon_mode)
1505          *mb2 = temp;      frame->general &= ~XVID_FILMEFFECT;
1506    
1507      if ((frame->general & (XVID_DEBLOCKY|XVID_DEBLOCKUV|XVID_FILMEFFECT) || brightness!=0)
1508        && mbs != NULL) /* post process */
1509      {
1510        /* note: image is stored to tmp */
1511        image_copy(&dec->tmp, img, dec->edged_width, dec->height);
1512        image_postproc(&dec->postproc, &dec->tmp, dec->edged_width,
1513                 mbs, dec->mb_width, dec->mb_height, dec->mb_width,
1514                 frame->general, brightness, dec->frames, (coding_type == B_VOP));
1515        img = &dec->tmp;
1516      }
1517    
1518      image_output(img, dec->width, dec->height,
1519             dec->edged_width, (uint8_t**)frame->output.plane, frame->output.stride,
1520             frame->output.csp, dec->interlacing);
1521    
1522      if (stats) {
1523        stats->type = coding2type(coding_type);
1524        stats->data.vop.time_base = (int)dec->time_base;
1525        stats->data.vop.time_increment = 0; /* XXX: todo */
1526        stats->data.vop.qscale_stride = dec->mb_width;
1527        stats->data.vop.qscale = dec->qscale;
1528        if (stats->data.vop.qscale != NULL && mbs != NULL) {
1529          unsigned int i;
1530          for (i = 0; i < dec->mb_width*dec->mb_height; i++)
1531            stats->data.vop.qscale[i] = mbs[i].quant;
1532        } else
1533          stats->data.vop.qscale = NULL;
1534      }
1535  }  }
1536    
1537  int  int
1538  decoder_decode(DECODER * dec,  decoder_decode(DECODER * dec,
1539                             XVID_DEC_FRAME * frame, XVID_DEC_STATS * stats)          xvid_dec_frame_t * frame, xvid_dec_stats_t * stats)
1540  {  {
1541    
1542          Bitstream bs;          Bitstream bs;
1543          uint32_t rounding;          uint32_t rounding;
1544          uint32_t reduced_resolution;    uint32_t quant = 2;
         uint32_t quant;  
1545          uint32_t fcode_forward;          uint32_t fcode_forward;
1546          uint32_t fcode_backward;          uint32_t fcode_backward;
1547          uint32_t intra_dc_threshold;          uint32_t intra_dc_threshold;
1548          VECTOR gmc_mv[5];    WARPPOINTS gmc_warp;
1549          uint32_t vop_type;    int coding_type;
1550          int success = 0;    int success, output, seen_something;
1551    
1552      if (XVID_VERSION_MAJOR(frame->version) != 1 || (stats && XVID_VERSION_MAJOR(stats->version) != 1))  /* v1.x.x */
1553        return XVID_ERR_VERSION;
1554    
1555          start_global_timer();          start_global_timer();
1556    
1557          dec->out_frm = (frame->colorspace == XVID_CSP_EXTERN) ? frame->image : NULL;    dec->low_delay_default = (frame->general & XVID_LOWDELAY);
1558      if ((frame->general & XVID_DISCONTINUITY))
1559        dec->frames = 0;
1560      dec->out_frm = (frame->output.csp == XVID_CSP_SLICE) ? &frame->output : NULL;
1561    
1562      if(frame->length<0) {  /* decoder flush */
1563        int ret;
1564        /* if not decoding "low_delay/packed", and this isn't low_delay and
1565          we have a reference frame, then outout the reference frame */
1566        if (!(dec->low_delay_default && dec->packed_mode) && !dec->low_delay && dec->frames>0) {
1567          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);
1568          dec->frames = 0;
1569          ret = 0;
1570        } else {
1571          if (stats) stats->type = XVID_TYPE_NOTHING;
1572          ret = XVID_ERR_END;
1573        }
1574    
1575        emms();
1576        stop_global_timer();
1577        return ret;
1578      }
1579    
1580          BitstreamInit(&bs, frame->bitstream, frame->length);          BitstreamInit(&bs, frame->bitstream, frame->length);
1581    
1582          // XXX: 0x7f is only valid whilst decoding vfw xvid/divx5 avi's    /* XXX: 0x7f is only valid whilst decoding vfw xvid/divx5 avi's */
1583          if(frame->length == 1 && BitstreamShowBits(&bs, 8) == 0x7f)    if(dec->low_delay_default && frame->length == 1 && BitstreamShowBits(&bs, 8) == 0x7f)
1584          {          {
                 if (stats)  
                         stats->notify = XVID_DEC_VOP;  
                 frame->length = 1;  
1585                  image_output(&dec->refn[0], dec->width, dec->height, dec->edged_width,                  image_output(&dec->refn[0], dec->width, dec->height, dec->edged_width,
1586                                           frame->image, frame->stride, frame->colorspace, dec->interlacing);             (uint8_t**)frame->output.plane, frame->output.stride, frame->output.csp, dec->interlacing);
1587        if (stats) stats->type = XVID_TYPE_NOTHING;
1588                  emms();                  emms();
1589                  return XVID_ERR_OK;      return 1; /* one byte consumed */
1590          }          }
1591    
1592  start:    success = 0;
1593          // add by chenm001 <chenm001@163.com>    output = 0;
1594          // for support B-frame to reference last 2 frame    seen_something = 0;
         dec->frames++;  
1595    
1596  xxx:  repeat:
         vop_type =  
                 BitstreamReadHeaders(&bs, dec, &rounding, &reduced_resolution,  
                         &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, gmc_mv);  
1597    
1598          DPRINTF(DPRINTF_HEADER, "vop_type=%i", vop_type);    coding_type = BitstreamReadHeaders(&bs, dec, &rounding,
1599          &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);
1600    
1601          if (vop_type == -1 && success)    DPRINTF(XVID_DEBUG_HEADER, "coding_type=%i,  packed=%i,  time=%"
1602                  goto done;  #if defined(_MSC_VER)
1603        "I64"
1604    #else
1605        "ll"
1606    #endif
1607        "i,  time_pp=%i,  time_bp=%i\n",
1608                  coding_type,  dec->packed_mode, dec->time, dec->time_pp, dec->time_bp);
1609    
1610          if (vop_type == -2 || vop_type == -3)    if (coding_type == -1) { /* nothing */
1611          {      if (success) goto done;
1612                  if (vop_type == -3)      if (stats) stats->type = XVID_TYPE_NOTHING;
1613        emms();
1614        return BitstreamPos(&bs)/8;
1615      }
1616    
1617      if (coding_type == -2 || coding_type == -3) { /* vol and/or resize */
1618    
1619        if (coding_type == -3)
1620                          decoder_resize(dec);                          decoder_resize(dec);
1621    
1622                  if (stats)      if(stats) {
1623                  {        stats->type = XVID_TYPE_VOL;
                         stats->notify = XVID_DEC_VOL;  
1624                          stats->data.vol.general = 0;                          stats->data.vol.general = 0;
1625                          if (dec->interlacing)        /*XXX: if (dec->interlacing)
1626                                  stats->data.vol.general |= XVID_INTERLACING;          stats->data.vol.general |= ++INTERLACING; */
1627                          stats->data.vol.width = dec->width;                          stats->data.vol.width = dec->width;
1628                          stats->data.vol.height = dec->height;                          stats->data.vol.height = dec->height;
1629                          stats->data.vol.aspect_ratio = dec->aspect_ratio;        stats->data.vol.par = dec->aspect_ratio;
1630                          stats->data.vol.par_width = dec->par_width;                          stats->data.vol.par_width = dec->par_width;
1631                          stats->data.vol.par_height = dec->par_height;                          stats->data.vol.par_height = dec->par_height;
1632                          frame->length = BitstreamPos(&bs) / 8;        emms();
1633                          return XVID_ERR_OK;        return BitstreamPos(&bs)/8; /* number of bytes consumed */
1634                  }                  }
1635                  goto xxx;      goto repeat;
1636          }          }
1637    
1638          dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;  // init pred vector to 0    if(dec->frames == 0 && coding_type != I_VOP) {
1639        /* 1st frame is not an i-vop */
1640        goto repeat;
1641      }
1642    
1643          switch (vop_type) {    dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;  /* init pred vector to 0 */
         case P_VOP:  
                 decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,  
                                                 fcode_forward, intra_dc_threshold, NULL);  
 #ifdef BFRAMES_DEC  
                 DEBUG1("P_VOP  Time=", dec->time);  
 #endif  
                 break;  
1644    
1645      /* packed_mode: special-N_VOP treament */
1646      if (dec->packed_mode && coding_type == N_VOP) {
1647        if (dec->low_delay_default && dec->frames > 0) {
1648          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);
1649          output = 1;
1650        }
1651        /* ignore otherwise */
1652      } else if (coding_type != B_VOP) {
1653        switch(coding_type) {
1654          case I_VOP:          case I_VOP:
1655                  decoder_iframe(dec, &bs, reduced_resolution, quant, intra_dc_threshold);        decoder_iframe(dec, &bs, quant, intra_dc_threshold);
 #ifdef BFRAMES_DEC  
                 DEBUG1("I_VOP  Time=", dec->time);  
 #endif  
1656                  break;                  break;
1657        case P_VOP :
1658          case B_VOP:        decoder_pframe(dec, &bs, rounding, quant,
1659  #ifdef BFRAMES_DEC                          fcode_forward, intra_dc_threshold, NULL);
                 if (dec->time_pp > dec->time_bp) {  
                         DEBUG1("B_VOP  Time=", dec->time);  
                         decoder_bframe(dec, &bs, quant, fcode_forward, fcode_backward);  
                 } else {  
                         DEBUG("broken B-frame!");  
                 }  
 #else  
                 image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);  
 #endif  
1660                  break;                  break;
   
1661          case S_VOP :          case S_VOP :
1662                  decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,        decoder_pframe(dec, &bs, rounding, quant,
1663                                                  fcode_forward, intra_dc_threshold, gmc_mv);                          fcode_forward, intra_dc_threshold, &gmc_warp);
1664                  break;                  break;
1665        case N_VOP :
1666          case N_VOP:                             // vop not coded        /* XXX: not_coded vops are not used for forward prediction */
1667                  // when low_delay==0, N_VOP's should interpolate between the past and future frames        /* we should not swap(last_mbs,mbs) */
1668                  image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);                  image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
1669  #ifdef BFRAMES_DEC        SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs); /* it will be swapped back */
                 DEBUG1("N_VOP  Time=", dec->time);  
 #endif  
1670                  break;                  break;
   
         default:  
                 if (stats)  
                         stats->notify = 0;  
   
                 emms();  
                 return XVID_ERR_FAIL;  
1671          }          }
1672    
1673          BitstreamByteAlign(&bs);      /* note: for packed_mode, output is performed when the special-N_VOP is decoded */
1674        if (!(dec->low_delay_default && dec->packed_mode)) {
1675  #ifdef BFRAMES_DEC        if(dec->low_delay) {
1676          // test if no B_VOP          decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant);
1677          if (dec->low_delay || dec->frames == 0 || ((dec->packed_mode) && !(frame->length > BitstreamPos(&bs) / 8))) {          output = 1;
1678  #endif        } else if (dec->frames > 0) { /* is the reference frame valid? */
1679                  image_output(&dec->cur, dec->width, dec->height, dec->edged_width,          /* output the reference frame */
1680                                           frame->image, frame->stride, frame->colorspace, dec->interlacing);          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);
1681            output = 1;
 #ifdef BFRAMES_DEC  
         } else {  
                 if (dec->frames >= 1 && !(dec->packed_mode)) {  
                         start_timer();  
                         if ((vop_type == I_VOP || vop_type == P_VOP || vop_type == S_VOP)) {  
                                 image_output(&dec->refn[0], dec->width, dec->height,  
                                                          dec->edged_width, frame->image, frame->stride,  
                                                          frame->colorspace, dec->interlacing);  
                         } else if (vop_type == B_VOP) {  
                                 image_output(&dec->cur, dec->width, dec->height,  
                                                          dec->edged_width, frame->image, frame->stride,  
                                                          frame->colorspace, dec->interlacing);  
                         }  
                         stop_conv_timer();  
1682                  }                  }
1683          }          }
 #endif  
1684    
         if (vop_type == I_VOP || vop_type == P_VOP || vop_type == S_VOP) {  
1685                  image_swap(&dec->refn[0], &dec->refn[1]);                  image_swap(&dec->refn[0], &dec->refn[1]);
1686        dec->is_edged[1] = dec->is_edged[0];
1687                  image_swap(&dec->cur, &dec->refn[0]);                  image_swap(&dec->cur, &dec->refn[0]);
1688        dec->is_edged[0] = 0;
1689        SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs);
1690        dec->last_coding_type = coding_type;
1691    
1692        dec->frames++;
1693        seen_something = 1;
1694    
1695                  // swap MACROBLOCK    } else {  /* B_VOP */
1696                  // the Divx will not set the low_delay flage some times  
1697                  // so follow code will wrong to not swap at that time      if (dec->low_delay) {
1698                  // this will broken bitstream! so I'm change it,        DPRINTF(XVID_DEBUG_ERROR, "warning: bvop found in low_delay==1 stream\n");
1699                  // But that is not the best way! can anyone tell me how        dec->low_delay = 0;
                 // to do another way?  
                 // 18-07-2002   MinChen<chenm001@163.com>  
                 //if (!dec->low_delay && vop_type == P_VOP)  
                 if (vop_type == P_VOP)  
                         mb_swap(&dec->mbs, &dec->last_mbs);  
1700          }          }
1701    
1702          success = 1;      if (dec->frames < 2) {
1703          /* attemping to decode a bvop without atleast 2 reference frames */
1704          image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16,
1705                "broken b-frame, mising ref frames");
1706          if (stats) stats->type = XVID_TYPE_NOTHING;
1707        } else if (dec->time_pp <= dec->time_bp) {
1708          /* this occurs when dx50_bvop_compatibility==0 sequences are
1709          decoded in vfw. */
1710          image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16,
1711                "broken b-frame, tpp=%i tbp=%i", dec->time_pp, dec->time_bp);
1712          if (stats) stats->type = XVID_TYPE_NOTHING;
1713        } else {
1714          decoder_bframe(dec, &bs, quant, fcode_forward, fcode_backward);
1715          decoder_output(dec, &dec->cur, dec->mbs, frame, stats, coding_type, quant);
1716        }
1717    
1718          if (frame->length > BitstreamPos(&bs) / 8)      // multiple vops packed together      output = 1;
1719                  goto start;      dec->frames++;
1720      }
1721    
1722  done :  #if 0 /* Avoids to read to much data because of 32bit reads in our BS functions */
1723       BitstreamByteAlign(&bs);
1724    #endif
1725    
1726          frame->length = BitstreamPos(&bs) / 8;    /* low_delay_default mode: repeat in packed_mode */
1727      if (dec->low_delay_default && dec->packed_mode && output == 0 && success == 0) {
1728        success = 1;
1729        goto repeat;
1730      }
1731    
1732          if (stats)  done :
1733          {  
1734                  stats->notify = XVID_DEC_VOP;    /* if we reach here without outputing anything _and_
1735                  stats->data.vop.time_base = (int)dec->time_base;       the calling application has specified low_delay_default,
1736                  stats->data.vop.time_increment = 0;     //XXX: todo       we *must* output something.
1737         this always occurs on the first call to decode() call
1738         when bframes are present in the bitstream. it may also
1739         occur if no vops  were seen in the bitstream
1740    
1741         if packed_mode is enabled, then we output the recently
1742         decoded frame (the very first ivop). otherwise we have
1743         nothing to display, and therefore output a black screen.
1744      */
1745      if (dec->low_delay_default && output == 0) {
1746        if (dec->packed_mode && seen_something) {
1747          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);
1748        } else {
1749          image_clear(&dec->cur, dec->width, dec->height, dec->edged_width, 0, 128, 128);
1750          decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP, quant);
1751          if (stats) stats->type = XVID_TYPE_NOTHING;
1752        }
1753          }          }
1754    
1755          emms();          emms();
   
1756          stop_global_timer();          stop_global_timer();
1757    
1758          return XVID_ERR_OK;    return (BitstreamPos(&bs)+7)/8; /* number of bytes consumed */
1759  }  }

Legend:
Removed from v.1.37.2.13  
changed lines
  Added in v.1.75.2.1

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