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

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

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

revision 530, Mon Sep 23 20:36:02 2002 UTC revision 539, Wed Sep 25 21:28:48 2002 UTC
# Line 40  Line 40 
40  #include "motion_est.h"  #include "motion_est.h"
41  #include "motion.h"  #include "motion.h"
42  #include "sad.h"  #include "sad.h"
43    #include "../utils/emms.h"
44    
45  #define INITIAL_SKIP_THRESH     (10)  #define INITIAL_SKIP_THRESH     (10)
46  #define FINAL_SKIP_THRESH       (50)  #define FINAL_SKIP_THRESH       (50)
47  #define MAX_SAD00_FOR_SKIP      (20)  #define MAX_SAD00_FOR_SKIP      (20)
48  #define MAX_CHROMA_SAD_FOR_SKIP (18)  #define MAX_CHROMA_SAD_FOR_SKIP (22)
49  #define SKIP_THRESH_B (10)  #define SKIP_THRESH_B (25)
50    
51  #define CHECK_CANDIDATE(X,Y,D) { \  #define CHECK_CANDIDATE(X,Y,D) { \
52  (*CheckCandidate)((const int)(X),(const int)(Y), (D), &iDirection, data ); }  (*CheckCandidate)((const int)(X),(const int)(Y), (D), &iDirection, data ); }
53    
54  #define iDiamondSize 2  #define iDiamondSize 2
55    
 //FILE * debug;  
   
