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

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

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

revision 345, Sat Jul 27 23:47:01 2002 UTC revision 486, Mon Sep 16 21:41:20 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   *   *
10   *      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
11   *      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 28 
28   *   *
29   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
30   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
31   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
32   *   *
33   *************************************************************************/   *************************************************************************/
34    
 /**************************************************************************  
  *  
  *  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>  
  *  
  **************************************************************************/  
   
35  #include <assert.h>  #include <assert.h>
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
# Line 174  Line 141 
141          static const VECTOR zeroMV = { 0, 0 };          static const VECTOR zeroMV = { 0, 0 };
142          VECTOR predMV;          VECTOR predMV;
143    
144          int32_t x, y;          uint32_t x, y;
145          int32_t iIntra = 0;          uint32_t iIntra = 0;
146          VECTOR pmv;          VECTOR pmv;
147    
148          if (sadInit)          if (sadInit)
# Line 723  Line 690 
690                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
691                                                  const int x,                                                  const int x,
692                                                  const int y,                                                  const int y,
693                                             int start_x,                                                  const int start_xi,
694                                             int start_y,                                                  const int start_yi,
695                                             int iMinSAD,                                             int iMinSAD,
696                                             VECTOR * const currMV,                                             VECTOR * const currMV,
697                                             const int center_x,                                             const int center_x,
# Line 741  Line 708 
708  {  {
709    
710          int32_t iSAD;          int32_t iSAD;
711            int start_x = start_xi, start_y = start_yi;
712    
713  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
714    
# Line 874  Line 842 
842          return iMinSAD;          return iMinSAD;
843  }  }
844    
845    #define CHECK_MV16_F_INTERPOL(X,Y) { \
846  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
847    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) ) \  
848    { \    { \
849      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
850      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),       \
851                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
852                            iEdgedWidth); \
853        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
854        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
855      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
856      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
857  }  }
858    
859    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
860  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
861    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
862    { \    { \
863      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
864      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),       \
865                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
866                            iEdgedWidth); \
867        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
868        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
869      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
870      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
871  }  }
872    
873    #define CHECK_MV16_B_INTERPOL(X,Y) { \
874  #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
875    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
876    { \    { \
877      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
878      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),   \
879                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
880                            iEdgedWidth); \
881        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
882        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
883      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
884      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
885  }  }
886    
887    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
888  #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
889    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
890    { \    { \
891      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
892      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),   \
893                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
894                            iEdgedWidth); \
895        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
896        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
897      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
898      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
899  }  }
900    
   
 #if (0==1)  
901  int32_t  int32_t
902  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(const uint8_t * const f_pRef,
                                         const uint8_t * const f_pRef,  
903                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
904                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
905                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
906    
907                                           const uint8_t * const cur,                                           const uint8_t * const cur,
908    
909                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 970  Line 928 
928                                     const int b_center_x,                                     const int b_center_x,
929                                     const int b_center_y,                                     const int b_center_y,
930    
931                                           const int32_t min_dx,                                                           const int32_t f_min_dx,
932                                           const int32_t max_dx,                                                           const int32_t f_max_dx,
933                                           const int32_t min_dy,                                                           const int32_t f_min_dy,
934                                           const int32_t max_dy,                                                           const int32_t f_max_dy,
935    
936                                                             const int32_t b_min_dx,
937                                                             const int32_t b_max_dx,
938                                                             const int32_t b_min_dy,
939                                                             const int32_t b_max_dy,
940    
941                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
942                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
943    
# Line 985  Line 949 
949  {  {
950  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
951    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
952          int32_t iSAD;          int32_t iSAD;
953    
954          VECTOR f_backupMV;          VECTOR f_backupMV;
955          VECTOR b_backupMV;          VECTOR b_backupMV;
956    
957          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
958          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
959          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
960          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
961    
962  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
963            {
964                    iFound = 1;
965    
966          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);  
967    
968          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
969                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
970                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
971                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
972    
973                    b_backupMV = *b_currMV;
974    
975                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
976                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
977                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
978                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
979    
980            } while (!iFound);
981    
982            return iMinSAD;
983    }
984    
985    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
986    
987    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
988            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
989            { int k;\
990            VECTOR mvs,b_mvs;       \
991            iSAD = 0;\
992            for (k = 0; k < 4; k++) {       \
993                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
994                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
995                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
996                                                : mvs.x - directmv[k].x);                           \
997                                                                                                                                                                    \
998                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
999                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1000                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1001                                                : mvs.y - directmv[k].y);                           \
1002                                                                                                                                                                    \
1003      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1004        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1005            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1006        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1007                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1008                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1009                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1010                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1011                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1012                            iEdgedWidth); \
1013                    }       \
1014            else    \
1015                    iSAD = 65535;   \
1016            } \
1017            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1018            if (iSAD < iMinSAD) \
1019                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1020    }
1021    
1022    
1023    
1024    int32_t
1025    Diamond16_DirectMainSearch(
1026                                            const uint8_t * const f_pRef,
1027                                            const uint8_t * const f_pRefH,
1028                                            const uint8_t * const f_pRefV,
1029                                            const uint8_t * const f_pRefHV,
1030    
1031                                            const uint8_t * const cur,
1032    
1033                                            const uint8_t * const b_pRef,
1034                                            const uint8_t * const b_pRefH,
1035                                            const uint8_t * const b_pRefV,
1036                                            const uint8_t * const b_pRefHV,
1037    
1038                                            const int x,
1039                                            const int y,
1040    
1041                                            const int TRB,
1042                                            const int TRD,
1043    
1044                                        const int start_x,
1045                                        const int start_y,
1046    
1047                                        int iMinSAD,
1048                                        VECTOR * const currMV,
1049                                            const VECTOR * const directmv,
1050    
1051                                        const int32_t min_dx,
1052                                            const int32_t max_dx,
1053                                            const int32_t min_dy,
1054                                            const int32_t max_dy,
1055    
1056                                            const int32_t iEdgedWidth,
1057                                            const int32_t iDiamondSize,
1058    
1059                                            const int32_t iQuant,
1060                                            int iFound)
1061    {
1062    /* Do a diamond search around given starting point, return SAD of best */
1063    
1064            int32_t iSAD;
1065    
1066            VECTOR backupMV;
1067    
                         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 {  
1068                  currMV->x = start_x;                  currMV->x = start_x;
1069                  currMV->y = start_y;                  currMV->y = start_y;
1070          }  
1071    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1072    
1073            do
1074            {
1075                    iFound = 1;
1076    
1077                    backupMV = *currMV;
1078    
1079                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1080                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1081                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1082                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1083    
1084            } while (!iFound);
1085    
1086          return iMinSAD;          return iMinSAD;
1087  }  }
 #endif  
