[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 345, Sat Jul 27 23:47:01 2002 UTC revision 430, Fri Sep 6 16:59:47 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      motion estimation   *  - Motion Estimation module -
5     *
6     *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>
7     *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>
8     *  Copyright(C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>
9     *  Copyright(C) 2002 chenm001 <chenm001@163.com>
10   *   *
11   *      This program is an implementation of a part of one or more MPEG-4   *      This program is an implementation of a part of one or more MPEG-4
12   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
# Line 24  Line 29 
29   *   *
30   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
31   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
32   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
33   *   *
34   *************************************************************************/   *************************************************************************/
35    
 /**************************************************************************  
  *  
  *  Modifications:  
  *  
  *      01.05.2002      updated MotionEstimationBVOP  
  *      25.04.2002 partial prevMB conversion  
  *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>  
  *  14.04.2002 added MotionEstimationBVOP()  
  *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between  
  *             EPZS and EPZS^2  
  *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop  
  *             PMVFast_Refine to support multiple searches with different start points  
  *  07.01.2002 uv-block-based interpolation  
  *  06.01.2002 INTER/INTRA-decision is now done before any SEARCH8 (speedup)  
  *             changed INTER_BIAS to 150 (as suggested by suxen_drol)  
  *             removed halfpel refinement step in PMVfastSearch8 + quality=5  
  *             added new quality mode = 6 which performs halfpel refinement  
  *             filesize difference between quality 5 and 6 is smaller than 1%  
  *             (Isibaar)  
  *  31.12.2001 PMVfastSearch16 and PMVfastSearch8 (gruel)  
  *  30.12.2001 get_range/MotionSearchX simplified; blue/green bug fix  
  *  22.12.2001 commented best_point==99 check  
  *  19.12.2001 modified get_range (purple bug fix)  
  *  15.12.2001 moved pmv displacement from mbprediction  
  *  02.12.2001 motion estimation/compensation split (Isibaar)  
  *  16.11.2001 rewrote/tweaked search algorithms; pross@cs.rmit.edu.au  
  *  10.11.2001 support for sad16/sad8 functions  
  *  28.08.2001 reactivated MODE_INTER4V for EXT_MODE  
  *  24.08.2001 removed MODE_INTER4V_Q, disabled MODE_INTER4V for EXT_MODE  
  *  22.08.2001 added MODE_INTER4V_Q  
  *  20.08.2001 added pragma to get rid of internal compiler error with VC6  
  *             idea by Cyril. Thanks.  
  *  
  *  Michael Militzer <isibaar@videocoding.de>  
  *  
  **************************************************************************/  
   
36  #include <assert.h>  #include <assert.h>
37  #include <stdio.h>  #include <stdio.h>
38  #include <stdlib.h>  #include <stdlib.h>
# Line 186  Line 154 
154    
155                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
156    
157                            if (pMB->mode == MODE_NOT_CODED)
158                                    continue;
159    
160                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
161    
162                          pMB->sad16 =                          pMB->sad16 =
# Line 874  Line 845 
845          return iMinSAD;          return iMinSAD;
846  }  }
847    
848    #define CHECK_MV16_F_INTERPOL(X,Y) { \
849  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
850    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((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); } } \  
 }  
   
 #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,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_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
851    { \    { \
852      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
853      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),       \
854                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
855                            iEdgedWidth); \
856        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
857        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
858      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
859      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
860  }  }
861    
862    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
863  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
864    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
865    { \    { \
866      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
867      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),       \
868                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
869                            iEdgedWidth); \
870        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
871        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
872      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
873      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
874  }  }
875    
876    #define CHECK_MV16_B_INTERPOL(X,Y) { \
877  #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
878    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
879    { \    { \
880      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
881      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),   \
882                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
883                            iEdgedWidth); \
884        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
885        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
886      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
887      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
888  }  }
889    
890    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
891  #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
892    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
893    { \    { \
894      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
895      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),   \
896                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
897                            iEdgedWidth); \
898        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
899        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
900      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
901      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
902  }  }
903    
   
 #if (0==1)  
