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

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

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

revision 337, Wed Jul 24 20:58:41 2002 UTC revision 347, Sun Jul 28 13:06:46 2002 UTC
# Line 458  Line 458 
458  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
459    
460          int32_t iDirection = 0;          int32_t iDirection = 0;
461            int32_t iDirectionBackup;
462          int32_t iSAD;          int32_t iSAD;
463          VECTOR backupMV;          VECTOR backupMV;
464    
# Line 471  Line 472 
472          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
473          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
474    
475          if (iDirection)          if (iDirection) {
476                  while (!iFound) {                  while (!iFound) {
477                          iFound = 1;                          iFound = 1;
478                          backupMV = *currMV;                          backupMV = *currMV;
479                            iDirectionBackup = iDirection;
480    
481                          if (iDirection != 2)                          if (iDirectionBackup != 2)
482                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
483                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
484                          if (iDirection != 1)                          if (iDirectionBackup != 1)
485                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
486                                                                                     backupMV.y, 2);                                                                                     backupMV.y, 2);
487                          if (iDirection != 4)                          if (iDirectionBackup != 4)
488                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
489                                                                                     backupMV.y - iDiamondSize, 3);                                                                                     backupMV.y - iDiamondSize, 3);
490                          if (iDirection != 3)                          if (iDirectionBackup != 3)
491                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
492                                                                                     backupMV.y + iDiamondSize, 4);                                                                                     backupMV.y + iDiamondSize, 4);
493                    }
494          } else {          } else {
495                  currMV->x = start_x;                  currMV->x = start_x;
496                  currMV->y = start_y;                  currMV->y = start_y;
# Line 551  Line 554 
554                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
555    
556    
557          if (iDirection)          if (iDirection) {
558                  while (!iFound) {                  while (!iFound) {
559                          iFound = 1;                          iFound = 1;
560                          backupMV = *currMV;                          backupMV = *currMV;
# Line 560  Line 563 
563                          case 1:                          case 1:
564                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
565                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
566                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
567                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
568                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
569                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
570                                  break;                                  break;
571                          case 2:                          case 2:
572                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
573                                                                                   2);                                                                                   2);
574                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
575                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
576                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
577                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
578                                  break;                                  break;
579    
580                          case 3:                          case 3:
581                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
582                                                                                   4);                                                                                   4);
583                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
584                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
585                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
586                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
587                                  break;                                  break;
588    
589                          case 4:                          case 4:
590                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
591                                                                                   3);                                                                                   3);
592                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
593                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
594                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
595                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
596                                  break;                                  break;
597    
598                          case 5:                          case 5:
599                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
600                                                                                   1);                                                                                   1);
601                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
602                                                                                   3);                                                                                   3);
603                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
604                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
605                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
606                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
607                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
608                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
609                                  break;                                  break;
610    
611                          case 6:                          case 6:
612                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
613                                                                                   2);                                                                                   2);
614                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
615                                                                                   3);                                                                                   3);
616    
617                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
618                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
619                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
620                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
621                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
622                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
623    
624                                  break;                                  break;
# Line 623  Line 626 
626                          case 7:                          case 7:
627                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
628                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
629                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
630                                                                                   4);                                                                                   4);
631                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
632                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
633                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
634                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
635                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
636                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
637                                  break;                                  break;
638    
639                          case 8:                          case 8:
640                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
641                                                                                   2);                                                                                   2);
642                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
643                                                                                   4);                                                                                   4);
644                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
645                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
646                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
647                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
648                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
649                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
650                                  break;                                  break;
651                          default:                          default:
652                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
653                                                                                   1);                                                                                   1);
654                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
655                                                                                   2);                                                                                   2);
656                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
657                                                                                   3);                                                                                   3);
658                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
659                                                                                   4);                                                                                   4);
660    
661                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
662                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
663                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
664                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
665                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
666                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
667                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
668                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
669                                  break;                                  break;
670                          }                          }
671                    }
672          } else {          } else {
673                  currMV->x = start_x;                  currMV->x = start_x;
674                  currMV->y = start_y;                  currMV->y = start_y;
# Line 870  Line 874 
874          return iMinSAD;          return iMinSAD;
875  }  }
876    
877    #define CHECK_MV16_F_INTERPOL(X,Y) { \
878  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
879    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
880    { \    { \
881      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
882      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
883                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
884                            iEdgedWidth); \
885        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
886        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
887      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
888      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
889  }  }
890    
891  #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
892    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
893      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
894    { \    { \
895      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
896      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
897                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
898                            iEdgedWidth); \
899        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
900        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
901      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
902      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
903  }  }
904    
905  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  #define CHECK_MV16_B_INTERPOL(X,Y) { \
906    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
907      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
908    { \    { \
909      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
910      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
911                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
912                            iEdgedWidth); \
913        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
914        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
915      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
916      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
917  }  }
918    
919    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
920  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
921    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
922    { \    { \
923      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
924      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
925                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
926                            iEdgedWidth); \
927        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
928        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
929      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
930      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
931  }  }
932    
   
 #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
   { \  
     iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \  
     iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \  
 }  
   
   
 #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
   { \  
     iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \  
     iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \  
 }  
   
   
 #if (0==1)  