56  static __inline int  static __inline int
57  d_mv_bits(int x, int y, const uint32_t iFcode)  d_mv_bits(int x, int y, const uint32_t iFcode)
58  {  {
# Line 79  Line 78 
78          return xb + yb;          return xb + yb;
79  }  }
80    
81  /* CHACK_CANDIATE FUNCTIONS START */  
82    /* CHECK_CANDIATE FUNCTIONS START */
83    
84  static void  static void
85  CheckCandidate16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)  CheckCandidate16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
86  {  {
87          int32_t * const sad = data->temp;          int32_t * const sad = data->temp;
 //      static int32_t sad[5];  
88          int t;          int t;
89          const uint8_t * Reference;          const uint8_t * Reference;
90    
# Line 149  Line 148 
148  }  }
149    
150  static void  static void
151    CheckCandidate16no4vI(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
152    {
153            int32_t sad;
154    
155            if (( x > data->max_dx) || ( x < data->min_dx)
156                    || ( y > data->max_dy) || (y < data->min_dy)) return;
157    
158            sad = lambda_vec16[data->iQuant] *
159                            d_mv_bits(x - data->predMV.x, y - data->predMV.y, data->iFcode);
160    
161            sad += sad16(data->Cur, data->Ref + x/2 + (y/2)*(data->iEdgedWidth),
162                                            data->iEdgedWidth, 256*4096);
163    
164            if (sad < *(data->iMinSAD)) {
165                    *(data->iMinSAD) = sad;
166                    data->currentMV[0].x = x; data->currentMV[0].y = y;
167                    *dir = Direction; }
168    }
169    
170    
171    static void
172  CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data)  CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data)
173  {  {
174          int32_t sad;          int32_t sad;
# Line 316  Line 336 
336                  *dir = Direction; }                  *dir = Direction; }
337  }  }
338    
339  /* CHACK_CANDIATE FUNCTIONS END */  /* CHECK_CANDIATE FUNCTIONS END */
340    
341  /* MAINSEARCH FUNCTIONS START */  /* MAINSEARCH FUNCTIONS START */
342    
# Line 508  Line 528 
528  SkipMacroblockP(MACROBLOCK *pMB, const int32_t sad)  SkipMacroblockP(MACROBLOCK *pMB, const int32_t sad)
529  {  {
530          pMB->mode = MODE_NOT_CODED;          pMB->mode = MODE_NOT_CODED;
531          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->mv16.x = 0;          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
532          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->mv16.y = 0;          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
533          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad;          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad;
534  }  }
535    
# Line 532  Line 552 
552          uint32_t iIntra = 0;          uint32_t iIntra = 0;
553          int32_t InterBias;          int32_t InterBias;
554    
555            // some pre-initialized thingies for SearchP
556            int32_t temp[5];
557            VECTOR currentMV[5];
558            int32_t iMinSAD[5];
559            SearchData Data;
560            Data.iEdgedWidth = pParam->edged_width;
561            Data.currentMV = currentMV;
562            Data.iMinSAD = iMinSAD;
563            Data.temp = temp;
564            Data.iFcode = current->fcode;
565    
566          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
567    
568          for (y = 0; y < pParam->mb_height; y++) {          for (y = 0; y < pParam->mb_height; y++) {
# Line 559  Line 590 
590    
591                          SearchP(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
592                                                  y, current->motion_flags, pMB->quant,                                                  y, current->motion_flags, pMB->quant,
593                                                  current->fcode, pParam, pMBs, reference->mbs,                                                  &Data, pParam, pMBs, reference->mbs,
594                                                  current->global_flags & XVID_INTER4V, pMB);                                                  current->global_flags & XVID_INTER4V, pMB);
595    
596  /* 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?" */
# Line 584  Line 615 
615                                  if (deviation < (pMB->sad16 - InterBias)) {                                  if (deviation < (pMB->sad16 - InterBias)) {
616                                          if (++iIntra >= iLimit) return 1;                                          if (++iIntra >= iLimit) return 1;
617                                          pMB->mode = MODE_INTRA;                                          pMB->mode = MODE_INTRA;
618                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =                                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =
619                                                  pMB->mvs[3] = zeroMV;                                                  pMB->mvs[3] = zeroMV;
620                                          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] =                                          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] =
621                                                  pMB->sad8[3] = 0;                                                  pMB->sad8[3] = 0;
# Line 601  Line 632 
632  static __inline int  static __inline int
633  make_mask(const VECTOR * const pmv, const int i)  make_mask(const VECTOR * const pmv, const int i)
634  {  {
635          int mask = 0xFF, j;          int mask = 255, j;
636          for (j = 0; j < i; j++) {          for (j = 0; j < i; j++) {
637                  if (MVequal(pmv[i], pmv[j])) return 0; // same vector has been checked already                  if (MVequal(pmv[i], pmv[j])) return 0; // same vector has been checked already
638                  if (pmv[i].x == pmv[j].x) {                  if (pmv[i].x == pmv[j].x) {
# Line 625  Line 656 
656    
657          if ( (y != 0) && (x != (iWcount-1)) ) {         // [5] top-right neighbour          if ( (y != 0) && (x != (iWcount-1)) ) {         // [5] top-right neighbour
658                  pmv[5].x = EVEN(pmv[3].x);                  pmv[5].x = EVEN(pmv[3].x);
659                  pmv[5].y = EVEN(pmv[3].y); }                  pmv[5].y = EVEN(pmv[3].y);
660          else pmv[5].x = pmv[5].y = 0;          } else pmv[5].x = pmv[5].y = 0;
661    
662          if (x != 0) { pmv[3].x = EVEN(pmv[1].x); pmv[3].y = EVEN(pmv[1].y); }// pmv[3] is left neighbour          if (x != 0) { pmv[3].x = EVEN(pmv[1].x); pmv[3].y = EVEN(pmv[1].y); }// pmv[3] is left neighbour
663          else pmv[3].x = pmv[3].y = 0;          else pmv[3].x = pmv[3].y = 0;
# Line 644  Line 675 
675    
676          if ((x != iWcount-1) && (y != iHcount-1)) {          if ((x != iWcount-1) && (y != iHcount-1)) {
677                  pmv[6].x = EVEN((prevMB+1+iWcount)->mvs[0].x); //[6] right-down neighbour in last frame                  pmv[6].x = EVEN((prevMB+1+iWcount)->mvs[0].x); //[6] right-down neighbour in last frame
678                  pmv[6].y = EVEN((prevMB+1+iWcount)->mvs[0].y); }                  pmv[6].y = EVEN((prevMB+1+iWcount)->mvs[0].y);
679          else pmv[6].x = pmv[6].y = 0;          } else pmv[6].x = pmv[6].y = 0;
680  }  }
681    
682  static void  static void
# Line 658  Line 689 
689                  const int y,                  const int y,
690                  const uint32_t MotionFlags,                  const uint32_t MotionFlags,
691                  const uint32_t iQuant,                  const uint32_t iQuant,
692                  const uint32_t iFcode,                  SearchData * const Data,
693                  const MBParam * const pParam,                  const MBParam * const pParam,
694                  const MACROBLOCK * const pMBs,                  const MACROBLOCK * const pMBs,
695                  const MACROBLOCK * const prevMBs,                  const MACROBLOCK * const prevMBs,
# Line 666  Line 697 
697                  MACROBLOCK * const pMB)                  MACROBLOCK * const pMB)
698  {  {
699    
         const int32_t iEdgedWidth = pParam->edged_width;  
   
700          int i, iDirection = 255, mask, threshA;          int i, iDirection = 255, mask, threshA;
701          int32_t temp[5];          VECTOR pmv[7];
         VECTOR currentMV[5], pmv[7];  
         int32_t psad[4], iMinSAD[5];  
         MainSearchFunc * MainSearchPtr;  
         SearchData Data;  
702    
703          get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, 0, pmv, psad);  //has to be changed to get_pmv(2)()          get_pmvdata2(pMBs, pParam->mb_width, 0, x, y, 0, pmv, Data->temp);  //has to be changed to get_pmv(2)()
704          get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 16,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
705                                  pParam->width, pParam->height, iFcode);                                  pParam->width, pParam->height, Data->iFcode);
706    
707            Data->predMV = pmv[0];
708            Data->Cur = pCur->y + (x + y * Data->iEdgedWidth) * 16;
709            Data->Ref = pRef + (x + Data->iEdgedWidth*y)*16;
710            Data->RefH = pRefH + (x + Data->iEdgedWidth*y) * 16;
711            Data->RefV = pRefV + (x + Data->iEdgedWidth*y) * 16;
712            Data->RefHV = pRefHV + (x + Data->iEdgedWidth*y) * 16;
713    
714          Data.predMV = pmv[0];          Data->iQuant = iQuant;
         Data.Cur = pCur->y + (x + y * iEdgedWidth) * 16;  
         Data.iEdgedWidth = iEdgedWidth;  
         Data.currentMV = currentMV;  
         Data.iMinSAD = iMinSAD;  
         Data.Ref = pRef + (x + iEdgedWidth*y)*16;  
         Data.RefH = pRefH + (x + iEdgedWidth*y) * 16;  
         Data.RefV = pRefV + (x + iEdgedWidth*y) * 16;  
         Data.RefHV = pRefHV + (x + iEdgedWidth*y) * 16;  
         Data.temp = temp;  
   
         Data.iQuant = iQuant;  
         Data.iFcode = iFcode;  
715    
716          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
717                  Data.min_dx = EVEN(Data.min_dx);                  Data->min_dx = EVEN(Data->min_dx);
718                  Data.max_dx = EVEN(Data.max_dx);                  Data->max_dx = EVEN(Data->max_dx);
719                  Data.min_dy = EVEN(Data.min_dy);                  Data->min_dy = EVEN(Data->min_dy);
720                  Data.max_dy = EVEN(Data.max_dy); }                  Data->max_dy = EVEN(Data->max_dy); }
721    
722            for(i = 0;  i < 5; i++) Data->iMinSAD[i] = 256*4096;
723    
724            if (inter4v) CheckCandidate = CheckCandidate16;
725            else CheckCandidate = CheckCandidate16no4v;
726    
727          for(i = 0;  i < 5; i++) currentMV[i].x = currentMV[i].y = 0;          (*CheckCandidate)(Data->predMV.x, Data->predMV.y, 0, &iDirection, Data);
728    
729          i = d_mv_bits(pmv[0].x, pmv[0].y, iFcode);          for(i = 0;  i < 5; i++) Data->currentMV[i].x = Data->currentMV[i].y = 0;
730    
731          iMinSAD[0] = pMB->sad16 + lambda_vec16[iQuant] * i;          i = d_mv_bits(Data->predMV.x, Data->predMV.y, Data->iFcode);
732          iMinSAD[1] = pMB->sad8[0] + lambda_vec8[iQuant] * i;          Data->iMinSAD[0] = pMB->sad16 + lambda_vec16[iQuant] * i;
733          iMinSAD[2] = pMB->sad8[1];          Data->iMinSAD[1] = pMB->sad8[0] + lambda_vec8[iQuant] * i;
734          iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[2] = pMB->sad8[1];
735          iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[3] = pMB->sad8[2];
736            Data->iMinSAD[4] = pMB->sad8[3];
737    
738          if (pMB->dquant != NO_CHANGE) inter4v = 0;          if (pMB->dquant != NO_CHANGE) inter4v = 0;
739    
740          if ((x == 0) && (y == 0)) threshA = 512;          if ((x == 0) && (y == 0)) threshA = 512;
741          else {          else {
742                  threshA = psad[0] + 20;                  threshA = Data->temp[0] + 20;
743                  if (threshA < 512) threshA = 512;                  if (threshA < 512) threshA = 512;
744                  if (threshA > 1024) threshA = 1024; }                  if (threshA > 1024) threshA = 1024; }
745    
746          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,
747                                          prevMBs + x + y * pParam->mb_width);                                          prevMBs + x + y * pParam->mb_width);
748    
         if (inter4v) CheckCandidate = CheckCandidate16;  
         else CheckCandidate = CheckCandidate16no4v;  
   
