[svn] / trunk / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/motion_est.c

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

revision 344, Sat Jul 27 23:07:33 2002 UTC revision 370, Mon Aug 12 10:07:16 2002 UTC
# Line 186  Line 186 
186    
187                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
188    
189                            if (pMB->mode == MODE_NOT_CODED)
190                                    continue;
191    
192                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
193    
194                          pMB->sad16 =                          pMB->sad16 =
# Line 554  Line 557 
557                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
558    
559    
560          if (iDirection)          if (iDirection) {
561                  while (!iFound) {                  while (!iFound) {
562                          iFound = 1;                          iFound = 1;
563                          backupMV = *currMV;                          backupMV = *currMV;
# Line 563  Line 566 
566                          case 1:                          case 1:
567                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
568                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
569                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
570                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
571                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
572                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
573                                  break;                                  break;
574                          case 2:                          case 2:
575                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
576                                                                                   2);                                                                                   2);
577                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
578                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
579                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
580                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
581                                  break;                                  break;
582    
583                          case 3:                          case 3:
584                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
585                                                                                   4);                                                                                   4);
586                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
587                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
588                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
589                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
590                                  break;                                  break;
591    
592                          case 4:                          case 4:
593                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
594                                                                                   3);                                                                                   3);
595                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
596                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
597                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
598                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
599                                  break;                                  break;
600    
601                          case 5:                          case 5:
602                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
603                                                                                   1);                                                                                   1);
604                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
605                                                                                   3);                                                                                   3);
606                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
607                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
608                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
609                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
610                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
611                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
612                                  break;                                  break;
613    
614                          case 6:                          case 6:
615                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
616                                                                                   2);                                                                                   2);
617                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
618                                                                                   3);                                                                                   3);
619    
620                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
621                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
622                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
623                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
624                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
625                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
626    
627                                  break;                                  break;
# Line 626  Line 629 
629                          case 7:                          case 7:
630                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
631                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
632                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
633                                                                                   4);                                                                                   4);
634                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
635                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
636                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
637                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
638                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
639                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
640                                  break;                                  break;
641    
642                          case 8:                          case 8:
643                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
644                                                                                   2);                                                                                   2);
645                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
646                                                                                   4);                                                                                   4);
647                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
648                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
649                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
650                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
651                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
652                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
653                                  break;                                  break;
654                          default:                          default:
655                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
656                                                                                   1);                                                                                   1);
657                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
658                                                                                   2);                                                                                   2);
659                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
660                                                                                   3);                                                                                   3);
661                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
662                                                                                   4);                                                                                   4);
663    
664                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
665                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
666                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
667                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
668                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
669                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
670                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
671                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
672                                  break;                                  break;
673                          }                          }
674                    }
675          } else {          } else {
676                  currMV->x = start_x;                  currMV->x = start_x;
677                  currMV->y = start_y;                  currMV->y = start_y;
# Line 873  Line 877 
877          return iMinSAD;          return iMinSAD;
878  }  }
879    
880    #define CHECK_MV16_F_INTERPOL(X,Y) { \
881  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
882    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
883    { \    { \
884      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
885      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),       \
886                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
887                            iEdgedWidth); \
888        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
889        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
890      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
891      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
892  }  }
893    
894  #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
895    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
896      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
897    { \    { \
898      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
899      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),       \
900                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
901                            iEdgedWidth); \
902        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
903        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
904      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
905      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
906  }  }
907    
908  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  #define CHECK_MV16_B_INTERPOL(X,Y) { \
909    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
910      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
911    { \    { \
912      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
913      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),   \
914                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
915                            iEdgedWidth); \
916        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
917        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
918      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
919      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
920  }  }
921    
922    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
923  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
924    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
925    { \    { \
926      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
927      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),   \
928      if (iSAD < iMinSAD) \                          get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
929      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \                          iEdgedWidth); \
930  }      iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
931        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
   
 #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);\  
932      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
933      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
934  }  }
935    
   
 #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)  
