[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 539, Wed Sep 25 21:28:48 2002 UTC revision 576, Thu Oct 3 08:26:19 2002 UTC
# Line 269  Line 269 
269          const uint8_t *ReferenceB;          const uint8_t *ReferenceB;
270          VECTOR mvs, b_mvs;          VECTOR mvs, b_mvs;
271    
272          if (( x > 31) || ( x < -31) || ( y > 31) || (y < -31)) return;          if (( x > 31) || ( x < -32) || ( y > 31) || (y < -32)) return;
273    
274                  sad = lambda_vec16[data->iQuant] * d_mv_bits(x, y, 1);                  sad = lambda_vec16[data->iQuant] * d_mv_bits(x, y, 1);
275    
# Line 517  Line 517 
517          uint32_t sadC = sad8(current->u + x*8 + y*(iEdgedWidth/2)*8,          uint32_t sadC = sad8(current->u + x*8 + y*(iEdgedWidth/2)*8,
518                                          reference->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2);                                          reference->u + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2);
519          if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;          if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;
520          sadC += sad8(current->v + x*8 + y*(iEdgedWidth/2)*8,          sadC += sad8(current->v + (x + y*(iEdgedWidth/2))*8,
521                                          reference->v + x*8 + y*(iEdgedWidth/2)*8, iEdgedWidth/2);                                          reference->v + (x + y*(iEdgedWidth/2))*8, iEdgedWidth/2);
522          if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;          if (sadC > iQuant * MAX_CHROMA_SAD_FOR_SKIP) return 0;
523    
524          return 1;          return 1;
# Line 550  Line 550 
550    
551          uint32_t x, y;          uint32_t x, y;
552          uint32_t iIntra = 0;          uint32_t iIntra = 0;
553          int32_t InterBias;          int32_t InterBias, quant = current->quant;
554    
555          // some pre-initialized thingies for SearchP          // some pre-initialized thingies for SearchP
556          int32_t temp[5];          int32_t temp[5];
# Line 577  Line 577 
577                          if (!(current->global_flags & XVID_LUMIMASKING)) {                          if (!(current->global_flags & XVID_LUMIMASKING)) {
578                                  pMB->dquant = NO_CHANGE;                                  pMB->dquant = NO_CHANGE;
579                                  pMB->quant = current->quant; }                                  pMB->quant = current->quant; }
580                            else
581                                    if (pMB->dquant != NO_CHANGE) {
582                                            quant += DQtab[pMB->dquant];
583                                            if (quant > 31) quant = 31;
584                                            else if (quant < 1) quant = 1;
585                                            pMB->quant = quant;
586                                    }
587    
588  //initial skip decision  //initial skip decision
589    
# Line 719  Line 726 
726                  Data->min_dy = EVEN(Data->min_dy);                  Data->min_dy = EVEN(Data->min_dy);
727                  Data->max_dy = EVEN(Data->max_dy); }                  Data->max_dy = EVEN(Data->max_dy); }
728    
729          for(i = 0;  i < 5; i++) Data->iMinSAD[i] = 256*4096;          if (pMB->dquant != NO_CHANGE) inter4v = 0;
730    
731          if (inter4v) CheckCandidate = CheckCandidate16;          if (inter4v) CheckCandidate = CheckCandidate16;
732          else CheckCandidate = CheckCandidate16no4v;          else CheckCandidate = CheckCandidate16no4v;
733    
         (*CheckCandidate)(Data->predMV.x, Data->predMV.y, 0, &iDirection, Data);  
   
734          for(i = 0;  i < 5; i++) Data->currentMV[i].x = Data->currentMV[i].y = 0;          for(i = 0;  i < 5; i++) Data->currentMV[i].x = Data->currentMV[i].y = 0;
735    
736          i = d_mv_bits(Data->predMV.x, Data->predMV.y, Data->iFcode);          i = d_mv_bits(Data->predMV.x, Data->predMV.y, Data->iFcode);
# Line 735  Line 740 
740          Data->iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[3] = pMB->sad8[2];
741          Data->iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[4] = pMB->sad8[3];
742    
         if (pMB->dquant != NO_CHANGE) inter4v = 0;  
   
743          if ((x == 0) && (y == 0)) threshA = 512;          if ((x == 0) && (y == 0)) threshA = 512;
744          else {          else {
745                  threshA = Data->temp[0] + 20;                  threshA = Data->temp[0]; // that's when we keep this SAD atm
746                  if (threshA < 512) threshA = 512;                  if (threshA < 512) threshA = 512;
747                  if (threshA > 1024) threshA = 1024; }                  if (threshA > 1024) threshA = 1024; }
748    
749          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,
750                                          prevMBs + x + y * pParam->mb_width);                                          prevMBs + x + y * pParam->mb_width);
751    
752            if (inter4v) CheckCandidate = CheckCandidate16;
753            else CheckCandidate = CheckCandidate16no4v;
754    
755    
756  /* main loop. checking all predictions */  /* main loop. checking all predictions */
757    
758          for (i = 1; i < 7; i++) {          for (i = 1; i < 7; i++) {
759                  if (!(mask = make_mask(pmv, i)) ) continue;                  if (!(mask = make_mask(pmv, i)) ) continue;
760                  CheckCandidate16(pmv[i].x, pmv[i].y, mask, &iDirection, Data);                  (*CheckCandidate)(pmv[i].x, pmv[i].y, mask, &iDirection, Data);
761                  if (Data->iMinSAD[0] <= threshA) break;                  if (Data->iMinSAD[0] <= threshA) break;
762          }          }
763    
# Line 947  Line 954 
954                          const IMAGE * const pCur,                          const IMAGE * const pCur,
955                          const int x, const int y,                          const int x, const int y,
956                          const uint32_t MotionFlags,                          const uint32_t MotionFlags,
                         const uint32_t iQuant,  
