[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.5, Fri Oct 11 15:07:32 2002 UTC revision 1.37.2.15, Sun Dec 8 05:38:56 2002 UTC
# Line 79  Line 79 
79  #include "dct/fdct.h"  #include "dct/fdct.h"
80  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
81  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
82    #include "image/reduced.h"
83    
84  #include "bitstream/mbcoding.h"  #include "bitstream/mbcoding.h"
85  #include "prediction/mbprediction.h"  #include "prediction/mbprediction.h"
86  #include "utils/timer.h"  #include "utils/timer.h"
87  #include "utils/emms.h"  #include "utils/emms.h"
88    #include "motion/motion.h"
89    
90  #include "image/image.h"  #include "image/image.h"
91  #include "image/colorspace.h"  #include "image/colorspace.h"
92  #include "utils/mem_align.h"  #include "utils/mem_align.h"
93    
94  int  int
95  decoder_create(XVID_DEC_PARAM * param)  decoder_resize(DECODER * dec)
96  {  {
97          DECODER *dec;          /* free existing */
98    
99          dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);          image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
100          if (dec == NULL) {          image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
101                  return XVID_ERR_MEMORY;          image_destroy(&dec->refn[2], dec->edged_width, dec->edged_height);
102          }          image_destroy(&dec->refh, dec->edged_width, dec->edged_height);
103          param->handle = dec;          image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
104    
105          dec->width = param->width;          if (dec->last_mbs)
106          dec->height = param->height;                  xvid_free(dec->last_mbs);
107            if (dec->mbs)
108                    xvid_free(dec->mbs);
109    
110            /* realloc */
111    
112          dec->mb_width = (dec->width + 15) / 16;          dec->mb_width = (dec->width + 15) / 16;
113          dec->mb_height = (dec->height + 15) / 16;          dec->mb_height = (dec->height + 15) / 16;
114    
115          dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;          dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;
116          dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;          dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;
         dec->low_delay = 0;  
117    
118          if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) {          if (image_create(&dec->cur, dec->edged_width, dec->edged_height)) {
119                  xvid_free(dec);                  xvid_free(dec);
# Line 120  Line 125 
125                  xvid_free(dec);                  xvid_free(dec);
126                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
127          }          }
128    
129          // add by chenm001 <chenm001@163.com>          // add by chenm001 <chenm001@163.com>
130          // for support B-frame to reference last 2 frame          // for support B-frame to reference last 2 frame
131          if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {          if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) {
# Line 157  Line 163 
163                  xvid_free(dec);                  xvid_free(dec);
164                  return XVID_ERR_MEMORY;                  return XVID_ERR_MEMORY;
165          }          }
   
166          memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);          memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);
167    
168          // add by chenm001 <chenm001@163.com>          // add by chenm001 <chenm001@163.com>
# Line 178  Line 183 
183    
184          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);
185    
186            return XVID_ERR_OK;
187    }
188    
189    
190    int
191    decoder_create(XVID_DEC_PARAM * param)
192    {
193            DECODER *dec;
194    
195            dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
196            if (dec == NULL) {
197                    return XVID_ERR_MEMORY;
198            }
199            memset(dec, 0, sizeof(DECODER));
200    
201            param->handle = dec;
202    
203            dec->width = param->width;
204            dec->height = param->height;
205    
206            image_null(&dec->cur);
207            image_null(&dec->refn[0]);
208            image_null(&dec->refn[1]);
209            image_null(&dec->refn[2]);
210            image_null(&dec->refh);
211    
212            dec->mbs = NULL;
213            dec->last_mbs = NULL;
214    
215          init_timer();          init_timer();
216    
217          // add by chenm001 <chenm001@163.com>          // add by chenm001 <chenm001@163.com>
218          // for support B-frame to save reference frame's time          // for support B-frame to save reference frame's time
219          dec->frames = -1;          dec->frames = -1;
220          dec->time = dec->time_base = dec->last_time_base = 0;          dec->time = dec->time_base = dec->last_time_base = 0;
221            dec->low_delay = 0;
222            dec->packed_mode = 0;
223    
224            dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);
225    
226            if (dec->fixed_dimensions)
227                    return decoder_resize(dec);
228            else
229          return XVID_ERR_OK;          return XVID_ERR_OK;
230  }  }
231    
# Line 226  Line 267 
267                                  Bitstream * bs,                                  Bitstream * bs,
268                                  const uint32_t quant,                                  const uint32_t quant,
269                                  const uint32_t intra_dc_threshold,                                  const uint32_t intra_dc_threshold,
270                                  const unsigned int bound)                                  const unsigned int bound,
271                                    const int reduced_resolution)
272  {  {
273    
274          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
# Line 239  Line 281 
281          uint32_t iQuant = pMB->quant;          uint32_t iQuant = pMB->quant;
282          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
283    
284            if (reduced_resolution) {
285                    pY_Cur = dec->cur.y + (y_pos << 5) * stride + (x_pos << 5);
286                    pU_Cur = dec->cur.u + (y_pos << 4) * stride2 + (x_pos << 4);
287                    pV_Cur = dec->cur.v + (y_pos << 4) * stride2 + (x_pos << 4);
288            }else{
289          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
290          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
291          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
292            }
293    
294          memset(block, 0, 6 * 64 * sizeof(int16_t));     // clear          memset(block, 0, 6 * 64 * sizeof(int16_t));     // clear
295    
# Line 302  Line 350 
350                  start_timer();                  start_timer();
351                  idct(&data[i * 64]);                  idct(&data[i * 64]);
352                  stop_idct_timer();                  stop_idct_timer();
353    
354          }          }
355    
356          if (dec->interlacing && pMB->field_dct) {          if (dec->interlacing && pMB->field_dct) {
# Line 310  Line 359 
359          }          }
360    
361          start_timer();          start_timer();
362    
363            if (reduced_resolution)
364            {
365                    next_block*=2;
366                    copy_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);
367                    copy_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);
368                    copy_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);
369                    copy_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);
370                    copy_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);
371                    copy_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);
372            }else{
373          transfer_16to8copy(pY_Cur, &data[0 * 64], stride);          transfer_16to8copy(pY_Cur, &data[0 * 64], stride);
374          transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);          transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);
375          transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);          transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);
376          transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);          transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);
377          transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);          transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);
378          transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);          transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);
379            }
380          stop_transfer_timer();          stop_transfer_timer();
381  }  }
382    
# Line 325  Line 386 
386    
387  #define SIGN(X) (((X)>0)?1:-1)  #define SIGN(X) (((X)>0)?1:-1)
388  #define ABS(X) (((X)>0)?(X):-(X))  #define ABS(X) (((X)>0)?(X):-(X))
 static const uint32_t roundtab[16] =  
         { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2 };  
   