933  int32_t  int32_t
934  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(
935                                          const uint8_t * const f_pRef,                                          const uint8_t * const f_pRef,
936                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
937                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
938                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
939    
940                                           const uint8_t * const cur,                                           const uint8_t * const cur,
941    
942                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 966  Line 961 
961                                     const int b_center_x,                                     const int b_center_x,
962                                     const int b_center_y,                                     const int b_center_y,
963    
964                                           const int32_t min_dx,                                      const int32_t f_min_dx,
965                                           const int32_t max_dx,                                          const int32_t f_max_dx,
966                                           const int32_t min_dy,                                          const int32_t f_min_dy,
967                                           const int32_t max_dy,                                          const int32_t f_max_dy,
968    
969                                        const int32_t b_min_dx,
970                                            const int32_t b_max_dx,
971                                            const int32_t b_min_dy,
972                                            const int32_t b_max_dy,
973    
974                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
975                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
976    
# Line 981  Line 982 
982  {  {
983  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
984    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
985          int32_t iSAD;          int32_t iSAD;
986    
987          VECTOR f_backupMV;          VECTOR f_backupMV;
988          VECTOR b_backupMV;          VECTOR b_backupMV;
989    
990          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
991          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
992          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
993          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
994    
995  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
996            {
997                    iFound = 1;
998    
999          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);                  f_backupMV = *f_currMV;
         CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);  
         CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);  
         CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);  
1000    
1001          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
1002                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
1003                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
1004                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
1005    
1006                    b_backupMV = *b_currMV;
1007    
1008                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
1009                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
1010                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
1011                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
1012    
1013            } while (!iFound);
1014    
1015            return iMinSAD;
1016    }
1017    
1018    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
1019    
1020    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
1021            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
1022            { int k;\
1023            VECTOR mvs,b_mvs;       \
1024            iSAD = 0;\
1025            for (k = 0; k < 4; k++) {       \
1026                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
1027                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
1028                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1029                                                : mvs.x - directmv[k].x);                           \
1030                                                                                                                                                                    \
1031                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1032                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1033                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1034                                                : mvs.y - directmv[k].y);                           \
1035                                                                                                                                                                    \
1036      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1037        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1038            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1039        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1040                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1041                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1042                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1043                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1044                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1045                            iEdgedWidth); \
1046                    }       \
1047            else    \
1048                    iSAD = 65535;   \
1049            } \
1050            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1051            if (iSAD < iMinSAD) \
1052                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1053    }
1054    
1055    
1056    
1057    int32_t
1058    Diamond16_DirectMainSearch(
1059                                            const uint8_t * const f_pRef,
1060                                            const uint8_t * const f_pRefH,
1061                                            const uint8_t * const f_pRefV,
1062                                            const uint8_t * const f_pRefHV,
1063    
1064                                            const uint8_t * const cur,
1065    
1066                                            const uint8_t * const b_pRef,
1067                                            const uint8_t * const b_pRefH,
1068                                            const uint8_t * const b_pRefV,
1069                                            const uint8_t * const b_pRefHV,
1070    
1071                                            const int x,
1072                                            const int y,
1073    
1074                                            const int TRB,
1075                                            const int TRD,
1076    
1077                                        const int start_x,
1078                                        const int start_y,
1079    
1080                                        int iMinSAD,
1081                                        VECTOR * const currMV,
1082                                            const VECTOR * const directmv,
1083    
1084                                        const int32_t min_dx,
1085                                            const int32_t max_dx,
1086                                            const int32_t min_dy,
1087                                            const int32_t max_dy,
1088    
1089                                            const int32_t iEdgedWidth,
1090                                            const int32_t iDiamondSize,
1091    
1092                                            const int32_t iQuant,
1093                                            int iFound)
1094    {
1095    /* Do a diamond search around given starting point, return SAD of best */
1096    
1097            int32_t iSAD;
1098    
1099            VECTOR backupMV;
1100    
                         if (iDirection != 2)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,  
                                                                                    backupMV.y, 1);  
                         if (iDirection != 1)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,  
                                                                                    backupMV.y, 2);  
                         if (iDirection != 4)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x,  
                                                                                    backupMV.y - iDiamondSize, 3);  
                         if (iDirection != 3)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x,  
                                                                                    backupMV.y + iDiamondSize, 4);  
         } else {  
1101                  currMV->x = start_x;                  currMV->x = start_x;
1102                  currMV->y = start_y;                  currMV->y = start_y;
1103          }  
1104    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1105    
1106            do
1107            {
1108                    iFound = 1;
1109    
1110                    backupMV = *currMV;
1111    
1112                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1113                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1114                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1115                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1116    
1117            } while (!iFound);
1118    
1119          return iMinSAD;          return iMinSAD;
1120  }  }
 #endif  