957                          const uint32_t iFcode,                          const uint32_t iFcode,
958                          const MBParam * const pParam,                          const MBParam * const pParam,
959                          MACROBLOCK * const pMB,                          MACROBLOCK * const pMB,
960                          const VECTOR * const predMV,                          const VECTOR * const predMV,
961                          int32_t * const best_sad,                          int32_t * const best_sad,
962                          const int32_t mode_current)                          const int32_t mode_current,
963                            SearchData * const Data)
964  {  {
965    
966          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
967    
968          int i, iDirection, mask;          int i, iDirection, mask;
969          VECTOR currentMV, pmv[7];          VECTOR pmv[7];
970          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
971          int32_t iMinSAD = MV_MAX_ERROR;          *Data->iMinSAD = MV_MAX_ERROR;
972          SearchData Data;          Data->iFcode = iFcode;
973    
974          Data.iMinSAD = &iMinSAD;          Data->Ref = pRef + (x + y * iEdgedWidth) * 16;
975          Data.Cur = pCur->y + (x + y * iEdgedWidth) * 16;          Data->RefH = pRefH + (x + y * iEdgedWidth) * 16;
976          Data.iEdgedWidth = iEdgedWidth;          Data->RefV = pRefV + (x + y * iEdgedWidth) * 16;
977          Data.currentMV = &currentMV;          Data->RefHV = pRefHV + (x + y * iEdgedWidth) * 16;
         Data.iMinSAD = &iMinSAD;  
         Data.Ref = pRef + (x + y * iEdgedWidth) * 16;  
         Data.RefH = pRefH + (x + y * iEdgedWidth) * 16;  
         Data.RefV = pRefV + (x + y * iEdgedWidth) * 16;  
         Data.RefHV = pRefHV + (x + y * iEdgedWidth) * 16;  
978    
979          Data.iQuant = iQuant;          Data->predMV = *predMV;
         Data.iFcode = iFcode;  
         Data.predMV = *predMV;  
980    
981          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,
982                                  pParam->width, pParam->height, iFcode);                                  pParam->width, pParam->height, iFcode);
983    
984          if (!(MotionFlags & PMV_HALFPEL16)) {          pmv[0] = Data->predMV;
985                  Data.min_dx = EVEN(Data.min_dx);          PreparePredictionsBF(pmv, x, y, pParam->mb_width, pMB, mode_current);
                 Data.max_dx = EVEN(Data.max_dx);  
                 Data.min_dy = EVEN(Data.min_dy);  
                 Data.max_dy = EVEN(Data.max_dy); } // no-halpel and b-frames. do we need it?  
986    
987            Data->currentMV->x = Data->currentMV->y = 0;
         pmv[0] = Data.predMV;  
         PreparePredictionsBF(pmv, x, y, pParam->mb_width,  
                                         pMB, mode_current);  
   
         currentMV.x = currentMV.y = 0;  
988    
989          CheckCandidate = CheckCandidate16no4v;          CheckCandidate = CheckCandidate16no4v;
990    
991  // main loop. checking all predictions  // main loop. checking all predictions
992          for (i = 0; i < 8; i++) {          for (i = 0; i < 8; i++) {
993                  if (!(mask = make_mask(pmv, i)) ) continue;                  if (!(mask = make_mask(pmv, i)) ) continue;
994                  CheckCandidate16no4v(pmv[i].x, pmv[i].y, mask, &iDirection, &Data);                  CheckCandidate16no4v(pmv[i].x, pmv[i].y, mask, &iDirection, Data);
995          }          }
996    
997          if (MotionFlags & PMV_USESQUARES16)          if (MotionFlags & PMV_USESQUARES16)
# Line 1008  Line 1000 
1000                  MainSearchPtr = AdvDiamondSearch;                  MainSearchPtr = AdvDiamondSearch;
1001                  else MainSearchPtr = DiamondSearch;                  else MainSearchPtr = DiamondSearch;
1002    
1003          (*MainSearchPtr)(currentMV.x, currentMV.y, &Data, 255);          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255);
1004    
1005          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(&Data);          HalfpelRefine(Data);
1006    
1007  // three bits are needed to code backward mode. four for forward  // three bits are needed to code backward mode. four for forward
1008  // we treat the bits just like they were vector's  // we treat the bits just like they were vector's
1009          if (mode_current == MODE_FORWARD) iMinSAD +=  4 * lambda_vec16[iQuant];          if (mode_current == MODE_FORWARD) *Data->iMinSAD +=  4 * lambda_vec16[Data->iQuant];
1010          else iMinSAD +=  3 * lambda_vec16[iQuant];          else *Data->iMinSAD +=  3 * lambda_vec16[Data->iQuant];
1011    
1012    
1013          if (iMinSAD < *best_sad) {          if (*Data->iMinSAD < *best_sad) {
1014                  *best_sad = iMinSAD;                  *best_sad = *Data->iMinSAD;
1015                  pMB->mode = mode_current;                  pMB->mode = mode_current;
1016                  pMB->pmvs[0].x = currentMV.x - predMV->x;                  pMB->pmvs[0].x = Data->currentMV->x - predMV->x;
1017                  pMB->pmvs[0].y = currentMV.y - predMV->y;                  pMB->pmvs[0].y = Data->currentMV->y - predMV->y;
1018                  if (mode_current == MODE_FORWARD) pMB->mvs[0] = currentMV;                  if (mode_current == MODE_FORWARD) pMB->mvs[0] = *Data->currentMV;
1019                  else pMB->b_mvs[0] = currentMV;                  else pMB->b_mvs[0] = *Data->currentMV;
1020          }          }
1021    
1022  }  }
# Line 1041  Line 1033 
1033                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1034                                  const int x, const int y,                                  const int x, const int y,
1035                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
                                 const uint32_t iQuant,  