389    
390  // decode an inter macroblock  // decode an inter macroblock
391    
392    static void
393    set_block(uint8_t * dst, int stride, int width, int height, int color)
394    {
395            int i;
396            for (i = 0; i < height; i++)
397            {
398                    memset(dst, color, width);
399                    dst += stride;
400            }
401    }
402    
403    static void
404    rrv_mv_scaleup(VECTOR * mv)
405    {
406            if (mv->x > 0) {
407                    mv->x = 2*mv->x - 1;
408            } else if (mv->x < 0) {
409                    mv->x = 2*mv->x + 1;
410            }
411    
412            if (mv->y > 0) {
413                    mv->y = 2*mv->y - 1;
414            } else if (mv->y < 0) {
415                    mv->y = 2*mv->y + 1;
416            }
417    }
418    
419    
420    
421  void  void
422  decoder_mbinter(DECODER * dec,  decoder_mbinter(DECODER * dec,
423                                  const MACROBLOCK * pMB,                                  const MACROBLOCK * pMB,
# Line 340  Line 427 
427                                  const uint32_t cbp,                                  const uint32_t cbp,
428                                  Bitstream * bs,                                  Bitstream * bs,
429                                  const uint32_t quant,                                  const uint32_t quant,
430                                  const uint32_t rounding)                                  const uint32_t rounding,
431                                    const int reduced_resolution)
432  {  {
433    
434          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
# Line 348  Line 436 
436    
437          uint32_t stride = dec->edged_width;          uint32_t stride = dec->edged_width;
438          uint32_t stride2 = stride / 2;          uint32_t stride2 = stride / 2;
439          uint32_t next_block = stride * 8;          uint32_t next_block = stride * (reduced_resolution ? 16 : 8);
440          uint32_t i;          uint32_t i;
441          uint32_t iQuant = pMB->quant;          uint32_t iQuant = pMB->quant;
442          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;          uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
443    
444          int uv_dx, uv_dy;          int uv_dx, uv_dy;
445            VECTOR mv[4];
446    
447            for (i = 0; i < 4; i++)
448            {
449                    mv[i] = pMB->mvs[i];
450                    //DPRINTF(DPRINTF_MB, "mv[%i]   orig=%i,%i   local=%i", i, pMB->mvs[i].x, pMB->mvs[i].y,                                                mv[i].x, mv[i].y);
451            }
452    
453            if (reduced_resolution) {
454                    pY_Cur = dec->cur.y + (y_pos << 5) * stride + (x_pos << 5);
455                    pU_Cur = dec->cur.u + (y_pos << 4) * stride2 + (x_pos << 4);
456                    pV_Cur = dec->cur.v + (y_pos << 4) * stride2 + (x_pos << 4);
457                    DPRINTF(DPRINTF_MB,"[%i,%i] %i,%i  %i,%i  %i,%i  %i,%i",
458                            x_pos, y_pos,
459                            mv[0].x, mv[0].y,
460                            mv[1].x, mv[1].y,
461                            mv[2].x, mv[2].y,
462                            mv[3].x, mv[3].y);
463    
464                    rrv_mv_scaleup(&mv[0]);
465                    rrv_mv_scaleup(&mv[1]);
466                    rrv_mv_scaleup(&mv[2]);
467                    rrv_mv_scaleup(&mv[3]);
468    
469                    DPRINTF(DPRINTF_MB,"        %i,%i  %i,%i  %i,%i  %i,%i",
470                            mv[0].x, mv[0].y,
471                            mv[1].x, mv[1].y,
472                            mv[2].x, mv[2].y,
473                            mv[3].x, mv[3].y);
474            }else{
475          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);          pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
476          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);          pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
477          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);          pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
478            }
479    
480          if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {          if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
481                  uv_dx = pMB->mvs[0].x;                  uv_dx = mv[0].x;
482                  uv_dy = pMB->mvs[0].y;                  uv_dy = mv[0].y;
483    
484                  if (dec->quarterpel)                  if (dec->quarterpel)
485                  {                  {
486                          uv_dx = (uv_dx >> 1) | (uv_dx & 1);                          uv_dx /= 2;
487                          uv_dy = (uv_dy >> 1) | (uv_dy & 1);                          uv_dy /= 2;
488                  }                  }
489    
490                  uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;                  uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
491                  uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;                  uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
492    
493                  start_timer();                  start_timer();
494                    if (reduced_resolution)
495                    {
496                            interpolate32x32_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,
497                                                                      mv[0].x, mv[0].y, stride,  rounding);
498                            interpolate16x16_switch(dec->cur.u, dec->refn[0].u, 16 * x_pos, 16 * y_pos,
499                                                                      uv_dx, uv_dy, stride2, rounding);
500                            interpolate16x16_switch(dec->cur.v, dec->refn[0].v, 16 * x_pos, 16 * y_pos,
501                                                                      uv_dx, uv_dy, stride2, rounding);
502    
503                    }
504                    else
505                    {
506                  if(dec->quarterpel) {                  if(dec->quarterpel) {
507                          interpolate16x16_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          interpolate16x16_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,
508                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,                                                                              dec->refh.y + 128, 16*x_pos, 16*y_pos,
509                                                                              pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                                                                                          mv[0].x, mv[0].y, stride,  rounding);
510                  }                  }
511                  else {                  else {
512                          interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,                                  interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos,
513                                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                                                                            mv[0].x, mv[0].y, stride,  rounding);
                         interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos,  
                                                               pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);  
                         interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8,  
                                                                   pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);  
                         interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8,  
                                                                   pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);  
514                  }                  }
515    
516                  interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,
517                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
518                  interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,
519                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
520                    }
521                  stop_comp_timer();                  stop_comp_timer();
522    
523          } else {          } else {        /* MODE_INTER4V */
524                  int sum;                  int sum;
                 sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;  
525    
526                  if (dec->quarterpel)                  if (dec->quarterpel)
527                  {                          sum = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);
528                          sum /= 2;                  else
529                  }                          sum = mv[0].x + mv[1].x + mv[2].x + mv[3].x;
   
                 uv_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));  
