[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 778, Sun Jan 12 13:13:36 2003 UTC revision 832, Wed Feb 12 11:48:21 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 173  Line 173 
173          }          }
174  }  }
175    
176    
177    static __inline void
178    compensate16x16_interpolate_ro(int16_t * const dct_codes,
179                                                                    const uint8_t * const cur,
180                                                                    const uint8_t * const ref,
181                                                                    const uint8_t * const refh,
182                                                                    const uint8_t * const refv,
183                                                                    const uint8_t * const refhv,
184                                                                    uint8_t * const tmp,
185                                                                    const uint32_t x, const uint32_t y,
186                                                                    const int32_t dx, const int32_t dy,
187                                                                    const int32_t stride,
188                                                                    const int quarterpel)
189    {
190            const uint8_t * ptr;
191    
192            if(quarterpel) {
193                    if ((dx&3) | (dy&3)) {
194                            interpolate16x16_quarterpel(tmp - y * stride - x,
195                                                                                    (uint8_t *) ref, tmp + 32,
196                                                                                    tmp + 64, tmp + 96, x, y, dx, dy, stride, 0);
197                            ptr = tmp;
198                    } else ptr =  ref + (y + dy/4)*stride + x + dx/4; // fullpixel position
199    
200            } else ptr = get_ref(ref, refh, refv, refhv, x, y, 1, dx, dy, stride);
201    
202            transfer_8to16subro(dct_codes, cur + y * stride + x,
203                                                      ptr, stride);
204            transfer_8to16subro(dct_codes+64, cur + y * stride + x + 8,
205                                                      ptr + 8, stride);
206            transfer_8to16subro(dct_codes+128, cur + y * stride + x + 8*stride,
207                                                      ptr + 8*stride, stride);
208            transfer_8to16subro(dct_codes+192, cur + y * stride + x + 8*stride+8,
209                                                      ptr + 8*stride + 8, stride);
210    
211    }
212    
213    
214  /* XXX: slow, inelegant... */  /* XXX: slow, inelegant... */
215  static void  static void
216  interpolate18x18_switch(uint8_t * const cur,  interpolate18x18_switch(uint8_t * const cur,
# Line 263  Line 301 
301          if ( (!reduced_resolution) && (mb->mode == MODE_NOT_CODED) ) {  /* quick copy for early SKIP */          if ( (!reduced_resolution) && (mb->mode == MODE_NOT_CODED) ) {  /* quick copy for early SKIP */
302  /* early SKIP is only activated in P-VOPs, not in S-VOPs, so mcsel can never be 1 */  /* early SKIP is only activated in P-VOPs, not in S-VOPs, so mcsel can never be 1 */
303    
 /*              if (mb->mcsel) {  
                         transfer16x16_copy(cur->y + 16 * (i + j * edged_width),  
                                                    refGMC->y + 16 * (i + j * edged_width),  
                                                    edged_width);  
                         transfer8x8_copy(cur->u + 8 * (i + j * edged_width/2),  
                                                         refGMC->u + 8 * (i + j * edged_width/2),  
                                                         edged_width / 2);  
                         transfer8x8_copy(cur->v + 8 * (i + j * edged_width/2),  
                                                         refGMC->v + 8 * (i + j * edged_width/2),  
                                                         edged_width / 2);  
                 } else  
 */  
                 {  
304                          transfer16x16_copy(cur->y + 16 * (i + j * edged_width),                          transfer16x16_copy(cur->y + 16 * (i + j * edged_width),
305                                                     ref->y + 16 * (i + j * edged_width),                                                     ref->y + 16 * (i + j * edged_width),
306                                                     edged_width);                                                     edged_width);
# Line 286  Line 311 
311                          transfer8x8_copy(cur->v + 8 * (i + j * edged_width/2),                          transfer8x8_copy(cur->v + 8 * (i + j * edged_width/2),
312                                                          ref->v + 8 * (i + j * edged_width/2),                                                          ref->v + 8 * (i + j * edged_width/2),
313                                                          edged_width / 2);                                                          edged_width / 2);
                 }  
314                  return;                  return;
315          }          }
316    
317          if ((mb->mode == MODE_NOT_CODED || mb->mode == MODE_INTER          if ((mb->mode == MODE_NOT_CODED || mb->mode == MODE_INTER
318                                  || mb->mode == MODE_INTER_Q) /*&& !quarterpel*/) {                                  || mb->mode == MODE_INTER_Q)) {
319    
320          /* reduced resolution + GMC:  not possible */          /* reduced resolution + GMC:  not possible */
321    
# Line 400  Line 424 
424                                                          f_refv->y, f_refhv->y, tmp, 16 * i, 16 * j, dx,                                                          f_refv->y, f_refhv->y, tmp, 16 * i, 16 * j, dx,
425                                                          dy, edged_width, quarterpel, 0, 0);                                                          dy, edged_width, quarterpel, 0, 0);
426    
427                  dx /= 1 + quarterpel;                  if (quarterpel) { dx /= 2; dy /= 2; }
428                  dy /= 1 + quarterpel;  
429                  CompensateChroma(       (dx >> 1) + roundtab_79[dx & 0x3],                  CompensateChroma(       (dx >> 1) + roundtab_79[dx & 0x3],
430                                                          (dy >> 1) + roundtab_79[dy & 0x3],                                                          (dy >> 1) + roundtab_79[dy & 0x3],
431                                                          i, j, cur, f_ref, tmp,                                                          i, j, cur, f_ref, tmp,
# Line 412  Line 436 
436          case MODE_BACKWARD:          case MODE_BACKWARD:
437                  b_dx = bmvs->x; b_dy = bmvs->y;                  b_dx = bmvs->x; b_dy = bmvs->y;
438    
439                  compensate16x16_interpolate(&dct_codes[0 * 64], cur->y, b_ref->y, b_refh->y,                  compensate16x16_interpolate_ro(&dct_codes[0 * 64], cur->y, b_ref->y, b_refh->y,
440                                                          b_refv->y, b_refhv->y, tmp, 16 * i, 16 * j, b_dx,                                                          b_refv->y, b_refhv->y, tmp, 16 * i, 16 * j, b_dx,
441                                                          b_dy, edged_width, quarterpel, 0, 0);                                                                                  b_dy, edged_width, quarterpel);
442    
443                    if (quarterpel) { b_dx /= 2; b_dy /= 2; }
444    
                 b_dx /= 1 + quarterpel;  
                 b_dy /= 1 + quarterpel;  
445                  CompensateChroma(       (b_dx >> 1) + roundtab_79[b_dx & 0x3],                  CompensateChroma(       (b_dx >> 1) + roundtab_79[b_dx & 0x3],
446                                                          (b_dy >> 1) + roundtab_79[b_dy & 0x3],                                                          (b_dy >> 1) + roundtab_79[b_dy & 0x3],
447                                                          i, j, cur, b_ref, tmp,                                                          i, j, cur, b_ref, tmp,
# Line 543  Line 567 
567    
568    
569    
570    void generate_GMCparameters( const int num_wp, const int res,
571                           const WARPPOINTS *const warp,
572                           const int width, const int height,
573                           GMC_DATA *const gmc)
574    {
575      const int du0 = warp->duv[0].x;
576      const int dv0 = warp->duv[0].y;
577      const int du1 = warp->duv[1].x;
578      const int dv1 = warp->duv[1].y;
579      const int du2 = warp->duv[2].x;
580      const int dv2 = warp->duv[2].y;
581    
582      gmc->W = width;
583      gmc->H = height;
584    
585      gmc->rho = 4 - log2bin(res-1);  // = {3,2,1,0} for res={2,4,8,16}
586    
587      gmc->alpha = log2bin(gmc->W-1);
588      gmc->Ws = (1 << gmc->alpha);
589    
590      gmc->dxF = 16*gmc->Ws + RDIV( 8*gmc->Ws*du1, gmc->W );
591      gmc->dxG =              RDIV( 8*gmc->Ws*dv1, gmc->W );
592      gmc->Fo  = (res*du0 + 1) << (gmc->alpha+gmc->rho-1);
593      gmc->Go  = (res*dv0 + 1) << (gmc->alpha+gmc->rho-1);
594    
595      if (num_wp==2) {
596        gmc->dyF = -gmc->dxG;
597        gmc->dyG =  gmc->dxF;
598      }
599      else if (num_wp==3) {
600        gmc->beta = log2bin(gmc->H-1);
601        gmc->Hs = (1 << gmc->beta);
602        gmc->dyF =              RDIV( 8*gmc->Hs*du2, gmc->H );
603        gmc->dyG = 16*gmc->Hs + RDIV( 8*gmc->Hs*dv2, gmc->H );
604        if (gmc->beta > gmc->alpha) {
605          gmc->dxF <<= (gmc->beta - gmc->alpha);
606          gmc->dxG <<= (gmc->beta - gmc->alpha);
607          gmc->alpha = gmc->beta;
608          gmc->Ws = 1<< gmc->beta;
609        }
610        else {
611          gmc->dyF <<= gmc->alpha - gmc->beta;
612          gmc->dyG <<= gmc->alpha - gmc->beta;
613        }
614      }
615    
616      gmc->cFo = gmc->dxF + gmc->dyF + (1 << (gmc->alpha+gmc->rho+1));
617      gmc->cFo += 16*gmc->Ws*(du0-1);
618    
619      gmc->cGo = gmc->dxG + gmc->dyG + (1 << (gmc->alpha+gmc->rho+1));
620      gmc->cGo += 16*gmc->Ws*(dv0-1);
621    }
622    
623    void
624    generate_GMCimage(      const GMC_DATA *const gmc_data,         // [input] precalculated data
625                                            const IMAGE *const pRef,                        // [input]
626                                            const int mb_width,
627                                            const int mb_height,
628                                            const int stride,
629                                            const int stride2,
630                                            const int fcode,                                        // [input] some parameters...
631                                            const int32_t quarterpel,                       // [input] for rounding avgMV
632                                            const int reduced_resolution,           // [input] ignored
633                                            const int32_t rounding,                 // [input] for rounding image data
634                                            MACROBLOCK *const pMBs,         // [output] average motion vectors
635                                            IMAGE *const pGMC)                      // [output] full warped image
636    {
637    
638            unsigned int mj,mi;
639            VECTOR avgMV;
640    
641            for (mj=0;mj<mb_height;mj++)
642            for (mi=0;mi<mb_width; mi++)
643            {
644                    avgMV = generate_GMCimageMB(gmc_data, pRef, mi, mj,
645                                            stride, stride2, quarterpel, rounding, pGMC);
646    
647                    pMBs[mj*mb_width+mi].amv.x = gmc_sanitize(avgMV.x, quarterpel, fcode);
648                    pMBs[mj*mb_width+mi].amv.y = gmc_sanitize(avgMV.y, quarterpel, fcode);
649                    pMBs[mj*mb_width+mi].mcsel = 0; /* until mode decision */
650            }
651    }
652    
653    
654    
655    #define MLT(i)  (((16-(i))<<16) + (i))
656    static const uint32_t MTab[16] = {
657      MLT( 0), MLT( 1), MLT( 2), MLT( 3), MLT( 4), MLT( 5), MLT( 6), MLT(7),
658      MLT( 8), MLT( 9), MLT(10), MLT(11), MLT(12), MLT(13), MLT(14), MLT(15)
659    };
660    #undef MLT
661    
662    VECTOR generate_GMCimageMB( const GMC_DATA *const gmc_data,
663                          const IMAGE *const pRef,
664                          const int mi, const int mj,
665                          const int stride,
666                          const int stride2,
667                          const int quarterpel,
668                          const int rounding,
669                          IMAGE *const pGMC)
670    {
671      const int W = gmc_data->W;
672      const int H = gmc_data->H;
673    
674      const int rho = gmc_data->rho;
675      const int alpha = gmc_data->alpha;
676    
677      const int rounder = ( 128 - (rounding<<(rho+rho)) ) << 16;
678    
679      const int dxF = gmc_data->dxF;
680      const int dyF = gmc_data->dyF;
681      const int dxG = gmc_data->dxG;
682      const int dyG = gmc_data->dyG;
683    
684      uint8_t *dstY, *dstU, *dstV;
685    
686      int I,J;
687      VECTOR avgMV = {0,0};
688    
689      int32_t Fj, Gj;
690    
691      dstY = &pGMC->y[(mj*16)*stride+mi*16] + 16;
692    
693      Fj = gmc_data->Fo + dyF*mj*16 + dxF*mi*16;
694      Gj = gmc_data->Go + dyG*mj*16 + dxG*mi*16;
695      for (J=16; J>0; --J)
696      {
697        int32_t Fi, Gi;
698    
699        Fi = Fj; Fj += dyF;
700        Gi = Gj; Gj += dyG;
701        for (I=-16; I<0; ++I)
702        {
703          int32_t F, G;
704          uint32_t ri, rj;
705    
706          F = ( Fi >> (alpha+rho) ) << rho; Fi += dxF;
707          G = ( Gi >> (alpha+rho) ) << rho; Gi += dxG;
708    
709          avgMV.x += F;
710          avgMV.y += G;
711    
712          ri = MTab[F&15];
713          rj = MTab[G&15];
714    
715          F >>= 4;
716          G >>= 4;
717    
718          if (F< -1) F=-1;
719          else if (F>W) F=W;
720          if (G< -1) G=-1;
721          else if (G>H) G=H;
722    
723          {     // MMX-like bilinear...
724            const int offset = G*stride + F;
725            uint32_t f0, f1;
726            f0  = pRef->y[ offset +0 ];
727            f0 |= pRef->y[ offset +1 ] << 16;
728            f1  = pRef->y[ offset+stride +0 ];
729            f1 |= pRef->y[ offset+stride +1 ] << 16;
730            f0 = (ri*f0)>>16;
731            f1 = (ri*f1) & 0x0fff0000;
732            f0 |= f1;
733            f0 = ( rj*f0 + rounder ) >> 24;
734    
735            dstY[I] = (uint8_t)f0;
736          }
737        }
738        dstY += stride;
739      }
740    
741      dstU = &pGMC->u[(mj*8)*stride2+mi*8] + 8;
742      dstV = &pGMC->v[(mj*8)*stride2+mi*8] + 8;
743    
744      Fj = gmc_data->cFo + dyF*4 *mj*8 + dxF*4 *mi*8;
745      Gj = gmc_data->cGo + dyG*4 *mj*8 + dxG*4 *mi*8;
746      for (J=8; J>0; --J)
747      {
748        int32_t Fi, Gi;
749        Fi = Fj; Fj += 4*dyF;
750        Gi = Gj; Gj += 4*dyG;
751    
752        for (I=-8; I<0; ++I)
753        {
754          int32_t F, G;
755          uint32_t ri, rj;
756    
757          F = ( Fi >> (alpha+rho+2) ) << rho; Fi += 4*dxF;
758          G = ( Gi >> (alpha+rho+2) ) << rho; Gi += 4*dxG;
759    
760          ri = MTab[F&15];
761          rj = MTab[G&15];
762    
763          F >>= 4;
764          G >>= 4;
765    
766          if (F< -1) F=-1;
767          else if (F>=W/2) F=W/2;
768          if (G< -1) G=-1;
769          else if (G>=H/2) G=H/2;
770    
771          {
772            const int offset = G*stride2 + F;
773            uint32_t f0, f1;
774    
775            f0  = pRef->u[ offset         +0 ];
776            f0 |= pRef->u[ offset         +1 ] << 16;
777            f1  = pRef->u[ offset+stride2 +0 ];
778            f1 |= pRef->u[ offset+stride2 +1 ] << 16;
779            f0 = (ri*f0)>>16;
780            f1 = (ri*f1) & 0x0fff0000;
781            f0 |= f1;
782            f0 = ( rj*f0 + rounder ) >> 24;
783    
784            dstU[I] = (uint8_t)f0;
785    
786    
787            f0  = pRef->v[ offset         +0 ];
788            f0 |= pRef->v[ offset         +1 ] << 16;
789            f1  = pRef->v[ offset+stride2 +0 ];
790            f1 |= pRef->v[ offset+stride2 +1 ] << 16;
791            f0 = (ri*f0)>>16;
792            f1 = (ri*f1) & 0x0fff0000;
793            f0 |= f1;
794            f0 = ( rj*f0 + rounder ) >> 24;
795    
796            dstV[I] = (uint8_t)f0;
797          }
798        }
799        dstU += stride2;
800        dstV += stride2;
801      }
802    
803    
804      avgMV.x -= 16*((256*mi+120)<<4);    // 120 = 15*16/2
805      avgMV.y -= 16*((256*mj+120)<<4);
806    
807      avgMV.x = RSHIFT( avgMV.x, (4+7-quarterpel) );
808      avgMV.y = RSHIFT( avgMV.y, (4+7-quarterpel) );
809    
810      return avgMV;
811    }
812    
813    
814    
815    #ifdef OLD_GRUEL_GMC
816  void  void
817  generate_GMCparameters( const int num_wp,                       // [input]: number of warppoints  generate_GMCparameters( const int num_wp,                       // [input]: number of warppoints
818                                                  const int res,                  // [input]: resolution                                                  const int res,                  // [input]: resolution
# Line 852  Line 1122 
1122          return avgMV;   /* clipping to fcode area is done outside! */          return avgMV;   /* clipping to fcode area is done outside! */
1123  }  }
1124    
1125    #endif

Legend:
Removed from v.778  
changed lines
  Added in v.832

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