749  /* main loop. checking all predictions */  /* main loop. checking all predictions */
750    
751          for (i = 1; i < 7; i++) {          for (i = 1; i < 7; i++) {
752                  if (!(mask = make_mask(pmv, i)) ) continue;                  if (!(mask = make_mask(pmv, i)) ) continue;
753                  CheckCandidate16(pmv[i].x, pmv[i].y, mask, &iDirection, &Data);                  CheckCandidate16(pmv[i].x, pmv[i].y, mask, &iDirection, Data);
754                  if (iMinSAD[0] < threshA) break;                  if (Data->iMinSAD[0] <= threshA) break;
755          }          }
756    
757          if ((iMinSAD[0] <= threshA) ||          if ((Data->iMinSAD[0] <= threshA) ||
758                          (MVequal(currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&                          (MVequal(Data->currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&
759                          (iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16))) {                          (Data->iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16))) {
760                  inter4v = 0;                  inter4v = 0;
761                  if (MotionFlags & PMV_QUICKSTOP16) goto PMVfast16_Terminate_without_Refine;          } else {
                 if (MotionFlags & PMV_EARLYSTOP16) {  
                         CheckCandidate = CheckCandidate16no4v; // I sure hope it's faster  
                         goto PMVfast16_Terminate_with_Refine;  
                 }  
         }  
762    
763          if (MotionFlags & PMV_USESQUARES16)                  MainSearchFunc * MainSearchPtr;
764                  MainSearchPtr = SquareSearch;                  if (MotionFlags & PMV_USESQUARES16) MainSearchPtr = SquareSearch;
765          else if (MotionFlags & PMV_ADVANCEDDIAMOND16)                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
                 MainSearchPtr = AdvDiamondSearch;  
766                  else MainSearchPtr = DiamondSearch;                  else MainSearchPtr = DiamondSearch;
767    
768          (*MainSearchPtr)(currentMV->x, currentMV->y, &Data, iDirection);                  (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, iDirection);
769    
770  /* extended search, diamond starting in 0,0 and in prediction.  /* extended search, diamond starting in 0,0 and in prediction.
771          note that this search is/might be done in halfpel positions,          note that this search is/might be done in halfpel positions,
# Line 756  Line 773 
773    
774          if (MotionFlags & PMV_EXTSEARCH16) {          if (MotionFlags & PMV_EXTSEARCH16) {
775                  int32_t bSAD;                  int32_t bSAD;
776                  VECTOR startMV = Data.predMV, backupMV = currentMV[0];                          VECTOR startMV = Data->predMV, backupMV = Data->currentMV[0];
777                  if (!(MotionFlags & PMV_HALFPELREFINE16)) // who's gonna use extsearch and no halfpel?                  if (!(MotionFlags & PMV_HALFPELREFINE16)) // who's gonna use extsearch and no halfpel?
778                          startMV.x = EVEN(startMV.x); startMV.y = EVEN(startMV.y);                          startMV.x = EVEN(startMV.x); startMV.y = EVEN(startMV.y);
779                  if (!(MVequal(startMV, backupMV))) {                  if (!(MVequal(startMV, backupMV))) {
780                          bSAD = iMinSAD[0]; iMinSAD[0] = MV_MAX_ERROR;                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;
781    
782                          CheckCandidate16(startMV.x, startMV.y, 255, &iDirection, &Data);                                  CheckCandidate16(startMV.x, startMV.y, 255, &iDirection, Data);
783                          (*MainSearchPtr)(startMV.x, startMV.y, &Data, 255);                                  (*MainSearchPtr)(startMV.x, startMV.y, Data, 255);
784                          if (bSAD < iMinSAD[0]) {                                  if (bSAD < Data->iMinSAD[0]) {
785                                  currentMV[0] = backupMV;                                          Data->currentMV[0] = backupMV;
786                                  iMinSAD[0] = bSAD; }                                          Data->iMinSAD[0] = bSAD; }
787                  }                  }
788    
789                  backupMV = currentMV[0];                          backupMV = Data->currentMV[0];
790                  if (MotionFlags & PMV_HALFPELREFINE16) startMV.x = startMV.y = 1;                  if (MotionFlags & PMV_HALFPELREFINE16) startMV.x = startMV.y = 1;
791                  else startMV.x = startMV.y = 0;                  else startMV.x = startMV.y = 0;
792                  if (!(MVequal(startMV, backupMV))) {                  if (!(MVequal(startMV, backupMV))) {
793                          bSAD = iMinSAD[0]; iMinSAD[0] = MV_MAX_ERROR;                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;
794    
795                          CheckCandidate16(startMV.x, startMV.y, 255, &iDirection, &Data);                                  CheckCandidate16(startMV.x, startMV.y, 255, &iDirection, Data);
796                          (*MainSearchPtr)(startMV.x, startMV.y, &Data, 255);                                  (*MainSearchPtr)(startMV.x, startMV.y, Data, 255);
797                          if (bSAD < iMinSAD[0]) {                                  if (bSAD < Data->iMinSAD[0]) {
798                                  currentMV[0] = backupMV;                                          Data->currentMV[0] = backupMV;
799                                  iMinSAD[0] = bSAD; }                                          Data->iMinSAD[0] = bSAD; }
800                            }
801                  }                  }
802          }          }
803    
804  PMVfast16_Terminate_with_Refine:          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(Data);
   
         if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(&Data);  
   
 PMVfast16_Terminate_without_Refine:  
805    
806          if (inter4v)          if (inter4v) {
807                  for(i = 0; i < 4; i++)                  SearchData Data8;
808                          Search8(&Data, 2*x+(i&1), 2*y+(i>>1), MotionFlags, pParam, pMB, pMBs, i);                  Data8.iFcode = Data->iFcode;
809                    Data8.iQuant = Data->iQuant;
810                    Data8.iEdgedWidth = Data->iEdgedWidth;
811                    Search8(Data, 2*x, 2*y, MotionFlags, pParam, pMB, pMBs, 0, &Data8);
812                    Search8(Data, 2*x + 1, 2*y, MotionFlags, pParam, pMB, pMBs, 1, &Data8);
813                    Search8(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8);
814                    Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8);
815            }
816    
817          if (!(inter4v) ||          if (!(inter4v) ||
818                  (iMinSAD[0] < iMinSAD[1] + iMinSAD[2] + iMinSAD[3] + iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) {                  (Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +
819                            Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) {
820  // INTER MODE  // INTER MODE
821                  pMB->mode = MODE_INTER;                  pMB->mode = MODE_INTER;
822                  pMB->mv16 = pMB->mvs[0] = pMB->mvs[1]                  pMB->mvs[0] = pMB->mvs[1]
823                          = pMB->mvs[2] = pMB->mvs[3] = currentMV[0];                          = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];
824    
825                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =
826                          pMB->sad8[2] = pMB->sad8[3] =  iMinSAD[0];                          pMB->sad8[2] = pMB->sad8[3] =  Data->iMinSAD[0];
827    
828                  pMB->pmvs[0].x = currentMV[0].x - Data.predMV.x;                  pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;
829                  pMB->pmvs[0].y = currentMV[0].y - Data.predMV.y;                  pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;
830          } else {          } else {
831  // INTER4V MODE; all other things are already set in Search8  // INTER4V MODE; all other things are already set in Search8
832                  pMB->mode = MODE_INTER4V;                  pMB->mode = MODE_INTER4V;
833                  pMB->sad16 = iMinSAD[1] + iMinSAD[2] + iMinSAD[3] + iMinSAD[4] + IMV16X16 * iQuant;                  pMB->sad16 = Data->iMinSAD[1] + Data->iMinSAD[2] +
834                            Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * iQuant;
835          }          }
836    
837  }  }
# Line 820  Line 843 
843                  const MBParam * const pParam,                  const MBParam * const pParam,
844                  MACROBLOCK * const pMB,                  MACROBLOCK * const pMB,
845                  const MACROBLOCK * const pMBs,                  const MACROBLOCK * const pMBs,
846                  const int block)                  const int block,
847                    SearchData * const Data)
848  {  {
849          SearchData Data;          Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2 , y/2, block);
850            Data->iMinSAD = OldData->iMinSAD + 1 + block;
851          Data.predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2 , y/2, block);          Data->currentMV = OldData->currentMV + 1 + block;
         Data.iMinSAD = OldData->iMinSAD + 1 + block;  
         Data.currentMV = OldData->currentMV+1+block;  
         Data.iFcode = OldData->iFcode;  
         Data.iQuant = OldData->iQuant;  
852    
853          if (block != 0)          if (block != 0)
854                  *(Data.iMinSAD) += lambda_vec8[Data.iQuant] *                  *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *
855                                                                  d_mv_bits(      Data.currentMV->x - Data.predMV.x,                                                                  d_mv_bits(      Data->currentMV->x - Data->predMV.x,
856                                                                                          Data.currentMV->y - Data.predMV.y,                                                                                          Data->currentMV->y - Data->predMV.y,
857                                                                                          Data.iFcode);                                                                                          Data->iFcode);
   
858    
859          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8)) {          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8)) {
860    
861                  Data.Ref = OldData->Ref + 8 * ((block&1) + pParam->edged_width*(block>>1));                  Data->Ref = OldData->Ref + 8 * ((block&1) + pParam->edged_width*(block>>1));
862                  Data.RefH = OldData->RefH + 8 * ((block&1) + pParam->edged_width*(block>>1));                  Data->RefH = OldData->RefH + 8 * ((block&1) + pParam->edged_width*(block>>1));
863                  Data.RefV = OldData->RefV + 8 * ((block&1) + pParam->edged_width*(block>>1));                  Data->RefV = OldData->RefV + 8 * ((block&1) + pParam->edged_width*(block>>1));
864                  Data.RefHV = OldData->RefHV + 8 * ((block&1) + pParam->edged_width*(block>>1));                  Data->RefHV = OldData->RefHV + 8 * ((block&1) + pParam->edged_width*(block>>1));
865    
866                  Data.iEdgedWidth = pParam->edged_width;                  Data->Cur = OldData->Cur + 8 * ((block&1) + pParam->edged_width*(block>>1));
   
                 Data.Cur = OldData->Cur + 8 * ((block&1) + pParam->edged_width*(block>>1));  
867    
868                  get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 8,                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8,
869                                  pParam->width, pParam->height, OldData->iFcode);                                  pParam->width, pParam->height, OldData->iFcode);
870    
871                  CheckCandidate = CheckCandidate8;                  CheckCandidate = CheckCandidate8;
# Line 860  Line 877 
877                                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;                                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;
878                                          else MainSearchPtr = DiamondSearch;                                          else MainSearchPtr = DiamondSearch;
879    
880                          (*MainSearchPtr)(Data.currentMV->x, Data.currentMV->y, &Data, 255);     }                          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255);    }
881    
882                  if (MotionFlags & PMV_HALFPELREFINE8) HalfpelRefine(&Data);                  if (MotionFlags & PMV_HALFPELREFINE8) HalfpelRefine(Data);
883          }          }
884    
885          pMB->pmvs[block].x = Data.currentMV->x - Data.predMV.x;          pMB->pmvs[block].x = Data->currentMV->x - Data->predMV.x;
886          pMB->pmvs[block].y = Data.currentMV->y - Data.predMV.y;          pMB->pmvs[block].y = Data->currentMV->y - Data->predMV.y;
887          pMB->mvs[block] = *(Data.currentMV);          pMB->mvs[block] = *(Data->currentMV);
888          pMB->sad8[block] =  4 * (*(Data.iMinSAD));          pMB->sad8[block] =  4 * (*Data->iMinSAD);
889    
890  }  }
891    
892  /* B-frames code starts here */  /* B-frames code starts here */
# Line 896  Line 914 
914          pmv[2] = ChoosePred(pMB, mode_curr);          pmv[2] = ChoosePred(pMB, mode_curr);
915          pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y);          pmv[2].x = EVEN(pmv[2].x); pmv[2].y = EVEN(pmv[2].y);
916    
         pmv[3].x = pmv[3].y = 0;  
917          if ((y != 0)&&(x != (int)(iWcount+1))) {                        // [3] top-right neighbour          if ((y != 0)&&(x != (int)(iWcount+1))) {                        // [3] top-right neighbour
918                  pmv[3] = ChoosePred(pMB+1-iWcount, mode_curr);                  pmv[3] = ChoosePred(pMB+1-iWcount, mode_curr);
919                  pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y); }                  pmv[3].x = EVEN(pmv[3].x); pmv[3].y = EVEN(pmv[3].y);
920            } else pmv[3].x = pmv[3].y = 0;
921    
922          if (y != 0) {          if (y != 0) {
923                  pmv[4] = ChoosePred(pMB-iWcount, mode_curr);                  pmv[4] = ChoosePred(pMB-iWcount, mode_curr);
# Line 1012  Line 1030 
1030  }  }
1031    
1032  static int32_t  static int32_t
1033  SearchDirect(const uint8_t * const f_Ref,  SearchDirect(const IMAGE * const f_Ref,
1034                                  const uint8_t * const f_RefH,                                  const uint8_t * const f_RefH,
1035                                  const uint8_t * const f_RefV,                                  const uint8_t * const f_RefV,
1036                                  const uint8_t * const f_RefHV,                                  const uint8_t * const f_RefHV,
1037                                  const uint8_t * const b_Ref,                                  const IMAGE * const b_Ref,
1038                                  const uint8_t * const b_RefH,                                  const uint8_t * const b_RefH,
1039                                  const uint8_t * const b_RefV,                                  const uint8_t * const b_RefV,
1040                                  const uint8_t * const b_RefHV,                                  const uint8_t * const b_RefHV,
# Line 1032  Line 1050 
1050    
1051  {  {
1052          const uint32_t iEdgedWidth = pParam->edged_width;          const uint32_t iEdgedWidth = pParam->edged_width;
1053          int32_t iMinSAD = 0, skip_sad;          int32_t iMinSAD = 266*4096, skip_sad;
1054          int k;          int k;
1055          VECTOR currentMV;          VECTOR currentMV;
1056          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
# Line 1045  Line 1063 
1063          Data.iQuant = iQuant;          Data.iQuant = iQuant;
1064          Data.referencemv = b_mb->mvs;          Data.referencemv = b_mb->mvs;
1065    
1066          Data.Ref= f_Ref + (x + iEdgedWidth*y) * 16;          Data.Ref= f_Ref->y + (x + iEdgedWidth*y) * 16;
1067          Data.RefH = f_RefH + (x + iEdgedWidth*y) * 16;          Data.RefH = f_RefH + (x + iEdgedWidth*y) * 16;
1068          Data.RefV = f_RefV + (x + iEdgedWidth*y) * 16;          Data.RefV = f_RefV + (x + iEdgedWidth*y) * 16;
1069          Data.RefHV = f_RefHV + (x + iEdgedWidth*y) * 16;          Data.RefHV = f_RefHV + (x + iEdgedWidth*y) * 16;
1070          Data.bRef = b_Ref + (x + iEdgedWidth*y) * 16;          Data.bRef = b_Ref->y + (x + iEdgedWidth*y) * 16;
1071          Data.bRefH = b_RefH + (x + iEdgedWidth*y) * 16;          Data.bRefH = b_RefH + (x + iEdgedWidth*y) * 16;
1072          Data.bRefV = b_RefV + (x + iEdgedWidth*y) * 16;          Data.bRefV = b_RefV + (x + iEdgedWidth*y) * 16;
1073          Data.bRefHV = b_RefHV + (x + iEdgedWidth*y) * 16;          Data.bRefHV = b_RefHV + (x + iEdgedWidth*y) * 16;
# Line 1073  Line 1091 
1091                          || ( pMB->mvs[k].y > Data.max_dy ) || ( pMB->mvs[k].y < Data.min_dy )                          || ( pMB->mvs[k].y > Data.max_dy ) || ( pMB->mvs[k].y < Data.min_dy )
1092                          || ( pMB->b_mvs[k].x > Data.max_dx ) || ( pMB->b_mvs[k].x < Data.min_dx )                          || ( pMB->b_mvs[k].x > Data.max_dx ) || ( pMB->b_mvs[k].x < Data.min_dx )
1093                          || ( pMB->b_mvs[k].y > Data.max_dy ) || ( pMB->b_mvs[k].y < Data.min_dy )) {                          || ( pMB->b_mvs[k].y > Data.max_dy ) || ( pMB->b_mvs[k].y < Data.min_dy )) {
1094  /*  
                 fprintf(debug, "\nERROR - out of range : vector %d,%d and %d,%d\n", pMB->mvs[k].x, pMB->mvs[k].y,pMB->b_mvs[k].x,pMB->b_mvs[k].y );  
                 fprintf(debug, " range is x: %d..%d y: %d..%d \n", Data.min_dx,Data.max_dx,Data.min_dy,Data.max_dy);  
                 fprintf(debug,"macroblock %d, %d \n", x, y);  
                 fprintf(debug, "direct MV is %d,%d \n", directmv[k].x, directmv[k].y);  
 */  
1095                  *best_sad = 256*4096; // in that case, we won't use direct mode                  *best_sad = 256*4096; // in that case, we won't use direct mode
1096                  pMB->mode = MODE_DIRECT; // just to make sure it doesn't say "MODE_DIRECT_NONE_MV"                  pMB->mode = MODE_DIRECT; // just to make sure it doesn't say "MODE_DIRECT_NONE_MV"
1097                  pMB->b_mvs[0].x = pMB->b_mvs[0].y = 0;  /* because backwards and interpol might rely on this */                          pMB->b_mvs[0].x = pMB->b_mvs[0].y = 0;
1098                  return 0; }                          return 0;
1099                    }
   
1100          if (b_mb->mode != MODE_INTER4V) {          if (b_mb->mode != MODE_INTER4V) {
1101                  iMinSAD = sad16bi(Data.Cur,                          pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mvs[0];
1102                                                  get_ref_mv(f_Ref, f_RefH, f_RefV, f_RefHV,                          pMB->b_mvs[1] = pMB->b_mvs[2] = pMB->b_mvs[3] = pMB->b_mvs[0];
                                                                 x, y, 16, &pMB->mvs[0], iEdgedWidth),  
                                                 get_ref_mv(b_Ref, b_RefH, b_RefV, b_RefHV,  
                                                                 x, y, 16, &pMB->b_mvs[0], iEdgedWidth), iEdgedWidth);  
   
1103                  Data.directmvF[1] = Data.directmvF[2] = Data.directmvF[3] = Data.directmvF[0];                  Data.directmvF[1] = Data.directmvF[2] = Data.directmvF[3] = Data.directmvF[0];
1104                  Data.directmvB[1] = Data.directmvB[2] = Data.directmvB[3] = Data.directmvB[0];                  Data.directmvB[1] = Data.directmvB[2] = Data.directmvB[3] = Data.directmvB[0];
1105                  break;                  break;
1106          }          }
         iMinSAD += sad8bi(Data.Cur + (k&1)*8 + (k>>1)* 8 * iEdgedWidth,  
                                                 get_ref_mv(f_Ref, f_RefH, f_RefV, f_RefHV,  
                                                                 (2*x+(k&1)), (2*y+(k>>1)), 8, &pMB->mvs[k], iEdgedWidth),  
                                                 get_ref_mv(b_Ref, b_RefH, b_RefV, b_RefHV,  
                                                                 (2*x+(k&1)), (2*y+(k>>1)), 8, &pMB->b_mvs[k], iEdgedWidth),  
                                                 iEdgedWidth);  
1107          }          }
1108    
1109            if (b_mb->mode == MODE_INTER4V)
1110                    CheckCandidate = CheckCandidateDirect;
1111            else CheckCandidate = CheckCandidateDirectno4v;
1112    
1113            (*CheckCandidate)(0, 0, 255, &k, &Data);
1114    
1115  // skip decision  // skip decision
1116          if (iMinSAD < (int32_t)iQuant * SKIP_THRESH_B) {          if (iMinSAD - 2 * lambda_vec16[iQuant] < (int32_t)iQuant * SKIP_THRESH_B) {
1117                    //checking chroma. everything copied from MC
1118                    //this is not full chroma compensation, only it's fullpel approximation. should work though
1119                    int sum, dx, dy, b_dx, b_dy;
1120    
1121                    sum = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1122                    dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
1123    
1124                    sum = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1125                    dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
1126    
1127                    sum = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;
1128                    b_dx = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
1129    
1130                    sum = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
1131                    b_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
1132    
1133                    sum = sad8bi(pCur->u + 8*x + 8*y*(iEdgedWidth/2),
1134                                            f_Ref->u + (y*8 + dy/2) * (iEdgedWidth/2) + x*8 + dx/2,
1135                                            b_Ref->u + (y*8 + b_dy/2) * (iEdgedWidth/2) + x*8 + b_dx/2,
1136                                            iEdgedWidth/2);
1137                    sum += sad8bi(pCur->v + 8*x + 8*y*(iEdgedWidth/2),
1138                                            f_Ref->v + (y*8 + dy/2) * (iEdgedWidth/2) + x*8 + dx/2,
1139                                            b_Ref->v + (y*8 + b_dy/2) * (iEdgedWidth/2) + x*8 + b_dx/2,
1140                                            iEdgedWidth/2);
1141    
1142                    if ((uint32_t) sum < MAX_CHROMA_SAD_FOR_SKIP * Data.iQuant) {
1143                  pMB->mode = MODE_DIRECT_NONE_MV;                  pMB->mode = MODE_DIRECT_NONE_MV;
1144                  return iMinSAD; }                          return iMinSAD;
1145                    }
1146            }
1147    
1148          skip_sad = iMinSAD;          skip_sad = iMinSAD;
         iMinSAD += 2 * lambda_vec16[iQuant]; // 2 bits needed to code vector 0,0  
         currentMV.x = currentMV.y = 0;  
         if (b_mb->mode == MODE_INTER4V)  
                 CheckCandidate = CheckCandidateDirect;  
         else CheckCandidate = CheckCandidateDirectno4v;  
