[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.54, Sun Apr 11 09:41:27 2004 UTC revision 1.81, Thu May 28 15:42:06 2009 UTC
# Line 46  Line 46 
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"
 #include "image/reduced.h"  
49  #include "image/font.h"  #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"
# Line 61  Line 61 
61  #include "image/postprocessing.h"  #include "image/postprocessing.h"
62  #include "utils/mem_align.h"  #include "utils/mem_align.h"
63    
64    #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  static int
69  decoder_resize(DECODER * dec)  decoder_resize(DECODER * dec)
70  {  {
# Line 73  Line 77 
77    
78          image_destroy(&dec->gmc, dec->edged_width, dec->edged_height);          image_destroy(&dec->gmc, dec->edged_width, dec->edged_height);
79    
80          if (dec->last_mbs)    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    
88                  xvid_free(dec->last_mbs);                  xvid_free(dec->last_mbs);
         if (dec->mbs)  
89                  xvid_free(dec->mbs);                  xvid_free(dec->mbs);
         if (dec->qscale)  
90                  xvid_free(dec->qscale);                  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;
# Line 87  Line 99 
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;  
         }  
   
         /* 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->tmp, 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->qtmp, 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->tmp, dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
   
         if (image_create(&dec->gmc, dec->edged_width, dec->edged_height)) {  
                 image_destroy(&dec->qtmp, 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->tmp, 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->tmp, dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->qtmp, 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          /* 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                  xvid_free(dec->mbs);            goto memory_error;
                 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->tmp, dec->edged_width, dec->edged_height);  
                 image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);  
                 xvid_free(dec);  
                 return XVID_ERR_MEMORY;  
         }  
   
123          memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);          memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
124    
125          /* nothing happens if that fails */          /* nothing happens if that fails */
# Line 171  Line 130 
130                  memset(dec->qscale, 0, sizeof(int) * dec->mb_width * dec->mb_height);                  memset(dec->qscale, 0, sizeof(int) * dec->mb_width * dec->mb_height);
131    
132          return 0;          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);
138      image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
139      image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
140      image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
141      image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
142      image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);
143    
144      xvid_free(dec);
145      return XVID_ERR_MEMORY;
146  }  }
147    
148    
# Line 222  Line 194 
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;          dec->packed_mode = 0;
197      dec->time_inc_resolution = 1; /* until VOL header says otherwise */
198      dec->ver_id = 1;
199    
200      dec->bs_version = 0xffff; /* Initialize to very high value -> assume bugfree stream */
201    
202          dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);          dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);
203    
204          if (dec->fixed_dimensions)    if (dec->fixed_dimensions) {
205                  return decoder_resize(dec);      int ret = decoder_resize(dec);
206        if (ret == XVID_ERR_MEMORY) create->handle = NULL;
207        return ret;
208      }
209          else          else
210                  return 0;                  return 0;
211  }  }
# Line 269  Line 248 
248                                  Bitstream * bs,                                  Bitstream * bs,
249                                  const uint32_t quant,                                  const uint32_t quant,
250                                  const uint32_t intra_dc_threshold,                                  const uint32_t intra_dc_threshold,
251                                  const unsigned int bound,          const unsigned int bound)
                                 const int reduced_resolution)  
252  {  {
253    
254          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
# Line 283  Line 261 
261          uint32_t iQuant = pMB->quant;          uint32_t iQuant = pMB->quant;
262          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
263    
         if (reduced_resolution) {  
                 pY_Cur = dec->cur.y + (y_pos << 5) * stride + (x_pos << 5);  
                 pU_Cur = dec->cur.u + (y_pos << 4) * stride2 + (x_pos << 4);  
                 pV_Cur = dec->cur.v + (y_pos << 4) * stride2 + (x_pos << 4);  
         }else{  
264                  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);                  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
265                  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
266                  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
         }  
267    
268          memset(block, 0, 6 * 64 * sizeof(int16_t));     /* clear */          memset(block, 0, 6 * 64 * sizeof(int16_t));     /* clear */
269    
# Line 338  Line 310 
310                  stop_coding_timer();                  stop_coding_timer();
311    
312                  start_timer();                  start_timer();
313                  add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors);      add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors, dec->bs_version);
314                  stop_prediction_timer();                  stop_prediction_timer();
315    
316                  start_timer();                  start_timer();
# Line 350  Line 322 
322                  stop_iquant_timer();                  stop_iquant_timer();
323    
324                  start_timer();                  start_timer();
325                  idct(&data[i * 64]);      idct((short * const)&data[i * 64]);
326                  stop_idct_timer();                  stop_idct_timer();
327    
328          }          }
# Line 361  Line 333 
333          }          }
334    
335          start_timer();          start_timer();
   
         if (reduced_resolution)  
         {  
                 next_block*=2;  
                 copy_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);  
                 copy_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);  
                 copy_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);  
                 copy_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);  
                 copy_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);  
                 copy_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);  
         }else{  
336                  transfer_16to8copy(pY_Cur, &data[0 * 64], stride);                  transfer_16to8copy(pY_Cur, &data[0 * 64], stride);
337                  transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);                  transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);
338                  transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);                  transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);
339                  transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);                  transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);
340                  transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);                  transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);
341                  transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);                  transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);
         }  
342          stop_transfer_timer();          stop_transfer_timer();
343  }  }
344    
# Line 389  Line 349 
349                                  uint8_t * pY_Cur,                                  uint8_t * pY_Cur,
350                                  uint8_t * pU_Cur,                                  uint8_t * pU_Cur,
351                                  uint8_t * pV_Cur,                                  uint8_t * pV_Cur,
                                 const int reduced_resolution,  