1088    
1089    
1090  int32_t  int32_t
# Line 1038  Line 1095 
1095                                             const uint8_t * const cur,                                             const uint8_t * const cur,
1096                                             const int x,                                             const int x,
1097                                             const int y,                                             const int y,
1098                                             int start_x,                                             const int start_xi,
1099                                             int start_y,                                             const int start_yi,
1100                                             int iMinSAD,                                             int iMinSAD,
1101                                             VECTOR * const currMV,                                             VECTOR * const currMV,
1102                                             const int center_x,                                             const int center_x,
# Line 1056  Line 1113 
1113  {  {
1114    
1115          int32_t iSAD;          int32_t iSAD;
1116            int start_x = start_xi, start_y = start_yi;
1117    
1118  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
1119    
# Line 1278  Line 1336 
1336                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1337                                  const int x,                                  const int x,
1338                                  const int y,                                  const int y,
1339                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1340                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1341                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1342                                  const int center_y,                                  const int center_y,
1343                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1344                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1335  Line 1393 
1393          }          }
1394    
1395          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
         //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);  
1396          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1397    
1398          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 1393  Line 1450 
1450          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1451                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1452                   ((int32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1453                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode
1454                  {                  {
1455                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
1456                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
# Line 1598  Line 1655 
1655                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1656                                          const int x,                                          const int x,
1657                                          const int y,                                          const int y,
1658                                          int32_t start_x,                                          const int32_t start_x,
1659                                          int32_t start_y,                                          const int32_t start_y,
1660                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1661                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1662                                     const int center_x,                                     const int center_x,
# Line 1668  Line 1725 
1725                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1726                                          const int x,                                          const int x,
1727                                          const int y,                                          const int y,
1728                                          int32_t start_x,                                     const int32_t start_x,
1729                                          int32_t start_y,                                     const int32_t start_y,
1730                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1731                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1732                                     const int center_x,                                     const int center_x,
# Line 1950  Line 2007 
2007          }          }
2008    
2009          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
         //bPredEq = get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad);  
2010          bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);
2011    
2012          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 2265  Line 2321 
2321                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2322          }          }
2323          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
         //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);  
2324          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2325    
2326  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2548  Line 2603 
2603                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2604          }          }
2605          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
         //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv[0].x, pmv[0].y, psad);  