530    
531                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                  uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];
532    
533                  if (dec->quarterpel)                  if (dec->quarterpel)
534                  {                          sum = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);
535                          sum /= 2;                  else
536                  }                          sum = mv[0].y + mv[1].y + mv[2].y + mv[3].y;
537    
538                  uv_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));                  uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];
539    
540                  start_timer();                  start_timer();
541                    if (reduced_resolution)
542                    {
543                            interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos,
544                                                                      mv[0].x, mv[0].y, stride,  rounding);
545                            interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos + 16, 32*y_pos,
546                                                                      mv[1].x, mv[1].y, stride,  rounding);
547                            interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos, 32*y_pos + 16,
548                                                                      mv[2].x, mv[2].y, stride,  rounding);
549                            interpolate16x16_switch(dec->cur.y, dec->refn[0].y, 32*x_pos + 16, 32*y_pos + 16,
550                                                                      mv[3].x, mv[3].y, stride,  rounding);
551                            interpolate16x16_switch(dec->cur.u, dec->refn[0].u, 16 * x_pos, 16 * y_pos,
552                                                                      uv_dx, uv_dy, stride2, rounding);
553                            interpolate16x16_switch(dec->cur.v, dec->refn[0].v, 16 * x_pos, 16 * y_pos,
554                                                                      uv_dx, uv_dy, stride2, rounding);
555    
556                            // set_block(pY_Cur, stride, 32, 32, 127);
557                    }
558                    else
559                    {
560                  if(dec->quarterpel) {                  if(dec->quarterpel) {
561                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,
562                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos,                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos,
563                                                                            pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                                                                                    mv[0].x, mv[0].y, stride,  rounding);
564                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,
565                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,
566                                                                            pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);                                                                                    mv[1].x, mv[1].y, stride,  rounding);
567                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,
568                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,                                                                            dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,
569                                                                            pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);                                                                                    mv[2].x, mv[2].y, stride,  rounding);
570                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,                          interpolate8x8_quarterpel(dec->cur.y, dec->refn[0].y, dec->refh.y, dec->refh.y + 64,
571                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,                                                                            dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,
572                                                                            pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);                                                                                    mv[3].x, mv[3].y, stride,  rounding);
573                  }                  }
574                  else {                  else {
575                          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,
576                                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride,  rounding);                                                                            mv[0].x, mv[0].y, stride,  rounding);
577                          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,
578                                                                    pMB->mvs[1].x, pMB->mvs[1].y, stride,  rounding);                                                                            mv[1].x, mv[1].y, stride,  rounding);
579                          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,
580                                                                    pMB->mvs[2].x, pMB->mvs[2].y, stride,  rounding);                                                                            mv[2].x, mv[2].y, stride,  rounding);
581                          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,
582                                                                    pMB->mvs[3].x, pMB->mvs[3].y, stride,  rounding);                                                                            mv[3].x, mv[3].y, stride,  rounding);
583                  }                  }
584    
585                  interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8 * x_pos, 8 * y_pos,
586                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
587                  interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,                  interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8 * x_pos, 8 * y_pos,
588                                                            uv_dx, uv_dy, stride2, rounding);                                                            uv_dx, uv_dy, stride2, rounding);
589                    }
590                  stop_comp_timer();                  stop_comp_timer();
591          }          }
592    
# Line 478  Line 621 
621          }          }
622    
623          start_timer();          start_timer();
624            if (reduced_resolution)
625            {
626                    if (cbp & 32)
627                            add_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);
628                    if (cbp & 16)
629                            add_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);
630                    if (cbp & 8)
631                            add_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);
632                    if (cbp & 4)
633                            add_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);
634                    if (cbp & 2)
635                            add_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);
636                    if (cbp & 1)
637                            add_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);
638            }
639            else
640            {
641          if (cbp & 32)          if (cbp & 32)
642                  transfer_16to8add(pY_Cur, &data[0 * 64], stride);                  transfer_16to8add(pY_Cur, &data[0 * 64], stride);
643          if (cbp & 16)          if (cbp & 16)
# Line 490  Line 650 
650                  transfer_16to8add(pU_Cur, &data[4 * 64], stride2);                  transfer_16to8add(pU_Cur, &data[4 * 64], stride2);
651          if (cbp & 1)          if (cbp & 1)
652                  transfer_16to8add(pV_Cur, &data[5 * 64], stride2);                  transfer_16to8add(pV_Cur, &data[5 * 64], stride2);
653            }
654          stop_transfer_timer();          stop_transfer_timer();
655  }  }
656    
# Line 497  Line 658 
658  void  void
659  decoder_iframe(DECODER * dec,  decoder_iframe(DECODER * dec,
660                             Bitstream * bs,                             Bitstream * bs,
661                               int reduced_resolution,
662                             int quant,                             int quant,
663                             int intra_dc_threshold)                             int intra_dc_threshold)
664  {  {
665          uint32_t bound;          uint32_t bound;
666          uint32_t x, y;          uint32_t x, y;
667            int mb_width = dec->mb_width;
668            int mb_height = dec->mb_height;
669    
670            if (reduced_resolution)
671            {
672                    mb_width /= 2;
673                    mb_height /= 2;
674            }
675    
676          bound = 0;          bound = 0;
677    
678          for (y = 0; y < dec->mb_height; y++) {          for (y = 0; y < mb_height; y++) {
679                  for (x = 0; x < dec->mb_width; x++) {                  for (x = 0; x < mb_width; x++) {
680                          MACROBLOCK *mb;                          MACROBLOCK *mb;
681                          uint32_t mcbpc;                          uint32_t mcbpc;
682                          uint32_t cbpc;                          uint32_t cbpc;
# Line 519  Line 689 
689    
690                          if (check_resync_marker(bs, 0))                          if (check_resync_marker(bs, 0))
691                          {                          {
692                                  bound = read_video_packet_header(bs, 0, &quant);                                  bound = read_video_packet_header(bs, dec, 0,
693                                  x = bound % dec->mb_width;                                                          &quant, NULL, NULL, &intra_dc_threshold);
694                                  y = bound / dec->mb_width;                                  x = bound % mb_width;
695                                    y = bound / mb_width;
696                          }                          }
697                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
698    
# Line 556  Line 727 
727                          }                          }
728    
729                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
730                                                          intra_dc_threshold, bound);                                                          intra_dc_threshold, bound, reduced_resolution);
731    
732                  }                  }
733                  if(dec->out_frm)                  if(dec->out_frm)
734                    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);
   
