[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.72, Mon Aug 1 18:37:46 2005 UTC revision 1.73, Tue Sep 13 12:12:15 2005 UTC
# 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 344  Line 348 
348          DECLARE_ALIGNED_MATRIX(data, 1, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(data, 1, 64, int16_t, CACHE_LINE);
349    
350          int stride = dec->edged_width;          int stride = dec->edged_width;
         int next_block = stride * 8;  
351          int i;          int i;
352          const uint32_t iQuant = pMB->quant;          const uint32_t iQuant = pMB->quant;
353          const int direction = dec->alternate_vertical_scan ? 2 : 0;          const int direction = dec->alternate_vertical_scan ? 2 : 0;
# Line 368  Line 371 
371    
372    
373          if (dec->interlacing && pMB->field_dct) {          if (dec->interlacing && pMB->field_dct) {
                 next_block = stride;  
                 stride *= 2;  
         }  
   
374          dst[0] = pY_Cur;          dst[0] = pY_Cur;
375          dst[2] = pY_Cur + next_block;      dst[1] = pY_Cur + 8;
376          dst[1] = dst[0] + 8;      dst[2] = pY_Cur + stride;
377        dst[3] = dst[2] + 8;
378        dst[4] = pU_Cur;
379        dst[5] = pV_Cur;
380        strides[0] = strides[1] = strides[2] = strides[3] = stride*2;
381        strides[4] = stride/2;
382        strides[5] = stride/2;
383      } else {
384        dst[0] = pY_Cur;
385        dst[1] = pY_Cur + 8;
386        dst[2] = pY_Cur + 8*stride;
387          dst[3] = dst[2] + 8;          dst[3] = dst[2] + 8;
388          dst[4] = pU_Cur;          dst[4] = pU_Cur;
389          dst[5] = pV_Cur;          dst[5] = pV_Cur;
390          strides[0] = strides[1] = strides[2] = strides[3] = stride;          strides[0] = strides[1] = strides[2] = strides[3] = stride;
391          strides[4] = stride/2;          strides[4] = stride/2;
392          strides[5] = stride/2;          strides[5] = stride/2;
393      }
394    
395          for (i = 0; i < 6; i++) {          for (i = 0; i < 6; i++) {
396                  /* Process only coded blocks */                  /* Process only coded blocks */
# Line 562  Line 572 
572                  decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);                  decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
573  }  }
574    
575    /* decode an inter macroblock in field mode */
576    static void
577    decoder_mbinter_field(DECODER * dec,
578            const MACROBLOCK * pMB,
579            const uint32_t x_pos,
580            const uint32_t y_pos,
581            const uint32_t cbp,
582            Bitstream * bs,
583            const uint32_t rounding,
584            const int ref)
585    {
586      uint32_t stride = dec->edged_width;
587      uint32_t stride2 = stride / 2;
588    
589      uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
590    
591      int uvtop_dx, uvtop_dy;
592      int uvbot_dx, uvbot_dy;
593      VECTOR mv[4]; /* local copy of mvs */
594    
595      /* Get pointer to memory areas */
596      pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
597      pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
598      pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
599    
600      mv[0] = pMB->mvs[0];
601      mv[1] = pMB->mvs[1];
602      memset(&mv[2],0,2*sizeof(VECTOR));
603    
604      validate_vector(mv, x_pos, y_pos, dec);
605    
606      start_timer();
607    
608      if(pMB->mode!=MODE_INTER4V)   /* INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD */
609      {
610        /* Prepare top field vector */
611        uvtop_dx = DIV2ROUND(mv[0].x);
612        uvtop_dy = DIV2ROUND(mv[0].y);
613    
614        /* Prepare bottom field vector */
615        uvbot_dx = DIV2ROUND(mv[1].x);
616        uvbot_dy = DIV2ROUND(mv[1].y);
617    
618        if(dec->quarterpel)
619        {
620          /* NOT supported */
621        }
622        else
623        {
624          /* Interpolate top field left part(we use double stride for every 2nd line) */
625          interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
626                                16*x_pos,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
627          /* top field right part */
628          interpolate8x8_switch(dec->cur.y,dec->refn[ref].y+pMB->field_for_top*stride,
629                                16*x_pos+8,8*y_pos,mv[0].x, mv[0].y>>1,2*stride, rounding);
630    
631          /* Interpolate bottom field left part(we use double stride for every 2nd line) */
632          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
633                                16*x_pos,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
634          /* Bottom field right part */
635          interpolate8x8_switch(dec->cur.y+stride,dec->refn[ref].y+pMB->field_for_bot*stride,
636                                16*x_pos+8,8*y_pos,mv[1].x, mv[1].y>>1,2*stride, rounding);
637    
638          /* Interpolate field1 U */
639          interpolate8x4_switch(dec->cur.u,dec->refn[ref].u+pMB->field_for_top*stride2,
640                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
641    
642          /* Interpolate field1 V */
643          interpolate8x4_switch(dec->cur.v,dec->refn[ref].v+pMB->field_for_top*stride2,
644                                8*x_pos,4*y_pos,uvtop_dx,DIV2ROUND(uvtop_dy),stride,rounding);
645    
646          /* Interpolate field2 U */
647          interpolate8x4_switch(dec->cur.u+stride2,dec->refn[ref].u+pMB->field_for_bot*stride2,
648                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
649    
650          /* Interpolate field2 V */
651          interpolate8x4_switch(dec->cur.v+stride2,dec->refn[ref].v+pMB->field_for_bot*stride2,
652                                8*x_pos,4*y_pos,uvbot_dx,DIV2ROUND(uvbot_dy),stride,rounding);
653        }
654      }
655      else
656      {
657        /* We don't expect 4 motion vectors in interlaced mode */
658      }
659    
660      stop_comp_timer();
661    
662      /* Must add error correction? */
663      if(cbp)
664       decoder_mb_decode(dec, cbp, bs, pY_Cur, pU_Cur, pV_Cur, pMB);
665    }
666    
667  static void  static void
668  decoder_mbgmc(DECODER * dec,  decoder_mbgmc(DECODER * dec,
669                                  MACROBLOCK * const pMB,                                  MACROBLOCK * const pMB,
# Line 729  Line 831 
831          ret_mv->y = mv.y;          ret_mv->y = mv.y;
832  }  }
833    
834    /* We use this when decoder runs interlaced -> different prediction */
835    
836    static void get_motion_vector_interlaced(DECODER * dec,
837            Bitstream * bs,
838            int x,
839            int y,
840            int k,
841            MACROBLOCK *pMB,
842            int fcode,
843            const int bound)
844    {
845      const int scale_fac = 1 << (fcode - 1);
846      const int high = (32 * scale_fac) - 1;
847      const int low = ((-32) * scale_fac);
848      const int range = (64 * scale_fac);
849    
850      /* Get interlaced prediction */
851      const VECTOR pmv=get_pmv2_interlaced(dec->mbs,dec->mb_width,bound,x,y,k);
852      VECTOR mv,mvf1,mvf2;
853    
854      if(!pMB->field_pred)
855      {
856        mv.x = get_mv(bs,fcode);
857        mv.y = get_mv(bs,fcode);
858    
859        mv.x += pmv.x;
860        mv.y += pmv.y;
861    
862        if(mv.x<low) {
863          mv.x += range;
864        } else if (mv.x>high) {
865          mv.x-=range;
866        }
867    
868        if (mv.y < low) {
869          mv.y += range;
870        } else if (mv.y > high) {
871          mv.y -= range;
872        }
873    
874        pMB->mvs[0]=pMB->mvs[1]=pMB->mvs[2]=pMB->mvs[3]=mv;
875      }
876      else
877      {
878        mvf1.x = get_mv(bs, fcode);
879        mvf1.y = get_mv(bs, fcode);
880    
881        mvf1.x += pmv.x;
882        mvf1.y = 2*(mvf1.y+pmv.y/2); /* It's multiple of 2 */
883    
884        if (mvf1.x < low) {
885          mvf1.x += range;
886        } else if (mvf1.x > high) {
887          mvf1.x -= range;
888        }
889    
890        if (mvf1.y < low) {
891          mvf1.y += range;
892        } else if (mvf1.y > high) {
893          mvf1.y -= range;
894        }
895    
896        mvf2.x = get_mv(bs, fcode);
897        mvf2.y = get_mv(bs, fcode);
898    
899        mvf2.x += pmv.x;
900        mvf2.y = 2*(mvf2.y+pmv.y/2); /* It's multiple of 2 */
901    
902        if (mvf2.x < low) {
903          mvf2.x += range;
904        } else if (mvf2.x > high) {
905          mvf2.x -= range;
906        }
907    
908        if (mvf2.y < low) {
909          mvf2.y += range;
910        } else if (mvf2.y > high) {
911          mvf2.y -= range;
912        }
913    
914        pMB->mvs[0]=mvf1;
915        pMB->mvs[1]=mvf2;
916        pMB->mvs[2].x=pMB->mvs[3].x=0;
917        pMB->mvs[2].y=pMB->mvs[3].y=0;
918    
919        /* Calculate average for as it is field predicted */
920        pMB->mvs_avg.x=DIV2ROUND(pMB->mvs[0].x+pMB->mvs[1].x);
921        pMB->mvs_avg.y=DIV2ROUND(pMB->mvs[0].y+pMB->mvs[1].y);
922      }
923    }
924    
925  /* for P_VOP set gmc_warp to NULL */  /* for P_VOP set gmc_warp to NULL */
926  static void  static void
927  decoder_pframe(DECODER * dec,  decoder_pframe(DECODER * dec,
# Line 821  Line 1014 
1014                                  }                                  }
1015                                  mb->quant = quant;                                  mb->quant = quant;
1016    
1017            mb->field_pred=0;
1018                                  if (dec->interlacing) {                                  if (dec->interlacing) {
1019                                          if (cbp || intra) {                                          if (cbp || intra) {
1020                                                  mb->field_dct = BitstreamGetBit(bs);                                                  mb->field_dct = BitstreamGetBit(bs);
# Line 846  Line 1040 
1040    
1041                                  } else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {                                  } else if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q) {
1042    
1043                                          if (dec->interlacing && mb->field_pred) {            if(dec->interlacing) {
1044                                                  get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound);              /* Get motion vectors interlaced, field_pred is handled there */
1045                                                  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);
1046                                          } else {                                          } else {
1047                                                  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);
1048                                                  mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];                                                  mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];
1049                                          }                                          }
1050                                  } else if (mb->mode == MODE_INTER4V ) {                                  } else if (mb->mode == MODE_INTER4V ) {
1051              /* interlaced missing here */
1052                                          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);
1053                                          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);
1054                                          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 866  Line 1061 
1061                                          continue;                                          continue;
1062                                  }                                  }
1063    
1064            /* See how to decode */
1065            if(!mb->field_pred)
1066                                  decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0);                                  decoder_mbinter(dec, mb, x, y, cbp, bs, rounding, 0);
1067            else
1068             decoder_mbinter_field(dec, mb, x, y, cbp, bs, rounding, 0);
1069    
1070                          } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */                          } else if (gmc_warp) {  /* a not coded S(GMC)-VOP macroblock */
1071                                  mb->mode = MODE_NOT_CODED_GMC;                                  mb->mode = MODE_NOT_CODED_GMC;
# Line 884  Line 1083 
1083    
1084                                  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;
1085                                  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;
1086            mb->field_pred=0; /* (!) */
1087    
1088                                  decoder_mbinter(dec, mb, x, y, 0, bs,                                  decoder_mbinter(dec, mb, x, y, 0, bs,
1089                                                                  rounding, 0);                                                                  rounding, 0);
# Line 1159  Line 1359 
1359                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];                          MACROBLOCK *mb = &dec->mbs[y * dec->mb_width + x];
1360                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];                          MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x];
1361                          const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;                          const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;
1362                          int32_t intra_dc_threshold; /* fake variable */        uint32_t intra_dc_threshold; /* fake variable */
1363    
1364                          if (check_resync_marker(bs, fcode_max  - 1)) {                          if (check_resync_marker(bs, fcode_max  - 1)) {
1365                                  int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,                                  int bound = read_video_packet_header(bs, dec, fcode_max - 1, &quant,
# Line 1316  Line 1516 
1516                  stats->data.vop.qscale_stride = dec->mb_width;                  stats->data.vop.qscale_stride = dec->mb_width;
1517                  stats->data.vop.qscale = dec->qscale;                  stats->data.vop.qscale = dec->qscale;
1518                  if (stats->data.vop.qscale != NULL && mbs != NULL) {                  if (stats->data.vop.qscale != NULL && mbs != NULL) {
1519                          int i;        unsigned int i;
1520                          for (i = 0; i < dec->mb_width*dec->mb_height; i++)                          for (i = 0; i < dec->mb_width*dec->mb_height; i++)
1521                                  stats->data.vop.qscale[i] = mbs[i].quant;                                  stats->data.vop.qscale[i] = mbs[i].quant;
1522                  } else                  } else

Legend:
Removed from v.1.72  
changed lines
  Added in v.1.73

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