352                                  const MACROBLOCK * pMB)                                  const MACROBLOCK * pMB)
353  {  {
354          DECLARE_ALIGNED_MATRIX(block, 1, 64, int16_t, CACHE_LINE);    DECLARE_ALIGNED_MATRIX(data, 1, 64, int16_t, CACHE_LINE);
         DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);  
355    
356          int stride = dec->edged_width;          int stride = dec->edged_width;
         int next_block = stride * (reduced_resolution ? 16 : 8);  
         const int stride2 = stride/2;  
357          int i;          int i;
358          const uint32_t iQuant = pMB->quant;          const uint32_t iQuant = pMB->quant;
359          const int direction = dec->alternate_vertical_scan ? 2 : 0;          const int direction = dec->alternate_vertical_scan ? 2 : 0;
360          const quant_interFuncPtr dequant = dec->quant_type == 0 ? dequant_h263_inter : dequant_mpeg_inter;    typedef void (*get_inter_block_function_t)(
361          Bitstream * bs,
362          int16_t * block,
363          int direction,
364          const int quant,
365          const uint16_t *matrix);
366      typedef void (*add_residual_function_t)(
367          uint8_t *predicted_block,
368          const int16_t *residual,
369          int stride);
370    
371      const get_inter_block_function_t get_inter_block = (dec->quant_type == 0)
372        ? (get_inter_block_function_t)get_inter_block_h263
373        : (get_inter_block_function_t)get_inter_block_mpeg;
374    
375          for (i = 0; i < 6; i++) {    uint8_t *dst[6];
376      int strides[6];
377    
                 if (cbp & (1 << (5 - i))) {     /* coded */  
378    
379                          memset(block, 0, 64 * sizeof(int16_t)); /* clear */    if (dec->interlacing && pMB->field_dct) {
380        dst[0] = pY_Cur;
381        dst[1] = pY_Cur + 8;
382        dst[2] = pY_Cur + stride;
383        dst[3] = dst[2] + 8;
384        dst[4] = pU_Cur;
385        dst[5] = pV_Cur;
386        strides[0] = strides[1] = strides[2] = strides[3] = stride*2;
387        strides[4] = stride/2;
388        strides[5] = stride/2;
389      } else {
390        dst[0] = pY_Cur;
391        dst[1] = pY_Cur + 8;
392        dst[2] = pY_Cur + 8*stride;
393        dst[3] = dst[2] + 8;
394        dst[4] = pU_Cur;
395        dst[5] = pV_Cur;
396        strides[0] = strides[1] = strides[2] = strides[3] = stride;
397        strides[4] = stride/2;
398        strides[5] = stride/2;
399      }
400    
401      for (i = 0; i < 6; i++) {
402        /* Process only coded blocks */
403        if (cbp & (1 << (5 - i))) {
404    
405          /* Clear the block */
406          memset(&data[0], 0, 64*sizeof(int16_t));
407    
408          /* Decode coeffs and dequantize on the fly */
409                          start_timer();                          start_timer();
410                          get_inter_block(bs, block, direction);        get_inter_block(bs, &data[0], direction, iQuant, get_inter_matrix(dec->mpeg_quant_matrices));
411                          stop_coding_timer();                          stop_coding_timer();
412    
413          /* iDCT */
414                          start_timer();                          start_timer();
415                          dequant(&data[i * 64], block, iQuant, dec->mpeg_quant_matrices);        idct((short * const)&data[0]);
416                          stop_iquant_timer();        stop_idct_timer();
417    
418          /* Add this residual to the predicted block */
419                          start_timer();                          start_timer();
420                          idct(&data[i * 64]);        transfer_16to8add(dst[i], &data[0], strides[i]);
421                          stop_idct_timer();        stop_transfer_timer();
422                  }                  }
423          }          }
   
         if (dec->interlacing && pMB->field_dct) {  
                 next_block = stride;  
                 stride *= 2;  
424          }          }
425    
426          start_timer();  static void __inline
427          if (reduced_resolution) {  validate_vector(VECTOR * mv, unsigned int x_pos, unsigned int y_pos, const DECODER * dec)
428                  if (cbp & 32)  {
429                          add_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);    /* clip a vector to valid range
430                  if (cbp & 16)       prevents crashes if bitstream is broken
431                          add_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);    */
432                  if (cbp & 8)    int shift = 5 + dec->quarterpel;
433                          add_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);    int xborder_high = (int)(dec->mb_width - x_pos) << shift;
434                  if (cbp & 4)    int xborder_low = (-(int)x_pos-1) << shift;
435                          add_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);    int yborder_high = (int)(dec->mb_height - y_pos) << shift;
436                  if (cbp & 2)    int yborder_low = (-(int)y_pos-1) << shift;
437                          add_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);  
438                  if (cbp & 1)  #define CHECK_MV(mv) \
439                          add_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);    do { \
440          } else {    if ((mv).x > xborder_high) { \
441                  if (cbp & 32)      DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", (mv).x, xborder_high, x_pos, y_pos); \
442                          transfer_16to8add(pY_Cur, &data[0 * 64], stride);      (mv).x = xborder_high; \
443                  if (cbp & 16)    } else if ((mv).x < xborder_low) { \
444                          transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);      DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", (mv).x, xborder_low, x_pos, y_pos); \
445                  if (cbp & 8)      (mv).x = xborder_low; \
446                          transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);    } \
447                  if (cbp & 4)    if ((mv).y > yborder_high) { \
448                          transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);      DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", (mv).y, yborder_high, x_pos, y_pos); \
449                  if (cbp & 2)      (mv).y = yborder_high; \
450                          transfer_16to8add(pU_Cur, &data[4 * 64], stride2);    } else if ((mv).y < yborder_low) { \
451                  if (cbp & 1)      DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", (mv).y, yborder_low, x_pos, y_pos); \
452                          transfer_16to8add(pV_Cur, &data[5 * 64], stride2);      (mv).y = yborder_low; \
453          }    } \
454          stop_transfer_timer();    } while (0)
455  }  
456      CHECK_MV(mv[0]);
457      CHECK_MV(mv[1]);
458      CHECK_MV(mv[2]);
459      CHECK_MV(mv[3]);
460    }
461    
462    /* Up to this version, chroma rounding was wrong with qpel.
463     * So we try to be backward compatible to avoid artifacts */
464    #define BS_VERSION_BUGGY_CHROMA_ROUNDING 1
465    
466  /* decode an inter macroblock */  /* decode an inter macroblock */
467  static void  static void
# Line 468  Line 472 
472                                  const uint32_t cbp,                                  const uint32_t cbp,
473                                  Bitstream * bs,                                  Bitstream * bs,
474                                  const uint32_t rounding,                                  const uint32_t rounding,
475                                  const int reduced_resolution,          const int ref,
476                                  const int ref)                  const int bvop)
477  {  {
478          uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
479          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
# Line 480  Line 484 
484          int uv_dx, uv_dy;          int uv_dx, uv_dy;
485          VECTOR mv[4];   /* local copy of mvs */          VECTOR mv[4];   /* local copy of mvs */
486    
         if (reduced_resolution) {  
                 pY_Cur = dec->cur.y + (y_pos << 5) * stride + (x_pos << 5);  
                 pU_Cur = dec->cur.u + (y_pos << 4) * stride2 + (x_pos << 4);  
                 pV_Cur = dec->cur.v + (y_pos << 4) * stride2 + (x_pos << 4);  
                 for (i = 0; i < 4; i++) {  
                         mv[i].x = RRV_MV_SCALEUP(pMB->mvs[i].x);  
                         mv[i].y = RRV_MV_SCALEUP(pMB->mvs[i].y);  
                 }  
         } else {  
487                  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);                  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
488                  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);                  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
489                  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);                  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
490                  for (i = 0; i < 4; i++)                  for (i = 0; i < 4; i++)
491                          mv[i] = pMB->mvs[i];                          mv[i] = pMB->mvs[i];
         }  