1036                                  const int32_t TRB, const int32_t TRD,                                  const int32_t TRB, const int32_t TRD,
1037                                  const MBParam * const pParam,                                  const MBParam * const pParam,
1038                                  MACROBLOCK * const pMB,                                  MACROBLOCK * const pMB,
1039                                  const MACROBLOCK * const b_mb,                                  const MACROBLOCK * const b_mb,
1040                                  int32_t * const best_sad)                                  int32_t * const best_sad,
1041                                    SearchData * const Data)
1042    
1043  {  {
1044          const uint32_t iEdgedWidth = pParam->edged_width;          int32_t skip_sad;
         int32_t iMinSAD = 266*4096, skip_sad;  
1045          int k;          int k;
1046          VECTOR currentMV;  
1047          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
         SearchData Data;  
1048    
1049          Data.iMinSAD = &iMinSAD;          *Data->iMinSAD = 256*4096;
1050          Data.Cur = pCur->y + x * 16 + y * 16 * iEdgedWidth;          Data->referencemv = b_mb->mvs;
         Data.iEdgedWidth = iEdgedWidth;  
         Data.currentMV = &currentMV;  
         Data.iQuant = iQuant;  
         Data.referencemv = b_mb->mvs;  
1051    
1052          Data.Ref= f_Ref->y + (x + iEdgedWidth*y) * 16;          Data->Ref = f_Ref->y + (x + Data->iEdgedWidth*y) * 16;
1053          Data.RefH = f_RefH + (x + iEdgedWidth*y) * 16;          Data->RefH = f_RefH + (x + Data->iEdgedWidth*y) * 16;
1054          Data.RefV = f_RefV + (x + iEdgedWidth*y) * 16;          Data->RefV = f_RefV + (x + Data->iEdgedWidth*y) * 16;
1055          Data.RefHV = f_RefHV + (x + iEdgedWidth*y) * 16;          Data->RefHV = f_RefHV + (x + Data->iEdgedWidth*y) * 16;
1056          Data.bRef = b_Ref->y + (x + iEdgedWidth*y) * 16;          Data->bRef = b_Ref->y + (x + Data->iEdgedWidth*y) * 16;
1057          Data.bRefH = b_RefH + (x + iEdgedWidth*y) * 16;          Data->bRefH = b_RefH + (x + Data->iEdgedWidth*y) * 16;
1058          Data.bRefV = b_RefV + (x + iEdgedWidth*y) * 16;          Data->bRefV = b_RefV + (x + Data->iEdgedWidth*y) * 16;
1059          Data.bRefHV = b_RefHV + (x + iEdgedWidth*y) * 16;          Data->bRefHV = b_RefHV + (x + Data->iEdgedWidth*y) * 16;
1060  /*  
1061  //What we do here is a complicated version of CheckCandidateDirect(0,0);          Data->max_dx = 2 * pParam->width - 2 * (x) * 16;
1062  get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 16, pParam->width, pParam->height, 19);          Data->max_dy = 2 * pParam->height - 2 * (y) * 16;
1063            Data->min_dx = -(2 * 16 + 2 * (x) * 16);
1064  */          Data->min_dy = -(2 * 16 + 2 * (y) * 16);
         Data.max_dx = 2 * pParam->width - 2 * (x) * 16;  
         Data.max_dy = 2 * pParam->height - 2 * (y) * 16;  
         Data.min_dx = -(2 * 16 + 2 * (x) * 16);  
         Data.min_dy = -(2 * 16 + 2 * (y) * 16);  
1065    
1066          for (k = 0; k < 4; k++) {          for (k = 0; k < 4; k++) {
1067                  pMB->mvs[k].x = Data.directmvF[k].x = ((TRB * Data.referencemv[k].x) / TRD);                  pMB->mvs[k].x = Data->directmvF[k].x = ((TRB * Data->referencemv[k].x) / TRD);
1068                  pMB->b_mvs[k].x = Data.directmvB[k].x = ((TRB - TRD) * Data.referencemv[k].x) / TRD;                  pMB->b_mvs[k].x = Data->directmvB[k].x = ((TRB - TRD) * Data->referencemv[k].x) / TRD;
1069                  pMB->mvs[k].y = Data.directmvF[k].y = ((TRB * Data.referencemv[k].y) / TRD);                  pMB->mvs[k].y = Data->directmvF[k].y = ((TRB * Data->referencemv[k].y) / TRD);
1070                  pMB->b_mvs[k].y = Data.directmvB[k].y = ((TRB - TRD) * Data.referencemv[k].y) / TRD;                  pMB->b_mvs[k].y = Data->directmvB[k].y = ((TRB - TRD) * Data->referencemv[k].y) / TRD;
1071    
1072                  if (( pMB->mvs[k].x > Data.max_dx ) || ( pMB->mvs[k].x < Data.min_dx )                  if ( ( pMB->b_mvs[k].x > Data->max_dx ) || ( pMB->b_mvs[k].x < Data->min_dx )
1073                          || ( pMB->mvs[k].y > Data.max_dy ) || ( pMB->mvs[k].y < Data.min_dy )                          || ( pMB->b_mvs[k].y > Data->max_dy ) || ( pMB->b_mvs[k].y < Data->min_dy )) {
                         || ( pMB->b_mvs[k].x > Data.max_dx ) || ( pMB->b_mvs[k].x < Data.min_dx )  
                         || ( pMB->b_mvs[k].y > Data.max_dy ) || ( pMB->b_mvs[k].y < Data.min_dy )) {  
1074    
1075                          *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
1076                          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"
# Line 1100  Line 1080 
1080                  if (b_mb->mode != MODE_INTER4V) {                  if (b_mb->mode != MODE_INTER4V) {
1081                          pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mvs[0];                          pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mvs[0];
1082                          pMB->b_mvs[1] = pMB->b_mvs[2] = pMB->b_mvs[3] = pMB->b_mvs[0];                          pMB->b_mvs[1] = pMB->b_mvs[2] = pMB->b_mvs[3] = pMB->b_mvs[0];
1083                          Data.directmvF[1] = Data.directmvF[2] = Data.directmvF[3] = Data.directmvF[0];                          Data->directmvF[1] = Data->directmvF[2] = Data->directmvF[3] = Data->directmvF[0];
1084                          Data.directmvB[1] = Data.directmvB[2] = Data.directmvB[3] = Data.directmvB[0];                          Data->directmvB[1] = Data->directmvB[2] = Data->directmvB[3] = Data->directmvB[0];
1085                          break;                          break;
1086                  }                  }
1087          }          }
# Line 1110  Line 1090 
1090                  CheckCandidate = CheckCandidateDirect;                  CheckCandidate = CheckCandidateDirect;
1091          else CheckCandidate = CheckCandidateDirectno4v;          else CheckCandidate = CheckCandidateDirectno4v;
1092    
1093          (*CheckCandidate)(0, 0, 255, &k, &Data);          (*CheckCandidate)(0, 0, 255, &k, Data);
1094    
1095  // skip decision  // skip decision
1096          if (iMinSAD - 2 * lambda_vec16[iQuant] < (int32_t)iQuant * SKIP_THRESH_B) {          if (*Data->iMinSAD - 2 * lambda_vec16[Data->iQuant] < (int32_t)Data->iQuant * SKIP_THRESH_B) {
1097                  //checking chroma. everything copied from MC                  //checking chroma. everything copied from MC
1098                  //this is not full chroma compensation, only it's fullpel approximation. should work though                  //this is not full chroma compensation, only it's fullpel approximation. should work though
1099                  int sum, dx, dy, b_dx, b_dy;                  int sum, dx, dy, b_dx, b_dy;
# Line 1130  Line 1110 
1110                  sum = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;                  sum = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;
1111                  b_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));                  b_dy = (sum == 0 ? 0 : SIGN(sum) * (roundtab[ABS(sum) % 16] + (ABS(sum) / 16) * 2));
1112    
1113                  sum = sad8bi(pCur->u + 8*x + 8*y*(iEdgedWidth/2),                  sum = sad8bi(pCur->u + 8*x + 8*y*(Data->iEdgedWidth/2),
1114                                          f_Ref->u + (y*8 + dy/2) * (iEdgedWidth/2) + x*8 + dx/2,                                          f_Ref->u + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,
1115                                          b_Ref->u + (y*8 + b_dy/2) * (iEdgedWidth/2) + x*8 + b_dx/2,                                          b_Ref->u + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,
1116                                          iEdgedWidth/2);                                          Data->iEdgedWidth/2);
1117                  sum += sad8bi(pCur->v + 8*x + 8*y*(iEdgedWidth/2),                  sum += sad8bi(pCur->v + 8*x + 8*y*(Data->iEdgedWidth/2),
1118                                          f_Ref->v + (y*8 + dy/2) * (iEdgedWidth/2) + x*8 + dx/2,                                          f_Ref->v + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,
1119                                          b_Ref->v + (y*8 + b_dy/2) * (iEdgedWidth/2) + x*8 + b_dx/2,                                          b_Ref->v + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,
1120                                          iEdgedWidth/2);                                          Data->iEdgedWidth/2);
1121    
1122                  if ((uint32_t) sum < MAX_CHROMA_SAD_FOR_SKIP * Data.iQuant) {                  if ((uint32_t) sum < MAX_CHROMA_SAD_FOR_SKIP * Data->iQuant) {
1123                          pMB->mode = MODE_DIRECT_NONE_MV;                          pMB->mode = MODE_DIRECT_NONE_MV;
1124                          return iMinSAD;                          return *Data->iMinSAD;
1125                  }                  }
1126          }          }
1127    
1128          skip_sad = iMinSAD;          skip_sad = *Data->iMinSAD;
1129    
1130  //  DIRECT MODE DELTA VECTOR SEARCH.  //  DIRECT MODE DELTA VECTOR SEARCH.
1131  //      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 1154  Line 1134 
1134                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
1135                          else MainSearchPtr = DiamondSearch;                          else MainSearchPtr = DiamondSearch;
1136    
1137          (*MainSearchPtr)(0, 0, &Data, 255);          (*MainSearchPtr)(0, 0, Data, 255);
1138    
1139          HalfpelRefine(&Data);          HalfpelRefine(Data);
1140    
1141          iMinSAD +=  1 * lambda_vec16[iQuant]; // one bit is needed to code direct mode. we treat this bit just like it was vector's          *Data->iMinSAD +=  1 * lambda_vec16[Data->iQuant]; // one bit is needed to code direct mode. we treat this bit just like it was vector's
1142          *best_sad = iMinSAD;          *best_sad = *Data->iMinSAD;
1143    
1144          if (b_mb->mode == MODE_INTER4V)          if (b_mb->mode == MODE_INTER4V)
1145                  pMB->mode = MODE_DIRECT;                  pMB->mode = MODE_DIRECT;
1146          else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation          else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation
1147    
1148          pMB->pmvs[3] = currentMV;          pMB->pmvs[3] = *Data->currentMV;
1149    
1150          for (k = 0; k < 4; k++) {          for (k = 0; k < 4; k++) {
1151                  pMB->mvs[k].x = Data.directmvF[k].x + currentMV.x;                  pMB->mvs[k].x = Data->directmvF[k].x + Data->currentMV->x;
1152                  pMB->b_mvs[k].x = ((currentMV.x == 0)                  pMB->b_mvs[k].x = ((Data->currentMV->x == 0)
1153                                                          ? Data.directmvB[k].x                                                          ? Data->directmvB[k].x
1154                                                          : pMB->mvs[k].x - Data.referencemv[k].x);                                                          : pMB->mvs[k].x - Data->referencemv[k].x);
1155                  pMB->mvs[k].y = (Data.directmvF[k].y + currentMV.y);                  pMB->mvs[k].y = (Data->directmvF[k].y + Data->currentMV->y);
1156                  pMB->b_mvs[k].y = ((currentMV.y == 0)                  pMB->b_mvs[k].y = ((Data->currentMV->y == 0)
1157                                                          ? Data.directmvB[k].y                                                          ? Data->directmvB[k].y
1158                                                          : pMB->mvs[k].y - Data.referencemv[k].y);                                                          : pMB->mvs[k].y - Data->referencemv[k].y);
1159                  if (b_mb->mode != MODE_INTER4V) {                  if (b_mb->mode != MODE_INTER4V) {
1160                          pMB->mvs[3] = pMB->mvs[2] = pMB->mvs[1] = pMB->mvs[0];                          pMB->mvs[3] = pMB->mvs[2] = pMB->mvs[1] = pMB->mvs[0];
1161                          pMB->b_mvs[3] = pMB->b_mvs[2] = pMB->b_mvs[1] = pMB->b_mvs[0];                          pMB->b_mvs[3] = pMB->b_mvs[2] = pMB->b_mvs[1] = pMB->b_mvs[0];
1162                          break;                          break;
1163                  }                  }
1164          }          }
1165          return 0;//skip_sad;          return skip_sad;
1166  }  }
1167    
1168    
1169  static __inline void  static __inline void
1170  SearchInterpolate(const uint8_t * const f_Ref,  SearchInterpolate(const uint8_t * const f_Ref,
1171                                  const uint8_t * const f_RefH,                                  const uint8_t * const f_RefH,
# Line 1199  Line 1180 
1180                                  const uint32_t fcode,                                  const uint32_t fcode,
1181                                  const uint32_t bcode,                                  const uint32_t bcode,
1182                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
                                 const uint32_t iQuant,  
1183                                  const MBParam * const pParam,                                  const MBParam * const pParam,
1184                                  const VECTOR * const f_predMV,                                  const VECTOR * const f_predMV,
1185                                  const VECTOR * const b_predMV,                                  const VECTOR * const b_predMV,
1186                                  MACROBLOCK * const pMB,                                  MACROBLOCK * const pMB,
1187                                  int32_t * const best_sad)                                  int32_t * const best_sad,
1188                                    SearchData * const fData)
1189    
1190  {  {
 /* Interpolated MC motion vector search, this is tedious and more complicated because there are  
    two values for everything, always one for backward and one for forward ME. Still, we don't gain  
    much from this search, maybe it should simply be skipped and simply current i_sad16 value used  
    as "optimal". */  
1191    
1192          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
1193    
1194          int iDirection, i, j;          int iDirection, i, j;
1195          int32_t iMinSAD = 256*4096;          SearchData bData;
         VECTOR currentMV[3];  
         SearchData fData, bData;  
   
         fData.iMinSAD = bData.iMinSAD = &iMinSAD;  
1196    
1197          fData.Cur = bData.Cur = pCur->y + (x + y * iEdgedWidth) * 16;          bData.iMinSAD = fData->iMinSAD;
1198          fData.iEdgedWidth = bData.iEdgedWidth = iEdgedWidth;          *bData.iMinSAD = 4096*256;
1199          fData.currentMV = currentMV; bData.currentMV = currentMV + 1;          bData.Cur = fData->Cur;
1200          fData.iQuant = bData.iQuant = iQuant;          fData->iEdgedWidth = bData.iEdgedWidth = iEdgedWidth;
1201          fData.iFcode = bData.bFcode = fcode; fData.bFcode = bData.iFcode = bcode;          bData.currentMV = fData->currentMV + 1;
1202            bData.iQuant = fData->iQuant;
1203          bData.bRef = fData.Ref = f_Ref + (x + y * iEdgedWidth) * 16;          fData->iFcode = bData.bFcode = fcode; fData->bFcode = bData.iFcode = bcode;
1204          bData.bRefH = fData.RefH = f_RefH + (x + y * iEdgedWidth) * 16;  
1205          bData.bRefV = fData.RefV = f_RefV + (x + y * iEdgedWidth) * 16;          bData.bRef = fData->Ref = f_Ref + (x + y * iEdgedWidth) * 16;
1206          bData.bRefHV = fData.RefHV = f_RefHV + (x + y * iEdgedWidth) * 16;          bData.bRefH = fData->RefH = f_RefH + (x + y * iEdgedWidth) * 16;
1207          bData.Ref = fData.bRef = b_Ref + (x + y * iEdgedWidth) * 16;          bData.bRefV = fData->RefV = f_RefV + (x + y * iEdgedWidth) * 16;
1208          bData.RefH = fData.bRefH = b_RefH + (x + y * iEdgedWidth) * 16;          bData.bRefHV = fData->RefHV = f_RefHV + (x + y * iEdgedWidth) * 16;
1209          bData.RefV = fData.bRefV = b_RefV + (x + y * iEdgedWidth) * 16;          bData.Ref = fData->bRef = b_Ref + (x + y * iEdgedWidth) * 16;
1210          bData.RefHV = fData.bRefHV = b_RefHV + (x + y * iEdgedWidth) * 16;          bData.RefH = fData->bRefH = b_RefH + (x + y * iEdgedWidth) * 16;
1211            bData.RefV = fData->bRefV = b_RefV + (x + y * iEdgedWidth) * 16;
1212          bData.bpredMV = fData.predMV = *f_predMV;          bData.RefHV = fData->bRefHV = b_RefHV + (x + y * iEdgedWidth) * 16;
1213          fData.bpredMV = bData.predMV = *b_predMV;  
1214            bData.bpredMV = fData->predMV = *f_predMV;
1215          currentMV[0] = pMB->mvs[0];          fData->bpredMV = bData.predMV = *b_predMV;
1216          currentMV[1] = pMB->b_mvs[0];  
1217          get_range(&fData.min_dx, &fData.max_dx, &fData.min_dy, &fData.max_dy, x, y, 16, pParam->width, pParam->height, fcode);          fData->currentMV[0] = pMB->mvs[0];
1218            fData->currentMV[1] = pMB->b_mvs[0];
1219            get_range(&fData->min_dx, &fData->max_dx, &fData->min_dy, &fData->max_dy, x, y, 16, pParam->width, pParam->height, fcode);
1220          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);
1221    
1222          if (currentMV[0].x > fData.max_dx) currentMV[0].x = fData.max_dx;          if (fData->currentMV[0].x > fData->max_dx) fData->currentMV[0].x = fData->max_dx;
1223          if (currentMV[0].x < fData.min_dx) currentMV[0].x = fData.min_dy;          if (fData->currentMV[0].x < fData->min_dx) fData->currentMV[0].x = fData->min_dy;
1224          if (currentMV[0].y > fData.max_dy) currentMV[0].y = fData.max_dx;          if (fData->currentMV[0].y > fData->max_dy) fData->currentMV[0].y = fData->max_dx;
1225          if (currentMV[0].y > fData.min_dy) currentMV[0].y = fData.min_dy;          if (fData->currentMV[0].y > fData->min_dy) fData->currentMV[0].y = fData->min_dy;
1226    
1227          if (currentMV[1].x > bData.max_dx) currentMV[1].x = bData.max_dx;          if (fData->currentMV[1].x > bData.max_dx) fData->currentMV[1].x = bData.max_dx;
1228          if (currentMV[1].x < bData.min_dx) currentMV[1].x = bData.min_dy;          if (fData->currentMV[1].x < bData.min_dx) fData->currentMV[1].x = bData.min_dy;
1229          if (currentMV[1].y > bData.max_dy) currentMV[1].y = bData.max_dx;          if (fData->currentMV[1].y > bData.max_dy) fData->currentMV[1].y = bData.max_dx;
1230          if (currentMV[1].y > bData.min_dy) currentMV[1].y = bData.min_dy;          if (fData->currentMV[1].y > bData.min_dy) fData->currentMV[1].y = bData.min_dy;
1231    
1232          CheckCandidateInt(currentMV[0].x, currentMV[0].y, 255, &iDirection, &fData);          CheckCandidateInt(fData->currentMV[0].x, fData->currentMV[0].y, 255, &iDirection, fData);
1233    
1234  //diamond. I wish we could use normal mainsearch functions (square, advdiamond)  //diamond. I wish we could use normal mainsearch functions (square, advdiamond)
1235    
1236          do {          do {
1237                  iDirection = 255;                  iDirection = 255;
1238                  // forward MV moves                  // forward MV moves
1239                  i = currentMV[0].x; j = currentMV[0].y;                  i = fData->currentMV[0].x; j = fData->currentMV[0].y;
1240    
1241                  CheckCandidateInt(i + 1, j, 0, &iDirection, &fData);                  CheckCandidateInt(i + 1, j, 0, &iDirection, fData);
1242                  CheckCandidateInt(i, j + 1, 0, &iDirection, &fData);                  CheckCandidateInt(i, j + 1, 0, &iDirection, fData);
1243                  CheckCandidateInt(i - 1, j, 0, &iDirection, &fData);                  CheckCandidateInt(i - 1, j, 0, &iDirection, fData);
1244                  CheckCandidateInt(i, j - 1, 0, &iDirection, &fData);                  CheckCandidateInt(i, j - 1, 0, &iDirection, fData);
1245    
1246                  // backward MV moves                  // backward MV moves
1247                  i = currentMV[1].x; j = currentMV[1].y;                  i = fData->currentMV[1].x; j = fData->currentMV[1].y;
1248                  currentMV[2] = currentMV[0];                  fData->currentMV[2] = fData->currentMV[0];
1249    
1250                  CheckCandidateInt(i + 1, j, 0, &iDirection, &bData);                  CheckCandidateInt(i + 1, j, 0, &iDirection, &bData);
1251                  CheckCandidateInt(i, j + 1, 0, &iDirection, &bData);                  CheckCandidateInt(i, j + 1, 0, &iDirection, &bData);
# Line 1280  Line 1255 
1255          } while (!(iDirection));          } while (!(iDirection));
1256    
1257  // 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
1258          iMinSAD +=  2 * lambda_vec16[iQuant];          *fData->iMinSAD +=  2 * lambda_vec16[fData->iQuant];
1259          if (iMinSAD < *best_sad) {          if (*fData->iMinSAD < *best_sad) {
1260                  *best_sad = iMinSAD;                  *best_sad = *fData->iMinSAD;
1261                  pMB->mvs[0] = currentMV[0];                  pMB->mvs[0] = fData->currentMV[0];
1262                  pMB->b_mvs[0] = currentMV[1];                  pMB->b_mvs[0] = fData->currentMV[1];
1263                  pMB->mode = MODE_INTERPOLATE;                  pMB->mode = MODE_INTERPOLATE;
1264    
1265                  pMB->pmvs[1].x = pMB->mvs[0].x - f_predMV->x;                  pMB->pmvs[1].x = pMB->mvs[0].x - f_predMV->x;
# Line 1294  Line 1269 
1269          }          }
1270  }  }
1271    
1272    
1273  void  void
1274  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
1275                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 1322  Line 1298 
1298          const int32_t TRB = time_pp - time_bp;          const int32_t TRB = time_pp - time_bp;
1299          const int32_t TRD = time_pp;          const int32_t TRD = time_pp;
1300    
1301    // some pre-inintialized data for the rest of the search
1302    
1303            SearchData Data;
1304            int32_t iMinSAD;
1305            VECTOR currentMV[3];
1306            Data.iEdgedWidth = pParam->edged_width;
1307            Data.currentMV = currentMV;
1308            Data.iMinSAD = &iMinSAD;
1309            Data.iQuant = frame->quant;
1310    
1311          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
1312    
1313          for (j = 0; j < pParam->mb_height; j++) {          for (j = 0; j < pParam->mb_height; j++) {
# Line 1338  Line 1324 
1324                                  continue;                                  continue;
1325                          }                          }
1326    
1327                            Data.Cur = frame->image.y + (j * Data.iEdgedWidth + i) * 16;
1328  /* direct search comes first, because it (1) checks for SKIP-mode  /* direct search comes first, because it (1) checks for SKIP-mode
1329          and (2) sets very good predictions for forward and backward search */          and (2) sets very good predictions for forward and backward search */
1330    
# Line 1346  Line 1333 
1333                                                                          &frame->image,                                                                          &frame->image,
1334                                                                          i, j,                                                                          i, j,
1335                                                                          frame->motion_flags,                                                                          frame->motion_flags,
                                                                         frame->quant,  