936  int32_t  int32_t
937  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(
938                                          const uint8_t * const f_pRef,                                          const uint8_t * const f_pRef,
939                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
940                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
941                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
942    
943                                           const uint8_t * const cur,                                           const uint8_t * const cur,
944    
945                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 969  Line 964 
964                                     const int b_center_x,                                     const int b_center_x,
965                                     const int b_center_y,                                     const int b_center_y,
966    
967                                           const int32_t min_dx,                                      const int32_t f_min_dx,
968                                           const int32_t max_dx,                                          const int32_t f_max_dx,
969                                           const int32_t min_dy,                                          const int32_t f_min_dy,
970                                           const int32_t max_dy,                                          const int32_t f_max_dy,
971    
972                                        const int32_t b_min_dx,
973                                            const int32_t b_max_dx,
974                                            const int32_t b_min_dy,
975                                            const int32_t b_max_dy,
976    
977                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
978                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
979    
# Line 984  Line 985 
985  {  {
986  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
987    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
988          int32_t iSAD;          int32_t iSAD;
989    
990          VECTOR f_backupMV;          VECTOR f_backupMV;
991          VECTOR b_backupMV;          VECTOR b_backupMV;
992    
993          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
994          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
995          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
996          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
997    
998  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
999            {
1000                    iFound = 1;
1001    
1002          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);  
1003    
1004          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
1005                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
1006                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
1007                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
1008    
1009                    b_backupMV = *b_currMV;
1010    
1011                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
1012                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
1013                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
1014                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
1015    
1016            } while (!iFound);
1017    
1018            return iMinSAD;
1019    }
1020    
1021    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
1022    
1023    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
1024            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
1025            { int k;\
1026            VECTOR mvs,b_mvs;       \
1027            iSAD = 0;\
1028            for (k = 0; k < 4; k++) {       \
1029                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
1030                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
1031                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1032                                                : mvs.x - directmv[k].x);                           \
1033                                                                                                                                                                    \
1034                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1035                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1036                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1037                                                : mvs.y - directmv[k].y);                           \
1038                                                                                                                                                                    \
1039      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1040        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1041            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1042        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1043                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1044                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1045                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1046                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1047                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1048                            iEdgedWidth); \
1049                    }       \
1050            else    \
1051                    iSAD = 65535;   \
1052            } \
1053            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1054            if (iSAD < iMinSAD) \
1055                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1056    }
1057    
1058    
1059    
1060    int32_t
1061    Diamond16_DirectMainSearch(
1062                                            const uint8_t * const f_pRef,
1063                                            const uint8_t * const f_pRefH,
1064                                            const uint8_t * const f_pRefV,
1065                                            const uint8_t * const f_pRefHV,
1066    
1067                                            const uint8_t * const cur,
1068    
1069                                            const uint8_t * const b_pRef,
1070                                            const uint8_t * const b_pRefH,
1071                                            const uint8_t * const b_pRefV,
1072                                            const uint8_t * const b_pRefHV,
1073    
1074                                            const int x,
1075                                            const int y,
1076    
1077                                            const int TRB,
1078                                            const int TRD,
1079    
1080                                        const int start_x,
1081                                        const int start_y,
1082    
1083                                        int iMinSAD,
1084                                        VECTOR * const currMV,
1085                                            const VECTOR * const directmv,
1086    
1087                                        const int32_t min_dx,
1088                                            const int32_t max_dx,
1089                                            const int32_t min_dy,
1090                                            const int32_t max_dy,
1091    
1092                                            const int32_t iEdgedWidth,
1093                                            const int32_t iDiamondSize,
1094    
1095                                            const int32_t iQuant,
1096                                            int iFound)
1097    {
1098    /* Do a diamond search around given starting point, return SAD of best */
1099    
1100            int32_t iSAD;
1101    
1102            VECTOR backupMV;
1103    
                         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 {  
1104                  currMV->x = start_x;                  currMV->x = start_x;
1105                  currMV->y = start_y;                  currMV->y = start_y;
1106          }  
1107    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1108    
1109            do
1110            {
1111                    iFound = 1;
1112    
1113                    backupMV = *currMV;
1114    
1115                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1116                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1117                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1118                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1119    
1120            } while (!iFound);
1121    
1122          return iMinSAD;          return iMinSAD;
1123  }  }
 #endif  