735          }          }
736    
737  }  }
# Line 572  Line 743 
743                                    int x,                                    int x,
744                                    int y,                                    int y,
745                                    int k,                                    int k,
746                                    VECTOR * mv,                                    VECTOR * ret_mv,
747                                    int fcode,                                    int fcode,
748                                    const int bound)                                    const int bound)
749  {  {
# Line 583  Line 754 
754          int range = (64 * scale_fac);          int range = (64 * scale_fac);
755    
756          VECTOR pmv;          VECTOR pmv;
757          int mv_x, mv_y;          VECTOR mv;
758    
759          pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);          pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k);
760    
761          mv_x = get_mv(bs, fcode);          mv.x = get_mv(bs, fcode);
762          mv_y = get_mv(bs, fcode);          mv.y = get_mv(bs, fcode);
763    
764          DPRINTF(DPRINTF_MV,"mv_diff (%i,%i) pred (%i,%i)", mv_x, mv_y, pmv.x, pmv.y);          DPRINTF(DPRINTF_MV,"mv_diff (%i,%i) pred (%i,%i)", mv.x, mv.y, pmv.x, pmv.y);
765    
766          mv_x += pmv.x;          mv.x += pmv.x;
767          mv_y += pmv.y;          mv.y += pmv.y;
768    
769          if (mv_x < low) {          if (mv.x < low) {
770                  mv_x += range;                  mv.x += range;
771          } else if (mv_x > high) {          } else if (mv.x > high) {
772                  mv_x -= range;                  mv.x -= range;
773          }          }
774    
775          if (mv_y < low) {          if (mv.y < low) {
776                  mv_y += range;                  mv.y += range;
777          } else if (mv_y > high) {          } else if (mv.y > high) {
778                  mv_y -= range;                  mv.y -= range;
779          }          }
780    
781          mv->x = mv_x;          ret_mv->x = mv.x;
782          mv->y = mv_y;          ret_mv->y = mv.y;
783    }
784    
785    
786    
787    static __inline int gmc_sanitize(int value, int quarterpel, int fcode)
788    {
789            int length = 1 << (fcode+4);
790    
791            if (quarterpel) value *= 2;
792    
793            if (value < -length)
794                    return -length;
795            else if (value >= length)
796                    return length-1;
797            else return value;
798  }  }
799    
800    
801    /* for P_VOP set gmc_mv to NULL */
802  void  void
803  decoder_pframe(DECODER * dec,  decoder_pframe(DECODER * dec,
804                             Bitstream * bs,                             Bitstream * bs,
805                             int rounding,                             int rounding,
806                               int reduced_resolution,
807                             int quant,                             int quant,
808                             int fcode,                             int fcode,
809                             int intra_dc_threshold)                             int intra_dc_threshold,
810                               VECTOR * gmc_mv)
811  {  {
812    
813          uint32_t x, y;          uint32_t x, y;
814          uint32_t bound;          uint32_t bound;
815          int cp_mb, st_mb;          int cp_mb, st_mb;
816            int mb_width = dec->mb_width;
817            int mb_height = dec->mb_height;
818    
819            if (reduced_resolution)
820            {
821                    mb_width /= 2;
822                    mb_height /= 2;
823            }
824    
825          start_timer();          start_timer();
826          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,          image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height,
# Line 633  Line 829 
829    
830          bound = 0;          bound = 0;
831    
832          for (y = 0; y < dec->mb_height; y++) {          for (y = 0; y < mb_height; y++) {
833                  cp_mb = st_mb = 0;                  cp_mb = st_mb = 0;
834                  for (x = 0; x < dec->mb_width; x++) {                  for (x = 0; x < mb_width; x++) {
835                          MACROBLOCK *mb;                          MACROBLOCK *mb;
836    
837                          // skip stuffing                          // skip stuffing
# Line 644  Line 840 
840    
841                          if (check_resync_marker(bs, fcode - 1))                          if (check_resync_marker(bs, fcode - 1))
842                          {                          {
843                                  bound = read_video_packet_header(bs, fcode - 1, &quant);                                  bound = read_video_packet_header(bs, dec, fcode - 1,
844                                  x = bound % dec->mb_width;                                          &quant, &fcode, NULL, &intra_dc_threshold);
845                                  y = bound / dec->mb_width;                                  x = bound % mb_width;
846                                    y = bound / mb_width;
847                          }                          }
848                          mb = &dec->mbs[y * dec->mb_width + x];                          mb = &dec->mbs[y * dec->mb_width + x];
849    
# Line 661  Line 858 
858                                  uint32_t cbpy;                                  uint32_t cbpy;
859                                  uint32_t cbp;                                  uint32_t cbp;
860                                  uint32_t intra;                                  uint32_t intra;
861                                    int mcsel = 0;          // mcsel: '0'=local motion, '1'=GMC
862    
863                                  cp_mb++;                                  cp_mb++;
864                                  mcbpc = get_mcbpc_inter(bs);                                  mcbpc = get_mcbpc_inter(bs);
# Line 677  Line 875 
875                                          acpred_flag = BitstreamGetBit(bs);                                          acpred_flag = BitstreamGetBit(bs);
876                                  }                                  }
877    
878                                    if (gmc_mv && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q))
879                                    {
880                                            mcsel = BitstreamGetBit(bs);
881                                    }
882    
883                                  cbpy = get_cbpy(bs, intra);                                  cbpy = get_cbpy(bs, intra);
884                                  DPRINTF(DPRINTF_MB, "cbpy %i", cbpy);                                  DPRINTF(DPRINTF_MB, "cbpy %i", cbpy);
885    
# Line 715  Line 918 
918                                  }                                  }
919    
920                                  if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {                                  if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
921                                          if (dec->interlacing && mb->field_pred) {  
922                                            if (mcsel)
923                                            {
924                                                    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);
925                                                    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);
926    
927                                            } else if (dec->interlacing && mb->field_pred) {
928                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0],
929                                                                                    fcode, bound);                                                                                    fcode, bound);
930                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1],                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1],
# Line 741  Line 950 
950                                          mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =                                          mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y =
951                                                  0;                                                  0;
952                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,                                          decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant,
953                                                                          intra_dc_threshold, bound);                                                                          intra_dc_threshold, bound, reduced_resolution);
954                                          continue;                                          continue;
955                                  }                                  }
956    
957                                  decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant,                                  decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant,
958                                                                  rounding);                                                                  rounding, reduced_resolution);
959                          } else                          // not coded  
960                            }
961                            else if (gmc_mv)        /* not coded S_VOP macroblock */
962                          {                          {
963                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
964                                    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);
965                                    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);
966                                    decoder_mbinter(dec, mb, x, y, 0, 0, bs, quant, rounding, reduced_resolution);
967                            }
968                            else    /* not coded P_VOP macroblock */
969                            {
970                                    mb->mode = MODE_NOT_CODED;
971    
972                                  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;
973                                  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;
   
974                                  // copy macroblock directly from ref to cur                                  // copy macroblock directly from ref to cur
975    
976                                  start_timer();                                  start_timer();
977    
978                                  transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +                                  if (reduced_resolution)
979                                                                   (16 * x),                                  {
980                                                                   dec->refn[0].y + (16 * y) * dec->edged_width +                                          transfer32x32_copy(dec->cur.y + (32*y)*dec->edged_width + (32*x),
981                                                                   (16 * x), dec->edged_width);                                                                           dec->refn[0].y + (32*y)*dec->edged_width + (32*x),
982                                                                             dec->edged_width);
983                                  transfer8x8_copy(dec->cur.y + (16 * y) * dec->edged_width +  
984                                                                   (16 * x + 8),                                          transfer16x16_copy(dec->cur.u + (16*y)*dec->edged_width/2 + (16*x),
985                                                                   dec->refn[0].y + (16 * y) * dec->edged_width +                                                                          dec->refn[0].u + (16*y)*dec->edged_width/2 + (16*x),
986                                                                   (16 * x + 8), dec->edged_width);                                                                          dec->edged_width/2);
987    
988                                  transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +                                          transfer16x16_copy(dec->cur.v + (16*y)*dec->edged_width/2 + (16*x),
989                                                                   (16 * x),                                                                           dec->refn[0].v + (16*y)*dec->edged_width/2 + (16*x),
990                                                                   dec->refn[0].y + (16 * y +                                                                           dec->edged_width/2);
991                                                                                                     8) * dec->edged_width +                                  }
992                                                                   (16 * x), dec->edged_width);                                  else
993                                    {
994                                  transfer8x8_copy(dec->cur.y + (16 * y + 8) * dec->edged_width +                                          transfer16x16_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x),
995                                                                   (16 * x + 8),                                                                           dec->refn[0].y + (16*y)*dec->edged_width + (16*x),
996                                                                   dec->refn[0].y + (16 * y +                                                                           dec->edged_width);
997                                                                                                     8) * dec->edged_width +  
998                                                                   (16 * x + 8), dec->edged_width);                                          transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x),
999                                                                            dec->refn[0].u + (8*y)*dec->edged_width/2 + (8*x),
                                 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),  