1336                                                                          TRB, TRD,                                                                          TRB, TRD,
1337                                                                          pParam,                                                                          pParam,
1338                                                                          pMB, b_mb,                                                                          pMB, b_mb,
1339                                                                          &best_sad);                                                                          &best_sad,
1340                                                                            &Data);
1341    
1342                          if (pMB->mode == MODE_DIRECT_NONE_MV) { n_count++; continue; }                          if (pMB->mode == MODE_DIRECT_NONE_MV) { n_count++; continue; }
1343    
# Line 1361  Line 1348 
1348                          SearchBF(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          SearchBF(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
1349                                                  &frame->image, i, j,                                                  &frame->image, i, j,
1350                                                  frame->motion_flags,                                                  frame->motion_flags,
1351                                                  frame->quant, frame->fcode, pParam,                                                  frame->fcode, pParam,
1352                                                  pMB, &f_predMV, &best_sad,                                                  pMB, &f_predMV, &best_sad,
1353                                                  MODE_FORWARD);                                                  MODE_FORWARD, &Data);
1354    
1355                          // backward search                          // backward search
1356                          SearchBF(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                          SearchBF(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
1357                                                  &frame->image, i, j,                                                  &frame->image, i, j,
1358                                                  frame->motion_flags,                                                  frame->motion_flags,
1359                                                  frame->quant, frame->bcode, pParam,                                                  frame->bcode, pParam,
1360                                                  pMB, &b_predMV, &best_sad,                                                  pMB, &b_predMV, &best_sad,
1361                                                  MODE_BACKWARD);                                                  MODE_BACKWARD, &Data);
1362    
1363                          // interpolate search comes last, because it uses data from forward and backward as prediction                          // interpolate search comes last, because it uses data from forward and backward as prediction
1364    
# Line 1381  Line 1368 
1368                                                  i, j,                                                  i, j,
1369                                                  frame->fcode, frame->bcode,                                                  frame->fcode, frame->bcode,
1370                                                  frame->motion_flags,                                                  frame->motion_flags,
1371                                                  frame->quant, pParam,                                                  pParam,
1372                                                  &f_predMV, &b_predMV,                                                  &f_predMV, &b_predMV,
1373                                                  pMB, &best_sad);                                                  pMB, &best_sad,
1374                                                    &Data);
1375    
1376                          switch (pMB->mode) {                          switch (pMB->mode) {
1377                                  case MODE_FORWARD:                                  case MODE_FORWARD:
# Line 1482  Line 1470 
1470                                  const int y,                                  const int y,
1471                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1472                                  const uint32_t iQuant,                                  const uint32_t iQuant,
                                 const uint32_t iFcode,  
1473                                  const MBParam * const pParam,                                  const MBParam * const pParam,
1474                                  const MACROBLOCK * const pMBs,                                  const MACROBLOCK * const pMBs,
1475                                  int inter4v,                                  int inter4v,
1476                                  MACROBLOCK * const pMB)                                  MACROBLOCK * const pMB,
1477                                    SearchData * const Data)
1478  {  {
1479    
1480          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
1481    
1482          int i;          int i, t;
         VECTOR currentMV[5];  
         int32_t iMinSAD[5];  
         int32_t temp[5];  
1483          MainSearchFunc * MainSearchPtr;          MainSearchFunc * MainSearchPtr;
         SearchData Data;  
1484    
1485          Data.predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
1486          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,
1487                                  pParam->width, pParam->height, iFcode);                                  pParam->width, pParam->height, Data->iFcode);
1488    
1489          Data.Cur = pCur->y + (x + y * iEdgedWidth) * 16;          Data->Cur = pCur->y + (x + y * iEdgedWidth) * 16;
1490          Data.iEdgedWidth = iEdgedWidth;          Data->Ref = pRef + (x + iEdgedWidth*y)*16;
1491          Data.currentMV = currentMV;          Data->RefH = pRefH + (x + iEdgedWidth*y) * 16;
1492          Data.iMinSAD = iMinSAD;          Data->RefV = pRefV + (x + iEdgedWidth*y) * 16;
1493          Data.Ref = pRef + (x + iEdgedWidth*y)*16;          Data->RefHV = pRefHV + (x + iEdgedWidth*y) * 16;
1494          Data.RefH = pRefH + (x + iEdgedWidth*y) * 16;          Data->iQuant = iQuant;
         Data.RefV = pRefV + (x + iEdgedWidth*y) * 16;  
         Data.RefHV = pRefHV + (x + iEdgedWidth*y) * 16;  
         Data.temp = temp;  
         Data.iQuant = iQuant;  
         Data.iFcode = iFcode;  