904  int32_t  int32_t
905  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(
906                                          const uint8_t * const f_pRef,                                          const uint8_t * const f_pRef,
907                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
908                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
909                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
910    
911                                           const uint8_t * const cur,                                           const uint8_t * const cur,
912    
913                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 970  Line 932 
932                                     const int b_center_x,                                     const int b_center_x,
933                                     const int b_center_y,                                     const int b_center_y,
934    
935                                           const int32_t min_dx,                                      const int32_t f_min_dx,
936                                           const int32_t max_dx,                                          const int32_t f_max_dx,
937                                           const int32_t min_dy,                                          const int32_t f_min_dy,
938                                           const int32_t max_dy,                                          const int32_t f_max_dy,
939    
940                                        const int32_t b_min_dx,
941                                            const int32_t b_max_dx,
942                                            const int32_t b_min_dy,
943                                            const int32_t b_max_dy,
944    
945                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
946                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
947    
# Line 985  Line 953 
953  {  {
954  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
955    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
956          int32_t iSAD;          int32_t iSAD;
957    
958          VECTOR f_backupMV;          VECTOR f_backupMV;
959          VECTOR b_backupMV;          VECTOR b_backupMV;
960    
961          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
962          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
963          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
964          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
965    
966  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
967            {
968                    iFound = 1;
969    
970          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);  
971    
972          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
973                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
974                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
975                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
976    
977                    b_backupMV = *b_currMV;
978    
979                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
980                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
981                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
982                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
983    
984            } while (!iFound);
985    
986            return iMinSAD;
987    }
988    
989    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
990    
991    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
992            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
993            { int k;\
994            VECTOR mvs,b_mvs;       \
995            iSAD = 0;\
996            for (k = 0; k < 4; k++) {       \
997                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
998                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
999                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1000                                                : mvs.x - directmv[k].x);                           \
1001                                                                                                                                                                    \
1002                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1003                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1004                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1005                                                : mvs.y - directmv[k].y);                           \
1006                                                                                                                                                                    \
1007      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1008        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1009            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1010        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1011                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1012                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1013                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1014                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1015                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1016                            iEdgedWidth); \
1017                    }       \
1018            else    \
1019                    iSAD = 65535;   \
1020            } \
1021            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1022            if (iSAD < iMinSAD) \
1023                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1024    }
1025    
1026    
1027    
1028    int32_t
1029    Diamond16_DirectMainSearch(
1030                                            const uint8_t * const f_pRef,
1031                                            const uint8_t * const f_pRefH,
1032                                            const uint8_t * const f_pRefV,
1033                                            const uint8_t * const f_pRefHV,
1034    
1035                                            const uint8_t * const cur,
1036    
1037                                            const uint8_t * const b_pRef,
1038                                            const uint8_t * const b_pRefH,
1039                                            const uint8_t * const b_pRefV,
1040                                            const uint8_t * const b_pRefHV,
1041    
1042                                            const int x,
1043                                            const int y,
1044    
1045                                            const int TRB,
1046                                            const int TRD,
1047    
1048                                        const int start_x,
1049                                        const int start_y,
1050    
1051                                        int iMinSAD,
1052                                        VECTOR * const currMV,
1053                                            const VECTOR * const directmv,
1054    
1055                                        const int32_t min_dx,
1056                                            const int32_t max_dx,
1057                                            const int32_t min_dy,
1058                                            const int32_t max_dy,
1059    
1060                                            const int32_t iEdgedWidth,
1061                                            const int32_t iDiamondSize,
1062    
1063                                            const int32_t iQuant,
1064                                            int iFound)
1065    {
1066    /* Do a diamond search around given starting point, return SAD of best */
1067    
1068            int32_t iSAD;
1069    
1070            VECTOR backupMV;
1071    
                         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 {  
1072                  currMV->x = start_x;                  currMV->x = start_x;
1073                  currMV->y = start_y;                  currMV->y = start_y;
1074          }  
1075    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1076    
1077            do
1078            {
1079                    iFound = 1;
1080    
1081                    backupMV = *currMV;
1082    
1083                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1084                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1085                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1086                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1087    
1088            } while (!iFound);
1089    
1090          return iMinSAD;          return iMinSAD;
1091  }  }
 #endif  