1121    
1122    
1123  int32_t  int32_t
# Line 1274  Line 1368 
1368                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1369                                  const int x,                                  const int x,
1370                                  const int y,                                  const int y,
1371                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1372                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1373                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1374                                  const int center_y,                                  const int center_y,
1375                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1376                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1613  Line 1707 
1707  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
1708    
1709          int32_t iDirection = 0;          int32_t iDirection = 0;
1710            int32_t iDirectionBackup;
1711          int32_t iSAD;          int32_t iSAD;
1712          VECTOR backupMV;          VECTOR backupMV;
1713    
# Line 1626  Line 1721 
1721          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1722          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1723    
1724          if (iDirection)          if (iDirection) {
1725                  while (!iFound) {                  while (!iFound) {
1726                          iFound = 1;                          iFound = 1;
1727                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     // since iDirection!=0, this is well defined!
1728                            iDirectionBackup = iDirection;
1729    
1730                          if (iDirection != 2)                          if (iDirectionBackup != 2)
1731                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1732                                                                                    backupMV.y, 1);                                                                                    backupMV.y, 1);
1733                          if (iDirection != 1)                          if (iDirectionBackup != 1)
1734                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1735                                                                                    backupMV.y, 2);                                                                                    backupMV.y, 2);
1736                          if (iDirection != 4)                          if (iDirectionBackup != 4)
1737                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1738                                                                                    backupMV.y - iDiamondSize, 3);                                                                                    backupMV.y - iDiamondSize, 3);
1739                          if (iDirection != 3)                          if (iDirectionBackup != 3)
1740                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1741                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1742                    }
1743            } else {
1744                    currMV->x = start_x;
1745                    currMV->y = start_y;
1746            }
1747            return iMinSAD;
1748    }
1749    
1750    
1751    
1752    
1753    int32_t
1754    Square8_MainSearch(const uint8_t * const pRef,
1755                                            const uint8_t * const pRefH,
1756                                            const uint8_t * const pRefV,
1757                                            const uint8_t * const pRefHV,
1758                                            const uint8_t * const cur,
1759                                            const int x,
1760                                            const int y,
1761                                            int32_t start_x,
1762                                            int32_t start_y,
1763                                            int32_t iMinSAD,
1764                                            VECTOR * const currMV,
1765                                       const int center_x,
1766                                       const int center_y,
1767                                            const int32_t min_dx,
1768                                            const int32_t max_dx,
1769                                            const int32_t min_dy,
1770                                            const int32_t max_dy,
1771                                            const int32_t iEdgedWidth,
1772                                            const int32_t iDiamondSize,
1773                                            const int32_t iFcode,
1774                                            const int32_t iQuant,
1775                                            int iFound)
1776    {
1777    /* Do a square search around given starting point, return SAD of best */
1778    
1779            int32_t iDirection = 0;
1780            int32_t iSAD;
1781            VECTOR backupMV;
1782    
1783            backupMV.x = start_x;
1784            backupMV.y = start_y;
1785    
1786    /* It's one search with full square pattern, and new parts for all following diamonds */
1787    
1788    /*   new direction are extra, so 1-4 is normal diamond
1789          537
1790          1*2
1791          648
1792    */
1793    
1794            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1795            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1796            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1797            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1798    
1799            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1800                                                             backupMV.y - iDiamondSize, 5);
1801            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1802                                                             backupMV.y + iDiamondSize, 6);
1803            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1804                                                             backupMV.y - iDiamondSize, 7);
1805            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1806                                                             backupMV.y + iDiamondSize, 8);
1807    
1808    
1809            if (iDirection) {
1810                    while (!iFound) {
1811                            iFound = 1;
1812                            backupMV = *currMV;
1813    
1814                            switch (iDirection) {
1815                            case 1:
1816                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1817                                                                                       backupMV.y, 1);
1818                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1819                                                                                     backupMV.y - iDiamondSize, 5);
1820                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1821                                                                                     backupMV.y - iDiamondSize, 7);
1822                                    break;
1823                            case 2:
1824                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1825                                                                                     2);
1826                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1827                                                                                     backupMV.y + iDiamondSize, 6);
1828                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1829                                                                                     backupMV.y + iDiamondSize, 8);
1830                                    break;
1831    
1832                            case 3:
1833                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1834                                                                                     4);
1835                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1836                                                                                     backupMV.y - iDiamondSize, 7);
1837                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1838                                                                                     backupMV.y + iDiamondSize, 8);
1839                                    break;
1840    
1841                            case 4:
1842                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1843                                                                                     3);
1844                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1845                                                                                     backupMV.y - iDiamondSize, 5);
1846                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1847                                                                                     backupMV.y + iDiamondSize, 6);
1848                                    break;
1849    
1850                            case 5:
1851                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1852                                                                                     1);
1853                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1854                                                                                     3);
1855                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1856                                                                                     backupMV.y - iDiamondSize, 5);
1857                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1858                                                                                     backupMV.y + iDiamondSize, 6);
1859                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1860                                                                                     backupMV.y - iDiamondSize, 7);
1861                                    break;
1862    
1863                            case 6:
1864                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1865                                                                                     2);
1866                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1867                                                                                     3);
1868    
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1870                                                                                     backupMV.y - iDiamondSize, 5);
1871                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1872                                                                                     backupMV.y + iDiamondSize, 6);
1873                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1874                                                                                     backupMV.y + iDiamondSize, 8);
1875    
1876                                    break;
1877    
1878                            case 7:
1879                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1880                                                                                       backupMV.y, 1);
1881                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1882                                                                                     4);
1883                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1884                                                                                     backupMV.y - iDiamondSize, 5);
1885                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1886                                                                                     backupMV.y - iDiamondSize, 7);
1887                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1888                                                                                     backupMV.y + iDiamondSize, 8);
1889                                    break;
1890    
1891                            case 8:
1892                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1893                                                                                     2);
1894                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1895                                                                                     4);
1896                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1897                                                                                     backupMV.y + iDiamondSize, 6);
1898                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1899                                                                                     backupMV.y - iDiamondSize, 7);
1900                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1901                                                                                     backupMV.y + iDiamondSize, 8);
1902                                    break;
1903                            default:
1904                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1905                                                                                     1);
1906                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1907                                                                                     2);
1908                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1909                                                                                     3);
1910                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1911                                                                                     4);
1912    
1913                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1914                                                                                     backupMV.y - iDiamondSize, 5);
1915                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1916                                                                                     backupMV.y + iDiamondSize, 6);
1917                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1918                                                                                     backupMV.y - iDiamondSize, 7);
1919                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1920                                                                                     backupMV.y + iDiamondSize, 8);
1921                                    break;
1922                            }
1923                    }
1924          } else {          } else {
1925                  currMV->x = start_x;                  currMV->x = start_x;
1926                  currMV->y = start_y;                  currMV->y = start_y;
# Line 1650  Line 1928 
1928          return iMinSAD;          return iMinSAD;
1929  }  }
1930    
1931    
1932    
1933    
1934    
1935  int32_t  int32_t
1936  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1937                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1788  Line 2070 
2070    
2071  // Prepare for main loop  // Prepare for main loop
2072    
2073  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2074  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2075  //  else    else
2076    
2077          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2078                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2468  Line 2750 
2750    
2751  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2752    
2753  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2754  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2755  //  else    else
2756    
2757          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2758                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2545  Line 2827 
2827                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2828                                  const int x,                                  const int x,
2829                                  const int y,                                  const int y,
2830                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2831                          const int start_y,                          const int start_y,
2832                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2833                          const int center_y,                          const int center_y,
2834                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2835                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2576  Line 2858 
2858          int32_t iFound;          int32_t iFound;
2859    
2860          VECTOR newMV;          VECTOR newMV;
2861          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2862    
2863          VECTOR pmv[4];          VECTOR pmv[4];
2864          int32_t psad[4];          int32_t psad[4];
# Line 2831  Line 3113 
3113    
3114  /* ***********************************************************  /* ***********************************************************
3115          bvop motion estimation          bvop motion estimation
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
3116  ***************************************************************/  ***************************************************************/
3117    
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
3118  void  void
3119  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3120                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 2860  Line 3137 
3137          const int mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3138          const int edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
3139    
3140            const int32_t iWidth = pParam->width;
3141            const int32_t iHeight = pParam->height;
3142    
3143          int i, j, k;          int i, j, k;
3144    
3145          static const VECTOR zeroMV={0,0};          static const VECTOR zeroMV={0,0};
# Line 2867  Line 3147 
3147          int f_sad16;    /* forward (as usual) search */          int f_sad16;    /* forward (as usual) search */
3148          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
3149          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
3150          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume almost linear motion) */
         int dnv_sad16;  /* direct mode (assume linear motion) without correction vector */  