1495    
1496          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
1497                  Data.min_dx = EVEN(Data.min_dx);                  Data->min_dx = EVEN(Data->min_dx);
1498                  Data.max_dx = EVEN(Data.max_dx);                  Data->max_dx = EVEN(Data->max_dx);
1499                  Data.min_dy = EVEN(Data.min_dy);                  Data->min_dy = EVEN(Data->min_dy);
1500                  Data.max_dy = EVEN(Data.max_dy);                  Data->max_dy = EVEN(Data->max_dy);
1501          }          }
1502    
1503          for(i = 0; i < 5; i++) iMinSAD[i] = MV_MAX_ERROR;          for(i = 0; i < 5; i++) Data->iMinSAD[i] = MV_MAX_ERROR;
1504    
1505          if (pMB->dquant != NO_CHANGE) inter4v = 0;          if (pMB->dquant != NO_CHANGE) inter4v = 0;
1506    
# Line 1532  Line 1511 
1511    
1512          pMB->mvs[0].x = EVEN(pMB->mvs[0].x);          pMB->mvs[0].x = EVEN(pMB->mvs[0].x);
1513          pMB->mvs[0].y = EVEN(pMB->mvs[0].y);          pMB->mvs[0].y = EVEN(pMB->mvs[0].y);
1514          if (pMB->mvs[0].x > Data.max_dx) pMB->mvs[0].x = Data.max_dx; // this is in case iFcode changed          if (pMB->mvs[0].x > Data->max_dx) pMB->mvs[0].x = Data->max_dx; // this is in case iFcode changed
1515          if (pMB->mvs[0].x < Data.min_dx) pMB->mvs[0].x = Data.min_dx;          if (pMB->mvs[0].x < Data->min_dx) pMB->mvs[0].x = Data->min_dx;
1516          if (pMB->mvs[0].y > Data.max_dy) pMB->mvs[0].y = Data.max_dy;          if (pMB->mvs[0].y > Data->max_dy) pMB->mvs[0].y = Data->max_dy;
1517          if (pMB->mvs[0].y < Data.min_dy) pMB->mvs[0].y = Data.min_dy;          if (pMB->mvs[0].y < Data->min_dy) pMB->mvs[0].y = Data->min_dy;
1518    
1519          CheckCandidate16(pMB->mvs[0].x, pMB->mvs[0].y, 0, &i, &Data);          (*CheckCandidate)(pMB->mvs[0].x, pMB->mvs[0].y, 0, &t, Data);
1520    
1521          if (pMB->mode == MODE_INTER4V)          if (pMB->mode == MODE_INTER4V)
1522                  for (i = 1; i < 4; i++) { // all four vectors will be used as four predictions for 16x16 search                  for (i = 1; i < 4; i++) { // all four vectors will be used as four predictions for 16x16 search
1523                          pMB->mvs[i].x = EVEN(pMB->mvs[i].x);                          pMB->mvs[i].x = EVEN(pMB->mvs[i].x);
1524                          pMB->mvs[i].y = EVEN(pMB->mvs[i].y);                          pMB->mvs[i].y = EVEN(pMB->mvs[i].y);
1525                          if (!(make_mask(pMB->mvs, i)))                          if (!(make_mask(pMB->mvs, i)))
1526                                  CheckCandidate16(pMB->mvs[i].x, pMB->mvs[i].y, 0, &i, &Data);                                  (*CheckCandidate)(pMB->mvs[i].x, pMB->mvs[i].y, 0, &t, Data);
1527                  }                  }
1528    
1529          if (MotionFlags & PMV_USESQUARES16)          if (MotionFlags & PMV_USESQUARES16)
# Line 1553  Line 1532 
1532                  MainSearchPtr = AdvDiamondSearch;                  MainSearchPtr = AdvDiamondSearch;
1533                  else MainSearchPtr = DiamondSearch;                  else MainSearchPtr = DiamondSearch;
1534    
1535          (*MainSearchPtr)(currentMV->x, currentMV->y, &Data, 255);          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255);
1536    
1537          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(&Data);          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(Data);
1538    
1539          if (inter4v)          if (inter4v)
1540                  for(i = 0; i < 4; i++)                  for(i = 0; i < 4; i++)
1541                          Search8hinted(&Data, 2*x+(i&1), 2*y+(i>>1), MotionFlags, pParam, pMB, pMBs, i);                          Search8hinted(Data, 2*x+(i&1), 2*y+(i>>1), MotionFlags, pParam, pMB, pMBs, i);
1542    
1543          if (!(inter4v) ||          if (!(inter4v) ||
1544                  (iMinSAD[0] < iMinSAD[1] + iMinSAD[2] + iMinSAD[3] + iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) {                  (Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] +
1545                                                            Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) {
1546  // INTER MODE  // INTER MODE
1547    
1548                  pMB->mode = MODE_INTER;                  pMB->mode = MODE_INTER;
1549                  pMB->mvs[0] = pMB->mvs[1]                  pMB->mvs[0] = pMB->mvs[1]
1550                          = pMB->mvs[2] = pMB->mvs[3] = currentMV[0];                          = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];
1551    
1552                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] =
1553                          pMB->sad8[2] = pMB->sad8[3] =  iMinSAD[0];                          pMB->sad8[2] = pMB->sad8[3] =  Data->iMinSAD[0];
1554    
1555                  pMB->pmvs[0].x = currentMV[0].x - Data.predMV.x;                  pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;
1556                  pMB->pmvs[0].y = currentMV[0].y - Data.predMV.y;                  pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;
1557          } else {          } else {
1558  // INTER4V MODE; all other things are already set in Search8hinted  // INTER4V MODE; all other things are already set in Search8hinted
1559                  pMB->mode = MODE_INTER4V;                  pMB->mode = MODE_INTER4V;
1560                  pMB->sad16 = iMinSAD[1] + iMinSAD[2] + iMinSAD[3] + iMinSAD[4] + IMV16X16 * iQuant;                  pMB->sad16 = Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3]
1561                                                    + Data->iMinSAD[4] + IMV16X16 * iQuant;
1562          }          }
1563    
1564  }  }
# Line 1595  Line 1576 
1576          const IMAGE *const pRef = &reference->image;          const IMAGE *const pRef = &reference->image;
1577    
1578          uint32_t x, y;          uint32_t x, y;
1579            int32_t temp[5], quant = current->quant;
1580            int32_t iMinSAD[5];
1581            VECTOR currentMV[5];
1582            SearchData Data;
1583            Data.iEdgedWidth = pParam->edged_width;
1584            Data.currentMV = currentMV;
1585            Data.iMinSAD = iMinSAD;
1586            Data.temp = temp;
1587            Data.iFcode = current->fcode;
1588    
1589          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
1590    
# Line 1606  Line 1596 
1596  //intra mode is copied from the first pass. At least for the time being  //intra mode is copied from the first pass. At least for the time being
1597                          if  ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_NOT_CODED) ) continue;                          if  ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_NOT_CODED) ) continue;
1598    
1599    
1600                          if (!(current->global_flags & XVID_LUMIMASKING)) {                          if (!(current->global_flags & XVID_LUMIMASKING)) {
1601                                  pMB->dquant = NO_CHANGE;                                  pMB->dquant = NO_CHANGE;
1602                                  pMB->quant = current->quant; }                                  pMB->quant = current->quant; }
1603                            else
1604                                    if (pMB->dquant != NO_CHANGE) {
1605                                            quant += DQtab[pMB->dquant];
1606                                            if (quant > 31) quant = 31;
1607                                            else if (quant < 1) quant = 1;
1608                                            pMB->quant = quant;
1609                                    }
1610    
1611                          SearchPhinted(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchPhinted(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1612                                                          y, current->motion_flags, pMB->quant,                                                          y, current->motion_flags, pMB->quant,
1613                                                          current->fcode, pParam, pMBs,                                                          pParam, pMBs, current->global_flags & XVID_INTER4V, pMB,
1614                                                          current->global_flags & XVID_INTER4V, pMB);                                                          &Data);
1615    
1616                  }                  }
1617          }          }
# Line 1624  Line 1622 
1622                                  const uint8_t * const pCur,                                  const uint8_t * const pCur,
1623                                  const int x,                                  const int x,
1624                                  const int y,                                  const int y,
                                 const uint32_t iFcode,  