2606          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2607    
2608    
# Line 2737  Line 2791 
2791                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2792                                  const int x,                                  const int x,
2793                                  const int y,                                  const int y,
2794                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2795                          const int start_y,                          const int start_y,
2796                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2797                          const int center_y,                          const int center_y,
2798                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2799                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2768  Line 2822 
2822          int32_t iFound;          int32_t iFound;
2823    
2824          VECTOR newMV;          VECTOR newMV;
2825          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2826    
2827          VECTOR pmv[4];          VECTOR pmv[4];
2828          int32_t psad[4];          int32_t psad[4];
2829    
2830          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
2831    
2832          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          MACROBLOCK *const prevMB = (MACROBLOCK *const)prevMBs + x + y * iWcount;
2833          MACROBLOCK *const pMB = pMBs + x + y * iWcount;          MACROBLOCK *const pMB = (MACROBLOCK *const)(pMBs + x + y * iWcount);
2834    
2835          int32_t threshA, threshB;          int32_t threshA, threshB;
2836          int32_t bPredEq;          int32_t bPredEq;
# Line 2798  Line 2852 
2852                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2853    
2854          } else {          } else {
2855    
2856                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2857    
2858                  threshA = psad[0];                  threshA = psad[0];
2859                  threshB = threshA + 256;                  threshB = threshA + 256;
2860                  if (threshA < 512)                  if (threshA < 512)
# Line 2807  Line 2864 
2864                  if (threshB > 1792)                  if (threshB > 1792)
2865                          threshB = 1792;                          threshB = 1792;
2866    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2867                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2868          }          }
2869    
# Line 2844  Line 2900 
2900          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
2901                  ((MVequal(*currMV, prevMB->i_mvs[0])) &&                  ((MVequal(*currMV, prevMB->i_mvs[0])) &&
2902                   ((int32_t) iMinSAD < prevMB->i_sad16))) {                   ((int32_t) iMinSAD < prevMB->i_sad16))) {
2903                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode
2904                  {                  {
2905                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
2906                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
# Line 3013  Line 3069 
3069    
3070          pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)          pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)
3071    
 PMVfastInt16_Terminate_without_Refine:  
3072          currPMV->x = currMV->x - center_x;          currPMV->x = currMV->x - center_x;
3073          currPMV->y = currMV->y - center_y;          currPMV->y = currMV->y - center_y;
3074          return iMinSAD;          return iMinSAD;
3075  }  }
3076    
   
   
 /* ***********************************************************  
         bvop motion estimation  
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
 ***************************************************************/  
   
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
 void  
 MotionEstimationBVOP(MBParam * const pParam,  
                                          FRAMEINFO * const frame,  
                                          const int32_t time_bp,  
                                          const int32_t time_pp,  
                                          // forward (past) reference  
                                          const MACROBLOCK * const f_mbs,  
                                          const IMAGE * const f_ref,  
                                          const IMAGE * const f_refH,  
                                          const IMAGE * const f_refV,  
                                          const IMAGE * const f_refHV,  
                                          // backward (future) reference  
                                          const MACROBLOCK * const b_mbs,  
                                          const IMAGE * const b_ref,  
                                          const IMAGE * const b_refH,  
                                          const IMAGE * const b_refV,  
                                          const IMAGE * const b_refHV)  
 {  
         const int mb_width = pParam->mb_width;  
         const int mb_height = pParam->mb_height;  
         const int edged_width = pParam->edged_width;  
   
         int i, j, k;  
   
         static const VECTOR zeroMV={0,0};  
   
         int f_sad16;    /* forward (as usual) search */  
         int b_sad16;    /* backward (only in b-frames) search */  
         int i_sad16;    /* interpolated (both direction, b-frames only) */  
         int d_sad16;    /* direct mode (assume linear motion) */  
   
         int best_sad;  
   
         VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/  
         VECTOR pmv_dontcare;  
   
         int f_count=0;  
         int b_count=0;  
         int i_count=0;  
         int d_count=0;  
         int s_count=0;  
   
         const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;  
     const int64_t TRD = (int32_t)time_pp;  
   
         // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);  
         // note: i==horizontal, j==vertical  
         for (j = 0; j < mb_height; j++) {  
   
                 f_predMV = zeroMV;      /* prediction is reset at left boundary */  
                 b_predMV = zeroMV;  
   
                 for (i = 0; i < mb_width; i++) {  
                         MACROBLOCK *mb = &frame->mbs[i + j * mb_width];  
                         const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];  
                         const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];  
   
                         mb->deltamv=zeroMV;  
   
 /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  
   
 #ifndef _DISABLE_SKIP  
                         if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&  
                                 b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {  
                                 mb->mode = MODE_NOT_CODED;  
                                 mb->mvs[0].x = 0;  
                                 mb->mvs[0].y = 0;  
                                 mb->b_mvs[0].x = 0;  
                                 mb->b_mvs[0].y = 0;  
                                 continue;  
                         }  
 #endif  
   
                         d_sad16 = DIRECT_PENALTY;  
   
                         if (b_mb->mode == MODE_INTER4V)  
                         {  
   
                         /* same method of scaling as in decoder.c, so we copy from there */  
                     for (k = 0; k < 4; k++) {  
   
                                         mb->directmv[k] = b_mb->mvs[k];  
   
                                         mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);  
                     mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[k].x) / TRD  
                                             : mb->mvs[k].x - mb->directmv[k].x);  
   
                     mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);  
                         mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[k].y) / TRD  
                                             : mb->mvs[k].y - mb->directmv[k].y);  
   
                                         d_sad16 +=  
                                                 sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),  
                                                   edged_width);  
                                 }  
                         }  
                         else  
                         {  
                                 mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =  
                                 mb->directmv[0] = b_mb->mvs[0];  
   
                                 mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);  
                     mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                         ? ((TRB - TRD) * mb->directmv[0].x) / TRD  
                                     : mb->mvs[0].x - mb->directmv[0].x);  
   
                     mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);  
                 mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)  
                                                                         ? ((TRB - TRD) * mb->directmv[0].y) / TRD  
                                     : mb->mvs[0].y - mb->directmv[0].y);  
   
                                 d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
   
             }  
                     d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);  
   
                         // forward search  
                         f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                 &frame->image, i, j,  
                                                 mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */  
                                                 f_predMV.x, f_predMV.y,                         /* center is f-prediction */  
                                                 frame->motion_flags,  
                                                 frame->quant, frame->fcode, pParam,  
                                                 f_mbs, f_mbs,  
                                                 &mb->mvs[0], &pmv_dontcare);  
   
   
                         // backward search  
                         b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                 &frame->image, i, j,  
                                                 mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */  
                                                 b_predMV.x, b_predMV.y,                         /* center is b-prediction */  
                                                 frame->motion_flags,  
                                                 frame->quant, frame->bcode, pParam,  
                                                 b_mbs, b_mbs,  
                                                 &mb->b_mvs[0], &pmv_dontcare);  
   
                         i_sad16 =  
                                 sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
                     i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,  
                                                                 frame->fcode, frame->quant);  
                     i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,  
                                                                 frame->bcode, frame->quant);  
   
                         // TODO: direct search  
                         // predictor + delta vector in range [-32,32] (fcode=1)  
   
                         i_sad16 = 65535;  
                         f_sad16 = 65535;  
                         b_sad16 = 65535;  
 //                      d_sad16 = 65535;  
   
                         if (f_sad16 < b_sad16) {  
                                 best_sad = f_sad16;  
                                 mb->mode = MODE_FORWARD;  
                         } else {  
                                 best_sad = b_sad16;  
                                 mb->mode = MODE_BACKWARD;  
                         }  
   
                         if (i_sad16 < best_sad) {  
                                 best_sad = i_sad16;  
                                 mb->mode = MODE_INTERPOLATE;  
                         }  
   
                         if (d_sad16 < best_sad) {  
   
                                 if (b_mb->mode == MODE_INTER4V)  
                                 {  
   
                                 /* same method of scaling as in decoder.c, so we copy from there */  
                             for (k = 0; k < 4; k++) {  
   
                                                 mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);  
                             mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                         ? ((TRB - TRD) * mb->directmv[k].x) / TRD  
                                                     : mb->mvs[k].x - mb->directmv[k].x);  
   
                             mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);  
                         mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)  
                                                                                         ? ((TRB - TRD) * mb->directmv[k].y) / TRD  
                                             : mb->mvs[k].y - mb->directmv[k].y);  
                                         }  
                                 }  
                                 else  
                                 {  
                                         mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);  
   
                     mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[0].x) / TRD  
                                         : mb->mvs[0].x - mb->directmv[0].x);  
   
                             mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);  
   
                         mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[0].y) / TRD  
                                             : mb->mvs[0].y - mb->directmv[0].y);  
   
                                         mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];  
                                         mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];  
                 }  
   
                                 best_sad = d_sad16;  
                                 mb->mode = MODE_DIRECT;  
                                 mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(  
                         }  
   
                         switch (mb->mode)  
                         {  
                                 case MODE_FORWARD:  
                                         f_count++;  
                                         f_predMV = mb->mvs[0];  
                                         break;  
                                 case MODE_BACKWARD:  
                                         b_count++;  
                                         b_predMV = mb->b_mvs[0];  
   
                                         break;  
                                 case MODE_INTERPOLATE:  
                                         i_count++;  
                                         f_predMV = mb->mvs[0];  
                                         b_predMV = mb->b_mvs[0];  
                                         break;  
                                 case MODE_DIRECT:  
                                         d_count++;  
                                         break;  
                                 default:  
                                         s_count++;              // ???  
                                         break;  
                         }  
   
                 }  
         }  
   
 #ifdef _DEBUG_BFRAME_STAT  
         fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",  
                                 f_count,b_count,i_count,d_count,s_count);  
 #endif  
   
 }  

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

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