1149    
1150  //  DIRECT MODE DELTA VECTOR SEARCH.  //  DIRECT MODE DELTA VECTOR SEARCH.
1151  //      This has to be made more effective, but at the moment I'm happy it's running at all  //      This has to be made more effective, but at the moment I'm happy it's running at all
# Line 1188  Line 1219 
1219          VECTOR currentMV[3];          VECTOR currentMV[3];
1220          SearchData fData, bData;          SearchData fData, bData;
1221    
   
1222          fData.iMinSAD = bData.iMinSAD = &iMinSAD;          fData.iMinSAD = bData.iMinSAD = &iMinSAD;
1223    
1224          fData.Cur = bData.Cur = pCur->y + (x + y * iEdgedWidth) * 16;          fData.Cur = bData.Cur = pCur->y + (x + y * iEdgedWidth) * 16;
# Line 1197  Line 1227 
1227          fData.iQuant = bData.iQuant = iQuant;          fData.iQuant = bData.iQuant = iQuant;
1228          fData.iFcode = bData.bFcode = fcode; fData.bFcode = bData.iFcode = bcode;          fData.iFcode = bData.bFcode = fcode; fData.bFcode = bData.iFcode = bcode;
1229    
   
1230          bData.bRef = fData.Ref = f_Ref + (x + y * iEdgedWidth) * 16;          bData.bRef = fData.Ref = f_Ref + (x + y * iEdgedWidth) * 16;
1231          bData.bRefH = fData.RefH = f_RefH + (x + y * iEdgedWidth) * 16;          bData.bRefH = fData.RefH = f_RefH + (x + y * iEdgedWidth) * 16;
1232          bData.bRefV = fData.RefV = f_RefV + (x + y * iEdgedWidth) * 16;          bData.bRefV = fData.RefV = f_RefV + (x + y * iEdgedWidth) * 16;
# Line 1210  Line 1239 
1239          bData.bpredMV = fData.predMV = *f_predMV;          bData.bpredMV = fData.predMV = *f_predMV;
1240          fData.bpredMV = bData.predMV = *b_predMV;          fData.bpredMV = bData.predMV = *b_predMV;
1241    
   
