[svn] / trunk / xvidcore / src / motion / estimation_pvop.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/estimation_pvop.c

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

revision 1564, Sun Dec 5 04:53:01 2004 UTC revision 1668, Sun Dec 18 06:52:12 2005 UTC
# Line 21  Line 21 
21   *  along with this program ; if not, write to the Free Software   *  along with this program ; if not, write to the Free Software
22   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23   *   *
24   * $Id: estimation_pvop.c,v 1.9 2004-12-05 04:53:01 syskin Exp $   * $Id: estimation_pvop.c,v 1.18 2005-12-18 06:52:12 syskin Exp $
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
# Line 41  Line 41 
41  #include "motion_inlines.h"  #include "motion_inlines.h"
42    
43  static const int xvid_me_lambda_vec8[32] =  static const int xvid_me_lambda_vec8[32] =
44          {     0    ,(int)(1.00235 * NEIGH_TEND_8X8 + 0.5),          {     0    ,(int)(1.0 * NEIGH_TEND_8X8 + 0.5),
45          (int)(1.15582*NEIGH_TEND_8X8 + 0.5), (int)(1.31976*NEIGH_TEND_8X8 + 0.5),          (int)(2.0*NEIGH_TEND_8X8 + 0.5), (int)(3.0*NEIGH_TEND_8X8 + 0.5),
46          (int)(1.49591*NEIGH_TEND_8X8 + 0.5), (int)(1.68601*NEIGH_TEND_8X8 + 0.5),          (int)(4.0*NEIGH_TEND_8X8 + 0.5), (int)(5.0*NEIGH_TEND_8X8 + 0.5),
47          (int)(1.89187*NEIGH_TEND_8X8 + 0.5), (int)(2.11542*NEIGH_TEND_8X8 + 0.5),          (int)(6.0*NEIGH_TEND_8X8 + 0.5), (int)(7.0*NEIGH_TEND_8X8 + 0.5),
48          (int)(2.35878*NEIGH_TEND_8X8 + 0.5), (int)(2.62429*NEIGH_TEND_8X8 + 0.5),          (int)(8.0*NEIGH_TEND_8X8 + 0.5), (int)(9.0*NEIGH_TEND_8X8 + 0.5),
49          (int)(2.91455*NEIGH_TEND_8X8 + 0.5), (int)(3.23253*NEIGH_TEND_8X8 + 0.5),          (int)(10.0*NEIGH_TEND_8X8 + 0.5), (int)(11.0*NEIGH_TEND_8X8 + 0.5),
50          (int)(3.58158*NEIGH_TEND_8X8 + 0.5), (int)(3.96555*NEIGH_TEND_8X8 + 0.5),          (int)(12.0*NEIGH_TEND_8X8 + 0.5), (int)(13.0*NEIGH_TEND_8X8 + 0.5),
51          (int)(4.38887*NEIGH_TEND_8X8 + 0.5), (int)(4.85673*NEIGH_TEND_8X8 + 0.5),          (int)(14.0*NEIGH_TEND_8X8 + 0.5), (int)(15.0*NEIGH_TEND_8X8 + 0.5),
52          (int)(5.37519*NEIGH_TEND_8X8 + 0.5), (int)(5.95144*NEIGH_TEND_8X8 + 0.5),          (int)(16.0*NEIGH_TEND_8X8 + 0.5), (int)(17.0*NEIGH_TEND_8X8 + 0.5),
53          (int)(6.59408*NEIGH_TEND_8X8 + 0.5), (int)(7.31349*NEIGH_TEND_8X8 + 0.5),          (int)(18.0*NEIGH_TEND_8X8 + 0.5), (int)(19.0*NEIGH_TEND_8X8 + 0.5),
54          (int)(8.12242*NEIGH_TEND_8X8 + 0.5), (int)(9.03669*NEIGH_TEND_8X8 + 0.5),          (int)(20.0*NEIGH_TEND_8X8 + 0.5), (int)(21.0*NEIGH_TEND_8X8 + 0.5),
55          (int)(10.0763*NEIGH_TEND_8X8 + 0.5), (int)(11.2669*NEIGH_TEND_8X8 + 0.5),          (int)(22.0*NEIGH_TEND_8X8 + 0.5), (int)(23.0*NEIGH_TEND_8X8 + 0.5),
56          (int)(12.6426*NEIGH_TEND_8X8 + 0.5), (int)(14.2493*NEIGH_TEND_8X8 + 0.5),          (int)(24.0*NEIGH_TEND_8X8 + 0.5), (int)(25.0*NEIGH_TEND_8X8 + 0.5),
57          (int)(16.1512*NEIGH_TEND_8X8 + 0.5), (int)(18.442*NEIGH_TEND_8X8 + 0.5),          (int)(26.0*NEIGH_TEND_8X8 + 0.5), (int)(27.0*NEIGH_TEND_8X8 + 0.5),
58          (int)(21.2656*NEIGH_TEND_8X8 + 0.5), (int)(24.8580*NEIGH_TEND_8X8 + 0.5),          (int)(28.0*NEIGH_TEND_8X8 + 0.5), (int)(29.0*NEIGH_TEND_8X8 + 0.5),
59          (int)(29.6436*NEIGH_TEND_8X8 + 0.5), (int)(36.4949*NEIGH_TEND_8X8 + 0.5)          (int)(30.0*NEIGH_TEND_8X8 + 0.5), (int)(31.0*NEIGH_TEND_8X8 + 0.5)
60  };  };
61    
62  static void  static void
# Line 82  Line 82 
82          sad = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp);          sad = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp);
83          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);
84    
85          sad += (data->lambda16 * t * sad)>>10;          sad += (data->lambda16 * t);
86          data->temp[0] += (data->lambda8 * t * (data->temp[0] + NEIGH_8X8_BIAS))>>10;          data->temp[0] += (data->lambda8 * t);
87    
88          if (data->chroma) {          if (data->chroma) {
89                  if (sad >= data->iMinSAD[0]) goto no16;                  if (sad >= data->iMinSAD[0]) goto no16;
# Line 129  Line 129 
129          sad = sad8(data->Cur, Reference, data->iEdgedWidth);          sad = sad8(data->Cur, Reference, data->iEdgedWidth);
130          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision);
131    
132          sad += (data->lambda8 * t * (sad+NEIGH_8X8_BIAS))>>10;          sad += (data->lambda8 * t);
133    
134          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
135                  *(data->iMinSAD) = sad;                  *(data->iMinSAD) = sad;
# Line 423  Line 423 
423                                                                                  Data->predMV, Data->iFcode, 0);                                                                                  Data->predMV, Data->iFcode, 0);
424          }          }
425    
426          *(Data->iMinSAD) += (Data->lambda8 * i * (*Data->iMinSAD + NEIGH_8X8_BIAS))>>10;          *(Data->iMinSAD) += (Data->lambda8 * i);
427    
428          if (MotionFlags & (XVID_ME_EXTSEARCH8|XVID_ME_HALFPELREFINE8|XVID_ME_QUARTERPELREFINE8)) {          if (MotionFlags & (XVID_ME_EXTSEARCH8|XVID_ME_HALFPELREFINE8|XVID_ME_QUARTERPELREFINE8)) {
429    
# Line 557  Line 557 
557          else Data->predMV = pmv[0];          else Data->predMV = pmv[0];
558    
559          i = d_mv_bits(0, 0, Data->predMV, Data->iFcode, 0);          i = d_mv_bits(0, 0, Data->predMV, Data->iFcode, 0);
560          Data->iMinSAD[0] = pMB->sad16 + ((Data->lambda16 * i * pMB->sad16)>>10);          Data->iMinSAD[0] = pMB->sad16 + (Data->lambda16 * i);
561          Data->iMinSAD[1] = pMB->sad8[0] + ((Data->lambda8 * i * (pMB->sad8[0]+NEIGH_8X8_BIAS)) >> 10);          Data->iMinSAD[1] = pMB->sad8[0] + (Data->lambda8 * i);
562          Data->iMinSAD[2] = pMB->sad8[1];          Data->iMinSAD[2] = pMB->sad8[1];
563          Data->iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[3] = pMB->sad8[2];
564          Data->iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[4] = pMB->sad8[3];
# Line 705  Line 705 
705          } else Data->iMinSAD[1] = 4096*256;          } else Data->iMinSAD[1] = 4096*256;
706  }  }
707    
708    static int
709    InitialSkipDecisionP(int sad00,
710                                             const MBParam * pParam,
711                                             const FRAMEINFO * current,
712                                             MACROBLOCK * pMB,
713                                             const MACROBLOCK * prevMB,
714                                             int x, int y,
715                                             const SearchData * Data,
716                                             const IMAGE * const pGMC,
717                                             const IMAGE * const pCurrent,
718                                             const IMAGE * const pRef,
719                                             const uint32_t MotionFlags)
720    {
721            const unsigned int iEdgedWidth = pParam->edged_width;
722    
723            int skip_thresh = INITIAL_SKIP_THRESH * \
724                    (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
725            int stat_thresh = 0;
726    
727            /* initial skip decision */
728            if (current->coding_type != S_VOP)      { /* no fast SKIP for S(GMC)-VOPs */
729                    if (pMB->dquant == 0 && sad00 < pMB->quant * skip_thresh)
730                            if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant)) {
731                                    ZeroMacroblockP(pMB, sad00);
732                                    pMB->mode = MODE_NOT_CODED;
733                                    return 1;
734                            }
735            }
736    
737            if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) {
738                    VECTOR *cmpMV;
739                    VECTOR staticMV = { 0, 0 };
740                    const MACROBLOCK * pMBs = current->mbs;
741    
742                    if (current->coding_type == S_VOP)
743                            cmpMV = &pMB->amv;
744                    else
745                            cmpMV = &staticMV;
746    
747                    if(x > 0 && y > 0 && x < pParam->mb_width) {
748                            if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], *cmpMV) &&
749                               MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&
750                               MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&
751                               MVequal(prevMB->mvs[0], *cmpMV)) {
752                                    stat_thresh = MAX((&pMBs[(x-1) + y * pParam->mb_width])->sad16,
753                                                              MAX((&pMBs[x + (y-1) * pParam->mb_width])->sad16,
754                                                              MAX((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,
755                                                              prevMB->sad16)));
756                            } else {
757                                    stat_thresh = MIN((&pMBs[(x-1) + y * pParam->mb_width])->sad16,
758                                                              MIN((&pMBs[x + (y-1) * pParam->mb_width])->sad16,
759                                                              MIN((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,
760                                                              prevMB->sad16)));
761                            }
762                    }
763            }
764    
765             /* favorize (0,0) or global vector for cartoons */
766            if (current->vop_flags & XVID_VOP_CARTOON) {
767                    if (current->coding_type == S_VOP) {
768                            int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16,
769                            pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536);
770    
771                            if (Data->chroma) {
772                                    iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
773                                    iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
774                            }
775    
776                            if (iSAD <= stat_thresh) {              /* mode decision GMC */
777                                    pMB->mode = MODE_INTER;
778                                    pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD;
779                                    pMB->mcsel = 1;
780                                    if (Data->qpel) {
781                                            pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv;
782                                            pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2;
783                                            pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2;
784                                    } else
785                                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;
786    
787                                    return 1;
788                            }
789                    }
790                    else if (sad00 < stat_thresh) {
791                            VECTOR predMV;
792                            if (Data->qpel)
793                                    predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, 0);
794                            else
795                                    predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, 0);
796    
797                            ZeroMacroblockP(pMB, sad00);
798                            pMB->cbp = 0x3f;
799                            pMB->pmvs[0].x = - predMV.x;
800                            pMB->pmvs[0].y = - predMV.y;
801                            return 1;
802                    }
803            }
804    
805            return 0;
806    }
807    
808  static __inline uint32_t  static __inline uint32_t
809  MakeGoodMotionFlags(const uint32_t MotionFlags, const uint32_t VopFlags, const uint32_t VolFlags)  MakeGoodMotionFlags(const uint32_t MotionFlags, const uint32_t VopFlags, const uint32_t VolFlags)
810  {  {
# Line 751  Line 851 
851          return Flags;          return Flags;
852  }  }
853    
854  bool  static __inline void
855    motionStatsPVOP(int * const MVmax, int * const mvCount, int * const mvSum,
856                                    const MACROBLOCK * const pMB, const int qpel)
857    {
858            const VECTOR * const mv = qpel ? pMB->qmvs : pMB->mvs;
859            int i;
860            int max = *MVmax;
861    
862            switch (pMB->mode) {
863            case MODE_INTER4V:
864                    *mvCount += 3;
865                    for(i = 3; i; i--) {
866                            if (mv[i].x > max) max = mv[i].x;
867                            else if (-mv[i].x - 1 > max) max = -mv[i].x - 1;
868                            *mvSum += mv[i].x * mv[i].x;
869                            if (mv[i].y > max) max = mv[i].y;
870                            else if (-mv[i].y - 1 > max) max = -mv[i].y - 1;
871                            *mvSum += mv[i].y * mv[i].y;
872                    }
873            case MODE_INTER:
874                    (*mvCount)++;
875                    *mvSum += mv[0].x * mv[0].x;
876                    *mvSum += mv[0].y * mv[0].y;
877                    if (mv[0].x > max) max = mv[0].x;
878                    else if (-mv[0].x - 1 > max) max = -mv[0].x - 1;
879                    if (mv[0].y > max) max = mv[0].y;
880                    else if (-mv[0].y - 1 > max) max = -mv[0].y - 1;
881                    *MVmax = max;
882            default:
883                    break;
884            }
885    }
886    
887    void
888  MotionEstimation(MBParam * const pParam,  MotionEstimation(MBParam * const pParam,
889                                   FRAMEINFO * const current,                                   FRAMEINFO * const current,
890                                   FRAMEINFO * const reference,                                   FRAMEINFO * const reference,
# Line 770  Line 903 
903          const uint32_t iEdgedWidth = pParam->edged_width;          const uint32_t iEdgedWidth = pParam->edged_width;
904          const uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags, current->vop_flags, current->vol_flags);          const uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags, current->vop_flags, current->vol_flags);
905          int stat_thresh = 0;          int stat_thresh = 0;
906            int MVmax = 0, mvSum = 0, mvCount = 0;
907    
908          uint32_t x, y;          uint32_t x, y;
909          int32_t sad00;          int sad00;
910          int skip_thresh = INITIAL_SKIP_THRESH * \          int skip_thresh = INITIAL_SKIP_THRESH * \
911                  (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);                  (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
912            int block = 0;
913    
914          /* some pre-initialized thingies for SearchP */          /* some pre-initialized thingies for SearchP */
915          DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
# Line 794  Line 929 
929    
930          for (y = 0; y < mb_height; y++) {          for (y = 0; y < mb_height; y++) {
931                  for (x = 0; x < mb_width; x++)  {                  for (x = 0; x < mb_width; x++)  {
932                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];                          MACROBLOCK *pMB = &pMBs[block];
933                          MACROBLOCK *prevMB = &reference->mbs[x + y * pParam->mb_width];                          MACROBLOCK *prevMB = &reference->mbs[block];
934                            int skip;
935                            block++;
936    
937                          pMB->sad16 =                          pMB->sad16 =
938                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
# Line 813  Line 950 
950                                  sad00 += Data.chromaSAD;                                  sad00 += Data.chromaSAD;
951                          }                          }
952    
953                          /* initial skip decision */                          skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC,
954                          if (current->coding_type != S_VOP)      { /* no fast SKIP for S(GMC)-VOPs */                                                                                  pCurrent, pRef, MotionFlags);
955                                  if (pMB->dquant == 0 && sad00 < pMB->quant * skip_thresh)                          if (skip) continue;
                                         if (Data.chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant)) {  
                                                 ZeroMacroblockP(pMB, sad00);  
                                                 pMB->mode = MODE_NOT_CODED;  
                                                 continue;  
                                         }  
                         }  
   
                         if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) {  
                                 if(x > 0 && y > 0 && x < pParam->mb_width) {  
                                         if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], zeroMV) &&  
                                            MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], zeroMV) &&  
                                        MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], zeroMV) &&  
                                        MVequal(prevMB->mvs[0], zeroMV)) {  
                                                 stat_thresh = MAX((&pMBs[(x-1) + y * pParam->mb_width])->sad16,  
                                                                           MAX((&pMBs[x + (y-1) * pParam->mb_width])->sad16,  
                                                                           MAX((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,  
                                                                           prevMB->sad16)));  
                                         } else {  
                                                 stat_thresh = MIN((&pMBs[(x-1) + y * pParam->mb_width])->sad16,  
                                                                           MIN((&pMBs[x + (y-1) * pParam->mb_width])->sad16,  
                                                                           MIN((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,  
                                                                           prevMB->sad16)));  
                                         }  
                                 }  
                         }  
   
                          /* favorize (0,0) vector for cartoons */  
                         if ((current->vop_flags & XVID_VOP_CARTOON) &&  
                                 ((sad00 < pMB->quant * 4 * skip_thresh) || (sad00 < stat_thresh))) {  
                                 ZeroMacroblockP(pMB, sad00);  
                                 continue;  
                         }  
956    
957                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
958                                          y, MotionFlags, current->vop_flags,                                          y, MotionFlags, current->vop_flags,
# Line 868  Line 973 
973                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);
974    
975    
976                            motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
977                  }                  }
978          }          }
         return 0;  
 }  
   
979    
980            current->fcode = getMinFcode(MVmax);
981            current->sStat.iMvSum = mvSum;
982            current->sStat.iMvCount = mvCount;
983    }

Legend:
Removed from v.1564  
changed lines
  Added in v.1668

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