ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/dev-api-3/xvidcore/src/motion/motion_est.c
(Generate patch)

Comparing trunk/xvidcore/src/motion/motion_est.c (file contents):
Revision 345 by chl, Sat Jul 27 23:47:01 2002 UTC vs.
Revision 346 by chl, Sun Jul 28 02:55:41 2002 UTC

# Line 874 | Line 874 | AdvDiamond16_MainSearch(const uint8_t *
874          return iMinSAD;
875   }
876  
877 <
878 < #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \
879 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
880 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
881 <  { \
882 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
883 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
884 <    if (iSAD < iMinSAD) \
885 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
886 < }
887 <
888 < #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \
889 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
890 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
891 <  { \
892 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
893 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
894 <    if (iSAD < iMinSAD) \
895 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
896 < }
897 <
898 < #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \
899 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
900 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
877 > #define CHECK_MV16_F_INTERPOL(X,Y) { \
878 >  if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
879 >    && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
880    { \
881 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
882 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
881 >    iSAD = sad16bi( cur, \
882 >                        get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
883 >                        get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
884 >                        iEdgedWidth); \
885 >    iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
886 >    iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
887      if (iSAD < iMinSAD) \
888 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
888 >    {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
889   }
890  
891 <
892 < #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \
893 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
911 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
891 > #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
892 >  if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
893 >    && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
894    { \
895 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
896 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
895 >    iSAD = sad16bi( cur, \
896 >                        get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
897 >                        get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
898 >                        iEdgedWidth); \
899 >    iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
900 >    iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
901      if (iSAD < iMinSAD) \
902 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
902 >    {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
903   }
904  
905 <
906 < #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \
907 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
922 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
905 > #define CHECK_MV16_B_INTERPOL(X,Y) { \
906 >  if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
907 >    && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
908    { \
909 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
910 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
909 >    iSAD = sad16bi( cur, \
910 >                        get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
911 >                        get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
912 >                        iEdgedWidth); \
913 >    iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
914 >    iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
915      if (iSAD < iMinSAD) \
916 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
916 >    {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
917   }
918  
919 <
920 < #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \
921 <  if ( ((X) <= max_dx) && ((X) >= min_dx) \
933 <    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
919 > #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
920 >  if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
921 >    && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
922    { \
923 <    iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
924 <    iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
923 >    iSAD = sad16bi( cur, \
924 >                        get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
925 >                        get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
926 >                        iEdgedWidth); \
927 >    iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
928 >    iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
929      if (iSAD < iMinSAD) \
930 <    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
930 >    {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
931   }
932  
941
942 #if (0==1)
933   int32_t
934   Diamond16_InterpolMainSearch(
935                                          const uint8_t * const f_pRef,
936                                           const uint8_t * const f_pRefH,
937                                           const uint8_t * const f_pRefV,
938                                           const uint8_t * const f_pRefHV,
939 +
940                                           const uint8_t * const cur,
941  
942                                          const uint8_t * const b_pRef,
# Line 970 | Line 961 | Diamond16_InterpolMainSearch(
961                                     const int b_center_x,
962                                     const int b_center_y,
963  
964 <                                         const int32_t min_dx,
965 <                                         const int32_t max_dx,
966 <                                         const int32_t min_dy,
967 <                                         const int32_t max_dy,
968 <                                         const int32_t iEdgedWidth,
969 <                                         const int32_t iDiamondSize,
964 >                                    const int32_t f_min_dx,
965 >                                        const int32_t f_max_dx,
966 >                                        const int32_t f_min_dy,
967 >                                        const int32_t f_max_dy,
968 >
969 >                                    const int32_t b_min_dx,
970 >                                        const int32_t b_max_dx,
971 >                                        const int32_t b_min_dy,
972 >                                        const int32_t b_max_dy,
973 >
974 >                                        const int32_t iEdgedWidth,
975 >                                        const int32_t iDiamondSize,
976  
977 <                                         const int32_t f_iFcode,
978 <                                         const int32_t b_iFcode,
977 >                                        const int32_t f_iFcode,
978 >                                        const int32_t b_iFcode,
979  
980 <                                         const int32_t iQuant,
981 <                                         int iFound)
980 >                                        const int32_t iQuant,
981 >                                        int iFound)
982   {
983   /* Do a diamond search around given starting point, return SAD of best */
984  
988        int32_t f_iDirection = 0;
989        int32_t b_iDirection = 0;
985          int32_t iSAD;
986  
987          VECTOR f_backupMV;
988          VECTOR b_backupMV;
989  
990 <        f_backupMV.x = start_x;
991 <        f_backupMV.y = start_y;
992 <        b_backupMV.x = start_x;
993 <        b_backupMV.y = start_y;
990 >        f_currMV->x = f_start_x;
991 >        f_currMV->y = f_start_y;
992 >        b_currMV->x = b_start_x;
993 >        b_currMV->y = b_start_y;
994 >
995 >        do
996 >        {      
997 >                iFound = 1;
998 >        
999 >                f_backupMV = *f_currMV;
1000 >        
1001 >                CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
1002 >                CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
1003 >                CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
1004 >                CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
1005 >
1006 >                b_backupMV = *b_currMV;
1007 >
1008 >                CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
1009 >                CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
1010 >                CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
1011 >                CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
1012 >
1013 >        } while (!iFound);
1014 >
1015 >        return iMinSAD;
1016 > }
1017 >
1018 > /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
1019 >
1020 > #define CHECK_MV16_DIRECT_FOUND(X,Y) \
1021 >        if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
1022 >        { int k;\
1023 >        VECTOR mvs,b_mvs;       \
1024 >        iSAD = 0;\
1025 >        for (k = 0; k < 4; k++) {       \
1026 >                                        mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
1027 >                    b_mvs.x = (int32_t) (((X) == 0)                                                     \
1028 >                                                                                ? ((TRB - TRD) * directmv[k].x) / TRD   \
1029 >                                            : mvs.x - directmv[k].x);                           \
1030 >                                                                                                                                                                \
1031 >                    mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1032 >                        b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1033 >                                                                                ? ((TRB - TRD) * directmv[k].y) / TRD   \
1034 >                                            : mvs.y - directmv[k].y);                           \
1035 >                                                                                                                                                                \
1036 >  if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1037 >    && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1038 >        && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1039 >    && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1040 >            iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1041 >                        get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1042 >                                        mvs.x, mvs.y, iEdgedWidth),                                                             \
1043 >                        get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1044 >                                        b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1045 >                        iEdgedWidth); \
1046 >                }       \
1047 >        else    \
1048 >                iSAD = 65535;   \
1049 >        } \
1050 >        iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1051 >        if (iSAD < iMinSAD) \
1052 >            {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1053 > }
1054 >
1055 >
1056 >
1057 > int32_t
1058 > Diamond16_DirectMainSearch(
1059 >                                        const uint8_t * const f_pRef,
1060 >                                        const uint8_t * const f_pRefH,
1061 >                                        const uint8_t * const f_pRefV,
1062 >                                        const uint8_t * const f_pRefHV,
1063 >
1064 >                                        const uint8_t * const cur,
1065 >
1066 >                                        const uint8_t * const b_pRef,
1067 >                                        const uint8_t * const b_pRefH,
1068 >                                        const uint8_t * const b_pRefV,
1069 >                                        const uint8_t * const b_pRefHV,
1070 >
1071 >                                        const int x,
1072 >                                        const int y,
1073 >
1074 >                                        const int TRB,
1075 >                                        const int TRD,
1076 >
1077 >                                    const int start_x,
1078 >                                    const int start_y,
1079 >
1080 >                                    int iMinSAD,
1081 >                                    VECTOR * const currMV,
1082 >                                        const VECTOR * const directmv,
1083 >
1084 >                                    const int32_t min_dx,
1085 >                                        const int32_t max_dx,
1086 >                                        const int32_t min_dy,
1087 >                                        const int32_t max_dy,
1088 >
1089 >                                        const int32_t iEdgedWidth,
1090 >                                        const int32_t iDiamondSize,
1091 >
1092 >                                        const int32_t iQuant,
1093 >                                        int iFound)
1094 > {
1095 > /* Do a diamond search around given starting point, return SAD of best */
1096 >
1097 >        int32_t iSAD;
1098 >
1099 >        VECTOR backupMV;
1100 >
1101 >        currMV->x = start_x;
1102 >        currMV->y = start_y;
1103  
1104   /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1105  
1106 <        CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1107 <        CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1108 <        CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1109 <        CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1106 >        do
1107 >        {
1108 >                iFound = 1;
1109 >        
1110 >                backupMV = *currMV;
1111 >        
1112 >                CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1113 >                CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1114 >                CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1115 >                CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1116  
1117 <        if (iDirection)
1008 <                while (!iFound) {
1009 <                        iFound = 1;
1010 <                        backupMV = *currMV;
1117 >        } while (!iFound);
1118  
1012                        if (iDirection != 2)
1013                                CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1014                                                                                   backupMV.y, 1);
1015                        if (iDirection != 1)
1016                                CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1017                                                                                   backupMV.y, 2);
1018                        if (iDirection != 4)
1019                                CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1020                                                                                   backupMV.y - iDiamondSize, 3);
1021                        if (iDirection != 3)
1022                                CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1023                                                                                   backupMV.y + iDiamondSize, 4);
1024        } else {
1025                currMV->x = start_x;
1026                currMV->y = start_y;
1027        }
1119          return iMinSAD;
1120   }
1030 #endif
1121  
1122  
1123   int32_t
# Line 1278 | Line 1368 | PMVfastSearch16(const uint8_t * const pR
1368                                  const IMAGE * const pCur,
1369                                  const int x,
1370                                  const int y,
1371 <                                const int start_x,
1372 <                                const int start_y,
1373 <                                const int center_x,
1371 >                                const int start_x,      /* start is searched first, so it should contain the most */
1372 >                                const int start_y,  /* likely motion vector for this block */
1373 >                                const int center_x,     /* center is from where length of MVs is measured */
1374                                  const int center_y,
1375                                  const uint32_t MotionFlags,
1376                                  const uint32_t iQuant,
# Line 2737 | Line 2827 | PMVfastIntSearch16(const uint8_t * const
2827                                  const IMAGE * const pCur,
2828                                  const int x,
2829                                  const int y,
2830 <                        const int start_x,
2831 <                        const int start_y,
2832 <                        const int center_x,
2833 <                        const int center_y,
2830 >                                const int start_x,              /* start should be most likely vector */
2831 >                                const int start_y,
2832 >                                const int center_x,             /* center is from where length of MVs is measured */
2833 >                                const int center_y,
2834                                  const uint32_t MotionFlags,
2835                                  const uint32_t iQuant,
2836                                  const uint32_t iFcode,
# Line 2768 | Line 2858 | PMVfastIntSearch16(const uint8_t * const
2858          int32_t iFound;
2859  
2860          VECTOR newMV;
2861 <        VECTOR backupMV;                        /* just for PMVFAST */
2861 >        VECTOR backupMV;        
2862  
2863          VECTOR pmv[4];
2864          int32_t psad[4];
# Line 3023 | Line 3113 | PMVfastInt16_Terminate_without_Refine:
3113  
3114   /* ***********************************************************
3115          bvop motion estimation
3026 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
3116   ***************************************************************/
3117  
3029
3030 #define DIRECT_PENALTY 0        
3031 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this
3032
3118   void
3119   MotionEstimationBVOP(MBParam * const pParam,
3120                                           FRAMEINFO * const frame,
# Line 3052 | Line 3137 | MotionEstimationBVOP(MBParam * const pPa
3137          const int mb_height = pParam->mb_height;
3138          const int edged_width = pParam->edged_width;
3139  
3140 +        const int32_t iWidth = pParam->width;
3141 +        const int32_t iHeight = pParam->height;
3142 +
3143          int i, j, k;
3144  
3145          static const VECTOR zeroMV={0,0};
# Line 3059 | Line 3147 | MotionEstimationBVOP(MBParam * const pPa
3147          int f_sad16;    /* forward (as usual) search */
3148          int b_sad16;    /* backward (only in b-frames) search */
3149          int i_sad16;    /* interpolated (both direction, b-frames only) */
3150 <        int d_sad16;    /* direct mode (assume linear motion) */
3150 >        int d_sad16;    /* direct mode (assume almost linear motion) */
3151  
3152          int best_sad;
3153  
3154          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3155 +        VECTOR f_interpolMV, b_interpolMV;      
3156          VECTOR pmv_dontcare;
3157  
3158 +        int min_dx, max_dx, min_dy, max_dy;
3159 +        int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3160 +        int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3161 +
3162          int f_count=0;
3163          int b_count=0;
3164          int i_count=0;
3165          int d_count=0;
3073        int s_count=0;
3166  
3167          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3168      const int64_t TRD = (int32_t)time_pp;
# Line 3089 | Line 3181 | MotionEstimationBVOP(MBParam * const pPa
3181  
3182                          mb->deltamv=zeroMV;
3183  
3184 < /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
3184 > /* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */
3185  
3186   #ifndef _DISABLE_SKIP
3187                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
# Line 3103 | Line 3195 | MotionEstimationBVOP(MBParam * const pPa
3195                          }
3196   #endif
3197  
3106                        d_sad16 = DIRECT_PENALTY;
3107
3198                          if (b_mb->mode == MODE_INTER4V)
3199                          {
3200 <
3200 >                                d_sad16 = 0;
3201                          /* same method of scaling as in decoder.c, so we copy from there */
3202                      for (k = 0; k < 4; k++) {
3203                  
# Line 3119 | Line 3209 | MotionEstimationBVOP(MBParam * const pPa
3209                                              : mb->mvs[k].x - mb->directmv[k].x);
3210  
3211                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3212 <                        mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3212 >                        mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3213                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3214                                              : mb->mvs[k].y - mb->directmv[k].y);
3215  
# Line 3135 | Line 3225 | MotionEstimationBVOP(MBParam * const pPa
3225                          else
3226                          {
3227                                  mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
3228 <                                mb->directmv[0] = b_mb->mvs[0];
3228 >                                        mb->directmv[0] = b_mb->mvs[0];
3229  
3230                                  mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3231                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
# Line 3147 | Line 3237 | MotionEstimationBVOP(MBParam * const pPa
3237                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3238                                      : mb->mvs[0].y - mb->directmv[0].y);
3239  
3240 <                                d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3240 >                                d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3241                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3242                                                                  i, j, 16, &mb->mvs[0], edged_width),
3243                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
# Line 3190 | Line 3280 | MotionEstimationBVOP(MBParam * const pPa
3280                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3281                                                                  frame->bcode, frame->quant);
3282  
3283 <                        // TODO: direct search
3284 <                        // predictor + delta vector in range [-32,32] (fcode=1)
3285 <                        
3286 <                        i_sad16 = 65535;
3287 <                        f_sad16 = 65535;
3288 <                        b_sad16 = 65535;
3283 >                        get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3284 >                          frame->fcode);
3285 >                        get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3286 >                          frame->bcode);
3287 >
3288 > /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3289 >   two values for everything, always one for backward and one for forward ME. Still, we don't gain
3290 >   much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3291 >   as "optimal". */
3292 >
3293 >                        i_sad16 = Diamond16_InterpolMainSearch(
3294 >                                                f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3295 >                                                frame->image.y + i * 16 + j * 16 * edged_width,
3296 >                                                b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3297 >                                                i, j,
3298 >                                                mb->mvs[0].x, mb->mvs[0].y,
3299 >                                                mb->b_mvs[0].x, mb->b_mvs[0].y,
3300 >                                                i_sad16,
3301 >                                                &f_interpolMV, &b_interpolMV,
3302 >                                                f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3303 >                                                f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3304 >                                                b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3305 >                                                edged_width,  1,
3306 >                                                frame->fcode, frame->bcode,frame->quant,0);
3307 >
3308 >
3309 > /*  DIRECT MODE DELTA VECTOR SEARCH.
3310 >    This has to be made more effective, but at the moment I'm happy it's running at all */
3311 >
3312 > /* range is taken without fcode restriction, just a hack instead of writing down the dimensions, of course */
3313 >
3314 >                        get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3315 >
3316 >                        d_sad16 = Diamond16_DirectMainSearch(
3317 >                                                f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3318 >                                                frame->image.y + i*16 + j*16*edged_width,
3319 >                                                b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3320 >                                                i, j,
3321 >                                                TRB,TRD,
3322 >                                                0,0,
3323 >                                                d_sad16,
3324 >                                                &mb->deltamv,
3325 >                                                mb->directmv, // this has to be pre-initialized with b_mb->mvs[}
3326 >                                        min_dx, max_dx, min_dy, max_dy,
3327 >                                                edged_width, 1, frame->quant, 0);
3328 >
3329 >
3330 > //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3331 > //                      f_sad16 = 65535;
3332 > //                      b_sad16 = 65535;
3333   //                      d_sad16 = 65535;
3334  
3335                          if (f_sad16 < b_sad16) {
# Line 3216 | Line 3350 | MotionEstimationBVOP(MBParam * const pPa
3350                                  if (b_mb->mode == MODE_INTER4V)
3351                                  {
3352  
3353 <                                /* same method of scaling as in decoder.c, so we copy from there */
3353 >                                /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */
3354 >                                /* for the bitstream, the value mb->deltamv is read directly */
3355 >                                
3356                              for (k = 0; k < 4; k++) {
3357          
3358                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
# Line 3225 | Line 3361 | MotionEstimationBVOP(MBParam * const pPa
3361                                                      : mb->mvs[k].x - mb->directmv[k].x);
3362  
3363                              mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3364 <                        mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3364 >                        mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3365                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3366                                              : mb->mvs[k].y - mb->directmv[k].y);
3367                                          }
# Line 3240 | Line 3376 | MotionEstimationBVOP(MBParam * const pPa
3376  
3377                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3378  
3379 <                        mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3379 >                        mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3380                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3381                                              : mb->mvs[0].y - mb->directmv[0].y);
3382                                                                                  
# Line 3250 | Line 3386 | MotionEstimationBVOP(MBParam * const pPa
3386          
3387                                  best_sad = d_sad16;
3388                                  mb->mode = MODE_DIRECT;
3253                                mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(
3389                          }
3390  
3391                          switch (mb->mode)
# Line 3266 | Line 3401 | MotionEstimationBVOP(MBParam * const pPa
3401                                          break;
3402                                  case MODE_INTERPOLATE:
3403                                          i_count++;
3404 +                                        mb->mvs[0] = f_interpolMV;
3405 +                                        mb->b_mvs[0] = b_interpolMV;
3406                                          f_predMV = mb->mvs[0];
3407                                          b_predMV = mb->b_mvs[0];
3408                                          break;
# Line 3273 | Line 3410 | MotionEstimationBVOP(MBParam * const pPa
3410                                          d_count++;
3411                                          break;
3412                                  default:
3276                                        s_count++;              // ???
3413                                          break;
3414                          }
3415                          
# Line 3281 | Line 3417 | MotionEstimationBVOP(MBParam * const pPa
3417          }
3418          
3419   #ifdef _DEBUG_BFRAME_STAT
3420 <        fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",
3421 <                                f_count,b_count,i_count,d_count,s_count);
3420 >        fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d\n",
3421 >                                f_count,b_count,i_count,d_count);
3422   #endif
3423  
3424   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines