[svn] / branches / dev-api-3 / xvidcore / src / motion / motion_comp.c Repository:
ViewVC logotype

Diff of /branches/dev-api-3/xvidcore/src/motion/motion_comp.c

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

revision 811, Sun Jan 26 14:59:12 2003 UTC revision 812, Fri Jan 31 22:25:18 2003 UTC
# Line 24  Line 24 
24  #endif  #endif
25    
26  /* assume b>0 */  /* assume b>0 */
27  #ifndef ROUNDED_DIV  #ifndef RDIV
28  #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))  #define RDIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
29  #endif  #endif
30    
31    
# Line 543  Line 543 
543    
544    
545    
546    void generate_GMCparameters( const int num_wp, const int res,
547                           const WARPPOINTS *const warp,
548                           const int width, const int height,
549                           GMC_DATA *const gmc)
550    {
551      const int du0 = warp->duv[0].x;
552      const int dv0 = warp->duv[0].y;
553      const int du1 = warp->duv[1].x;
554      const int dv1 = warp->duv[1].y;
555      const int du2 = warp->duv[2].x;
556      const int dv2 = warp->duv[2].y;
557    
558      gmc->W = width;
559      gmc->H = height;
560    
561      gmc->rho = 4 - log2bin(res-1);  // = {3,2,1,0} for res={2,4,8,16}
562    
563      gmc->alpha = log2bin(gmc->W-1);
564      gmc->Ws = (1 << gmc->alpha);
565    
566      gmc->dxF = 16*gmc->Ws + RDIV( 8*gmc->Ws*du1, gmc->W );
567      gmc->dxG =              RDIV( 8*gmc->Ws*dv1, gmc->W );
568      gmc->Fo  = (res*du0 + 1) << (gmc->alpha+gmc->rho-1);
569      gmc->Go  = (res*dv0 + 1) << (gmc->alpha+gmc->rho-1);
570    
571      if (num_wp==2) {
572        gmc->dyF = -gmc->dxG;
573        gmc->dyG =  gmc->dxF;
574      }
575      else if (num_wp==3) {
576        gmc->beta = log2bin(gmc->H-1);
577        gmc->Hs = (1 << gmc->beta);
578        gmc->dyF =              RDIV( 8*gmc->Hs*du2, gmc->H );
579        gmc->dyG = 16*gmc->Hs + RDIV( 8*gmc->Hs*dv2, gmc->H );
580        if (gmc->beta > gmc->alpha) {
581          gmc->dxF <<= (gmc->beta - gmc->alpha);
582          gmc->dxG <<= (gmc->beta - gmc->alpha);
583          gmc->alpha = gmc->beta;
584          gmc->Ws = 1<< gmc->beta;
585        }
586        else {
587          gmc->dyF <<= gmc->alpha - gmc->beta;
588          gmc->dyG <<= gmc->alpha - gmc->beta;
589        }
590      }
591    
592      gmc->cFo = gmc->dxF + gmc->dyF + (1 << (gmc->alpha+gmc->rho+1));
593      gmc->cFo += 16*gmc->Ws*(du0-1);
594    
595      gmc->cGo = gmc->dxG + gmc->dyG + (1 << (gmc->alpha+gmc->rho+1));
596      gmc->cGo += 16*gmc->Ws*(dv0-1);
597    }
598    
599    void
600    generate_GMCimage(      const GMC_DATA *const gmc_data,         // [input] precalculated data
601                                            const IMAGE *const pRef,                        // [input]
602                                            const int mb_width,
603                                            const int mb_height,
604                                            const int stride,
605                                            const int stride2,
606                                            const int fcode,                                        // [input] some parameters...
607                                            const int32_t quarterpel,                       // [input] for rounding avgMV
608                                            const int reduced_resolution,           // [input] ignored
609                                            const int32_t rounding,                 // [input] for rounding image data
610                                            MACROBLOCK *const pMBs,         // [output] average motion vectors
611                                            IMAGE *const pGMC)                      // [output] full warped image
612    {
613    
614            unsigned int mj,mi;
615            VECTOR avgMV;
616    
617            for (mj=0;mj<mb_height;mj++)
618            for (mi=0;mi<mb_width; mi++)
619            {
620                    avgMV = generate_GMCimageMB(gmc_data, pRef, mi, mj,
621                                            stride, stride2, quarterpel, rounding, pGMC);
622    
623                    pMBs[mj*mb_width+mi].amv.x = gmc_sanitize(avgMV.x, quarterpel, fcode);
624                    pMBs[mj*mb_width+mi].amv.y = gmc_sanitize(avgMV.y, quarterpel, fcode);
625                    pMBs[mj*mb_width+mi].mcsel = 0; /* until mode decision */
626            }
627    }
628    
629    
630    
631    #define MLT(i)  (((16-(i))<<16) + (i))
632    static const uint32_t MTab[16] = {
633      MLT( 0), MLT( 1), MLT( 2), MLT( 3), MLT( 4), MLT( 5), MLT( 6), MLT(7),
634      MLT( 8), MLT( 9), MLT(10), MLT(11), MLT(12), MLT(13), MLT(14), MLT(15)
635    };
636    #undef MLT
637    
638    VECTOR generate_GMCimageMB( const GMC_DATA *const gmc_data,
639                          const IMAGE *const pRef,
640                          const int mi, const int mj,
641                          const int stride,
642                          const int stride2,
643                          const int quarterpel,
644                          const int rounding,
645                          IMAGE *const pGMC)
646    {
647      const int W = gmc_data->W;
648      const int H = gmc_data->H;
649    
650      const int rho = gmc_data->rho;
651      const int alpha = gmc_data->alpha;
652    
653      const int rounder = ( 128 - (rounding<<(rho+rho)) ) << 16;
654    
655      const int dxF = gmc_data->dxF;
656      const int dyF = gmc_data->dyF;
657      const int dxG = gmc_data->dxG;
658      const int dyG = gmc_data->dyG;
659    
660      uint8_t *dstY, *dstU, *dstV;
661    
662      int I,J;
663      VECTOR avgMV = {0,0};
664    
665      int32_t Fj, Gj;
666    
667      dstY = &pGMC->y[(mj*16)*stride+mi*16] + 16;
668    
669      Fj = gmc_data->Fo + dyF*mj*16 + dxF*mi*16;
670      Gj = gmc_data->Go + dyG*mj*16 + dxG*mi*16;
671      for (J=16; J>0; --J)
672      {
673        int32_t Fi, Gi;
674    
675        Fi = Fj; Fj += dyF;
676        Gi = Gj; Gj += dyG;
677        for (I=-16; I<0; ++I)
678        {
679          int32_t F, G;
680          uint32_t ri, rj;
681    
682          F = ( Fi >> (alpha+rho) ) << rho; Fi += dxF;
683          G = ( Gi >> (alpha+rho) ) << rho; Gi += dxG;
684    
685          avgMV.x += F;
686          avgMV.y += G;
687    
688          ri = MTab[F&15];
689          rj = MTab[G&15];
690    
691          F >>= 4;
692          G >>= 4;
693    
694          if (F< -1) F=-1;
695          else if (F>W) F=W;
696          if (G< -1) G=-1;
697          else if (G>H) G=H;
698    
699          {     // MMX-like bilinear...
700            const int offset = G*stride + F;
701            uint32_t f0, f1;
702            f0  = pRef->y[ offset +0 ];
703            f0 |= pRef->y[ offset +1 ] << 16;
704            f1  = pRef->y[ offset+stride +0 ];
705            f1 |= pRef->y[ offset+stride +1 ] << 16;
706            f0 = (ri*f0)>>16;
707            f1 = (ri*f1) & 0x0fff0000;
708            f0 |= f1;
709            f0 = ( rj*f0 + rounder ) >> 24;
710    
711            dstY[I] = (uint8_t)f0;
712          }
713        }
714        dstY += stride;
715      }
716    
717      dstU = &pGMC->u[(mj*8)*stride2+mi*8] + 8;
718      dstV = &pGMC->v[(mj*8)*stride2+mi*8] + 8;
719    
720      Fj = gmc_data->cFo + dyF*4 *mj*8 + dxF*4 *mi*8;
721      Gj = gmc_data->cGo + dyG*4 *mj*8 + dxG*4 *mi*8;
722      for (J=8; J>0; --J)
723      {
724        int32_t Fi, Gi;
725        Fi = Fj; Fj += 4*dyF;
726        Gi = Gj; Gj += 4*dyG;
727    
728        for (I=-8; I<0; ++I)
729        {
730          int32_t F, G;
731          uint32_t ri, rj;
732    
733          F = ( Fi >> (alpha+rho+2) ) << rho; Fi += 4*dxF;
734          G = ( Gi >> (alpha+rho+2) ) << rho; Gi += 4*dxG;
735    
736          ri = MTab[F&15];
737          rj = MTab[G&15];
738    
739          F >>= 4;
740          G >>= 4;
741    
742          if (F< -1) F=-1;
743          else if (F>=W/2) F=W/2;
744          if (G< -1) G=-1;
745          else if (G>=H/2) G=H/2;
746    
747          {
748            const int offset = G*stride2 + F;
749            uint32_t f0, f1;
750    
751            f0  = pRef->u[ offset         +0 ];
752            f0 |= pRef->u[ offset         +1 ] << 16;
753            f1  = pRef->u[ offset+stride2 +0 ];
754            f1 |= pRef->u[ offset+stride2 +1 ] << 16;
755            f0 = (ri*f0)>>16;
756            f1 = (ri*f1) & 0x0fff0000;
757            f0 |= f1;
758            f0 = ( rj*f0 + rounder ) >> 24;
759    
760            dstU[I] = (uint8_t)f0;
761    
762    
763            f0  = pRef->v[ offset         +0 ];
764            f0 |= pRef->v[ offset         +1 ] << 16;
765            f1  = pRef->v[ offset+stride2 +0 ];
766            f1 |= pRef->v[ offset+stride2 +1 ] << 16;
767            f0 = (ri*f0)>>16;
768            f1 = (ri*f1) & 0x0fff0000;
769            f0 |= f1;
770            f0 = ( rj*f0 + rounder ) >> 24;
771    
772            dstV[I] = (uint8_t)f0;
773          }
774        }
775        dstU += stride2;
776        dstV += stride2;
777      }
778    
779    
780      avgMV.x -= 16*((256*mi+120)<<4);    // 120 = 15*16/2
781      avgMV.y -= 16*((256*mj+120)<<4);
782    
783      avgMV.x = RSHIFT( avgMV.x, (4+7-quarterpel) );
784      avgMV.y = RSHIFT( avgMV.y, (4+7-quarterpel) );
785    
786      return avgMV;
787    }
788    
789    
790    
791    #ifdef OLD_GRUEL_GMC
792  void  void
793  generate_GMCparameters( const int num_wp,                       // [input]: number of warppoints  generate_GMCparameters( const int num_wp,                       // [input]: number of warppoints
794                                                  const int res,                  // [input]: resolution                                                  const int res,                  // [input]: resolution
# Line 852  Line 1098 
1098          return avgMV;   /* clipping to fcode area is done outside! */          return avgMV;   /* clipping to fcode area is done outside! */
1099  }  }
1100    
1101    #endif

Legend:
Removed from v.811  
changed lines
  Added in v.812

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