1000                                                                   dec->edged_width / 2);                                                                   dec->edged_width / 2);
1001    
1002                                  transfer8x8_copy(dec->cur.v + (8 * y) * dec->edged_width / 2 +                                          transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x),
1003                                                                   (8 * x),                                                                           dec->refn[0].v + (8*y)*dec->edged_width/2 + (8*x),
                                                                  dec->refn[0].v +  
                                                                  (8 * y) * dec->edged_width / 2 + (8 * x),  
1004                                                                   dec->edged_width / 2);                                                                   dec->edged_width / 2);
1005                                    }
1006    
1007                                  stop_transfer_timer();                                  stop_transfer_timer();
1008    
1009                                  if(dec->out_frm && cp_mb > 0) {                                  if(dec->out_frm && cp_mb > 0) {
1010                                    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);
1011                                    cp_mb = 0;                                    cp_mb = 0;
# Line 882  Line 1097 
1097                  uv_dx = pMB->mvs[0].x;                  uv_dx = pMB->mvs[0].x;
1098                  uv_dy = pMB->mvs[0].y;                  uv_dy = pMB->mvs[0].y;
1099    
1100                  uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;                  if (dec->quarterpel)
1101                  uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;                  {
1102                            uv_dx /= 2;
1103                            uv_dy /= 2;
1104                    }
1105    
1106                    uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
1107                    uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
1108          } else {          } else {
1109                  int sum;                  int sum;
1110    
1111                    if(dec->quarterpel)
1112                            sum = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
1113                    else
1114                  sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;                  sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
                 uv_dx =  
                         (sum ==  
                          0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
                                                                   (ABS(sum) / 16) * 2));  
1115    
1116                    uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];
1117    
1118                    if(dec->quarterpel)
1119                            sum = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
1120                    else
1121                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1122                  uv_dy =  
1123                          (sum ==                  uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];
                          0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
                                                                   (ABS(sum) / 16) * 2));  
1124          }          }
1125    
1126          start_timer();          start_timer();
1127            if(dec->quarterpel) {
1128                    interpolate16x16_quarterpel(dec->cur.y, dec->refn[ref].y, dec->refh.y, dec->refh.y + 64,
1129                                                                        dec->refh.y + 128, 16*x_pos, 16*y_pos,
1130                                                                        pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1131            }
1132            else {
1133          interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos, 16 * y_pos,          interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos, 16 * y_pos,
1134                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1135          interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos + 8,                  interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos + 8, 16*y_pos,
1136                                                    16 * y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);                                                        pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
1137          interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos,                  interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos, 16*y_pos + 8,
1138                                                    16 * y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride,                                                            pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
1139                                                    0);                  interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16*x_pos + 8, 16*y_pos + 8,
1140          interpolate8x8_switch(dec->cur.y, dec->refn[ref].y, 16 * x_pos + 8,                                                            pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
1141                                                    16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,          }
1142                                                    0);  
1143          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,
1144                                                    uv_dx, uv_dy, stride2, 0);                                                    uv_dx, uv_dy, stride2, 0);
1145          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,
# Line 997  Line 1226 
1226                  uv_dx = pMB->mvs[0].x;                  uv_dx = pMB->mvs[0].x;
1227                  uv_dy = pMB->mvs[0].y;                  uv_dy = pMB->mvs[0].y;
1228    
                 uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;  
                 uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;  
   
1229                  b_uv_dx = pMB->b_mvs[0].x;                  b_uv_dx = pMB->b_mvs[0].x;
1230                  b_uv_dy = pMB->b_mvs[0].y;                  b_uv_dy = pMB->b_mvs[0].y;
1231    
1232                  b_uv_dx = (uv_dx & 3) ? (uv_dx >> 1) | 1 : uv_dx / 2;                  if (dec->quarterpel)
1233                  b_uv_dy = (uv_dy & 3) ? (uv_dy >> 1) | 1 : uv_dy / 2;                  {
1234                            uv_dx /= 2;
1235                            uv_dy /= 2;
1236    
1237                            b_uv_dx /= 2;
1238                            b_uv_dy /= 2;
1239                    }
1240    
1241                    uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];
1242                    uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];
1243    
1244                    b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];
1245                    b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];
1246          } else {          } else {
1247                  int sum;                  int sum;
1248    
1249                    if(dec->quarterpel)
1250                            sum = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);
1251                    else
1252                  sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;                  sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
                 uv_dx =  
                         (sum ==  
                          0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
                                                                   (ABS(sum) / 16) * 2));  
