[svn] / branches / release-1_3-branch / xvidcore / src / motion / estimation_pvop.c Repository:
ViewVC logotype

Diff of /branches/release-1_3-branch/xvidcore/src/motion/estimation_pvop.c

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

revision 1603, Fri Mar 4 22:13:33 2005 UTC revision 1913, Sat Dec 18 16:02:08 2010 UTC
# Line 4  Line 4 
4   *  - Motion Estimation for P- and S- VOPs  -   *  - Motion Estimation for P- and S- VOPs  -
5   *   *
6   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>
7   *               2002 Michael Militzer <michael@xvid.org>   *               2002-2010 Michael Militzer <michael@xvid.org>
8   *               2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net>   *               2002-2003 Radoslaw Czyz <xvid@syskin.cjb.net>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
# 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.15 2005-03-04 22:13:33 Isibaar Exp $   * $Id: estimation_pvop.c,v 1.24 2010-12-18 16:02:00 Isibaar Exp $
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
# Line 39  Line 39 
39  #include "motion.h"  #include "motion.h"
40  #include "sad.h"  #include "sad.h"
41  #include "motion_inlines.h"  #include "motion_inlines.h"
42    #include "motion_smp.h"
43    
44    
45  static const int xvid_me_lambda_vec8[32] =  static const int xvid_me_lambda_vec8[32] =
46          {     0    ,(int)(1.00235 * NEIGH_TEND_8X8 + 0.5),          {     0    ,(int)(1.0 * NEIGH_TEND_8X8 + 0.5),
47          (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),
48          (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),
49          (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),
50          (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),
51          (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),
52          (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),
53          (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),
54          (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),
55          (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),
56          (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),
57          (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),
58          (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),
59          (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),
60          (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),
61          (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)
62  };  };
63    
64  static void  static void
# Line 82  Line 84 
84          sad = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp);          sad = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp);
85          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);
86    
87          sad += (data->lambda16 * t * sad)>>10;          sad += (data->lambda16 * t);
88          data->temp[0] += (data->lambda8 * t * (data->temp[0] + NEIGH_8X8_BIAS))>>10;          data->temp[0] += (data->lambda8 * t);
89    
90          if (data->chroma) {          if (data->chroma) {
91                  if (sad >= data->iMinSAD[0]) goto no16;                  if (sad >= data->iMinSAD[0]) goto no16;
# Line 129  Line 131 
131          sad = sad8(data->Cur, Reference, data->iEdgedWidth);          sad = sad8(data->Cur, Reference, data->iEdgedWidth);
132          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);
133    
134          sad += (data->lambda8 * t * (sad+NEIGH_8X8_BIAS))>>10;          sad += (data->lambda8 * t);
135    
136          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
137                  *(data->iMinSAD) = sad;                  *(data->iMinSAD) = sad;
# Line 294  Line 296 
296    
297          /* final skip decision, a.k.a. "the vector you found, really that good?" */          /* final skip decision, a.k.a. "the vector you found, really that good?" */
298          if (skip_possible && (skip_sad < (int)iQuant * MAX_SAD00_FOR_SKIP))          if (skip_possible && (skip_sad < (int)iQuant * MAX_SAD00_FOR_SKIP))
299                  if ( (100*skip_sad)/(pMB->sad16+1) > FINAL_SKIP_THRESH)                  if ( (100*skip_sad)/(pMB->sad16+1) < FINAL_SKIP_THRESH)
300                          if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, Data->iEdgedWidth/2, iQuant)) {                          if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, Data->iEdgedWidth/2, iQuant)) {
301                                  mode = MODE_NOT_CODED;                                  mode = MODE_NOT_CODED;
302                                  sad = 0;                                  sad = 0;
# Line 405  Line 407 
407                  MACROBLOCK * const pMB,                  MACROBLOCK * const pMB,
408                  const MACROBLOCK * const pMBs,                  const MACROBLOCK * const pMBs,
409                  const int block,                  const int block,
410                  SearchData * const Data)                  SearchData * const Data,
411                    const int bound)
412  {  {
413          int i = 0;          int i = 0;
414          VECTOR vbest_q; int32_t sbest_q;          VECTOR vbest_q; int32_t sbest_q;
# Line 414  Line 417 
417          *Data->currentQMV = *(OldData->currentQMV + 1 + block);          *Data->currentQMV = *(OldData->currentQMV + 1 + block);
418    
419          if(Data->qpel) {          if(Data->qpel) {
420                  Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x/2, y/2, block);                  Data->predMV = get_qpmv2(pMBs, pParam->mb_width, bound, x/2, y/2, block);
421                  if (block != 0) i = d_mv_bits(  Data->currentQMV->x, Data->currentQMV->y,                  if (block != 0) i = d_mv_bits(  Data->currentQMV->x, Data->currentQMV->y,
422                                                                                  Data->predMV, Data->iFcode, 0);                                                                                  Data->predMV, Data->iFcode, 0);
423          } else {          } else {
424                  Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2, y/2, block);                  Data->predMV = get_pmv2(pMBs, pParam->mb_width, bound, x/2, y/2, block);
425                  if (block != 0) i = d_mv_bits(  Data->currentMV->x, Data->currentMV->y,                  if (block != 0) i = d_mv_bits(  Data->currentMV->x, Data->currentMV->y,
426                                                                                  Data->predMV, Data->iFcode, 0);                                                                                  Data->predMV, Data->iFcode, 0);
427          }          }
428    
429          *(Data->iMinSAD) += (Data->lambda8 * i * (*Data->iMinSAD + NEIGH_8X8_BIAS))>>10;          *(Data->iMinSAD) += (Data->lambda8 * i);
430    
431          if (MotionFlags & (XVID_ME_EXTSEARCH8|XVID_ME_HALFPELREFINE8|XVID_ME_QUARTERPELREFINE8)) {          if (MotionFlags & (XVID_ME_EXTSEARCH8|XVID_ME_HALFPELREFINE8|XVID_ME_QUARTERPELREFINE8)) {
432    
# Line 521  Line 524 
524                  const MBParam * const pParam,                  const MBParam * const pParam,
525                  const MACROBLOCK * const pMBs,                  const MACROBLOCK * const pMBs,
526                  const MACROBLOCK * const prevMBs,                  const MACROBLOCK * const prevMBs,
527                  MACROBLOCK * const pMB)                  MACROBLOCK * const pMB,
528                    const int bound)
529  {  {
530    
531          int i, threshA;          int i, threshA;
# Line 532  Line 536 
536          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
537                                                  pParam->width, pParam->height, Data->iFcode - Data->qpel, 1);                                                  pParam->width, pParam->height, Data->iFcode - Data->qpel, 1);
538    
539          get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, pmv, Data->temp);          get_pmvdata2(pMBs, pParam->mb_width, bound, x, y, pmv, Data->temp);
540    
541          Data->chromaX = Data->chromaY = 0; /* chroma-sad cache */          Data->chromaX = Data->chromaY = 0; /* chroma-sad cache */
542          Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16;          Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16;
# Line 553  Line 557 
557    
558          memset(Data->currentMV, 0, 5*sizeof(VECTOR));          memset(Data->currentMV, 0, 5*sizeof(VECTOR));
559    
560          if (Data->qpel) Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, 0);          if (Data->qpel) Data->predMV = get_qpmv2(pMBs, pParam->mb_width, bound, x, y, 0);
561          else Data->predMV = pmv[0];          else Data->predMV = pmv[0];
562    
563          i = d_mv_bits(0, 0, Data->predMV, Data->iFcode, 0);          i = d_mv_bits(0, 0, Data->predMV, Data->iFcode, 0);
564          Data->iMinSAD[0] = pMB->sad16 + ((Data->lambda16 * i * pMB->sad16)>>10);          Data->iMinSAD[0] = pMB->sad16 + (Data->lambda16 * i);
565          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);
566          Data->iMinSAD[2] = pMB->sad8[1];          Data->iMinSAD[2] = pMB->sad8[1];
567          Data->iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[3] = pMB->sad8[2];
568          Data->iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[4] = pMB->sad8[3];
# Line 679  Line 683 
683                  SearchData Data8;                  SearchData Data8;
684                  memcpy(&Data8, Data, sizeof(SearchData)); /* quick copy of common data */                  memcpy(&Data8, Data, sizeof(SearchData)); /* quick copy of common data */
685    
686                  Search8(Data, 2*x, 2*y, MotionFlags, pParam, pMB, pMBs, 0, &Data8);                  Search8(Data, 2*x, 2*y, MotionFlags, pParam, pMB, pMBs, 0, &Data8, bound);
687                  Search8(Data, 2*x + 1, 2*y, MotionFlags, pParam, pMB, pMBs, 1, &Data8);                  Search8(Data, 2*x + 1, 2*y, MotionFlags, pParam, pMB, pMBs, 1, &Data8, bound);
688                  Search8(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8);                  Search8(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8, bound);
689                  Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8);                  Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8, bound);
690    
691                  if ((Data->chroma) && (!(VopFlags & XVID_VOP_MODEDECISION_RD))) {                  if ((Data->chroma) && (!(VopFlags & XVID_VOP_MODEDECISION_RD))) {
692                          /* chroma is only used for comparison to INTER. if the comparison will be done in RD domain, it will not be used */                          /* chroma is only used for comparison to INTER. if the comparison will be done in RD domain, it will not be used */
# Line 705  Line 709 
709          } else Data->iMinSAD[1] = 4096*256;          } else Data->iMinSAD[1] = 4096*256;
710  }  }
711    
712    static int
713    InitialSkipDecisionP(int sad00,
714                                             const MBParam * pParam,
715                                             const FRAMEINFO * current,
716                                             MACROBLOCK * pMB,
717                                             const MACROBLOCK * prevMB,
718                                             int x, int y,
719                                             const SearchData * Data,
720                                             const IMAGE * const pGMC,
721                                             const IMAGE * const pCurrent,
722                                             const IMAGE * const pRef,
723                                             const uint32_t MotionFlags,
724                                             const int bound)
725    {
726            const unsigned int iEdgedWidth = pParam->edged_width;
727    
728            int skip_thresh = INITIAL_SKIP_THRESH * \
729                    (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
730            int stat_thresh = 0;
731    
732            /* initial skip decision */
733            if (current->coding_type != S_VOP)      { /* no fast SKIP for S(GMC)-VOPs */
734                    if (pMB->dquant == 0 && sad00 < pMB->quant * skip_thresh)
735                            if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant)) {
736                                    ZeroMacroblockP(pMB, sad00);
737                                    pMB->mode = MODE_NOT_CODED;
738                                    return 1;
739                            }
740            }
741    
742            if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) {
743                    VECTOR *cmpMV;
744                    VECTOR staticMV = { 0, 0 };
745                    const MACROBLOCK * pMBs = current->mbs;
746    
747                    if (current->coding_type == S_VOP)
748                            cmpMV = &pMB->amv;
749                    else
750                            cmpMV = &staticMV;
751    
752                    if(x > 0 && y > 0 && x < (int) pParam->mb_width) {
753                            if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], *cmpMV) &&
754                               MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&
755                               MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&
756                               MVequal(prevMB->mvs[0], *cmpMV)) {
757                                    stat_thresh = MAX((&pMBs[(x-1) + y * pParam->mb_width])->sad16,
758                                                              MAX((&pMBs[x + (y-1) * pParam->mb_width])->sad16,
759                                                              MAX((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,
760                                                              prevMB->sad16)));
761                            } else {
762                                    stat_thresh = MIN((&pMBs[(x-1) + y * pParam->mb_width])->sad16,
763                                                              MIN((&pMBs[x + (y-1) * pParam->mb_width])->sad16,
764                                                              MIN((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16,
765                                                              prevMB->sad16)));
766                            }
767                    }
768            }
769    
770             /* favorize (0,0) or global vector for cartoons */
771            if (current->vop_flags & XVID_VOP_CARTOON) {
772                    if (current->coding_type == S_VOP) {
773                            int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16,
774                            pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536);
775    
776                            if (Data->chroma) {
777                                    iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
778                                    iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);
779                            }
780    
781                            if (iSAD <= stat_thresh) {              /* mode decision GMC */
782                                    pMB->mode = MODE_INTER;
783                                    pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD;
784                                    pMB->mcsel = 1;
785                                    if (Data->qpel) {
786                                            pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv;
787                                            pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2;
788                                            pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2;
789                                    } else
790                                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;
791    
792                                    return 1;
793                            }
794                    }
795                    else if (sad00 < stat_thresh) {
796                            VECTOR predMV;
797                            if (Data->qpel)
798                                    predMV = get_qpmv2(current->mbs, pParam->mb_width, bound, x, y, 0);
799                            else
800                                    predMV = get_pmv2(current->mbs, pParam->mb_width, bound, x, y, 0);
801    
802                            ZeroMacroblockP(pMB, sad00);
803                            pMB->cbp = 0x3f;
804                            pMB->pmvs[0].x = - predMV.x;
805                            pMB->pmvs[0].y = - predMV.y;
806                            return 1;
807                    }
808            }
809    
810            return 0;
811    }
812    
813  static __inline uint32_t  static __inline uint32_t
814  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)
815  {  {
# Line 784  Line 889 
889          }          }
890  }  }
891    
892  bool  void
893  MotionEstimation(MBParam * const pParam,  MotionEstimation(MBParam * const pParam,
894                                   FRAMEINFO * const current,                                   FRAMEINFO * const current,
895                                   FRAMEINFO * const reference,                                   FRAMEINFO * const reference,
# Line 792  Line 897 
897                                   const IMAGE * const pRefV,                                   const IMAGE * const pRefV,
898                                   const IMAGE * const pRefHV,                                   const IMAGE * const pRefHV,
899                                  const IMAGE * const pGMC,                                  const IMAGE * const pGMC,
900                                   const uint32_t iLimit)                                   const uint32_t iLimit,
901                                     const int num_slices)
902  {  {
903          MACROBLOCK *const pMBs = current->mbs;          MACROBLOCK *const pMBs = current->mbs;
904          const IMAGE *const pCurrent = &current->image;          const IMAGE *const pCurrent = &current->image;
# Line 803  Line 909 
909          const uint32_t iEdgedWidth = pParam->edged_width;          const uint32_t iEdgedWidth = pParam->edged_width;
910          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);
911          int stat_thresh = 0;          int stat_thresh = 0;
912            int bound = 0;
913          int MVmax = 0, mvSum = 0, mvCount = 0;          int MVmax = 0, mvSum = 0, mvCount = 0;
914    
915          uint32_t x, y;          uint32_t x, y;
916          int32_t sad00;          int sad00;
917          int skip_thresh = INITIAL_SKIP_THRESH * \          int skip_thresh = INITIAL_SKIP_THRESH * \
918                  (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);                  (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
919            int block = 0;
920    
921          /* some pre-initialized thingies for SearchP */          /* some pre-initialized thingies for SearchP */
922          DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);          DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
# Line 827  Line 935 
935          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
936    
937          for (y = 0; y < mb_height; y++) {          for (y = 0; y < mb_height; y++) {
938    
939                    bound = mb_width * ((((y*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
940    
941                  for (x = 0; x < mb_width; x++)  {                  for (x = 0; x < mb_width; x++)  {
942                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];                          MACROBLOCK *pMB = &pMBs[block];
943                          MACROBLOCK *prevMB = &reference->mbs[x + y * pParam->mb_width];                          MACROBLOCK *prevMB = &reference->mbs[block];
944                            int skip;
945                            block++;
946    
947                          pMB->sad16 =                          pMB->sad16 =
948                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
# Line 847  Line 960 
960                                  sad00 += Data.chromaSAD;                                  sad00 += Data.chromaSAD;
961                          }                          }
962    
963                          /* initial skip decision */                          skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC,
964                          if (current->coding_type != S_VOP)      { /* no fast SKIP for S(GMC)-VOPs */                                                                                  pCurrent, pRef, MotionFlags, bound);
965                                  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;  
                                         }  
                         }  
966    
967                          if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) {                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
968                                  VECTOR *cmpMV;                                          y, MotionFlags, current->vop_flags,
969                                  VECTOR staticMV = { 0, 0 };                                          &Data, pParam, pMBs, reference->mbs, pMB, bound);
970    
971                                  if (current->coding_type == S_VOP)                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
972                                          cmpMV = &pMB->amv;                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
973                                                                    MotionFlags, current->vop_flags, current->vol_flags,
974                                                                    pCurrent, pRef, pGMC, current->coding_type, bound);
975    
976                            else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
977                                    xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
978                                                                    MotionFlags, current->vop_flags, current->vol_flags,
979                                                                    pCurrent, pRef, pGMC, current->coding_type, bound);
980                                  else                                  else
981                                          cmpMV = &staticMV;                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
982                                                                    MotionFlags, current->vop_flags, current->vol_flags,
983                                                                    pCurrent, pRef, pGMC, current->coding_type, sad00);
984    
985                                  if(x > 0 && y > 0 && x < pParam->mb_width) {  
986                                          if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], *cmpMV) &&                          motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
                                            MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&  
                                        MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) &&  
                                        MVequal(prevMB->mvs[0], *cmpMV)) {  
                                                 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)));  