3151    
3152          int best_sad;          int best_sad;
3153    
3154          VECTOR f_predMV, b_predMV;      /* there is no direct prediction */          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3155            VECTOR f_interpolMV, b_interpolMV;
3156          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3157    
3158            int min_dx, max_dx, min_dy, max_dy;
3159            int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3160            int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3161    
3162          int f_count=0;          int f_count=0;
3163          int b_count=0;          int b_count=0;
3164          int i_count=0;          int i_count=0;
3165          int d_count=0;          int d_count=0;
3166          int dnv_count=0;  
         int s_count=0;  
3167          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3168      const int64_t TRD = (int32_t)time_pp;      const int64_t TRD = (int32_t)time_pp;
3169    
# Line 2896  Line 3179 
3179                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
3180                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
3181    
3182                          VECTOR directMV;                          mb->deltamv=zeroMV;
                         VECTOR deltaMV=zeroMV;  
3183    
3184  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  /* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */
3185    
 #ifndef _DISABLE_SKIP  
3186                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3187                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3188                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
3189                                  mb->mvs[0].x = 0;                                  mb->b_mvs[0] = mb->mvs[0] = zeroMV;
                                 mb->mvs[0].y = 0;  
                                 mb->b_mvs[0].x = 0;  
                                 mb->b_mvs[0].y = 0;  