1253    
1254                    uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];
1255    
1256                    if(dec->quarterpel)
1257                            sum = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);
1258                    else
1259                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                  sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1260                  uv_dy =  
1261                          (sum ==                  uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];
1262                           0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
1263                                                                    (ABS(sum) / 16) * 2));  
1264                    if(dec->quarterpel)
1265                  sum =                          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);
1266                          pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x +                  else
1267                          pMB->b_mvs[3].x;                          sum = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;
1268                  b_uv_dx =  
1269                          (sum ==                  b_uv_dx = (sum >> 3) + roundtab_76[sum & 0xf];
1270                           0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
1271                                                                    (ABS(sum) / 16) * 2));                  if(dec->quarterpel)
1272                            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);
1273                  sum =                  else
1274                          pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y +                          sum = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
1275                          pMB->b_mvs[3].y;  
1276                  b_uv_dy =                  b_uv_dy = (sum >> 3) + roundtab_76[sum & 0xf];
                         (sum ==  
                          0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] +  
                                                                   (ABS(sum) / 16) * 2));  
1277          }          }
1278    
1279    
1280          start_timer();          start_timer();
1281            if(dec->quarterpel) {
1282                    if((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q))
1283                            interpolate16x16_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,
1284                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos,
1285                                                                                pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1286                    else {
1287                            interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,
1288                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos,
1289                                                                                pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1290                            interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,
1291                                                                                dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,
1292                                                                                pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);
1293                            interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,
1294                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,
1295                                                                                pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);
1296                            interpolate8x8_quarterpel(dec->cur.y, forward.y, dec->refh.y, dec->refh.y + 64,
1297                                                                                dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,
1298                                                                                pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);
1299                    }
1300            }
1301            else {
1302          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,
1303                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);                                                    pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);
1304          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,
# Line 1048  Line 1308 
1308          interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8,          interpolate8x8_switch(dec->cur.y, forward.y, 16 * x_pos + 8,
1309                                                    16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,                                                    16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride,
1310                                                    0);                                                    0);
1311            }
1312    
1313          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,
1314                                                    uv_dy, stride2, 0);                                                    uv_dy, stride2, 0);
1315          interpolate8x8_switch(dec->cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx,          interpolate8x8_switch(dec->cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx,
1316                                                    uv_dy, stride2, 0);                                                    uv_dy, stride2, 0);
1317    
1318    
1319            if(dec->quarterpel) {
1320                    if((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q))
1321                            interpolate16x16_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,
1322                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos,
1323                                                                                pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1324                    else {
1325                            interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,
1326                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos,
1327                                                                                pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1328                            interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,
1329                                                                                dec->refh.y + 128, 16*x_pos + 8, 16*y_pos,
1330                                                                                pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);
1331                            interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,
1332                                                                                dec->refh.y + 128, 16*x_pos, 16*y_pos + 8,
1333                                                                                pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);
1334                            interpolate8x8_quarterpel(dec->refn[2].y, backward.y, dec->refh.y, dec->refh.y + 64,
1335                                                                                dec->refh.y + 128, 16*x_pos + 8, 16*y_pos + 8,
1336                                                                                pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);
1337                    }
1338            }
1339            else {
1340          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos, 16 * y_pos,          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos, 16 * y_pos,
1341                                                    pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);                                                    pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);
1342          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,
# Line 1065  Line 1348 
1348          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,          interpolate8x8_switch(dec->refn[2].y, backward.y, 16 * x_pos + 8,
1349                                                    16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y,                                                    16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y,
1350                                                    stride, 0);                                                    stride, 0);
1351            }
1352    
1353          interpolate8x8_switch(dec->refn[2].u, backward.u, 8 * x_pos, 8 * y_pos,          interpolate8x8_switch(dec->refn[2].u, backward.u, 8 * x_pos, 8 * y_pos,
1354                                                    b_uv_dx, b_uv_dy, stride2, 0);                                                    b_uv_dx, b_uv_dy, stride2, 0);
1355          interpolate8x8_switch(dec->refn[2].v, backward.v, 8 * x_pos, 8 * y_pos,          interpolate8x8_switch(dec->refn[2].v, backward.v, 8 * x_pos, 8 * y_pos,
# Line 1073  Line 1358 
1358          interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,          interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,
1359                                                  dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,                                                  dec->cur.y + (16 * y_pos * stride) + 16 * x_pos,
1360                                                  dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos,                                                  dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos,
1361                                                  stride, 0);                                                  stride, 1, 8);
1362    
1363          interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,          interpolate8x8_avg2(dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,
1364                                                  dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,                                                  dec->cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,
1365                                                  dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos + 8,                                                  dec->refn[2].y + (16 * y_pos * stride) + 16 * x_pos + 8,
1366                                                  stride, 0);                                                  stride, 1, 8);
1367    
1368          interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,          interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,
1369                                                  dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,                                                  dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,
1370                                                  dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos,                                                  dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos,
1371                                                  stride, 0);                                                  stride, 1, 8);
1372    
1373          interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,          interpolate8x8_avg2(dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,
1374                                                  dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,                                                  dec->cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,
1375                                                  dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,                                                  dec->refn[2].y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,
1376                                                  stride, 0);                                                  stride, 1, 8);
1377    
1378          interpolate8x8_avg2(dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,          interpolate8x8_avg2(dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,
1379                                                  dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,                                                  dec->cur.u + (8 * y_pos * stride2) + 8 * x_pos,
1380                                                  dec->refn[2].u + (8 * y_pos * stride2) + 8 * x_pos,                                                  dec->refn[2].u + (8 * y_pos * stride2) + 8 * x_pos,
1381                                                  stride2, 0);                                                  stride2, 1, 8);
1382    
1383          interpolate8x8_avg2(dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,          interpolate8x8_avg2(dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,
1384                                                  dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,                                                  dec->cur.v + (8 * y_pos * stride2) + 8 * x_pos,
1385                                                  dec->refn[2].v + (8 * y_pos * stride2) + 8 * x_pos,                                                  dec->refn[2].v + (8 * y_pos * stride2) + 8 * x_pos,
1386                                                  stride2, 0);                                                  stride2, 1, 8);
1387    
1388          stop_comp_timer();          stop_comp_timer();
1389    
# Line 1368  Line 1653 
1653    
1654  int  int
1655  decoder_decode(DECODER * dec,  decoder_decode(DECODER * dec,
1656                             XVID_DEC_FRAME * frame)                             XVID_DEC_FRAME * frame, XVID_DEC_STATS * stats)
1657  {  {
1658    
1659          Bitstream bs;          Bitstream bs;
1660          uint32_t rounding;          uint32_t rounding;
1661            uint32_t reduced_resolution;
1662          uint32_t quant;          uint32_t quant;
1663          uint32_t fcode_forward;          uint32_t fcode_forward;
1664          uint32_t fcode_backward;          uint32_t fcode_backward;
1665          uint32_t intra_dc_threshold;          uint32_t intra_dc_threshold;
1666            VECTOR gmc_mv[5];
1667          uint32_t vop_type;          uint32_t vop_type;
1668            int success = 0;
1669    
1670          start_global_timer();          start_global_timer();
1671    
# Line 1385  Line 1673 
1673    
1674          BitstreamInit(&bs, frame->bitstream, frame->length);          BitstreamInit(&bs, frame->bitstream, frame->length);
1675    
1676          if(BitstreamShowBits(&bs, 8) == 0x7f)          // XXX: 0x7f is only valid whilst decoding vfw xvid/divx5 avi's
1677            if(frame->length == 1 && BitstreamShowBits(&bs, 8) == 0x7f)
1678            {
1679                    if (stats)
1680                            stats->notify = XVID_DEC_VOP;
1681                    frame->length = 1;
1682                    image_output(&dec->refn[0], dec->width, dec->height, dec->edged_width,
1683                                             frame->image, frame->stride, frame->colorspace, dec->interlacing);
1684                    emms();
1685                  return XVID_ERR_OK;                  return XVID_ERR_OK;
1686            }
1687    
1688    start:
1689          // add by chenm001 <chenm001@163.com>          // add by chenm001 <chenm001@163.com>
1690          // for support B-frame to reference last 2 frame          // for support B-frame to reference last 2 frame
1691          dec->frames++;          dec->frames++;
1692    
1693    xxx:
1694          vop_type =          vop_type =
1695                  BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode_forward,                  BitstreamReadHeaders(&bs, dec, &rounding, &reduced_resolution,
1696                                                           &fcode_backward, &intra_dc_threshold);                          &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, gmc_mv);
1697    
1698            //DPRINTF(DPRINTF_HEADER, "vop_type=%i", vop_type);
1699    
1700            if (vop_type == -1 && success)
1701                    goto done;
1702    
1703            if (vop_type == -2 || vop_type == -3)
1704            {
1705                    if (vop_type == -3)
1706                            decoder_resize(dec);
1707    
1708                    if (stats)
1709                    {
1710                            stats->notify = XVID_DEC_VOL;
1711                            stats->data.vol.general = 0;
1712                            if (dec->interlacing)
1713                                    stats->data.vol.general |= XVID_INTERLACING;
1714                            stats->data.vol.width = dec->width;
1715                            stats->data.vol.height = dec->height;
1716                            stats->data.vol.aspect_ratio = dec->aspect_ratio;
1717                            stats->data.vol.par_width = dec->par_width;
1718                            stats->data.vol.par_height = dec->par_height;
1719                            frame->length = BitstreamPos(&bs) / 8;
1720                            return XVID_ERR_OK;
1721                    }
1722                    goto xxx;
1723            }
1724    
1725          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
1726    
1727          switch (vop_type) {          switch (vop_type) {
1728          case P_VOP:          case P_VOP:
1729                  decoder_pframe(dec, &bs, rounding, quant, fcode_forward,                  decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,
1730                                             intra_dc_threshold);                                                  fcode_forward, intra_dc_threshold, NULL);
1731  #ifdef BFRAMES_DEC  #ifdef BFRAMES_DEC
1732                  DEBUG1("P_VOP  Time=", dec->time);                  DEBUG1("P_VOP  Time=", dec->time);
1733  #endif  #endif
1734                  break;                  break;
1735    
1736          case I_VOP:          case I_VOP:
1737                  decoder_iframe(dec, &bs, quant, intra_dc_threshold);                  decoder_iframe(dec, &bs, reduced_resolution, quant, intra_dc_threshold);
1738  #ifdef BFRAMES_DEC  #ifdef BFRAMES_DEC
1739                  DEBUG1("I_VOP  Time=", dec->time);                  DEBUG1("I_VOP  Time=", dec->time);
1740  #endif  #endif
# Line 1426  Line 1753 
1753  #endif  #endif
1754                  break;                  break;
1755    
1756            case S_VOP :
1757                    decoder_pframe(dec, &bs, rounding, reduced_resolution, quant,
1758                                                    fcode_forward, intra_dc_threshold, gmc_mv);
1759                    break;
1760    
1761          case N_VOP:                             // vop not coded          case N_VOP:                             // vop not coded
1762                  // when low_delay==0, N_VOP's should interpolate between the past and future frames                  // when low_delay==0, N_VOP's should interpolate between the past and future frames
1763                  image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);                  image_copy(&dec->cur, &dec->refn[0], dec->edged_width, dec->height);
# Line 1435  Line 1767 
1767                  break;                  break;
1768    
1769          default:          default:
1770                    if (stats)
1771                            stats->notify = 0;
1772    
1773                    emms();
1774                  return XVID_ERR_FAIL;                  return XVID_ERR_FAIL;
1775          }          }
1776    
1777  #ifdef BFRAMES_DEC_DEBUG  
1778          if (frame->length != BitstreamPos(&bs) / 8){          /* reduced resolution deblocking filter */
1779                  DEBUG2("InLen/UseLen",frame->length, BitstreamPos(&bs) / 8);  
1780            if (reduced_resolution)
1781            {
1782                    const int rmb_height = dec->mb_height / 2;
1783                    const int rmb_width = dec->mb_width / 2;
1784                    const int edged_width2 = dec->edged_width /2;
1785                    int i,j;
1786    
1787                    /* horizontal deblocking */
1788    
1789                    for (j = 1; j < rmb_height*2; j++)      // luma: j,i in block units
1790                    for (i = 0; i < rmb_width*2; i++)
1791                    {
1792                            if (dec->mbs[(j-1)/2*dec->mb_width + (i/2)].mode != MODE_NOT_CODED ||
1793                                    dec->mbs[(j+0)/2*dec->mb_width + (i/2)].mode != MODE_NOT_CODED)
1794                            {
1795                                    xvid_HFilter_31_C(dec->cur.y + (j*16 - 1)*dec->edged_width + i*16,
1796                                                                  dec->cur.y + (j*16 + 0)*dec->edged_width + i*16, 2);
1797                            }
1798                    }
1799    
1800                    for (j = 1; j < rmb_height; j++)        // chroma
1801                    for (i = 0; i < rmb_width; i++)
1802                    {
1803                            if (dec->mbs[(j-1)*dec->mb_width + i].mode != MODE_NOT_CODED ||
1804                                    dec->mbs[(j+0)*dec->mb_width + i].mode != MODE_NOT_CODED)
1805                            {
1806                                    hfilter_31(dec->cur.u + (j*16 - 1)*edged_width2 + i*16,
1807                                                                      dec->cur.u + (j*16 + 0)*edged_width2 + i*16, 2);
1808                                    hfilter_31(dec->cur.v + (j*16 - 1)*edged_width2 + i*16,
1809                                                                      dec->cur.v + (j*16 + 0)*edged_width2 + i*16, 2);
1810                            }
1811                    }
1812    
1813                    /* vertical deblocking */
1814    
1815                    for (j = 0; j < rmb_height*2; j++)              // luma: i,j in block units
1816                    for (i = 1; i < rmb_width*2; i++)
1817                    {
1818                            if (dec->mbs[(j/2)*dec->mb_width + (i-1)/2].mode != MODE_NOT_CODED ||
1819                                    dec->mbs[(j/2)*dec->mb_width + (i+0)/2].mode != MODE_NOT_CODED)
1820                            {
1821                                    vfilter_31(dec->cur.y + (j*16)*dec->edged_width + i*16 - 1,
1822                                                                  dec->cur.y + (j*16)*dec->edged_width + i*16 + 0,
1823                                                                      dec->edged_width, 2);
1824                            }
1825                    }
1826    
1827                    for (j = 0; j < rmb_height; j++)        // chroma
1828                    for (i = 1; i < rmb_width; i++)
1829                    {
1830                            if (dec->mbs[j*dec->mb_width + i - 1].mode != MODE_NOT_CODED ||
1831                                    dec->mbs[j*dec->mb_width + i + 0].mode != MODE_NOT_CODED)
1832                            {
1833                                    vfilter_31(dec->cur.u + (j*16)*edged_width2 + i*16 - 1,
1834                                                                      dec->cur.u + (j*16)*edged_width2 + i*16 + 0,
1835                                                                      edged_width2, 2);
1836                                    vfilter_31(dec->cur.v + (j*16)*edged_width2 + i*16 - 1,
1837                                                                      dec->cur.v + (j*16)*edged_width2 + i*16 + 0,
1838                                                                      edged_width2, 2);
1839                            }
1840                    }
1841          }          }
 #endif  
         frame->length = BitstreamPos(&bs) / 8;  