1092    
1093    
1094  int32_t  int32_t
# Line 1278  Line 1339 
1339                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1340                                  const int x,                                  const int x,
1341                                  const int y,                                  const int y,
1342                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1343                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1344                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1345                                  const int center_y,                                  const int center_y,
1346                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1347                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2737  Line 2798 
2798                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2799                                  const int x,                                  const int x,
2800                                  const int y,                                  const int y,
2801                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2802                          const int start_y,                          const int start_y,
2803                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2804                          const int center_y,                          const int center_y,
2805                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2806                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2768  Line 2829 
2829          int32_t iFound;          int32_t iFound;
2830    
2831          VECTOR newMV;          VECTOR newMV;
2832          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2833    
2834          VECTOR pmv[4];          VECTOR pmv[4];
2835          int32_t psad[4];          int32_t psad[4];
# Line 2798  Line 2859 
2859                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2860    
2861          } else {          } else {
2862    
2863                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2864    
2865                  threshA = psad[0];                  threshA = psad[0];
2866                  threshB = threshA + 256;                  threshB = threshA + 256;
2867                  if (threshA < 512)                  if (threshA < 512)
# Line 2807  Line 2871 
2871                  if (threshB > 1792)                  if (threshB > 1792)
2872                          threshB = 1792;                          threshB = 1792;
2873    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2874                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2875          }          }
2876    
# Line 3023  Line 3086 
3086    
3087  /* ***********************************************************  /* ***********************************************************
3088          bvop motion estimation          bvop motion estimation
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
3089  ***************************************************************/  ***************************************************************/
3090    
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
3091  void  void
3092  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3093                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 3052  Line 3110 
3110          const int mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3111          const int edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
3112    
3113            const int32_t iWidth = pParam->width;
3114            const int32_t iHeight = pParam->height;
3115    
3116          int i, j, k;          int i, j, k;
3117    
3118          static const VECTOR zeroMV={0,0};          static const VECTOR zeroMV={0,0};
# Line 3059  Line 3120 
3120          int f_sad16;    /* forward (as usual) search */          int f_sad16;    /* forward (as usual) search */
3121          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
3122          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
3123          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume almost linear motion) */
3124    
3125          int best_sad;          int best_sad;
3126    
3127          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3128            VECTOR f_interpolMV, b_interpolMV;
3129          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3130    
3131            int min_dx, max_dx, min_dy, max_dy;
3132            int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3133            int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3134    
3135          int f_count=0;          int f_count=0;
3136          int b_count=0;          int b_count=0;
3137          int i_count=0;          int i_count=0;
3138          int d_count=0;          int d_count=0;
         int s_count=0;  
3139    
3140          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3141      const int64_t TRD = (int32_t)time_pp;      const int64_t TRD = (int32_t)time_pp;
# Line 3089  Line 3154 
3154    
3155                          mb->deltamv=zeroMV;                          mb->deltamv=zeroMV;
3156    
3157  /* 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 */
3158    
 #ifndef _DISABLE_SKIP  
3159                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3160                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3161                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
3162                                  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;  
3163                                  continue;                                  continue;
3164                          }                          }
 #endif  
   
                         d_sad16 = DIRECT_PENALTY;  