3190                                  continue;                                  continue;
3191                          }                          }
 #endif  
   
                         dnv_sad16 = DIRECT_PENALTY;  
3192    
3193                          if (b_mb->mode == MODE_INTER4V)                          if (b_mb->mode == MODE_INTER4V)
3194                          {                          {
3195                                    d_sad16 = 0;
3196                          /* same method of scaling as in decoder.c, so we copy from there */                          /* same method of scaling as in decoder.c, so we copy from there */
3197                      for (k = 0; k < 4; k++) {                      for (k = 0; k < 4; k++) {
3198    
3199                                          directMV = b_mb->mvs[k];                                          mb->directmv[k] = b_mb->mvs[k];
3200    
3201                                          mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                                          mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3202                      mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0)                      mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3203                                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3204                                              : mb->mvs[k].x - directMV.x);                                              : mb->mvs[k].x - mb->directmv[k].x);
3205                      mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
3206                          mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0)                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3207                                                                                  ? ((TRB - TRD) * directMV.y) / TRD                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3208                                              : mb->mvs[k].y - directMV.y);                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3209                                                : mb->mvs[k].y - mb->directmv[k].y);
3210    
3211                                          dnv_sad16 +=                                          d_sad16 +=
3212                                                  sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,                                                  sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
3213                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3214                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
# Line 2943  Line 3219 
3219                          }                          }
3220                          else                          else
3221                          {                          {
3222                                  directMV = b_mb->mvs[0];                                  mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
3223                                            mb->directmv[0] = b_mb->mvs[0];
3224    
3225                                  mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                                  mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3226                  mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3227                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                                                          ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3228                                      : mb->mvs[0].x - directMV.x);                                      : mb->mvs[0].x - mb->directmv[0].x);
3229                  mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
3230                      mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)                      mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3231                                                                  ? ((TRB - TRD) * directMV.y) / TRD                  mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3232                                  : mb->mvs[0].y - directMV.y);                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3233                                        : mb->mvs[0].y - mb->directmv[0].y);
3234    
3235                                  dnv_sad16 = DIRECT_PENALTY +                                  d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
                                         sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