492    
493          for (i = 0; i < 4; i++) {    validate_vector(mv, x_pos, y_pos, dec);
                 /* clip to valid range */  
                 int border = (int)(dec->mb_width - x_pos) << (5 + dec->quarterpel);  
                 if (mv[i].x > border) {  
                         DPRINTF(XVID_DEBUG_MV, "mv.x > max -- %d > %d, MB %d, %d", mv[i].x, border, x_pos, y_pos);  
                         mv[i].x = border;  
                 } else {  
                         border = (-(int)x_pos-1) << (5 + dec->quarterpel);  
                         if (mv[i].x < border) {  
                                 DPRINTF(XVID_DEBUG_MV, "mv.x < min -- %d < %d, MB %d, %d", mv[i].x, border, x_pos, y_pos);  
                                 mv[i].x = border;  
                         }  
                 }  
   
                 border = (int)(dec->mb_height - y_pos) << (5 + dec->quarterpel);  
                 if (mv[i].y >  border) {  
                         DPRINTF(XVID_DEBUG_MV, "mv.y > max -- %d > %d, MB %d, %d", mv[i].y, border, x_pos, y_pos);  
                         mv[i].y = border;  
                 } else {  
                         border = (-(int)y_pos-1) << (5 + dec->quarterpel);  
                         if (mv[i].y < border) {  
                                 DPRINTF(XVID_DEBUG_MV, "mv.y < min -- %d < %d, MB %d, %d", mv[i].y, border, x_pos, y_pos);  
                                 mv[i].y = border;  
                         }  
                 }  
         }  
494    
495          start_timer();          start_timer();
496    
497          if (pMB->mode != MODE_INTER4V) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */    if ((pMB->mode != MODE_INTER4V) || (bvop)) { /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
498    
499                  uv_dx = mv[0].x;                  uv_dx = mv[0].x;
500                  uv_dy = mv[0].y;                  uv_dy = mv[0].y;
501                  if (dec->quarterpel) {                  if (dec->quarterpel) {
502                            if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
503                                    uv_dx = (uv_dx>>1) | (uv_dx&1);
504                                    uv_dy = (uv_dy>>1) | (uv_dy&1);
505                            }
506                            else {
507                          uv_dx /= 2;                          uv_dx /= 2;
508                          uv_dy /= 2;                          uv_dy /= 2;
509                  }                  }
510        }
511                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
512                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
513    
514                  if (reduced_resolution)      if (dec->quarterpel)
                         interpolate32x32_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,  
                                                                         mv[0].x, mv[0].y, stride, rounding);  
                 else if (dec->quarterpel)  