1242          currentMV[0] = pMB->mvs[0];          currentMV[0] = pMB->mvs[0];
1243          currentMV[1] = pMB->b_mvs[0];          currentMV[1] = pMB->b_mvs[0];
1244          get_range(&fData.min_dx, &fData.max_dx, &fData.min_dy, &fData.max_dy, x, y, 16, pParam->width, pParam->height, fcode);          get_range(&fData.min_dx, &fData.max_dx, &fData.min_dy, &fData.max_dy, x, y, 16, pParam->width, pParam->height, fcode);
1245          get_range(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode);          get_range(&bData.min_dx, &bData.max_dx, &bData.min_dy, &bData.max_dy, x, y, 16, pParam->width, pParam->height, bcode);
1246    
1247            if (currentMV[0].x > fData.max_dx) currentMV[0].x = fData.max_dx;
1248            if (currentMV[0].x < fData.min_dx) currentMV[0].x = fData.min_dy;
1249            if (currentMV[0].y > fData.max_dy) currentMV[0].y = fData.max_dx;
1250            if (currentMV[0].y > fData.min_dy) currentMV[0].y = fData.min_dy;
1251    
1252            if (currentMV[1].x > bData.max_dx) currentMV[1].x = bData.max_dx;
1253            if (currentMV[1].x < bData.min_dx) currentMV[1].x = bData.min_dy;
1254            if (currentMV[1].y > bData.max_dy) currentMV[1].y = bData.max_dx;
1255            if (currentMV[1].y > bData.min_dy) currentMV[1].y = bData.min_dy;
1256    
1257          CheckCandidateInt(currentMV[0].x, currentMV[0].y, 255, &iDirection, &fData);          CheckCandidateInt(currentMV[0].x, currentMV[0].y, 255, &iDirection, &fData);
1258    
1259  //diamond. I wish we could use normal mainsearch functions (square, advdiamond)  //diamond. I wish we could use normal mainsearch functions (square, advdiamond)
# Line 1225  Line 1263 
1263                  // forward MV moves                  // forward MV moves
1264                  i = currentMV[0].x; j = currentMV[0].y;                  i = currentMV[0].x; j = currentMV[0].y;
1265    
1266                  CheckCandidateInt(i + 2, j, 0, &iDirection, &fData);                  CheckCandidateInt(i + 1, j, 0, &iDirection, &fData);
1267                  CheckCandidateInt(i, j + 2, 0, &iDirection, &fData);                  CheckCandidateInt(i, j + 1, 0, &iDirection, &fData);
1268                  CheckCandidateInt(i - 2, j, 0, &iDirection, &fData);                  CheckCandidateInt(i - 1, j, 0, &iDirection, &fData);
1269                  CheckCandidateInt(i, j - 2, 0, &iDirection, &fData);                  CheckCandidateInt(i, j - 1, 0, &iDirection, &fData);
1270    
1271                  // backward MV moves                  // backward MV moves
1272                  i = currentMV[1].x; j = currentMV[1].y;                  i = currentMV[1].x; j = currentMV[1].y;
1273                  currentMV[2] = currentMV[0];                  currentMV[2] = currentMV[0];
1274    
1275                  CheckCandidateInt(i + 2, j, 0, &iDirection, &bData);                  CheckCandidateInt(i + 1, j, 0, &iDirection, &bData);
1276                  CheckCandidateInt(i, j + 2, 0, &iDirection, &bData);                  CheckCandidateInt(i, j + 1, 0, &iDirection, &bData);
1277                  CheckCandidateInt(i - 2, j, 0, &iDirection, &bData);                  CheckCandidateInt(i - 1, j, 0, &iDirection, &bData);
1278                  CheckCandidateInt(i, j - 2, 0, &iDirection, &bData);                  CheckCandidateInt(i, j - 1, 0, &iDirection, &bData);
1279    
1280          } while (!(iDirection));          } while (!(iDirection));
1281    
 /* halfpel refinement. luckly we can use normal halfpel function for it */  
   
         if (MotionFlags & PMV_HALFPELREFINE16) {  
                 CheckCandidate = CheckCandidateInt;  
                 HalfpelRefine(&fData);  
                 currentMV[2] = currentMV[0];  
                 HalfpelRefine(&bData);  
         }  
   