3236                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3237                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3238                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3239                                                                  i, j, 16, &mb->b_mvs[0], edged_width),                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
3240                                                    edged_width);                                                    edged_width);
3241    
   
3242              }              }
3243                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
3244    
3245                          // forward search                          // forward search
3246                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3247                                                  &frame->image, i, j,                                                  &frame->image, i, j,
3248                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
3249                                                  f_predMV.x, f_predMV.y,                         /* center is f-prediction */                                                  f_predMV.x, f_predMV.y,                         /* center is f-prediction */
3250                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),                                                  frame->motion_flags,
3251                                                  frame->quant, frame->fcode, pParam,                                                  frame->quant, frame->fcode, pParam,
3252                                                  f_mbs, f_mbs,                                                  f_mbs, f_mbs,
3253                                                  &mb->mvs[0], &pmv_dontcare);                                                  &mb->mvs[0], &pmv_dontcare);
# Line 2981  Line 3258 
3258                                                  &frame->image, i, j,                                                  &frame->image, i, j,
3259                                                  mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */                                                  mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
3260                                                  b_predMV.x, b_predMV.y,                         /* center is b-prediction */                                                  b_predMV.x, b_predMV.y,                         /* center is b-prediction */
3261                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),                                                  frame->motion_flags,
3262                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
3263                                                  b_mbs, b_mbs,                                                  b_mbs, b_mbs,
3264                                                  &mb->b_mvs[0], &pmv_dontcare);                                                  &mb->b_mvs[0], &pmv_dontcare);
# Line 2995  Line 3272 
3272                                                    edged_width);                                                    edged_width);
3273                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3274                                                                  frame->fcode, frame->quant);                                                                  frame->fcode, frame->quant);
3275                      i_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3276                                                                  frame->bcode, frame->quant);                                                                  frame->bcode, frame->quant);
3277    
3278                          // TODO: direct search                          get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3279                          // predictor + delta vector in range [-32,32] (fcode=1)                            frame->fcode);
3280                            get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3281                              frame->bcode);
3282    
3283    /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3284       two values for everything, always one for backward and one for forward ME. Still, we don't gain
3285       much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3286       as "optimal". */
3287    
3288                            i_sad16 = Diamond16_InterpolMainSearch(
3289                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3290                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3291                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3292                                                    i, j,
3293                                                    mb->mvs[0].x, mb->mvs[0].y,
3294                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,
3295                                                    i_sad16,
3296                                                    &f_interpolMV, &b_interpolMV,
3297                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3298                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3299                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3300                                                    edged_width,  1,
3301                                                    frame->fcode, frame->bcode,frame->quant,0);
3302    
3303    
3304    /*  DIRECT MODE DELTA VECTOR SEARCH.
3305        This has to be made more effective, but at the moment I'm happy it's running at all */
3306    
3307    /* range is taken without fcode restriction, just a hack instead of writing down the dimensions, of course */
3308    
3309                            get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3310    
3311                            d_sad16 = Diamond16_DirectMainSearch(
3312                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3313                                                    frame->image.y + i*16 + j*16*edged_width,
3314                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3315                                                    i, j,
3316                                                    TRB,TRD,
3317                                                    0,0,
3318                                                    d_sad16,
3319                                                    &mb->deltamv,
3320                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[}
3321                                            min_dx, max_dx, min_dy, max_dy,
3322                                                    edged_width, 1, frame->quant, 0);
3323    
3324    
3325  //                      i_sad16 = 65535;  //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3326  //                      f_sad16 = 65535;  //                      f_sad16 = 65535;
3327  //                      b_sad16 = 65535;  //                      b_sad16 = 65535;
3328    //                      d_sad16 = 65535;
3329    
3330                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3331                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 3018  Line 3340 
3340                                  mb->mode = MODE_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
3341                          }                          }
3342    
3343                          if (dnv_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3344    
3345                                  if (dnv_sad16 > DIRECT_UPPERLIMIT)                                  if (b_mb->mode == MODE_INTER4V)
3346                                  {                                  {
                                         /* if SAD value is too large, try same vector with MODE_INTERPOLATE  
                                            instead (interpolate has residue encoding, direct mode without MV  
                                            doesn't)  
3347    
3348                                                  This has to be replaced later by "real" direct mode, including delta                                  /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */
3349                                                  vector and (if needed) residue encoding                                  /* for the bitstream, the value mb->deltamv is read directly */
3350    
3351                                          */                              for (k = 0; k < 4; k++) {
3352    
3353                                          directMV = b_mb->mvs[0];                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3354                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3355                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3356                                                        : mb->mvs[k].x - mb->directmv[k].x);
3357    
3358                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3359                            mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3360                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3361                                                : mb->mvs[k].y - mb->directmv[k].y);
3362                                            }
3363                                    }
3364                                    else
3365                                    {
3366                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3367    
3368                                          mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3369                      mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)                                                                                  ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3370                                                                                  ? ((TRB - TRD) * directMV.x) / TRD                                          : mb->mvs[0].x - mb->directmv[0].x);
                                         : mb->mvs[0].x - directMV.x);  
                         mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);  
                         mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)  
                                                                                 ? ((TRB - TRD) * directMV.y) / TRD  
                                             : mb->mvs[0].y - directMV.y);  