515                          interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->qtmp.y, dec->qtmp.y + 64,                          interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->qtmp.y, dec->qtmp.y + 64,
516                                                                          dec->qtmp.y + 128, 16*x_pos, 16*y_pos,                                                                          dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
517                                                                                          mv[0].x, mv[0].y, stride, rounding);                                                                                          mv[0].x, mv[0].y, stride, rounding);
# Line 550  Line 522 
522          } else {        /* MODE_INTER4V */          } else {        /* MODE_INTER4V */
523    
524                  if(dec->quarterpel) {                  if(dec->quarterpel) {
525                            if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
526                                    int z;
527                                    uv_dx = 0; uv_dy = 0;
528                                    for (z = 0; z < 4; z++) {
529                                      uv_dx += ((mv[z].x>>1) | (mv[z].x&1));
530                                      uv_dy += ((mv[z].y>>1) | (mv[z].y&1));
531                                    }
532                            }
533                            else {
534                          uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);                          uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);
535                          uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);                          uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);
536          }
537                  } else {                  } else {
538                          uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x;                          uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x;
539                          uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y;                          uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y;
# Line 560  Line 542 
542                  uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];                  uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];
543                  uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];                  uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];
544    
545                  if (reduced_resolution) {      if (dec->quarterpel) {
                         interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,  
                                                                 mv[0].x, mv[0].y, stride, rounding);  
                         interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos + 16, 32*y_pos,  
                                                                 mv[1].x, mv[1].y, stride, rounding);  
                         interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos, 32*y_pos + 16,  
                                                                 mv[2].x, mv[2].y, stride, rounding);  
                         interpolate16x16_switch(dec->cur.y, dec->refn[0].y , 32*x_pos + 16, 32*y_pos + 16,  
                                                                 mv[3].x, mv[3].y, stride, rounding);  
                         interpolate16x16_switch(dec->cur.u, dec->refn[0].u , 16 * x_pos, 16 * y_pos,  
                                                                 uv_dx, uv_dy, stride2, rounding);  
                         interpolate16x16_switch(dec->cur.v, dec->refn[0].v , 16 * x_pos, 16 * y_pos,  
                                                                 uv_dx, uv_dy, stride2, rounding);  
   
                 } else if (dec->quarterpel) {  
546                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y , dec->qtmp.y, dec->qtmp.y + 64,
547                                                                          dec->qtmp.y + 128, 16*x_pos, 16*y_pos,                                                                          dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
548                                                                          mv[0].x, mv[0].y, stride, rounding);                                                                          mv[0].x, mv[0].y, stride, rounding);
# Line 600  Line 568 
568          }          }
569    
570          /* chroma */          /* chroma */
         if (reduced_resolution) {  
                 interpolate16x16_switch(dec->cur.u, dec->refn[0].u, 16 * x_pos, 16 * y_pos,  
                                                                 uv_dx, uv_dy, stride2, rounding);  
                 interpolate16x16_switch(dec->cur.v, dec->refn[0].v, 16 * x_pos, 16 * y_pos,  
                                                                 uv_dx, uv_dy, stride2, rounding);  
         } else {  
571                  interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.u, dec->refn[ref].u, 8 * x_pos, 8 * y_pos,
572                                                                  uv_dx, uv_dy, stride2, rounding);                                                                  uv_dx, uv_dy, stride2, rounding);
573                  interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.v, dec->refn[ref].v, 8 * x_pos, 8 * y_pos,
574                                                                  uv_dx, uv_dy, stride2, rounding);                                                                  uv_dx, uv_dy, stride2, rounding);
575    
576      stop_comp_timer();
577    
578      if (cbp)
579        decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
580    }
581    
582    /* decode an inter macroblock in field mode */
583    static void
584    decoder_mbinter_field(DECODER * dec,
585            const MACROBLOCK * pMB,
586            const uint32_t x_pos,
587            const uint32_t y_pos,
588            const uint32_t cbp,
589            Bitstream * bs,
590            const uint32_t rounding,
591            const int ref,
592                    const int bvop)
593    {
594      uint32_t stride = dec->edged_width;
595      uint32_t stride2 = stride / 2;
596    
597      uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
598    
599      int uvtop_dx, uvtop_dy;
600      int uvbot_dx, uvbot_dy;
601      VECTOR mv[4]; /* local copy of mvs */
602    
603      /* Get pointer to memory areas */
604      pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
605      pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
606      pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
607    
608      mv[0] = pMB->mvs[0];
609      mv[1] = pMB->mvs[1];
610      memset(&mv[2],0,2*sizeof(VECTOR));
611    
612      validate_vector(mv, x_pos, y_pos, dec);
613    
614      start_timer();
615    
616      if((pMB->mode!=MODE_INTER4V) || (bvop))   /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
617      {
618        /* Prepare top field vector */
619        uvtop_dx = DIV2ROUND(mv[0].x);
620        uvtop_dy = DIV2ROUND(mv[0].y);
621    
622        /* Prepare bottom field vector */
623        uvbot_dx = DIV2ROUND(mv[1].x);
624        uvbot_dy = DIV2ROUND(mv[1].y);
625    
626        if(dec->quarterpel)
627        {
628          /* NOT supported */
629        }
630        else
631        {
632          /* Interpolate top field left part(we use double stride for every 2nd line) */
633          interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
634                                16*x_pos,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
635          /* top field right part */
636          interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
637                                16*x_pos+8,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
638    
639          /* Interpolate bottom field left part(we use double stride for every 2nd line) */
640          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
641                                16*x_pos,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
642          /* Bottom field right part */
643          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
644                                16*x_pos+8,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
645    
646          /* Interpolate field1 U */
647          interpolate8x4_switch(dec->cur.u,dec->refn[ref].u+pMB->field_for_top*stride2,
648                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
649    
650          /* Interpolate field1 V */
651          interpolate8x4_switch(dec->cur.v,dec->refn[ref].v+pMB->field_for_top*stride2,
652                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
653    
654          /* Interpolate field2 U */
655          interpolate8x4_switch(dec->cur.u+stride2,dec->refn[ref].u+pMB->field_for_bot*stride2,
656                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
657    
658          /* Interpolate field2 V */
659          interpolate8x4_switch(dec->cur.v+stride2,dec->refn[ref].v+pMB->field_for_bot*stride2,
660                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
661        }
662      }
663      else
664      {
665        /* We don't expect 4 motion vectors in interlaced mode */
666          }          }
667    
668          stop_comp_timer();          stop_comp_timer();
669    
670      /* Must add error correction? */
671          if (cbp)          if (cbp)
672                  decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur,     decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
                                                         reduced_resolution, pMB);  
673  }  }
674    
675  static void  static void
# Line 663  Line 716 
716          stop_transfer_timer();          stop_transfer_timer();
717    
718          if (cbp)          if (cbp)
719                  decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);      decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
720    
721  }  }
722    
# Line 671  Line 724 
724  static void  static void
725  decoder_iframe(DECODER * dec,  decoder_iframe(DECODER * dec,
726                                  Bitstream * bs,                                  Bitstream * bs,
                                 int reduced_resolution,  
727                                  int quant,                                  int quant,
728                                  int intra_dc_threshold)                                  int intra_dc_threshold)
729  {  {
730          uint32_t bound;          uint32_t bound;
731          uint32_t x, y;          uint32_t x, y;
732          uint32_t mb_width = dec->mb_width;    const uint32_t mb_width = dec->mb_width;
733          uint32_t mb_height = dec->mb_height;    const uint32_t mb_height = dec->mb_height;
   
         if (reduced_resolution) {  
                 mb_width = (dec->width + 31) / 32;  
                 mb_height = (dec->height + 31) / 32;  
         }  
734    
735          bound = 0;          bound = 0;
736    
# Line 704  Line 751 
751                                  bound = read_video_packet_header(bs, dec, 0,                                  bound = read_video_packet_header(bs, dec, 0,
752                                                          &quant, NULL, NULL, &intra_dc_threshold);                                                          &quant, NULL, NULL, &intra_dc_threshold);
753                                  x = bound % mb_width;                                  x = bound % mb_width;
754                                  y = bound / mb_width;          y = MIN((bound / mb_width), (mb_height-1));
755                          }                          }
756                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
757    
# Line 739  Line 786 
786                          }                          }
787    
788                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
789                                                          intra_dc_threshold, bound, reduced_resolution);                intra_dc_threshold, bound);
790    
791                  }                  }
792                  if(dec->out_frm)                  if(dec->out_frm)
# Line 792  Line 839 
839          ret_mv->y = mv.y;          ret_mv->y = mv.y;
840  }  }
841    
842    /* We use this when decoder runs interlaced -> different prediction */
843    
844    static void get_motion_vector_interlaced(DECODER * dec,
845            Bitstream * bs,
846            int x,
847            int y,
848            int k,
849            MACROBLOCK *pMB,
850            int fcode,
851            const int bound)
852    {
853      const int scale_fac = 1 << (fcode - 1);
854      const int high = (32 * scale_fac) - 1;
855      const int low = ((-32) * scale_fac);
856      const int range = (64 * scale_fac);
857    
858      /* Get interlaced prediction */
859      const VECTOR pmv=get_pmv2_interlaced(dec->mbs,dec->mb_width,bound,x,y,k);
860      VECTOR mv,mvf1,mvf2;
861    
862      if(!pMB->field_pred)
863      {
864        mv.x = get_mv(bs,fcode);
865        mv.y = get_mv(bs,fcode);
866    
867        mv.x += pmv.x;
868        mv.y += pmv.y;
869    
870        if(mv.x<low) {
871          mv.x += range;
872        } else if (mv.x>high) {
873          mv.x-=range;
874        }
875    
876        if (mv.y < low) {
877          mv.y += range;
878        } else if (mv.y > high) {
879          mv.y -= range;
880        }
881    
882        pMB->mvs[0]=pMB->mvs[1]=pMB->mvs[2]=pMB->mvs[3]=mv;
883      }
884      else
885      {
886        mvf1.x = get_mv(bs, fcode);
887        mvf1.y = get_mv(bs, fcode);
888    
889        mvf1.x += pmv.x;
890        mvf1.y = 2*(mvf1.y+pmv.y/2); /* It's multiple of 2 */
891    
892        if (mvf1.x < low) {
893          mvf1.x += range;
894        } else if (mvf1.x > high) {
895          mvf1.x -= range;
896        }
897    
898        if (mvf1.y < low) {
899          mvf1.y += range;
900        } else if (mvf1.y > high) {
901          mvf1.y -= range;
902        }
903    
904        mvf2.x = get_mv(bs, fcode);
905        mvf2.y = get_mv(bs, fcode);
906    
907        mvf2.x += pmv.x;
908        mvf2.y = 2*(mvf2.y+pmv.y/2); /* It's multiple of 2 */
909    
910        if (mvf2.x < low) {
911          mvf2.x += range;
912        } else if (mvf2.x > high) {
913          mvf2.x -= range;
914        }
915    
916        if (mvf2.y < low) {
917          mvf2.y += range;
918        } else if (mvf2.y > high) {
919          mvf2.y -= range;
920        }
921    
922        pMB->mvs[0]=mvf1;
923        pMB->mvs[1]=mvf2;
924        pMB->mvs[2].x=pMB->mvs[3].x=0;
925        pMB->mvs[2].y=pMB->mvs[3].y=0;
926    
927        /* Calculate average for as it is field predicted */
928        pMB->mvs_avg.x=DIV2ROUND(pMB->mvs[0].x+pMB->mvs[1].x);
929        pMB->mvs_avg.y=DIV2ROUND(pMB->mvs[0].y+pMB->mvs[1].y);
930      }
931    }
932    
933  /* for P_VOP set gmc_warp to NULL */  /* for P_VOP set gmc_warp to NULL */
934  static void  static void
935  decoder_pframe(DECODER * dec,  decoder_pframe(DECODER * dec,
936                                  Bitstream * bs,                                  Bitstream * bs,
937                                  int rounding,                                  int rounding,
                                 int reduced_resolution,  
938                                  int quant,                                  int quant,
939                                  int fcode,                                  int fcode,
940                                  int intra_dc_threshold,                                  int intra_dc_threshold,
# Line 806  Line 943 
943          uint32_t x, y;          uint32_t x, y;
944          uint32_t bound;          uint32_t bound;
945          int cp_mb, st_mb;          int cp_mb, st_mb;
946          uint32_t mb_width = dec->mb_width;    const uint32_t mb_width = dec->mb_width;
947          uint32_t mb_height = dec->mb_height;    const uint32_t mb_height = dec->mb_height;
   
         if (reduced_resolution) {  
                 mb_width = (dec->width + 31) / 32;  
                 mb_height = (dec->height + 31) / 32;  
         }  
948    
949      if (!dec->is_edged[0]) {
950          start_timer();          start_timer();
951          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
952                                          dec->width, dec->height, dec->bs_version);                                          dec->width, dec->height, dec->bs_version);
953        dec->is_edged[0] = 1;
954          stop_edges_timer();          stop_edges_timer();
955      }
956    
957          if (gmc_warp) {          if (gmc_warp) {
958                  /* accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16 */                  /* accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16 */
# Line 843  Line 978 
978                                  bound = read_video_packet_header(bs, dec, fcode - 1,                                  bound = read_video_packet_header(bs, dec, fcode - 1,
979                                          &quant, &fcode, NULL, &intra_dc_threshold);                                          &quant, &fcode, NULL, &intra_dc_threshold);
980                                  x = bound % mb_width;                                  x = bound % mb_width;
981                                  y = bound / mb_width;          y = MIN((bound / mb_width), (mb_height-1));
982                          }                          }
983                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
984    
# Line 887  Line 1022 
1022                                  }                                  }
1023                                  mb->quant = quant;                                  mb->quant = quant;
1024    
1025            mb->field_pred=0;
1026                                  if (dec->interlacing) {                                  if (dec->interlacing) {
1027                                          if (cbp || intra) {                                          if (cbp || intra) {
1028                                                  mb->field_dct = BitstreamGetBit(bs);                                                  mb->field_dct = BitstreamGetBit(bs);
# Line 912  Line 1048 
1048    
1049                                  } else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {                                  } else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
1050    
1051                                          if (dec->interlacing && mb->field_pred) {            if(dec->interlacing) {
1052                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);              /* Get motion vectors interlaced, field_pred is handled there */
1053                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode, bound);              get_motion_vector_interlaced(dec, bs, x, y, 0, mb, fcode, bound);
1054                                          } else {                                          } else {
1055                                                  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);
1056                                                  mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];                                                  mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];
1057                                          }                                          }
1058                                  } else if (mb->mode == MODE_INTER4V ) {                                  } else if (mb->mode == MODE_INTER4V ) {
1059              /* interlaced missing here */
1060                                          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);
1061                                          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);
1062                                          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);
# Line 928  Line 1065 
1065                                          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;
1066                                          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;
1067                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
1068                                                                          intra_dc_threshold, bound, reduced_resolution);                    intra_dc_threshold, bound);
1069                                          continue;                                          continue;
1070                                  }                                  }
1071    
1072                                  decoder_mbinter(dec, mb, x, y, cbp, bs,          /* See how to decode */
1073                                                                  rounding, reduced_resolution, 0);          if(!mb->field_pred)
1074             decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1075            else
1076             decoder_mbinter_field(dec, mb, x, y, cbp, bs, rounding, 0, 0);
1077    
1078                          } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */                          } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */
1079                                  mb->mode = MODE_NOT_CODED_GMC;                                  mb->mode = MODE_NOT_CODED_GMC;
# Line 951  Line 1091 
1091    
1092                                  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;
1093                                  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;
1094            mb->field_pred=0; /* (!) */
1095    
1096                                  decoder_mbinter(dec, mb, x, y, 0, bs,                                  decoder_mbinter(dec, mb, x, y, 0, bs,
1097                                                                  rounding, reduced_resolution, 0);                                  rounding, 0, 0);
1098    
1099                                  if(dec->out_frm && cp_mb > 0) {                                  if(dec->out_frm && cp_mb > 0) {
1100                                          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 1008  Line 1149 
1149  decoder_bf_interpolate_mbinter(DECODER * dec,  decoder_bf_interpolate_mbinter(DECODER * dec,
1150                                                                  IMAGE forward,                                                                  IMAGE forward,
1151                                                                  IMAGE backward,                                                                  IMAGE backward,
1152                                                                  const MACROBLOCK * pMB,                  MACROBLOCK * pMB,
1153                                                                  const uint32_t x_pos,                                                                  const uint32_t x_pos,
1154                                                                  const uint32_t y_pos,                                                                  const uint32_t y_pos,
1155                                                                  Bitstream * bs,                                                                  Bitstream * bs,
# Line 1025  Line 1166 
1166          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
1167          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
1168    
1169      validate_vector(pMB->mvs, x_pos, y_pos, dec);
1170      validate_vector(pMB->b_mvs, x_pos, y_pos, dec);
1171    
1172          if (!direct) {          if (!direct) {
1173                  uv_dx = pMB->mvs[0].x;                  uv_dx = pMB->mvs[0].x;
1174                  uv_dy = pMB->mvs[0].y;                  uv_dy = pMB->mvs[0].y;
   
1175                  b_uv_dx = pMB->b_mvs[0].x;                  b_uv_dx = pMB->b_mvs[0].x;
1176                  b_uv_dy = pMB->b_mvs[0].y;                  b_uv_dy = pMB->b_mvs[0].y;
1177    
1178                  if (dec->quarterpel) {                  if (dec->quarterpel) {
1179                            if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
1180                                    uv_dx = (uv_dx>>1) | (uv_dx&1);
1181                                    uv_dy = (uv_dy>>1) | (uv_dy&1);
1182                                    b_uv_dx = (b_uv_dx>>1) | (b_uv_dx&1);
1183                                    b_uv_dy = (b_uv_dy>>1) | (b_uv_dy&1);
1184                            }
1185                            else {
1186                          uv_dx /= 2;                          uv_dx /= 2;
1187                          uv_dy /= 2;                          uv_dy /= 2;
1188                          b_uv_dx /= 2;                          b_uv_dx /= 2;
1189                          b_uv_dy /= 2;                          b_uv_dy /= 2;
1190                  }                  }
1191        }
1192    
1193                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
1194                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
   
1195                  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];
1196                  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];
1197    
1198          } else {          } else {
1199                  if(dec->quarterpel) {            if (dec->quarterpel) { /* for qpel the /2 shall be done before summation. We've done it right in the encoder in the past. */
1200                                                             /* TODO: figure out if we ever did it wrong on the encoder side. If yes, add some workaround */
1201                    if (dec->bs_version <= BS_VERSION_BUGGY_CHROMA_ROUNDING) {
1202                            int z;
1203                            uv_dx = 0; uv_dy = 0;
1204                            b_uv_dx = 0; b_uv_dy = 0;
1205                            for (z = 0; z < 4; z++) {
1206                              uv_dx += ((pMB->mvs[z].x>>1) | (pMB->mvs[z].x&1));
1207                              uv_dy += ((pMB->mvs[z].y>>1) | (pMB->mvs[z].y&1));
1208                              b_uv_dx += ((pMB->b_mvs[z].x>>1) | (pMB->b_mvs[z].x&1));
1209                              b_uv_dy += ((pMB->b_mvs[z].y>>1) | (pMB->b_mvs[z].y&1));
1210                            }
1211                    }
1212                    else {
1213                          uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);                          uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
1214                          uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);                          uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
1215                          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);                          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);
1216                          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);                          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);
1217                    }
1218                  } else {                  } else {
1219                          uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;                          uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1220                          uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                          uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
# Line 1103  Line 1267 
1267    
1268          if(dec->quarterpel) {          if(dec->quarterpel) {
1269                  if(!direct) {                  if(!direct) {
1270                          interpolate16x16_quarterpel(dec->tmp.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,        interpolate16x16_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1271                                                                                  dec->qtmp.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                  } else {                  } else {
1274                          interpolate8x8_quarterpel(dec->tmp.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1275                                                                                  dec->qtmp.y + 128, 16*x_pos, 16*y_pos,                                                                                  dec->qtmp.y + 128, 16*x_pos, 16*y_pos,
1276                                                                                  pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                                                  pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1277                          interpolate8x8_quarterpel(dec->tmp.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1278                                                                                  dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,                                                                                  dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos,
1279                                                                                  pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);                                                                                  pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
1280                          interpolate8x8_quarterpel(dec->tmp.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1281                                                                                  dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,                                                                                  dec->qtmp.y + 128, 16*x_pos, 16*y_pos + 8,
1282                                                                                  pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);                                                                                  pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
1283                          interpolate8x8_quarterpel(dec->tmp.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,        interpolate8x8_add_quarterpel(dec->cur.y, backward.y, dec->qtmp.y, dec->qtmp.y + 64,
1284                                                                                  dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,                                                                                  dec->qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8,
1285                                                                                  pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);                                                                                  pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
1286                  }                  }
1287          } else {          } else {
1288                  interpolate8x8_switch(dec->tmp.y, backward.y, 16 * x_pos, 16 * y_pos,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos, 16 * y_pos,
1289                                                          pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                          pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1290                  interpolate8x8_switch(dec->tmp.y, backward.y, 16 * x_pos + 8,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
1291                                                          16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);                                                          16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
1292                  interpolate8x8_switch(dec->tmp.y, backward.y, 16 * x_pos,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos,
1293                                                          16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);                                                          16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
1294                  interpolate8x8_switch(dec->tmp.y, backward.y, 16 * x_pos + 8,      interpolate8x8_add_switch(dec->cur.y, backward.y, 16 * x_pos + 8,
1295                                                          16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);                                                          16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
1296          }          }
1297    
1298          interpolate8x8_switch(dec->tmp.u, backward.u, 8 * x_pos, 8 * y_pos,    interpolate8x8_add_switch(dec->cur.u, backward.u, 8 * x_pos, 8 * y_pos,
1299                                                  b_uv_dx, b_uv_dy, stride2, 0);                                                  b_uv_dx, b_uv_dy, stride2, 0);
1300          interpolate8x8_switch(dec->tmp.v, backward.v, 8 * x_pos, 8 * y_pos,    interpolate8x8_add_switch(dec->cur.v, backward.v, 8 * x_pos, 8 * y_pos,
1301                                                  b_uv_dx, b_uv_dy, stride2, 0);                                                  b_uv_dx, b_uv_dy, stride2, 0);
1302    
         interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 dec->tmp.y + (16 * y_pos * stride) + 16 * x_pos,  
                                                 stride, 1, 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->tmp.y + (16 * y_pos * stride) + 16 * x_pos + 8,  
                                                 stride, 1, 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->tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,  
                                                 stride, 1, 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->tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,  
                                                 stride, 1, 8);  
   
         interpolate8x8_avg2(dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->tmp.u + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 stride2, 1, 8);  
   
         interpolate8x8_avg2(dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 dec->tmp.v + (8 * y_pos * stride2) + 8 * x_pos,  
                                                 stride2, 1, 8);  
   
1303          stop_comp_timer();          stop_comp_timer();
1304    
1305          if (cbp)          if (cbp)
1306                  decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);      decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
1307  }  }
1308    
1309  /* for decode B-frame dbquant */  /* for decode B-frame dbquant */
# Line 1204  Line 1338 
1338          return -1;          return -1;
1339  }  }
1340    
1341    static int __inline get_resync_len_b(const int fcode_backward,
1342                                         const int fcode_forward) {
1343      int resync_len = ((fcode_forward>fcode_backward) ? fcode_forward : fcode_backward) - 1;
1344      if (resync_len < 1) resync_len = 1;
1345      return resync_len;
1346    }
1347    
1348  static void  static void
1349  decoder_bframe(DECODER * dec,  decoder_bframe(DECODER * dec,
1350                                  Bitstream * bs,                                  Bitstream * bs,
# Line 1214  Line 1355 
1355          uint32_t x, y;          uint32_t x, y;
1356          VECTOR mv;          VECTOR mv;
1357          const VECTOR zeromv = {0,0};          const VECTOR zeromv = {0,0};
         const int64_t TRB = dec->time_pp - dec->time_bp, TRD = dec->time_pp;  
1358          int i;          int i;
1359      int resync_len;
1360    
1361      if (!dec->is_edged[0]) {
1362          start_timer();          start_timer();
1363          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
1364                                          dec->width, dec->height, dec->bs_version);                                          dec->width, dec->height, dec->bs_version);
1365        dec->is_edged[0] = 1;
1366        stop_edges_timer();
1367      }
1368    
1369      if (!dec->is_edged[1]) {
1370        start_timer();
1371          image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[1], dec->edged_width, dec->edged_height,
1372                                          dec->width, dec->height, dec->bs_version);                                          dec->width, dec->height, dec->bs_version);
1373        dec->is_edged[1] = 1;
1374          stop_edges_timer();          stop_edges_timer();
1375      }
1376    
1377      resync_len = get_resync_len_b(fcode_backward, fcode_forward);
1378          for (y = 0; y < dec->mb_height; y++) {          for (y = 0; y < dec->mb_height; y++) {
1379                  /* Initialize Pred Motion Vector */                  /* Initialize Pred Motion Vector */
1380                  dec->p_fmv = dec->p_bmv = zeromv;                  dec->p_fmv = dec->p_bmv = zeromv;
1381                  for (x = 0; x < dec->mb_width; x++) {                  for (x = 0; x < dec->mb_width; x++) {
1382                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
1383                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];
1384                          const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;        int intra_dc_threshold; /* fake variable */
                         uint32_t intra_dc_threshold; /* fake variable */  
1385    
1386                          if (check_resync_marker(bs, fcode_max  - 1)) {        if (check_resync_marker(bs, resync_len)) {
1387                                  int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,          int bound = read_video_packet_header(bs, dec, resync_len, &quant,
1388                                                                                                           &fcode_forward, &fcode_backward, &intra_dc_threshold);                                                                                                           &fcode_forward, &fcode_backward, &intra_dc_threshold);
1389                                  x = bound % dec->mb_width;                                  x = bound % dec->mb_width;
1390                                  y = bound / dec->mb_width;          y = MIN((bound / dec->mb_width), (dec->mb_height-1));
1391                                  /* reset predicted macroblocks */                                  /* reset predicted macroblocks */
1392                                  dec->p_fmv = dec->p_bmv = zeromv;                                  dec->p_fmv = dec->p_bmv = zeromv;
1393            /* update resync len with new fcodes */
1394            resync_len = get_resync_len_b(fcode_backward, fcode_forward);
1395                          }                          }
1396    
1397                          mv =                          mv =
# Line 1256  Line 1408 
1408                          if (last_mb->mode == MODE_NOT_CODED) {                          if (last_mb->mode == MODE_NOT_CODED) {
1409                                  mb->cbp = 0;                                  mb->cbp = 0;
1410                                  mb->mode = MODE_FORWARD;                                  mb->mode = MODE_FORWARD;
1411                                  decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 1);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
1412                                  continue;                                  continue;
1413                          }                          }
1414    
# Line 1309  Line 1461 
1461    
1462                          case MODE_DIRECT_NONE_MV:                          case MODE_DIRECT_NONE_MV:
1463                                  for (i = 0; i < 4; i++) {                                  for (i = 0; i < 4; i++) {
1464                                          mb->mvs[i].x = (int32_t) ((TRB * last_mb->mvs[i].x) / TRD + mv.x);            mb->mvs[i].x = last_mb->mvs[i].x*dec->time_bp/dec->time_pp + mv.x;
1465                                          mb->b_mvs[i].x = (int32_t) ((mv.x == 0)            mb->mvs[i].y = last_mb->mvs[i].y*dec->time_bp/dec->time_pp + mv.y;
1466                                                                          ? ((TRB - TRD) * last_mb->mvs[i].x) / TRD  
1467                                                                          : mb->mvs[i].x - last_mb->mvs[i].x);            mb->b_mvs[i].x = (mv.x)
1468                                          mb->mvs[i].y = (int32_t) ((TRB * last_mb->mvs[i].y) / TRD + mv.y);              ?  mb->mvs[i].x - last_mb->mvs[i].x
1469                                          mb->b_mvs[i].y = (int32_t) ((mv.y == 0)              : last_mb->mvs[i].x*(dec->time_bp - dec->time_pp)/dec->time_pp;
1470                                                                          ? ((TRB - TRD) * last_mb->mvs[i].y) / TRD            mb->b_mvs[i].y = (mv.y)
1471                                                                          : mb->mvs[i].y - last_mb->mvs[i].y);              ? mb->mvs[i].y - last_mb->mvs[i].y
1472                : last_mb->mvs[i].y*(dec->time_bp - dec->time_pp)/dec->time_pp;
1473                                  }                                  }
1474    
1475                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],                                  decoder_bf_interpolate_mbinter(dec, dec->refn[1], dec->refn[0],
# Line 1338  Line 1491 
1491                                  get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);                                  get_b_motion_vector(bs, &mb->mvs[0], fcode_backward, dec->p_bmv, dec, x, y);
1492                                  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];
1493    
1494                                  decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 0);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 1);
1495                                  break;                                  break;
1496    
1497                          case MODE_FORWARD:                          case MODE_FORWARD:
1498                                  get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);                                  get_b_motion_vector(bs, &mb->mvs[0], fcode_forward, dec->p_fmv, dec, x, y);
1499                                  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];
1500    
1501                                  decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 0, 1);          decoder_mbinter(dec, mb, x, y, mb->cbp, bs, 0, 1, 1);
1502                                  break;                                  break;
1503    
1504                          default:                          default:
# Line 1356  Line 1509 
1509  }  }
1510    
1511  /* perform post processing if necessary, and output the image */  /* perform post processing if necessary, and output the image */
1512  void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,  static void decoder_output(DECODER * dec, IMAGE * img, MACROBLOCK * mbs,
1513                                          xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,                                          xvid_dec_frame_t * frame, xvid_dec_stats_t * stats,
1514                                          int coding_type, int quant)                                          int coding_type, int quant)
1515  {  {
1516      const int brightness = XVID_VERSION_MINOR(frame->version) >= 1 ? frame->brightness : 0;
1517    
1518          if (dec->cartoon_mode)          if (dec->cartoon_mode)
1519                  frame->general &= ~XVID_FILMEFFECT;                  frame->general &= ~XVID_FILMEFFECT;
1520    
1521          if ((frame->general & (XVID_DEBLOCKY|XVID_DEBLOCKUV|XVID_FILMEFFECT) || frame->brightness!=0)    if ((frame->general & (XVID_DEBLOCKY|XVID_DEBLOCKUV|XVID_FILMEFFECT) || brightness!=0)
1522                  && mbs != NULL) /* post process */                  && mbs != NULL) /* post process */
1523          {          {
1524                  /* note: image is stored to tmp */                  /* note: image is stored to tmp */
1525                  image_copy(&dec->tmp, img, dec->edged_width, dec->height);                  image_copy(&dec->tmp, img, dec->edged_width, dec->height);
1526                  image_postproc(&dec->postproc, &dec->tmp, dec->edged_width,                  image_postproc(&dec->postproc, &dec->tmp, dec->edged_width,
1527                                             mbs, dec->mb_width, dec->mb_height, dec->mb_width,                                             mbs, dec->mb_width, dec->mb_height, dec->mb_width,
1528                                             frame->general, frame->brightness, dec->frames, (coding_type == B_VOP));               frame->general, brightness, dec->frames, (coding_type == B_VOP));
1529                  img = &dec->tmp;                  img = &dec->tmp;
1530          }          }
1531    
# Line 1385  Line 1540 
1540                  stats->data.vop.qscale_stride = dec->mb_width;                  stats->data.vop.qscale_stride = dec->mb_width;
1541                  stats->data.vop.qscale = dec->qscale;                  stats->data.vop.qscale = dec->qscale;
1542                  if (stats->data.vop.qscale != NULL && mbs != NULL) {                  if (stats->data.vop.qscale != NULL && mbs != NULL) {
1543                          int i;        unsigned int i;
1544                          for (i = 0; i < dec->mb_width*dec->mb_height; i++)                          for (i = 0; i < dec->mb_width*dec->mb_height; i++)
1545                                  stats->data.vop.qscale[i] = mbs[i].quant;                                  stats->data.vop.qscale[i] = mbs[i].quant;
1546                  } else                  } else
# Line 1393  Line 1548 
1548          }          }
1549  }  }
1550    
   