1625                                  const MBParam * const pParam,                                  const MBParam * const pParam,
1626                                  const MACROBLOCK * const pMBs,                                  const MACROBLOCK * const pMBs,
1627                                  MACROBLOCK * const pMB)                                  MACROBLOCK * const pMB,
1628                                    SearchData * const Data)
1629  {  {
1630    
         const int32_t iEdgedWidth = pParam->edged_width;  
1631          int i, mask;          int i, mask;
1632          VECTOR currentMV, pmv[3];          VECTOR pmv[3];
         int32_t iMinSAD = MV_MAX_ERROR;  
         SearchData Data;  
1633    
1634          Data.predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          *(Data->iMinSAD) = MV_MAX_ERROR;
1635          get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 16,          Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
1636                                  pParam->width, pParam->height, iFcode);          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
1637                                    pParam->width, pParam->height, Data->iFcode);
1638    
1639          Data.Cur = pCur + (x + y * iEdgedWidth) * 16;          Data->Cur = pCur + (x + y * pParam->edged_width) * 16;
1640          Data.iEdgedWidth = iEdgedWidth;          Data->Ref = pRef + (x + y * pParam->edged_width) * 16;
         Data.currentMV = &currentMV;  
         Data.iMinSAD = &iMinSAD;  
         Data.Ref = pRef + (x + iEdgedWidth*y)*16;  
         Data.iQuant = 2;  
         Data.iFcode = iFcode;  