1124    
1125    
1126  int32_t  int32_t
# Line 1277  Line 1371 
1371                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1372                                  const int x,                                  const int x,
1373                                  const int y,                                  const int y,
1374                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1375                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1376                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1377                                  const int center_y,                                  const int center_y,
1378                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1379                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1656  Line 1750 
1750          return iMinSAD;          return iMinSAD;
1751  }  }
1752    
1753    
1754    
1755    
1756    int32_t
1757    Square8_MainSearch(const uint8_t * const pRef,
1758                                            const uint8_t * const pRefH,
1759                                            const uint8_t * const pRefV,
1760                                            const uint8_t * const pRefHV,
1761                                            const uint8_t * const cur,
1762                                            const int x,
1763                                            const int y,
1764                                            int32_t start_x,
1765                                            int32_t start_y,
1766                                            int32_t iMinSAD,
1767                                            VECTOR * const currMV,
1768                                       const int center_x,
1769                                       const int center_y,
1770                                            const int32_t min_dx,
1771                                            const int32_t max_dx,
1772                                            const int32_t min_dy,
1773                                            const int32_t max_dy,
1774                                            const int32_t iEdgedWidth,
1775                                            const int32_t iDiamondSize,
1776                                            const int32_t iFcode,
1777                                            const int32_t iQuant,
1778                                            int iFound)
1779    {
1780    /* Do a square search around given starting point, return SAD of best */
1781    
1782            int32_t iDirection = 0;
1783            int32_t iSAD;
1784            VECTOR backupMV;
1785    
1786            backupMV.x = start_x;
1787            backupMV.y = start_y;
1788    
1789    /* It's one search with full square pattern, and new parts for all following diamonds */
1790    
1791    /*   new direction are extra, so 1-4 is normal diamond
1792          537
1793          1*2
1794          648
1795    */
1796    
1797            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1798            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1799            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1800            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1801    
1802            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1803                                                             backupMV.y - iDiamondSize, 5);
1804            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1805                                                             backupMV.y + iDiamondSize, 6);
1806            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1807                                                             backupMV.y - iDiamondSize, 7);
1808            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1809                                                             backupMV.y + iDiamondSize, 8);
1810    
1811    
1812            if (iDirection) {
1813                    while (!iFound) {
1814                            iFound = 1;
1815                            backupMV = *currMV;
1816    
1817                            switch (iDirection) {
1818                            case 1:
1819                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1820                                                                                       backupMV.y, 1);
1821                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1822                                                                                     backupMV.y - iDiamondSize, 5);
1823                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1824                                                                                     backupMV.y - iDiamondSize, 7);
1825                                    break;
1826                            case 2:
1827                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1828                                                                                     2);
1829                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1830                                                                                     backupMV.y + iDiamondSize, 6);
1831                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1832                                                                                     backupMV.y + iDiamondSize, 8);
1833                                    break;
1834    
1835                            case 3:
1836                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1837                                                                                     4);
1838                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1839                                                                                     backupMV.y - iDiamondSize, 7);
1840                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1841                                                                                     backupMV.y + iDiamondSize, 8);
1842                                    break;
1843    
1844                            case 4:
1845                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1846                                                                                     3);
1847                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1848                                                                                     backupMV.y - iDiamondSize, 5);
1849                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1850                                                                                     backupMV.y + iDiamondSize, 6);
1851                                    break;
1852    
1853                            case 5:
1854                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1855                                                                                     1);
1856                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1857                                                                                     3);
1858                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1859                                                                                     backupMV.y - iDiamondSize, 5);
1860                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1861                                                                                     backupMV.y + iDiamondSize, 6);
1862                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1863                                                                                     backupMV.y - iDiamondSize, 7);
1864                                    break;
1865    
1866                            case 6:
1867                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1868                                                                                     2);
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1870                                                                                     3);
1871    
1872                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1873                                                                                     backupMV.y - iDiamondSize, 5);
1874                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1875                                                                                     backupMV.y + iDiamondSize, 6);
1876                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1877                                                                                     backupMV.y + iDiamondSize, 8);
1878    
1879                                    break;
1880    
1881                            case 7:
1882                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1883                                                                                       backupMV.y, 1);
1884                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1885                                                                                     4);
1886                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1887                                                                                     backupMV.y - iDiamondSize, 5);
1888                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1889                                                                                     backupMV.y - iDiamondSize, 7);
1890                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1891                                                                                     backupMV.y + iDiamondSize, 8);
1892                                    break;
1893    
1894                            case 8:
1895                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1896                                                                                     2);
1897                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1898                                                                                     4);
1899                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1900                                                                                     backupMV.y + iDiamondSize, 6);
1901                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1902                                                                                     backupMV.y - iDiamondSize, 7);
1903                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1904                                                                                     backupMV.y + iDiamondSize, 8);
1905                                    break;
1906                            default:
1907                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1908                                                                                     1);
1909                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1910                                                                                     2);
1911                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1912                                                                                     3);
1913                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1914                                                                                     4);
1915    
1916                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1917                                                                                     backupMV.y - iDiamondSize, 5);
1918                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1919                                                                                     backupMV.y + iDiamondSize, 6);
1920                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1921                                                                                     backupMV.y - iDiamondSize, 7);
1922                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1923                                                                                     backupMV.y + iDiamondSize, 8);
1924                                    break;
1925                            }
1926                    }
1927            } else {
1928                    currMV->x = start_x;
1929                    currMV->y = start_y;
1930            }
1931            return iMinSAD;
1932    }
1933    
1934    
1935    
1936    
1937    
1938  int32_t  int32_t
1939  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1940                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1794  Line 2073 
2073    
2074  // Prepare for main loop  // Prepare for main loop
2075    
2076  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2077  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2078  //  else    else
2079    
2080          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2081                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2474  Line 2753 
2753    
2754  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2755    
2756  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2757  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2758  //  else    else
2759    
2760          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2761                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2551  Line 2830 
2830                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2831                                  const int x,                                  const int x,
2832                                  const int y,                                  const int y,
2833                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2834                          const int start_y,                          const int start_y,
2835                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2836                          const int center_y,                          const int center_y,
2837                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2838                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2582  Line 2861 
2861          int32_t iFound;          int32_t iFound;
2862    
2863          VECTOR newMV;          VECTOR newMV;
2864          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2865    
2866          VECTOR pmv[4];          VECTOR pmv[4];
2867          int32_t psad[4];          int32_t psad[4];
# Line 2612  Line 2891 
2891                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2892    
2893          } else {          } else {
2894    
2895                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2896    
2897                  threshA = psad[0];                  threshA = psad[0];
2898                  threshB = threshA + 256;                  threshB = threshA + 256;
2899                  if (threshA < 512)                  if (threshA < 512)
# Line 2621  Line 2903 
2903                  if (threshB > 1792)                  if (threshB > 1792)
2904                          threshB = 1792;                          threshB = 1792;
2905    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2906                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2907          }          }
2908    
# Line 2837  Line 3118 
3118    
3119  /* ***********************************************************  /* ***********************************************************
3120          bvop motion estimation          bvop motion estimation
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
3121  ***************************************************************/  ***************************************************************/
3122    
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
3123  void  void
3124  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3125                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 2866  Line 3142 
3142          const int mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3143          const int edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
3144    
3145            const int32_t iWidth = pParam->width;
3146            const int32_t iHeight = pParam->height;
3147    
3148          int i, j, k;          int i, j, k;
3149    
3150          static const VECTOR zeroMV={0,0};          static const VECTOR zeroMV={0,0};
# Line 2873  Line 3152 
3152          int f_sad16;    /* forward (as usual) search */          int f_sad16;    /* forward (as usual) search */
3153          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
3154          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
3155          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume almost linear motion) */
3156    
3157          int best_sad;          int best_sad;
3158    
3159          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3160            VECTOR f_interpolMV, b_interpolMV;
3161          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3162    
3163            int min_dx, max_dx, min_dy, max_dy;
3164            int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3165            int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3166    
3167          int f_count=0;          int f_count=0;
3168          int b_count=0;          int b_count=0;
3169          int i_count=0;          int i_count=0;
3170          int d_count=0;          int d_count=0;
         int s_count=0;  
