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

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

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

revision 1.17, Thu Mar 31 22:14:20 2005 UTC revision 1.25, Tue Dec 28 19:19:43 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 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.0 * NEIGH_TEND_8X8 + 0.5),          {     0    ,(int)(1.0 * NEIGH_TEND_8X8 + 0.5),
# 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          }          }
# 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);
# 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 802  Line 908 
908          const uint32_t mb_height = pParam->mb_height;          const uint32_t mb_height = pParam->mb_height;
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 bound = 0;
912          int MVmax = 0, mvSum = 0, mvCount = 0;          int MVmax = 0, mvSum = 0, mvCount = 0;
913    
914          uint32_t x, y;          uint32_t x, y;
915          int32_t sad00;          int sad00;
916          int skip_thresh = INITIAL_SKIP_THRESH * \          int block = 0;
                 (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1);  
917    
918          /* some pre-initialized thingies for SearchP */          /* some pre-initialized thingies for SearchP */
919          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 932 
932          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
933    
934          for (y = 0; y < mb_height; y++) {          for (y = 0; y < mb_height; y++) {
935    
936                    bound = mb_width * ((((y*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
937    
938                  for (x = 0; x < mb_width; x++)  {                  for (x = 0; x < mb_width; x++)  {
939                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];                          MACROBLOCK *pMB = &pMBs[block];
940                          MACROBLOCK *prevMB = &reference->mbs[x + y * pParam->mb_width];                          MACROBLOCK *prevMB = &reference->mbs[block];
941                            int skip;
942                            block++;
943    
944                          pMB->sad16 =                          pMB->sad16 =
945                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,                                  sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
# Line 847  Line 957 
957                                  sad00 += Data.chromaSAD;                                  sad00 += Data.chromaSAD;
958                          }                          }
959    
960                          /* initial skip decision */                          skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC,
961                          if (current->coding_type != S_VOP)      { /* no fast SKIP for S(GMC)-VOPs */                                                                                  pCurrent, pRef, MotionFlags, bound);
962                                  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;  
                                         }  
                         }  
963    
964                          if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) {                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
965                                  VECTOR *cmpMV;                                          y, MotionFlags, current->vop_flags,
966                                  VECTOR staticMV = { 0, 0 };                                          &Data, pParam, pMBs, reference->mbs, pMB, bound);
967    
968                                  if (current->coding_type == S_VOP)                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
969                                          cmpMV = &pMB->amv;                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
970                                                                    MotionFlags, current->vop_flags, current->vol_flags,
971                                                                    pCurrent, pRef, pGMC, current->coding_type, bound);
972    
973                            else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
974                                    xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
975                                                                    MotionFlags, current->vop_flags, current->vol_flags,
976                                                                    pCurrent, pRef, pGMC, current->coding_type, bound);
977                                  else                                  else
978                                          cmpMV = &staticMV;                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
979                                                                    MotionFlags, current->vop_flags, current->vol_flags,
980                                                                    pCurrent, pRef, pGMC, current->coding_type, sad00);
981    
982                                  if(x > 0 && y > 0 && x < pParam->mb_width) {  
983                                          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)));  
984                                          }                                          }
985                                  }                                  }
986    
987            current->fcode = getMinFcode(MVmax);
988            current->sStat.iMvSum = mvSum;
989            current->sStat.iMvCount = mvCount;
990                          }                          }
991    
992                           /* favorize (0,0) or global vector for cartoons */  void
993                          if (current->vop_flags & XVID_VOP_CARTOON) {  MotionEstimateSMP(SMPData * h)
994                                  if (current->coding_type == S_VOP) {  {
995                                          int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16,          Encoder *pEnc = (Encoder *) h->pEnc;
                                         pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536);  
996    
997                                          if (Data.chroma) {          const MBParam * const pParam = &pEnc->mbParam;
998                                                  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;
999                                                  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;
1000                                          }          const IMAGE * const pRefH = &pEnc->vInterH;
1001            const IMAGE * const pRefV = &pEnc->vInterV;
1002            const IMAGE * const pRefHV = &pEnc->vInterHV;
1003            const IMAGE * const pGMC = &pEnc->vGMC;
1004            uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags,
1005                                                                                                    current->vop_flags,
1006                                                                                                    current->vol_flags);
1007    
1008                                          if (iSAD <= stat_thresh) {              /* mode decision GMC */          MACROBLOCK *const pMBs = current->mbs;
1009                                                  pMB->mode = MODE_INTER;          const IMAGE *const pCurrent = &current->image;
1010                                                  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;  
1011    
1012                                                  continue;          const int mb_width = pParam->mb_width;
1013            const int mb_height = pParam->mb_height;
1014            const uint32_t iEdgedWidth = pParam->edged_width;
1015            int bound = 0;
1016            int num_slices = pEnc->num_slices;
1017            int y_step = h->y_step;
1018            int y_row = h->y_row;
1019            int start_y = h->start_y;
1020            int stop_y = h->stop_y;
1021            int MVmax = 0, mvSum = 0, mvCount = 0;
1022    
1023            int x, y;
1024            int sad00;
1025            int block = (start_y+y_row)*mb_width;
1026            int * complete_count_self = h->complete_count_self;
1027            const volatile int * complete_count_above = h->complete_count_above;
1028            int max_mbs;
1029            int current_mb = 0;
1030    
1031            /* some pre-initialized thingies for SearchP */
1032            DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE);
1033            SearchData Data;
1034            memset(&Data, 0, sizeof(SearchData));
1035            Data.iEdgedWidth = iEdgedWidth;
1036            Data.iFcode = current->fcode;
1037            Data.rounding = pParam->m_rounding_type;
1038            Data.qpel = (current->vol_flags & XVID_VOL_QUARTERPEL ? 1:0);
1039            Data.chroma = MotionFlags & XVID_ME_CHROMA_PVOP;
1040            Data.dctSpace = dct_space;
1041            Data.quant_type = !(pParam->vol_flags & XVID_VOL_MPEGQUANT);
1042            Data.mpeg_quant_matrices = pParam->mpeg_quant_matrices;
1043    
1044            /* todo: sort out temp memory space */
1045            Data.RefQ = h->RefQ;
1046            if (sadInit) (*sadInit) ();
1047    
1048            max_mbs = 0;
1049    
1050            for (y = (start_y + y_row); y < stop_y; y += y_step)    {
1051                    bound = mb_width * ((((y*num_slices) / mb_height) * mb_height + (num_slices-1)) / num_slices);
1052    
1053                    if (y == start_y) max_mbs = mb_width; /* we can process all blocks of the first row */
1054    
1055                    for (x = 0; x < mb_width; x++)  {
1056    
1057                            MACROBLOCK *pMB, *prevMB;
1058                            int skip;
1059    
1060                            if (current_mb >= max_mbs) {
1061                                    /* we ME-ed all macroblocks we safely could. grab next portion */
1062                                    int above_count = *complete_count_above; /* sync point */
1063                                    if (above_count == mb_width) {
1064                                            /* full line above is ready */
1065                                            above_count = mb_width+1;
1066                                            if (y < (stop_y-y_step)) {
1067                                                    /* this is not last line, grab a portion of MBs from the next line too */
1068                                                    above_count += MAX(0, complete_count_above[1] - 1);
1069                                          }                                          }
1070                                  }                                  }
                                 else if (sad00 < stat_thresh) {  
                                         VECTOR predMV;  
                                         if (current->vol_flags & XVID_VOL_QUARTERPEL)  
                                                 predMV = get_qpmv2(current->mbs, mb_width, 0, x, y, 0);  
                                         else  
                                                 predMV = get_pmv2(current->mbs, mb_width, 0, x, y, 0);  
1071    
1072                                          ZeroMacroblockP(pMB, sad00);                                  max_mbs = current_mb + above_count - x - 1;
1073                                          pMB->cbp = 0x3f;  
1074                                          pMB->pmvs[0].x = - predMV.x;                                  if (current_mb >= max_mbs) {
1075                                          pMB->pmvs[0].y = - predMV.y;                                          /* current workload is zero */
1076                                            x--;
1077                                            sched_yield();
1078                                          continue;                                          continue;
1079                                  }                                  }
1080                          }                          }
1081    
1082                            pMB = &pMBs[block];
1083                            prevMB = &reference->mbs[block];
1084    
1085                            pMB->sad16 =
1086                                    sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16,
1087                                                            pRef->y + (x + y * iEdgedWidth) * 16,
1088                                                            pParam->edged_width, pMB->sad8);
1089    
1090                            sad00 = 4*MAX(MAX(pMB->sad8[0], pMB->sad8[1]), MAX(pMB->sad8[2], pMB->sad8[3]));
1091    
1092                            if (Data.chroma) {
1093                                    Data.chromaSAD = sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8,
1094                                                                            pRef->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2)
1095                                                                    + sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8,
1096                                                                            pRef->v + (x + y*(iEdgedWidth/2))*8, iEdgedWidth/2);
1097                                    pMB->sad16 += Data.chromaSAD;
1098                                    sad00 += Data.chromaSAD;
1099                            }
1100    
1101                            skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC,
1102                                                                                    pCurrent, pRef, MotionFlags, bound);
1103    
1104                            if (skip) {
1105                                    current_mb++;
1106                                    block++;
1107                                    *complete_count_self = x+1;
1108                                    continue;
1109                            }
1110    
1111                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1112                                          y, MotionFlags, current->vop_flags,                                          y, MotionFlags, current->vop_flags,
1113                                          &Data, pParam, pMBs, reference->mbs, pMB);                                          &Data, pParam, pMBs, reference->mbs, pMB, bound);
1114    
1115                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)                          if (current->vop_flags & XVID_VOP_MODEDECISION_RD)
1116                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,                                  xvid_me_ModeDecision_RD(&Data, pMB, pMBs, x, y, pParam,
1117                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1118                                                                  pCurrent, pRef, pGMC, current->coding_type);                                                                  pCurrent, pRef, pGMC, current->coding_type, bound);
1119    
1120                          else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)                          else if (current->vop_flags & XVID_VOP_FAST_MODEDECISION_RD)
1121                                  xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,                                  xvid_me_ModeDecision_Fast(&Data, pMB, pMBs, x, y, pParam,
1122                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1123                                                                  pCurrent, pRef, pGMC, current->coding_type);                                                                  pCurrent, pRef, pGMC, current->coding_type, bound);
1124                          else                          else
1125                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,                                  ModeDecision_SAD(&Data, pMB, pMBs, x, y, pParam,
1126                                                                  MotionFlags, current->vop_flags, current->vol_flags,                                                                  MotionFlags, current->vop_flags, current->vol_flags,
1127                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);                                                                  pCurrent, pRef, pGMC, current->coding_type, sad00);
1128    
1129                            *complete_count_self = x+1;
1130    
1131                            current_mb++;
1132                            block++;
1133    
1134                          motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);                          motionStatsPVOP(&MVmax, &mvCount, &mvSum, pMB, Data.qpel);
1135    
1136                  }                  }
1137    
1138                    block += (y_step-1)*pParam->mb_width;
1139    
1140                    complete_count_self++;
1141                    complete_count_above++;
1142          }          }
1143    
1144          current->fcode = getMinFcode(MVmax);          h->minfcode = getMinFcode(MVmax);
         current->sStat.iMvSum = mvSum;  
         current->sStat.iMvCount = mvCount;  
1145    
1146          return 0;          h->MVmax = MVmax;
1147            h->mvSum = mvSum;
1148            h->mvCount = mvCount;
1149  }  }
1150    
1151    

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.25

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