1282  // two bits are needed to code interpolate mode. we treat the bits just like they were vector's  // two bits are needed to code interpolate mode. we treat the bits just like they were vector's
1283          iMinSAD +=  2 * lambda_vec16[iQuant];          iMinSAD +=  2 * lambda_vec16[iQuant];
1284          if (iMinSAD < *best_sad) {          if (iMinSAD < *best_sad) {
# Line 1312  Line 1341 
1341  /* direct search comes first, because it (1) checks for SKIP-mode  /* direct search comes first, because it (1) checks for SKIP-mode
1342          and (2) sets very good predictions for forward and backward search */          and (2) sets very good predictions for forward and backward search */
1343    
1344                          skip_sad = SearchDirect(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          skip_sad = SearchDirect(f_ref, f_refH->y, f_refV->y, f_refHV->y,
1345                                                                          b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                                          b_ref, b_refH->y, b_refV->y, b_refHV->y,
1346                                                                          &frame->image,                                                                          &frame->image,
1347                                                                          i, j,                                                                          i, j,
1348                                                                          frame->motion_flags,                                                                          frame->motion_flags,
# Line 1323  Line 1352 
1352                                                                          pMB, b_mb,                                                                          pMB, b_mb,
1353                                                                          &best_sad);                                                                          &best_sad);
1354    
                         if (!(frame->global_flags & XVID_HALFPEL)) best_sad = skip_sad = 256*4096;  
                         else  
1355                                  if (pMB->mode == MODE_DIRECT_NONE_MV) { n_count++; continue; }                                  if (pMB->mode == MODE_DIRECT_NONE_MV) { n_count++; continue; }
1356    
1357  //                      best_sad = 256*4096; //uncomment to disable Directsearch.  //                      best_sad = 256*4096; //uncomment to disable Directsearch.
# Line 1539  Line 1566 
1566  // INTER MODE  // INTER MODE
1567    
1568                  pMB->mode = MODE_INTER;                  pMB->mode = MODE_INTER;
1569                  pMB->mv16 = pMB->mvs[0] = pMB->mvs[1]                  pMB->mvs[0] = pMB->mvs[1]
1570                          = pMB->mvs[2] = pMB->mvs[3] = currentMV[0];                          = pMB->mvs[2] = pMB->mvs[3] = currentMV[0];
1571    
1572                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =
# Line 1573  Line 1600 
1600    
1601          for (y = 0; y < pParam->mb_height; y++) {          for (y = 0; y < pParam->mb_height; y++) {
1602                  for (x = 0; x < pParam->mb_width; x++)  {                  for (x = 0; x < pParam->mb_width; x++)  {
                         int32_t sad00;  
1603    
1604                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];
1605    
# Line 1584  Line 1610 
1610                                  pMB->dquant = NO_CHANGE;                                  pMB->dquant = NO_CHANGE;
1611                                  pMB->quant = current->quant; }                                  pMB->quant = current->quant; }
1612    
1613                          if (pMB->dquant == NO_CHANGE) //no skip otherwise, anyway                          SearchPhinted(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1614                                  sad00 = pMB->sad16                                                          y, current->motion_flags, pMB->quant,
1615                                          = sad16(pCurrent->y + (x + y * pParam->edged_width) * 16,                                                          current->fcode, pParam, pMBs,
1616                                                                  pRef->y + (x + y * pParam->edged_width) * 16,                                                          current->global_flags & XVID_INTER4V, pMB);
                                                                 pParam->edged_width, 256*4096 );  
                         else sad00 = 256*4096;  
1617    
1618                    }
1619            }
1620    }
1621    
1622  //initial skip decision  static __inline int
1623    MEanalyzeMB (   const uint8_t * const pRef,
1624                                    const uint8_t * const pCur,
1625                                    const int x,
1626                                    const int y,
1627                                    const uint32_t iFcode,
1628                                    const MBParam * const pParam,
1629                                    const MACROBLOCK * const pMBs,
1630                                    MACROBLOCK * const pMB)
1631    {
1632    
1633                          if ( (pMB->dquant == NO_CHANGE) && (sad00 <= MAX_SAD00_FOR_SKIP * pMB->quant)          const int32_t iEdgedWidth = pParam->edged_width;
1634                                  && ( //(pMB->mode == MODE_NOT_CODED) ||          int i, mask;
1635                                          (SkipDecisionP(pCurrent, pRef, x, y, pParam->edged_width, pMB->quant) )) ) {          VECTOR currentMV, pmv[3];
1636                                  if (sad00 < pMB->quant * INITIAL_SKIP_THRESH) {          int32_t iMinSAD = MV_MAX_ERROR;
1637                                          SkipMacroblockP(pMB, sad00);          SearchData Data;
1638                                          continue; } //skipped  
1639            Data.predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
1640            get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 16,
1641                                    pParam->width, pParam->height, iFcode);
1642    
1643            Data.Cur = pCur + (x + y * iEdgedWidth) * 16;
1644            Data.iEdgedWidth = iEdgedWidth;
1645            Data.currentMV = &currentMV;
1646            Data.iMinSAD = &iMinSAD;
1647            Data.Ref = pRef + (x + iEdgedWidth*y)*16;
1648            Data.iQuant = 2;
1649            Data.iFcode = iFcode;
1650    
1651            CheckCandidate = CheckCandidate16no4vI;
1652    
1653            pmv[1].x = EVEN(pMB->mvs[0].x);
1654            pmv[1].y = EVEN(pMB->mvs[0].y);
1655            pmv[0].x = EVEN(Data.predMV.x);
1656            pmv[0].y = EVEN(Data.predMV.y);
1657            pmv[2].x = pmv[2].y = 0;
1658    
1659            CheckCandidate16no4vI(pmv[0].x, pmv[0].y, 255, &i, &Data);
1660            if (!(mask = make_mask(pmv, 1)))
1661                    CheckCandidate16no4vI(pmv[1].x, pmv[1].y, mask, &i, &Data);
1662            if (!(mask = make_mask(pmv, 2)))
1663                    CheckCandidate16no4vI(0, 0, mask, &i, &Data);
1664    
1665            DiamondSearch(currentMV.x, currentMV.y, &Data, i);
1666    
1667            pMB->mvs[0] = pMB->mvs[1]
1668                            = pMB->mvs[2] = pMB->mvs[3] = currentMV; // all, for future get_pmv()
1669    
1670            return iMinSAD;
1671                          }                          }
                         else sad00 = 256*4096;  