1641    
1642          CheckCandidate = CheckCandidate16no4vI;          CheckCandidate = CheckCandidate16no4vI;
1643    
1644          pmv[1].x = EVEN(pMB->mvs[0].x);          pmv[1].x = EVEN(pMB->mvs[0].x);
1645          pmv[1].y = EVEN(pMB->mvs[0].y);          pmv[1].y = EVEN(pMB->mvs[0].y);
1646          pmv[0].x = EVEN(Data.predMV.x);          pmv[0].x = EVEN(Data->predMV.x);
1647          pmv[0].y = EVEN(Data.predMV.y);          pmv[0].y = EVEN(Data->predMV.y);
1648          pmv[2].x = pmv[2].y = 0;          pmv[2].x = pmv[2].y = 0;
1649    
1650          CheckCandidate16no4vI(pmv[0].x, pmv[0].y, 255, &i, &Data);          CheckCandidate16no4vI(pmv[0].x, pmv[0].y, 255, &i, Data);
1651          if (!(mask = make_mask(pmv, 1)))          if (!(mask = make_mask(pmv, 1)))
1652                  CheckCandidate16no4vI(pmv[1].x, pmv[1].y, mask, &i, &Data);                  CheckCandidate16no4vI(pmv[1].x, pmv[1].y, mask, &i, Data);
1653          if (!(mask = make_mask(pmv, 2)))          if (!(mask = make_mask(pmv, 2)))
1654                  CheckCandidate16no4vI(0, 0, mask, &i, &Data);                  CheckCandidate16no4vI(0, 0, mask, &i, Data);
1655    
1656          DiamondSearch(currentMV.x, currentMV.y, &Data, i);          DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, i);
1657    
1658          pMB->mvs[0] = pMB->mvs[1]          pMB->mvs[0] = pMB->mvs[1]
1659                          = pMB->mvs[2] = pMB->mvs[3] = currentMV; // all, for future get_pmv()                          = pMB->mvs[2] = pMB->mvs[3] = *Data->currentMV; // all, for future get_pmv()
1660    
1661          return iMinSAD;          return *(Data->iMinSAD);
1662  }  }
1663    
1664  #define INTRA_THRESH    1350  #define INTRA_THRESH    1350
# Line 1683  Line 1674 
1674          uint32_t x, y, intra = 0;          uint32_t x, y, intra = 0;
1675          int sSAD = 0;          int sSAD = 0;
1676    
1677            VECTOR currentMV;
1678            int32_t iMinSAD;
1679            SearchData Data;
1680            Data.iEdgedWidth = pParam->edged_width;
1681            Data.currentMV = &currentMV;
1682            Data.iMinSAD = &iMinSAD;
1683            Data.iFcode = iFcode;
1684            Data.iQuant = 2;
1685    
1686          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
1687    
1688          for (y = 0; y < pParam->mb_height-1; y++) {          for (y = 0; y < pParam->mb_height-1; y++) {
1689                  for (x = 0; x < pParam->mb_width; x++) {                  for (x = 0; x < pParam->mb_width; x++) {
1690                          int sad, dev;                          int sad, dev;
   
1691                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];                          MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width];
1692    
1693                          sad = MEanalyzeMB(pRef->y, pCurrent->y, x, y,                          sad = MEanalyzeMB(pRef->y, pCurrent->y, x, y,
1694                                                                  iFcode, pParam, pMBs, pMB);                                                                  pParam, pMBs, pMB, &Data);
1695    
1696                          if ( x != 0 && y != 0 && x != pParam->mb_width-1 ) { //no edge macroblocks, they just don't work                          if ( x != 0 && y != 0 && x != pParam->mb_width-1 ) { //no edge macroblocks, they just don't work
1697                                  if (sad > INTRA_THRESH) {                                  if (sad > INTRA_THRESH) {
# Line 1712  Line 1711 
1711          return 0; // B frame          return 0; // B frame
1712    
1713  }  }
1714    
1715    int
1716    FindFcode(      const MBParam * const pParam,
1717                            const FRAMEINFO * const current)
1718    {
1719            uint32_t x, y;
1720            int max = 0, min = 0, i;
1721    
1722            for (y = 0; y < pParam->mb_height; y++) {
1723                    for (x = 0; x < pParam->mb_width; x++) {
1724    
1725                            MACROBLOCK *pMB = &current->mbs[x + y * pParam->mb_width];
1726                            for(i = 0; i < (pMB->mode == MODE_INTER4V ? 4:1); i++) {
1727                                    if (pMB->mvs[i].x > max) max = pMB->mvs[i].x;
1728                                    if (pMB->mvs[i].y > max) max = pMB->mvs[i].y;
1729    
1730                                    if (pMB->mvs[i].x < min) min = pMB->mvs[i].x;
1731                                    if (pMB->mvs[i].y < min) min = pMB->mvs[i].y;
1732                            }
1733                    }
1734            }
1735    
1736            min = -min;
1737            max += 1;
1738            if (min > max) max = min;
1739    
1740            for (i = 1; (max > 32 << (i - 1)); i++);
1741            return i;
1742    }

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

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