987                                          }                                          }
988                                  }                                  }
989    
990            current->fcode = getMinFcode(MVmax);
991            current->sStat.iMvSum = mvSum;
992            current->sStat.iMvCount = mvCount;
993                          }                          }
994    
995                           /* favorize (0,0) or global vector for cartoons */  void
996                          if (current->vop_flags & XVID_VOP_CARTOON) {  MotionEstimateSMP(SMPData * h)
997                                  if (current->coding_type == S_VOP) {  {
998                                          int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16,          Encoder *pEnc = (Encoder *) h->pEnc;
                                         pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536);  
999    
1000                                          if (Data.chroma) {          const MBParam * const pParam = &pEnc->mbParam;
1001                                                  iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);          const FRAMEINFO * const current = pEnc->current;
1002                                                  iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2);          const FRAMEINFO * const reference = pEnc->reference;
1003                                          }          const IMAGE * const pRefH = &pEnc->vInterH;
1004            const IMAGE * const pRefV = &pEnc->vInterV;
1005            const IMAGE * const pRefHV = &pEnc->vInterHV;
1006            const IMAGE * const pGMC = &pEnc->vGMC;
1007            uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags,
1008                                                                                                    current->vop_flags,
1009                                                                                                    current->vol_flags);
1010    
1011                                          if (iSAD <= stat_thresh) {              /* mode decision GMC */          MACROBLOCK *const pMBs = current->mbs;
1012                                                  pMB->mode = MODE_INTER;          const IMAGE *const pCurrent = &current->image;
1013                                                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD;          const IMAGE *const pRef = &reference->image;
                                                 pMB->mcsel = 1;  
                                                 if (Data.qpel) {  
                                                         pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv;  
                                                         pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2;  
                                                         pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2;  
                                                 } else  
                                                         pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;  
1014    
1015                                                  continue;          const int mb_width = pParam->mb_width;
1016            const int mb_height = pParam->mb_height;
1017            const uint32_t iEdgedWidth = pParam->edged_width;
1018            int stat_thresh = 0;
1019            int bound = 0;
1020            int num_slices = pEnc->num_slices;
1021            int y_step = h->y_step;
1022            int y_row = h->y_row;
1023            int start_y = h->start_y;
1024            int stop_y = h->stop_y;
1025            int MVmax = 0, mvSum = 0, mvCount = 0;
1026    
1027            int x, y;
1028            int sad00;
1029            int skip_thresh = INITIAL_SKIP_THRESH * \
1030                    (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);
1031            int block = (start_y+y_row)*mb_width;
1032            int * complete_count_self = h->complete_count_self;
1033            const volatile int * complete_count_above = h->complete_count_above;
1034            int max_mbs;
1035            int current_mb = 0;
1036    
1037            /* some pre-initialized thingies for SearchP */
1038            DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
1039            SearchData Data;
1040            memset(&Data, 0, sizeof(SearchData));
1041            Data.iEdgedWidth = iEdgedWidth;
1042            Data.iFcode = current->fcode;
1043            Data.rounding = pParam->m_rounding_type;
1044            Data.qpel = (current->vol_flags & XVID_VOL_QUARTERPEL ? 1:0);
1045            Data.chroma = MotionFlags & XVID_ME_CHROMA_PVOP;
1046            Data.dctSpace = dct_space;
1047            Data.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
1048            Data.mpeg_quant_matrices = pParam->mpeg_quant_matrices;
1049    
1050            /* todo: sort out temp memory space */
1051            Data.RefQ = h->RefQ;
1052            if (sadInit) (*sadInit) ();
1053    
1054            max_mbs = 0;
1055    
1056            for (y = (start_y + y_row); y < stop_y; y += y_step)    {
1057                    bound = mb_width * ((((y*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
1058    
1059                    if (y == start_y) max_mbs = mb_width; /* we can process all blocks of the first row */
1060    
1061                    for (x = 0; x < mb_width; x++)  {
1062    
1063                            MACROBLOCK *pMB, *prevMB;
1064                            int skip;
1065    
1066                            if (current_mb >= max_mbs) {
1067                                    /* we ME-ed all macroblocks we safely could. grab next portion */
1068                                    int above_count = *complete_count_above; /* sync point */
1069                                    if (above_count == mb_width) {
1070                                            /* full line above is ready */
1071                                            above_count = mb_width+1;
1072                                            if (y < (stop_y-y_step)) {
1073                                                    /* this is not last line, grab a portion of MBs from the next line too */
1074                                                    above_count += MAX(0, complete_count_above[1] - 1);
1075                                          }                                          }
1076                                  }                                  }
1077                                  else if (sad00 < stat_thresh) {  
1078                                          ZeroMacroblockP(pMB, sad00);                                  max_mbs = current_mb + above_count - x - 1;
1079                                          pMB->cbp = 0x3f;  
1080                                    if (current_mb >= max_mbs) {
1081                                            /* current workload is zero */
1082                                            x--;
1083                                            sched_yield();
1084                                          continue;                                          continue;
1085                                  }                                  }
1086                          }                          }
1087    
1088                            pMB = &pMBs[block];
1089                            prevMB = &reference->mbs[block];
1090    
1091                            pMB->sad16 =
1092                                    sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
1093                                                            pRef->y + (x + y * iEdgedWidth) * 16,
1094                                                            pParam->edged_width, pMB->sad8);
1095    
1096                            sad00 = 4*MAX(MAX(pMB->sad8[0], pMB->sad8[1]), MAX(pMB->sad8[2], pMB->sad8[3]));
1097    
1098                            if (Data.chroma) {
1099                                    Data.chromaSAD = sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8,
1100                                                                            pRef->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2)
1101                                                                    + sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8,
1102                                                                            pRef->v + (x + y*(iEdgedWidth/2))*8, iEdgedWidth/2);
1103                                    pMB->sad16 += Data.chromaSAD;
1104                                    sad00 += Data.chromaSAD;
1105                            }
1106    
1107                            skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC,
1108                                                                                    pCurrent, pRef, MotionFlags, bound);
1109    
1110                            if (skip) {
1111                                    current_mb++;
1112                                    block++;
1113                                    *complete_count_self = x+1;
1114                                    continue;
1115                            }
1116    
1117                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1118                                          y, MotionFlags, current->vop_flags,                                          y, MotionFlags, current->vop_flags,
1119                                          &Data, pParam, pMBs, reference->mbs, pMB);                                          &Data, pParam, pMBs, reference->mbs, pMB, bound);
1120    
1121                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
1122                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
1123                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1124                                                                  pCurrent, pRef, pGMC, current->coding_type);                                                                  pCurrent, pRef, pGMC, current->coding_type, bound);
1125    
1126                          else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)                          else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
1127                                  xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,                                  xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
1128                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1129                                                                  pCurrent, pRef, pGMC, current->coding_type);                                                                  pCurrent, pRef, pGMC, current->coding_type, bound);
1130                          else                          else
1131                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
1132                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1133                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);
1134    
1135                            *complete_count_self = x+1;
1136    
1137                            current_mb++;
1138                            block++;
1139    
1140                          motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);                          motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
1141    
1142                  }                  }
1143    
1144                    block += (y_step-1)*pParam->mb_width;
1145    
1146                    complete_count_self++;
1147                    complete_count_above++;
1148          }          }
1149    
1150          current->fcode = getMinFcode(MVmax);          h->minfcode = getMinFcode(MVmax);
         current->sStat.iMvSum = mvSum;  
         current->sStat.iMvCount = mvCount;  
1151    
1152          return 0;          h->MVmax = MVmax;
1153            h->mvSum = mvSum;
1154            h->mvCount = mvCount;
1155  }  }
1156    
1157    

Legend:
Removed from v.1603  
changed lines
  Added in v.1913

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