3165    
3166                          if (b_mb->mode == MODE_INTER4V)                          if (b_mb->mode == MODE_INTER4V)
3167                          {                          {
3168                                    d_sad16 = 0;
3169                          /* 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 */
3170                      for (k = 0; k < 4; k++) {                      for (k = 0; k < 4; k++) {
3171    
# Line 3119  Line 3177 
3177                                              : mb->mvs[k].x - mb->directmv[k].x);                                              : mb->mvs[k].x - mb->directmv[k].x);
3178    
3179                      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);
3180                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3181                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3182                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3183    
3184                                          d_sad16 +=                                          d_sad16 +=
3185                                                  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,
3186                                                    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,
3187                                                                  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),
3188                                                    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,
3189                                                                  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),
3190                                                    edged_width);                                                    edged_width);
3191                                  }                                  }
3192                          }                          }
# Line 3147  Line 3205 
3205                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3206                                      : mb->mvs[0].y - mb->directmv[0].y);                                      : mb->mvs[0].y - mb->directmv[0].y);
3207    
3208                                  d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,                                  d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3209                                                    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,
3210                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3211                                                    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 3190  Line 3248 
3248                      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,
3249                                                                  frame->bcode, frame->quant);                                                                  frame->bcode, frame->quant);
3250    
3251                          // TODO: direct search                          get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3252                          // predictor + delta vector in range [-32,32] (fcode=1)                            frame->fcode);
3253                            get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3254                              frame->bcode);
3255    
3256    /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3257       two values for everything, always one for backward and one for forward ME. Still, we don't gain
3258       much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3259       as "optimal". */
3260    
3261                            i_sad16 = Diamond16_InterpolMainSearch(
3262                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3263                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3264                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3265                                                    i, j,
3266                                                    mb->mvs[0].x, mb->mvs[0].y,
3267                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,
3268                                                    i_sad16,
3269                                                    &f_interpolMV, &b_interpolMV,
3270                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3271                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3272                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3273                                                    edged_width,  2,
3274                                                    frame->fcode, frame->bcode,frame->quant,0);
3275    
3276                            i_sad16 = Diamond16_InterpolMainSearch(
3277                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3278                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3279                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3280                                                    i, j,
3281                                                    f_interpolMV.x, f_interpolMV.y,
3282                                                    b_interpolMV.x, b_interpolMV.y,
3283                                                    i_sad16,
3284                                                    &f_interpolMV, &b_interpolMV,
3285                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3286                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3287                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3288                                                    edged_width,  1,
3289                                                    frame->fcode, frame->bcode,frame->quant,0);             // equiv to halfpel refine
3290    
3291    
3292    /*  DIRECT MODE DELTA VECTOR SEARCH.
3293        This has to be made more effective, but at the moment I'm happy it's running at all */
3294    
3295    /* There are two range restrictions for direct mode: deltaMV is limited to [-32,31] in halfpel units, and
3296       absolute vector must not lie outside of image dimensions. Constraint one is dealt with by CHECK_MV16_DIRECT
3297       and for constraint two we need distance to boundary. This is done by get_range very large fcode (hack!) */
3298    
3299                            get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3300    
3301                            d_sad16 = Diamond16_DirectMainSearch(
3302                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3303                                                    frame->image.y + i*16 + j*16*edged_width,
3304                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3305                                                    i, j,
3306                                                    TRB,TRD,
3307                                                    0,0,
3308                                                    d_sad16,
3309                                                    &mb->deltamv,
3310                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3311                                            min_dx, max_dx, min_dy, max_dy,
3312                                                    edged_width, 2, frame->quant, 0);
3313    
3314                            d_sad16 = Diamond16_DirectMainSearch(
3315                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3316                                                    frame->image.y + i*16 + j*16*edged_width,
3317                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3318                                                    i, j,
3319                                                    TRB,TRD,
3320                                                    mb->deltamv.x, mb->deltamv.y,
3321                                                    d_sad16,
3322                                                    &mb->deltamv,
3323                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3324                                            min_dx, max_dx, min_dy, max_dy,
3325                                                    edged_width, 1, frame->quant, 0);               // equiv to halfpel refine
3326    
3327    
3328                          i_sad16 = 65535;  //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3329                          f_sad16 = 65535;  //                      f_sad16 = 65535;
3330                          b_sad16 = 65535;  //                      b_sad16 = 65535;
3331  //                      d_sad16 = 65535;  //                      d_sad16 = 65535;
3332    
3333                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
# Line 3216  Line 3348 
3348                                  if (b_mb->mode == MODE_INTER4V)                                  if (b_mb->mode == MODE_INTER4V)
3349                                  {                                  {
3350    
3351                                  /* 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 */
3352                                    /* for the bitstream, the value mb->deltamv is read directly */
3353    
3354                              for (k = 0; k < 4; k++) {                              for (k = 0; k < 4; k++) {
3355    
3356                                                  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 3225  Line 3359 
3359                                                      : mb->mvs[k].x - mb->directmv[k].x);                                                      : mb->mvs[k].x - mb->directmv[k].x);
3360    
3361                              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);
3362                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3363                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3364                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3365                                          }                                          }
# Line 3240  Line 3374 
3374    
3375                              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);
3376    
3377                          mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)                          mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3378                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3379                                              : mb->mvs[0].y - mb->directmv[0].y);                                              : mb->mvs[0].y - mb->directmv[0].y);
3380    
# Line 3250  Line 3384 
3384    
3385                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3386                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
                                 mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(  
3387                          }                          }
3388    
3389                          switch (mb->mode)                          switch (mb->mode)
# Line 3266  Line 3399 
3399                                          break;                                          break;
3400                                  case MODE_INTERPOLATE:                                  case MODE_INTERPOLATE:
3401                                          i_count++;                                          i_count++;
3402                                            mb->mvs[0] = f_interpolMV;
3403                                            mb->b_mvs[0] = b_interpolMV;
3404                                          f_predMV = mb->mvs[0];                                          f_predMV = mb->mvs[0];
3405                                          b_predMV = mb->b_mvs[0];                                          b_predMV = mb->b_mvs[0];
3406                                          break;                                          break;
# Line 3273  Line 3408 
3408                                          d_count++;                                          d_count++;
3409                                          break;                                          break;
3410                                  default:                                  default:
                                         s_count++;              // ???  
3411                                          break;                                          break;
3412                          }                          }
3413    
# Line 3281  Line 3415 
3415          }          }
3416    
3417  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3418          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",
3419                                  f_count,b_count,i_count,d_count,s_count);                                  f_count,b_count,i_count,d_count);
3420  #endif  #endif
3421    
3422  }  }

Legend:
Removed from v.345  
changed lines
  Added in v.430

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