1842    
1843            BitstreamByteAlign(&bs);
1844    
1845  #ifdef BFRAMES_DEC  #ifdef BFRAMES_DEC
1846          // test if no B_VOP          // test if no B_VOP
1847          if (dec->low_delay || dec->frames == 0) {          if (dec->low_delay || dec->frames == 0 || ((dec->packed_mode) && !(frame->length > BitstreamPos(&bs) / 8))) {
1848  #endif  #endif
1849          image_output(&dec->cur, dec->width, dec->height, dec->edged_width,          image_output(&dec->cur, dec->width, dec->height, dec->edged_width,
1850                                           frame->image, frame->stride, frame->colorspace);                                           frame->image, frame->stride, frame->colorspace, dec->interlacing);
1851    
1852  #ifdef BFRAMES_DEC  #ifdef BFRAMES_DEC
1853          } else {          } else {
1854                  if (dec->frames >= 1) {                  if (dec->frames >= 1 && !(dec->packed_mode)) {
1855                          start_timer();                          start_timer();
1856                          if ((vop_type == I_VOP || vop_type == P_VOP)) {                          if ((vop_type == I_VOP || vop_type == P_VOP || vop_type == S_VOP)) {
1857                                  image_output(&dec->refn[0], dec->width, dec->height,                                  image_output(&dec->refn[0], dec->width, dec->height,
1858                                                           dec->edged_width, frame->image, frame->stride,                                                           dec->edged_width, frame->image, frame->stride,
1859                                                           frame->colorspace);                                                           frame->colorspace, dec->interlacing);
1860                          } else if (vop_type == B_VOP) {                          } else if (vop_type == B_VOP) {
1861                                  image_output(&dec->cur, dec->width, dec->height,                                  image_output(&dec->cur, dec->width, dec->height,
1862                                                           dec->edged_width, frame->image, frame->stride,                                                           dec->edged_width, frame->image, frame->stride,
1863                                                           frame->colorspace);                                                           frame->colorspace, dec->interlacing);
1864                          }                          }
1865                          stop_conv_timer();                          stop_conv_timer();
1866                  }                  }
1867          }          }
1868  #endif  #endif
1869    
1870          if (vop_type == I_VOP || vop_type == P_VOP) {          if (vop_type == I_VOP || vop_type == P_VOP || vop_type == S_VOP) {
1871                  image_swap(&dec->refn[0], &dec->refn[1]);                  image_swap(&dec->refn[0], &dec->refn[1]);
1872                  image_swap(&dec->cur, &dec->refn[0]);                  image_swap(&dec->cur, &dec->refn[0]);
1873    
# Line 1487  Line 1883 
1883                          mb_swap(&dec->mbs, &dec->last_mbs);                          mb_swap(&dec->mbs, &dec->last_mbs);
1884          }          }
1885    
1886    
1887            if (success == 0 && dec->packed_mode)
1888            {
1889                    success = 1;
1890            //      if (frame->length > BitstreamPos(&bs) / 8)      // multiple vops packed together
1891                    goto start;
1892            }
1893    
1894    done :
1895    
1896            frame->length = BitstreamPos(&bs) / 8;
1897    
1898            if (stats)
1899            {
1900                    stats->notify = XVID_DEC_VOP;
1901                    stats->data.vop.time_base = (int)dec->time_base;
1902                    stats->data.vop.time_increment = 0;     //XXX: todo
1903            }
1904    
1905          emms();          emms();
1906    
1907          stop_global_timer();          stop_global_timer();

Legend:
Removed from v.1.37.2.5  
changed lines
  Added in v.1.37.2.15

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