3371    
3372                                          dnv_sad16 =                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
                                                 sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
                                 dnv_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,  
                                                                 frame->fcode, frame->quant);  
                                     dnv_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,  
                                                                 frame->bcode, frame->quant);  
3373    
3374                                          if (dnv_sad16 < best_sad)                          mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3375                                          {                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3376                                                  best_sad = dnv_sad16;                                              : mb->mvs[0].y - mb->directmv[0].y);
                                                 mb->mode = MODE_INTERPOLATE;  
3377    
3378  /*                                              fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n",                                          mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3379                                                          f_sad16,b_sad16,i_sad16,dnv_sad16);                                          mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
 */                                      }  
                                 }  
                                 else  
                                 {  
                                         best_sad = dnv_sad16;  
                                         mb->mode = MODE_DIRECT_NONE_MV;  
3380                                  }                                  }
3381    
3382                                    best_sad = d_sad16;
3383                                    mb->mode = MODE_DIRECT;
3384                          }                          }
3385    
3386                          switch (mb->mode)                          switch (mb->mode)
# Line 3083  Line 3396 
3396                                          break;                                          break;
3397                                  case MODE_INTERPOLATE:                                  case MODE_INTERPOLATE:
3398                                          i_count++;                                          i_count++;
3399                                            mb->mvs[0] = f_interpolMV;
3400                                            mb->b_mvs[0] = b_interpolMV;
3401                                          f_predMV = mb->mvs[0];                                          f_predMV = mb->mvs[0];
3402                                          b_predMV = mb->b_mvs[0];                                          b_predMV = mb->b_mvs[0];
3403                                          break;                                          break;
3404                                  case MODE_DIRECT:                                  case MODE_DIRECT:
3405                                          d_count++; break;                                          d_count++;
3406                                  case MODE_DIRECT_NONE_MV:                                          break;
                                         dnv_count++; break;  
3407                                  default:                                  default:
3408                                          s_count++; break;                                          break;
3409                          }                          }
3410    
3411                  }                  }
3412          }          }
3413    
3414  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3415          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D0: %04d   D: %04d   S: %04d\n",          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d\n",
3416                                  f_count,b_count,i_count,dnv_count,d_count,s_count);                                  f_count,b_count,i_count,d_count);
3417  #endif  #endif
3418    
3419  }  }

Legend:
Removed from v.337  
changed lines
  Added in v.347

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