3171    
3172          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3173      const int64_t TRD = (int32_t)time_pp;      const int64_t TRD = (int32_t)time_pp;
# Line 2903  Line 3186 
3186    
3187                          mb->deltamv=zeroMV;                          mb->deltamv=zeroMV;
3188    
3189  /* 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 */
3190    
 #ifndef _DISABLE_SKIP  
3191                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3192                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3193                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
3194                                  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;  
3195                                  continue;                                  continue;
3196                          }                          }
 #endif  
   
                         d_sad16 = DIRECT_PENALTY;  
3197    
3198                          if (b_mb->mode == MODE_INTER4V)                          if (b_mb->mode == MODE_INTER4V)
3199                          {                          {
3200                                    d_sad16 = 0;
3201                          /* 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 */
3202                      for (k = 0; k < 4; k++) {                      for (k = 0; k < 4; k++) {
3203    
# Line 2933  Line 3209 
3209                                              : mb->mvs[k].x - mb->directmv[k].x);                                              : mb->mvs[k].x - mb->directmv[k].x);
3210    
3211                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3212                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3213                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3214                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3215    
3216                                          d_sad16 +=                                          d_sad16 +=
3217                                                  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,
3218                                                    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,
3219                                                                  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),
3220                                                    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,
3221                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),                                                                  (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
3222                                                    edged_width);                                                    edged_width);
3223                                  }                                  }
3224                          }                          }
# Line 2961  Line 3237 
3237                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3238                                      : mb->mvs[0].y - mb->directmv[0].y);                                      : mb->mvs[0].y - mb->directmv[0].y);
3239    
3240                                  d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,                                  d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3241                                                    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,
3242                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3243                                                    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,
# Line 3004  Line 3280 
3280                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, 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,
3281                                                                  frame->bcode, frame->quant);                                                                  frame->bcode, frame->quant);
3282    
3283                          // TODO: direct search                          get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3284                          // predictor + delta vector in range [-32,32] (fcode=1)                            frame->fcode);
3285                            get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3286                              frame->bcode);
3287    
3288    /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3289       two values for everything, always one for backward and one for forward ME. Still, we don't gain
3290       much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3291       as "optimal". */
3292    
3293                            i_sad16 = Diamond16_InterpolMainSearch(
3294                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3295                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3296                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3297                                                    i, j,
3298                                                    mb->mvs[0].x, mb->mvs[0].y,
3299                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,
3300                                                    i_sad16,
3301                                                    &f_interpolMV, &b_interpolMV,
3302                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3303                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3304                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3305                                                    edged_width,  2,
3306                                                    frame->fcode, frame->bcode,frame->quant,0);
3307    
3308                            i_sad16 = Diamond16_InterpolMainSearch(
3309                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3310                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3311                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3312                                                    i, j,
3313                                                    f_interpolMV.x, f_interpolMV.y,
3314                                                    b_interpolMV.x, b_interpolMV.y,
3315                                                    i_sad16,
3316                                                    &f_interpolMV, &b_interpolMV,
3317                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3318                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3319                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3320                                                    edged_width,  1,
3321                                                    frame->fcode, frame->bcode,frame->quant,0);             // equiv to halfpel refine
3322    
3323    
3324    /*  DIRECT MODE DELTA VECTOR SEARCH.
3325        This has to be made more effective, but at the moment I'm happy it's running at all */
3326    
3327    /* There are two range restrictions for direct mode: deltaMV is limited to [-32,31] in halfpel units, and
3328       absolute vector must not lie outside of image dimensions. Constraint one is dealt with by CHECK_MV16_DIRECT
3329       and for constraint two we need distance to boundary. This is done by get_range very large fcode (hack!) */
3330    
3331                            get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3332    
3333                            d_sad16 = Diamond16_DirectMainSearch(
3334                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3335                                                    frame->image.y + i*16 + j*16*edged_width,
3336                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3337                                                    i, j,
3338                                                    TRB,TRD,
3339                                                    0,0,
3340                                                    d_sad16,
3341                                                    &mb->deltamv,
3342                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3343                                            min_dx, max_dx, min_dy, max_dy,
3344                                                    edged_width, 2, frame->quant, 0);
3345    
3346                          i_sad16 = 65535;                          d_sad16 = Diamond16_DirectMainSearch(
3347                          f_sad16 = 65535;                                                  f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3348                          b_sad16 = 65535;                                                  frame->image.y + i*16 + j*16*edged_width,
3349                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3350                                                    i, j,
3351                                                    TRB,TRD,
3352                                                    mb->deltamv.x, mb->deltamv.y,
3353                                                    d_sad16,
3354                                                    &mb->deltamv,
3355                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3356                                            min_dx, max_dx, min_dy, max_dy,
3357                                                    edged_width, 1, frame->quant, 0);               // equiv to halfpel refine
3358    
3359    
3360    //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3361    //                      f_sad16 = 65535;
3362    //                      b_sad16 = 65535;
3363  //                      d_sad16 = 65535;  //                      d_sad16 = 65535;
3364    
3365                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
# Line 3030  Line 3380 
3380                                  if (b_mb->mode == MODE_INTER4V)                                  if (b_mb->mode == MODE_INTER4V)
3381                                  {                                  {
3382    
3383                                  /* same method of scaling as in decoder.c, so we copy from there */                                  /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */
3384                                    /* for the bitstream, the value mb->deltamv is read directly */
3385    
3386                              for (k = 0; k < 4; k++) {                              for (k = 0; k < 4; k++) {
3387    
3388                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
# Line 3039  Line 3391 
3391                                                      : mb->mvs[k].x - mb->directmv[k].x);                                                      : mb->mvs[k].x - mb->directmv[k].x);
3392    
3393                              mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);                              mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3394                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3395                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3396                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3397                                          }                                          }
# Line 3054  Line 3406 
3406    
3407                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3408    
3409                          mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)                          mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3410                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3411                                              : mb->mvs[0].y - mb->directmv[0].y);                                              : mb->mvs[0].y - mb->directmv[0].y);
3412    
# Line 3064  Line 3416 
3416    
3417                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3418                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
                                 mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(  
3419                          }                          }
3420    
3421                          switch (mb->mode)                          switch (mb->mode)
# Line 3080  Line 3431 
3431                                          break;                                          break;
3432                                  case MODE_INTERPOLATE:                                  case MODE_INTERPOLATE:
3433                                          i_count++;                                          i_count++;
3434                                            mb->mvs[0] = f_interpolMV;
3435                                            mb->b_mvs[0] = b_interpolMV;
3436                                          f_predMV = mb->mvs[0];                                          f_predMV = mb->mvs[0];
3437                                          b_predMV = mb->b_mvs[0];                                          b_predMV = mb->b_mvs[0];
3438                                          break;                                          break;
# Line 3087  Line 3440 
3440                                          d_count++;                                          d_count++;
3441                                          break;                                          break;
3442                                  default:                                  default:
                                         s_count++;              // ???  
3443                                          break;                                          break;
3444                          }                          }
3445    
# Line 3095  Line 3447 
3447          }          }
3448    
3449  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3450          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d\n",
3451                                  f_count,b_count,i_count,d_count,s_count);                                  f_count,b_count,i_count,d_count);
3452  #endif  #endif
3453    
3454  }  }

Legend:
Removed from v.344  
changed lines
  Added in v.370

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