1672    
1673                          if (pMB->mode == MODE_NOT_CODED)  #define INTRA_THRESH    1350
1674                                  SearchP(        pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,  #define INTER_THRESH    900
                                                         y, current->motion_flags, pMB->quant,  
                                                         current->fcode, pParam, pMBs, reference->mbs,  
                                                         current->global_flags & XVID_INTER4V, pMB);  
1675    
1676                          else  int
1677                                  SearchPhinted(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,  MEanalysis(     const IMAGE * const pRef,
1678                                                          y, current->motion_flags, pMB->quant,                          const IMAGE * const pCurrent,
1679                                                          current->fcode, pParam, pMBs,                          MBParam * const pParam,
1680                                                          current->global_flags & XVID_INTER4V, pMB);                          MACROBLOCK * const pMBs,
1681                            const uint32_t iFcode)
1682    {
1683            uint32_t x, y, intra = 0;
1684            int sSAD = 0;
1685    
1686  /* final skip decision, a.k.a. "the vector you found, really that good?" */          if (sadInit) (*sadInit) ();
1687                          if (sad00 < pMB->quant * MAX_SAD00_FOR_SKIP)  
1688                                  if ((100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH)          for (y = 0; y < pParam->mb_height-1; y++) {
1689                                  SkipMacroblockP(pMB, sad00);                  for (x = 0; x < pParam->mb_width; x++) {
1690                            int sad, dev;
1691    
1692                            MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];
1693    
1694                            sad = MEanalyzeMB(pRef->y, pCurrent->y, x, y,
1695                                                                    iFcode, pParam, pMBs, pMB);
1696    
1697                            if ( x != 0 && y != 0 && x != pParam->mb_width-1 ) { //no edge macroblocks, they just don't work
1698                                    if (sad > INTRA_THRESH) {
1699                                            dev = dev16(pCurrent->y + (x + y * pParam->edged_width) * 16,
1700                                                                      pParam->edged_width);
1701                                            if (dev + INTRA_THRESH < sad) intra++;
1702                                            if (intra > (pParam->mb_height-2)*(pParam->mb_width-2)/2) return 2;  // I frame
1703                  }                  }
1704                                    sSAD += sad;
1705                            }
1706    
1707          }          }
1708  }  }
1709            sSAD /= (pParam->mb_height-2)*(pParam->mb_width-2);
1710            if (sSAD > INTER_THRESH ) return 1; //P frame
1711            emms();
1712            return 0; // B frame
1713    
1714    }

Legend:
Removed from v.530  
changed lines
  Added in v.539

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