1551  int  int
1552  decoder_decode(DECODER * dec,  decoder_decode(DECODER * dec,
1553                                  xvid_dec_frame_t * frame, xvid_dec_stats_t * stats)                                  xvid_dec_frame_t * frame, xvid_dec_stats_t * stats)
# Line 1401  Line 1555 
1555    
1556          Bitstream bs;          Bitstream bs;
1557          uint32_t rounding;          uint32_t rounding;
         uint32_t reduced_resolution;  
1558          uint32_t quant = 2;          uint32_t quant = 2;
1559          uint32_t fcode_forward;          uint32_t fcode_forward;
1560          uint32_t fcode_backward;          uint32_t fcode_backward;
# Line 1456  Line 1609 
1609    
1610  repeat:  repeat:
1611    
1612          coding_type = BitstreamReadHeaders(&bs, dec, &rounding, &reduced_resolution,    coding_type = BitstreamReadHeaders(&bs, dec, &rounding,
1613                          &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);                          &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);
1614    
1615          DPRINTF(XVID_DEBUG_HEADER, "coding_type=%i,  packed=%i,  time=%lli,  time_pp=%i,  time_bp=%i\n",    DPRINTF(XVID_DEBUG_HEADER, "coding_type=%i,  packed=%i,  time=%"
1616    #if defined(_MSC_VER)
1617        "I64"
1618    #else
1619        "ll"
1620    #endif
1621        "i,  time_pp=%i,  time_bp=%i\n",
1622                                                          coding_type,    dec->packed_mode, dec->time, dec->time_pp, dec->time_bp);                                                          coding_type,    dec->packed_mode, dec->time, dec->time_pp, dec->time_bp);
1623    
1624          if (coding_type == -1) { /* nothing */          if (coding_type == -1) { /* nothing */
# Line 1472  Line 1631 
1631          if (coding_type == -2 || coding_type == -3) {   /* vol and/or resize */          if (coding_type == -2 || coding_type == -3) {   /* vol and/or resize */
1632    
1633                  if (coding_type == -3)                  if (coding_type == -3)
1634                          decoder_resize(dec);        if (decoder_resize(dec)) return XVID_ERR_MEMORY;
1635    
1636                  if (stats) {                  if (stats) {
1637                          stats->type = XVID_TYPE_VOL;                          stats->type = XVID_TYPE_VOL;
# Line 1490  Line 1649 
1649                  goto repeat;                  goto repeat;
1650          }          }
1651    
1652      if(dec->frames == 0 && coding_type != I_VOP) {
1653        /* 1st frame is not an i-vop */
1654        goto repeat;
1655      }
1656    
1657          dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;  /* init pred vector to 0 */          dec->p_bmv.x = dec->p_bmv.y = dec->p_fmv.y = dec->p_fmv.y = 0;  /* init pred vector to 0 */
1658    
1659          /* packed_mode: special-N_VOP treament */          /* packed_mode: special-N_VOP treament */
# Line 1502  Line 1666 
1666          } else if (coding_type != B_VOP) {          } else if (coding_type != B_VOP) {
1667                  switch(coding_type) {                  switch(coding_type) {
1668                  case I_VOP :                  case I_VOP :
1669                          decoder_iframe(dec, &bs, reduced_resolution, quant, intra_dc_threshold);        decoder_iframe(dec, &bs, quant, intra_dc_threshold);
1670                          break;                          break;
1671                  case P_VOP :                  case P_VOP :
1672                          decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,        decoder_pframe(dec, &bs, rounding, quant,
1673                                                  fcode_forward, intra_dc_threshold, NULL);                                                  fcode_forward, intra_dc_threshold, NULL);
1674                          break;                          break;
1675                  case S_VOP :                  case S_VOP :
1676                          decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,        decoder_pframe(dec, &bs, rounding, quant,
1677                                                  fcode_forward, intra_dc_threshold, &gmc_warp);                                                  fcode_forward, intra_dc_threshold, &gmc_warp);
1678                          break;                          break;
1679                  case N_VOP :                  case N_VOP :
# Line 1520  Line 1684 
1684                          break;                          break;
1685                  }                  }
1686    
                 if (reduced_resolution) {  
                         image_deblock_rrv(&dec->cur, dec->edged_width, dec->mbs,  
                                 (dec->width + 31) / 32, (dec->height + 31) / 32, dec->mb_width,  
                                 16, 0);  
                 }  
   
1687                  /* note: for packed_mode, output is performed when the special-N_VOP is decoded */                  /* note: for packed_mode, output is performed when the special-N_VOP is decoded */
1688                  if (!(dec->low_delay_default && dec->packed_mode)) {                  if (!(dec->low_delay_default && dec->packed_mode)) {
1689                          if (dec->low_delay) {                          if (dec->low_delay) {
# Line 1539  Line 1697 
1697                  }                  }
1698    
1699                  image_swap(&dec->refn[0], &dec->refn[1]);                  image_swap(&dec->refn[0], &dec->refn[1]);
1700        dec->is_edged[1] = dec->is_edged[0];
1701                  image_swap(&dec->cur, &dec->refn[0]);                  image_swap(&dec->cur, &dec->refn[0]);
1702        dec->is_edged[0] = 0;
1703                  SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs);                  SWAP(MACROBLOCK *, dec->mbs, dec->last_mbs);
                 dec->last_reduced_resolution = reduced_resolution;  
1704                  dec->last_coding_type = coding_type;                  dec->last_coding_type = coding_type;
1705    
1706                  dec->frames++;                  dec->frames++;
# Line 1551  Line 1710 
1710    
1711                  if (dec->low_delay) {                  if (dec->low_delay) {
1712                          DPRINTF(XVID_DEBUG_ERROR, "warning: bvop found in low_delay==1 stream\n");                          DPRINTF(XVID_DEBUG_ERROR, "warning: bvop found in low_delay==1 stream\n");
1713                          dec->low_delay = 1;        dec->low_delay = 0;
1714                  }                  }
1715    
1716                  if (dec->frames < 2) {                  if (dec->frames < 2) {
# Line 1586  Line 1745 
1745    
1746  done :  done :
1747    
1748          /* low_delay_default mode: if we've gotten here without outputting anything,    /* if we reach here without outputing anything _and_
1749             then output the recently decoded frame, or print an error message  */       the calling application has specified low_delay_default,
1750         we *must* output something.
1751         this always occurs on the first call to decode() call
1752         when bframes are present in the bitstream. it may also
1753         occur if no vops  were seen in the bitstream
1754    
1755         if packed_mode is enabled, then we output the recently
1756         decoded frame (the very first ivop). otherwise we have
1757         nothing to display, and therefore output a black screen.
1758      */
1759          if (dec->low_delay_default && output == 0) {          if (dec->low_delay_default && output == 0) {
1760                  if (dec->packed_mode && seen_something) {                  if (dec->packed_mode && seen_something) {
                         /* output the recently decoded frame */  
1761                          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);                          decoder_output(dec, &dec->refn[0], dec->last_mbs, frame, stats, dec->last_coding_type, quant);
1762                  } else {                  } else {
1763                          image_clear(&dec->cur, dec->width, dec->height, dec->edged_width, 0, 128, 128);                          image_clear(&dec->cur, dec->width, dec->height, dec->edged_width, 0, 128, 128);
                         image_printf(&dec->cur, dec->edged_width, dec->height, 16, 16,  
                                 "warning: nothing to output");  
                         image_printf(&dec->cur, dec->edged_width, dec->height, 16, 64,  
                                 "bframe decoder lag");  
   
1764                          decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP, quant);                          decoder_output(dec, &dec->cur, NULL, frame, stats, P_VOP, quant);
1765                          if (stats) stats->type = XVID_TYPE_NOTHING;                          if (stats) stats->type = XVID_TYPE_NOTHING;
1766                  }                  }

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.81

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