[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 248, Fri Jun 28 15:14:40 2002 UTC revision 289, Wed Jul 10 20:11:05 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /**************************************************************************
2   *   *
3     *      XVID MPEG-4 VIDEO CODEC
4     *      motion estimation
5     *
6     *      This program is an implementation of a part of one or more MPEG-4
7     *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
8     *      to use this software module in hardware or software products are
9     *      advised that its use may infringe existing patents or copyrights, and
10     *      any such use would be at such party's own risk.  The original
11     *      developer of this software module and his/her company, and subsequent
12     *      editors and their companies, will have no liability for use of this
13     *      software or modifications or derivatives thereof.
14     *
15     *      This program is free software; you can redistribute it and/or modify
16     *      it under the terms of the GNU General Public License as published by
17     *      the Free Software Foundation; either version 2 of the License, or
18     *      (at your option) any later version.
19     *
20     *      This program is distributed in the hope that it will be useful,
21     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
22     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     *      GNU General Public License for more details.
24     *
25     *      You should have received a copy of the GNU General Public License
26     *      along with this program; if not, write to the Free Software
27     *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28     *
29     *************************************************************************/
30    
31    /**************************************************************************
32     *
33   *  Modifications:   *  Modifications:
34   *   *
35   *      01.05.2002      updated MotionEstimationBVOP   *      01.05.2002      updated MotionEstimationBVOP
# Line 47  Line 77 
77  #include "motion.h"  #include "motion.h"
78  #include "sad.h"  #include "sad.h"
79    
 // very large value  
 #define MV_MAX_ERROR    (4096 * 256)  
   
 // stop search if sdelta < THRESHOLD  
 #define MV16_THRESHOLD  192  
 #define MV8_THRESHOLD   56  
   
 #define NEIGH_MOVE_THRESH 0  
 // how much a block's MV must differ from his neighbour  
 // to be search for INTER4V. The more, the faster...  
   
 /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  
 /* nb  = vop pixels * 2^(bpp-8) */  
 #define MV16_00_BIAS    (128+1)  
 #define MV8_00_BIAS     (0)  
   
 /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  
 #define MV16_INTER_BIAS 512  
   
 /* Parameters which control inter/inter4v decision */  
 #define IMV16X16                        5  
   
 /* vector map (vlc delta size) smoother parameters */  
 #define NEIGH_TEND_16X16        2  
 #define NEIGH_TEND_8X8          2  
   
 // fast ((A)/2)*2  
 #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  
   
 #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )  
 #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )  
   
 int32_t PMVfastSearch16(const uint8_t * const pRef,  
                                                 const uint8_t * const pRefH,  
                                                 const uint8_t * const pRefV,  
                                                 const uint8_t * const pRefHV,  
                                                 const IMAGE * const pCur,  
                                                 const int x,  
                                                 const int y,  
                                                 const uint32_t MotionFlags,  
                                                 const uint32_t iQuant,  
                                                 const uint32_t iFcode,  
                                                 const MBParam * const pParam,  
                                                 const MACROBLOCK * const pMBs,  
                                                 const MACROBLOCK * const prevMBs,  
                                                 VECTOR * const currMV,  
                                                 VECTOR * const currPMV);  
   
 int32_t EPZSSearch16(const uint8_t * const pRef,  
                                          const uint8_t * const pRefH,  
                                          const uint8_t * const pRefV,  
                                          const uint8_t * const pRefHV,  
                                          const IMAGE * const pCur,  
                                          const int x,  
                                          const int y,  
                                          const uint32_t MotionFlags,  
                                          const uint32_t iQuant,  
                                          const uint32_t iFcode,  
                                          const MBParam * const pParam,  
                                          const MACROBLOCK * const pMBs,  
                                          const MACROBLOCK * const prevMBs,  
                                          VECTOR * const currMV,  
                                          VECTOR * const currPMV);  
   
   
 int32_t PMVfastSearch8(const uint8_t * const pRef,  
                                            const uint8_t * const pRefH,  
                                            const uint8_t * const pRefV,  
                                            const uint8_t * const pRefHV,  
                                            const IMAGE * const pCur,  
                                            const int x,  
                                            const int y,  
                                            const int start_x,  
                                            const int start_y,  
                                            const uint32_t MotionFlags,  
                                            const uint32_t iQuant,  
                                            const uint32_t iFcode,  
                                            const MBParam * const pParam,  
                                            const MACROBLOCK * const pMBs,  
                                            const MACROBLOCK * const prevMBs,  
                                            VECTOR * const currMV,  
                                            VECTOR * const currPMV);  
   
 int32_t EPZSSearch8(const uint8_t * const pRef,  
                                         const uint8_t * const pRefH,  
                                         const uint8_t * const pRefV,  
                                         const uint8_t * const pRefHV,  
                                         const IMAGE * const pCur,  
                                         const int x,  
                                         const int y,  
                                         const int start_x,  
                                         const int start_y,  
                                         const uint32_t MotionFlags,  
                                         const uint32_t iQuant,  
                                         const uint32_t iFcode,  
                                         const MBParam * const pParam,  
                                         const MACROBLOCK * const pMBs,  
                                         const MACROBLOCK * const prevMBs,  
                                         VECTOR * const currMV,  
                                         VECTOR * const currPMV);  
   
   
 typedef int32_t(MainSearch16Func) (const uint8_t * const pRef,  
                                                                    const uint8_t * const pRefH,  
                                                                    const uint8_t * const pRefV,  
                                                                    const uint8_t * const pRefHV,  
                                                                    const uint8_t * const cur,  
                                                                    const int x,  
                                                                    const int y,  
                                                                    int32_t startx,  
                                                                    int32_t starty,  
                                                                    int32_t iMinSAD,  
                                                                    VECTOR * const currMV,  
                                                                    const VECTOR * const pmv,  
                                                                    const int32_t min_dx,  
                                                                    const int32_t max_dx,  
                                                                    const int32_t min_dy,  
                                                                    const int32_t max_dy,  
                                                                    const int32_t iEdgedWidth,  
                                                                    const int32_t iDiamondSize,  
                                                                    const int32_t iFcode,  
                                                                    const int32_t iQuant,  
                                                                    int iFound);  
   
 typedef MainSearch16Func *MainSearch16FuncPtr;  
80    
81    
 typedef int32_t(MainSearch8Func) (const uint8_t * const pRef,  
                                                                   const uint8_t * const pRefH,  
                                                                   const uint8_t * const pRefV,  
                                                                   const uint8_t * const pRefHV,  
                                                                   const uint8_t * const cur,  
                                                                   const int x,  
                                                                   const int y,  
                                                                   int32_t startx,  
                                                                   int32_t starty,  
                                                                   int32_t iMinSAD,  
                                                                   VECTOR * const currMV,  
                                                                   const VECTOR * const pmv,  
                                                                   const int32_t min_dx,  
                                                                   const int32_t max_dx,  
                                                                   const int32_t min_dy,  
                                                                   const int32_t max_dy,  
                                                                   const int32_t iEdgedWidth,  
                                                                   const int32_t iDiamondSize,  
                                                                   const int32_t iFcode,  
                                                                   const int32_t iQuant,  
                                                                   int iFound);  
   
 typedef MainSearch8Func *MainSearch8FuncPtr;  
   
82  static int32_t lambda_vec16[32] =       /* rounded values for lambda param for weight of motion bits as in modified H.26L */  static int32_t lambda_vec16[32] =       /* rounded values for lambda param for weight of motion bits as in modified H.26L */
83  { 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),  { 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),
84                  (int) (1.49591 + 0.5), (int) (1.68601 + 0.5),                  (int) (1.49591 + 0.5), (int) (1.68601 + 0.5),
# Line 274  Line 155 
155                                                                                                     mv_bits(dy, iFcode));                                                                                                     mv_bits(dy, iFcode));
156  }  }
157    
   
   
   
   
 #ifndef SEARCH16  
 #define SEARCH16        PMVfastSearch16  
 //#define SEARCH16  FullSearch16  
 //#define SEARCH16  EPZSSearch16  
 #endif  
   
 #ifndef SEARCH8  
 #define SEARCH8         PMVfastSearch8  
 //#define SEARCH8   EPZSSearch8  
 #endif  
   
158  bool  bool
159  MotionEstimation(MBParam * const pParam,  MotionEstimation(MBParam * const pParam,
160                                   FRAMEINFO * const current,                                   FRAMEINFO * const current,
# Line 314  Line 180 
180          if (sadInit)          if (sadInit)
181                  (*sadInit) ();                  (*sadInit) ();
182    
183          for (y = 0; y < iHcount; y++)          for (y = 0; y < iHcount; y++)   {
184                  for (x = 0; x < iWcount; x++) {                  for (x = 0; x < iWcount; x++) {
185    
186                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
187    
188                          pMB->sad16 =                          pMB->sad16 =
# Line 409  Line 276 
276                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
277                          pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =                          pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =
278                                  pMB->sad16;                                  pMB->sad16;
   
279                  }                  }
280                            }
281    
282          return 0;          return 0;
283  }  }
284    
# Line 528  Line 396 
396          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
397          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
398          int32_t iSAD;          int32_t iSAD;
399          int32_t pred_x,pred_y;          VECTOR pred;
400    
401    
402          get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y);          pred = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
403    
404          iSAD = sad16( cur,          iSAD = sad16( cur,
405                  get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),                  get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),
# Line 540  Line 409 
409    
410          currMV->x = 0;          currMV->x = 0;
411          currMV->y = 0;          currMV->y = 0;
412          currPMV->x = -pred_x;          currPMV->x = -pred.x;
413          currPMV->y = -pred_y;          currPMV->y = -pred.y;
414    
415          return iSAD;          return iSAD;
416    
# Line 1259  Line 1128 
1128    
1129          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1130    
 //  const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  
1131          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
1132    
1133          static int32_t threshA, threshB;          int32_t threshA, threshB;
1134          int32_t bPredEq;          int32_t bPredEq;
1135          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
1136    
# Line 1280  Line 1148 
1148          }          }
1149    
1150          /* 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; */
1151          bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad, 0, 0);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1152            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1153    
1154    /*      fprintf(stderr,"pmv: %d %d / %d --- %d %d   %d %d   %d %d - %d %d %d\n",
1155                    pmv[0].x,pmv[0].y,psad[0],
1156                    pmv[1].x,pmv[1].y,pmv[2].x,pmv[2].y,pmv[3].x,pmv[3].y,
1157                    psad[1],psad[2],psad[3]);
1158    */
1159          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1160                  threshA = 512;                  threshA = 512;
1161                  threshB = 1024;                  threshB = 1024;
   
1162          } else {          } else {
1163                  threshA = psad[0];                  threshA = psad[0];
1164                  threshB = threshA + 256;                  threshB = threshA + 256;
# Line 1335  Line 1208 
1208    
1209          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1210                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1211                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1212                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
1213                  {                  {
1214                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
# Line 1439  Line 1312 
1312    
1313          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1314                  (MVequal(*currMV, prevMB->mvs[0]) &&                  (MVequal(*currMV, prevMB->mvs[0]) &&
1315                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1316                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1317                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
1318                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1466  Line 1339 
1339    
1340          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
1341    
1342    
1343    //      fprintf(stderr,"Entering Diamond %d %d (%d):\n",x,y,iMinSAD);
1344    
1345  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1346          iSAD =          iSAD =
1347                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
# Line 1519  Line 1395 
1395                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
1396                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1397    
1398    /*fprintf(stderr,"Chosen for %d %d: %d %d - %d %d\n",x,y,currMV->x,currMV->y,pmv[0].x,pmv[0].y);
1399    */
1400    PMVfast16_Terminate_without_Refine:    PMVfast16_Terminate_without_Refine:
1401          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1402          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1674  Line 1552 
1552  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1553          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
1554    
1555          static int32_t threshA, threshB;           int32_t threshA, threshB;
1556          int32_t iFound, bPredEq;          int32_t iFound, bPredEq;
1557          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
1558    
# Line 1698  Line 1576 
1576          }          }
1577    
1578          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
1579          bPredEq =          //bPredEq = get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad);
1580                  get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad, 0, 0);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);
1581    
1582          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1583                  threshA = 512 / 4;                  threshA = 512 / 4;
# Line 1749  Line 1627 
1627                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
1628    
1629          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
1630                                                                  && ((uint32_t) iMinSAD <                                                                  && ((int32_t) iMinSAD <
1631                                                                          prevMB->sad8[iSubBlock]))) {                                                                          prevMB->sad8[iSubBlock]))) {
1632                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1633                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1804  Line 1682 
1682    
1683          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1684                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1685                   ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {                   ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1686                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1687                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1688                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1863  Line 1741 
1741    
1742          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1743                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1744                   ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {                   ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1745                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1746                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1747                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1986  Line 1864 
1864          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
1865          MACROBLOCK *oldMB = NULL;          MACROBLOCK *oldMB = NULL;
1866    
1867          static int32_t thresh2;           int32_t thresh2;
1868          int32_t bPredEq;          int32_t bPredEq;
1869          int32_t iMinSAD, iSAD = 9999;          int32_t iMinSAD, iSAD = 9999;
1870    
# Line 2009  Line 1887 
1887                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
1888          }          }
1889          /* 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; */
1890          bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad, 0, 0);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1891            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1892    
1893  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1894          MinSAD=SAD          MinSAD=SAD
# Line 2048  Line 1927 
1927  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1928          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1929                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1930                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1931                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1932                          goto EPZS16_Terminate_without_Refine;                          goto EPZS16_Terminate_without_Refine;
1933                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 2108  Line 1987 
1987    
1988          if ((iMinSAD <= thresh2)          if ((iMinSAD <= thresh2)
1989                  || (MVequal(*currMV, prevMB->mvs[0]) &&                  || (MVequal(*currMV, prevMB->mvs[0]) &&
1990                          ((uint32_t) iMinSAD <= prevMB->sad16))) {                          ((int32_t) iMinSAD <= prevMB->sad16))) {
1991                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1992                          goto EPZS16_Terminate_without_Refine;                          goto EPZS16_Terminate_without_Refine;
1993                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 2154  Line 2033 
2033    
2034          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
2035    
2036          if (MotionFlags & PMV_USESQUARES8)          if (MotionFlags & PMV_USESQUARES16)
2037                  MainSearchPtr = Square16_MainSearch;                  MainSearchPtr = Square16_MainSearch;
2038          else          else
2039           if (MotionFlags & PMV_ADVANCEDDIAMOND8)           if (MotionFlags & PMV_ADVANCEDDIAMOND16)
2040                  MainSearchPtr = AdvDiamond16_MainSearch;                  MainSearchPtr = AdvDiamond16_MainSearch;
2041          else          else
2042                  MainSearchPtr = Diamond16_MainSearch;                  MainSearchPtr = Diamond16_MainSearch;
# Line 2287  Line 2166 
2166                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2167          }          }
2168          /* 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; */
2169          bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv, psad, 0, 0);          //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv, psad);
2170            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2171    
2172    
2173  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2467  Line 2347 
2347    
2348    
2349    
2350    int32_t
2351    PMVfastIntSearch16(const uint8_t * const pRef,
2352                                    const uint8_t * const pRefH,
2353                                    const uint8_t * const pRefV,
2354                                    const uint8_t * const pRefHV,
2355                                    const IMAGE * const pCur,
2356                                    const int x,
2357                                    const int y,
2358                                    const uint32_t MotionFlags,
2359                                    const uint32_t iQuant,
2360                                    const uint32_t iFcode,
2361                                    const MBParam * const pParam,
2362                                    const MACROBLOCK * const pMBs,
2363                                    const MACROBLOCK * const prevMBs,
2364                                    VECTOR * const currMV,
2365                                    VECTOR * const currPMV)
2366    {
2367            const uint32_t iWcount = pParam->mb_width;
2368            const int32_t iWidth = pParam->width;
2369            const int32_t iHeight = pParam->height;
2370            const int32_t iEdgedWidth = pParam->edged_width;
2371    
2372            const uint8_t *cur = pCur->y + x * 16 + y * 16 * iEdgedWidth;
2373            const VECTOR zeroMV = { 0, 0 };
2374    
2375            int32_t iDiamondSize;
2376    
2377            int32_t min_dx;
2378            int32_t max_dx;
2379            int32_t min_dy;
2380            int32_t max_dy;
2381    
2382            int32_t iFound;
2383    
2384            VECTOR newMV;
2385            VECTOR backupMV;                        /* just for PMVFAST */
2386    
2387            VECTOR pmv[4];
2388            int32_t psad[4];
2389    
2390            MainSearch16FuncPtr MainSearchPtr;
2391    
2392            const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
2393            MACROBLOCK *const pMB = pMBs + x + y * iWcount;
2394    
2395            int32_t threshA, threshB;
2396            int32_t bPredEq;
2397            int32_t iMinSAD, iSAD;
2398    
2399    /* Get maximum range */
2400            get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
2401                              iFcode);
2402    
2403    /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */
2404    
2405            if ((x == 0) && (y == 0)) {
2406                    threshA = 512;
2407                    threshB = 1024;
2408    
2409                    bPredEq = 0;
2410                    psad[0] = psad[1] = psad[2] = psad[3] = 0;
2411                    *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2412    
2413            } else {
2414                    threshA = psad[0];
2415                    threshB = threshA + 256;
2416                    if (threshA < 512)
2417                            threshA = 512;
2418                    if (threshA > 1024)
2419                            threshA = 1024;
2420                    if (threshB > 1792)
2421                            threshB = 1792;
2422    
2423                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2424                    *currMV = pmv[0];                       /* current best := prediction */
2425            }
2426    
2427            iFound = 0;
2428    
2429    /* Step 4: Calculate SAD around the Median prediction.
2430       MinSAD=SAD
2431       If Motion Vector equal to Previous frame motion vector
2432       and MinSAD<PrevFrmSAD goto Step 10.
2433       If SAD<=256 goto Step 10.
2434    */
2435    
2436            if (currMV->x > max_dx) {
2437                    currMV->x = EVEN(max_dx);
2438            }
2439            if (currMV->x < min_dx) {
2440                    currMV->x = EVEN(min_dx);
2441            }
2442            if (currMV->y > max_dy) {
2443                    currMV->y = EVEN(max_dy);
2444            }
2445            if (currMV->y < min_dy) {
2446                    currMV->y = EVEN(min_dy);
2447            }
2448    
2449            iMinSAD =
2450                    sad16(cur,
2451                              get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2452                                                     iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2453            iMinSAD +=
2454                    calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
2455                                              (uint8_t) iFcode, iQuant);
2456    
2457            if ((iMinSAD < 256) ||
2458                    ((MVequal(*currMV, prevMB->i_mvs[0])) &&
2459                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2460                    if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
2461                    {
2462                            if (!MVzero(*currMV)) {
2463                                    iMinSAD += MV16_00_BIAS;
2464                                    CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures
2465                                    iMinSAD -= MV16_00_BIAS;
2466                            }
2467                    }
2468    
2469                    if (MotionFlags & PMV_EARLYSTOP16)
2470                            goto PMVfastInt16_Terminate_with_Refine;
2471            }
2472    
2473    
2474    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
2475       vector of the median.
2476       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
2477    */
2478    
2479            if ((bPredEq) && (MVequal(pmv[0], prevMB->i_mvs[0])))
2480                    iFound = 2;
2481    
2482    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
2483       Otherwise select large Diamond Search.
2484    */
2485    
2486            if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))
2487                    iDiamondSize = 2;               // halfpel units!
2488            else
2489                    iDiamondSize = 4;               // halfpel units!
2490    
2491    /*
2492       Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
2493       Also calculate (0,0) but do not subtract offset.
2494       Let MinSAD be the smallest SAD up to this point.
2495       If MV is (0,0) subtract offset.
2496    */
2497    
2498    // (0,0) is often a good choice
2499    
2500            if (!MVzero(pmv[0]))
2501                    CHECK_MV16_ZERO;
2502    
2503    // previous frame MV is always possible
2504    
2505            if (!MVzero(prevMB->i_mvs[0]))
2506                    if (!MVequal(prevMB->i_mvs[0], pmv[0]))
2507                            CHECK_MV16_CANDIDATE(prevMB->i_mvs[0].x, prevMB->i_mvs[0].y);
2508    
2509    // left neighbour, if allowed
2510    
2511            if (!MVzero(pmv[1]))
2512                    if (!MVequal(pmv[1], prevMB->i_mvs[0]))
2513                            if (!MVequal(pmv[1], pmv[0]))
2514                                    CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);
2515    
2516    // top neighbour, if allowed
2517            if (!MVzero(pmv[2]))
2518                    if (!MVequal(pmv[2], prevMB->i_mvs[0]))
2519                            if (!MVequal(pmv[2], pmv[0]))
2520                                    if (!MVequal(pmv[2], pmv[1]))
2521                                            CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);
2522    
2523    // top right neighbour, if allowed
2524                                            if (!MVzero(pmv[3]))
2525                                                    if (!MVequal(pmv[3], prevMB->i_mvs[0]))
2526                                                            if (!MVequal(pmv[3], pmv[0]))
2527                                                                    if (!MVequal(pmv[3], pmv[1]))
2528                                                                            if (!MVequal(pmv[3], pmv[2]))
2529                                                                                    CHECK_MV16_CANDIDATE(pmv[3].x,
2530                                                                                                                             pmv[3].y);
2531    
2532            if ((MVzero(*currMV)) &&
2533                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
2534                    iMinSAD -= MV16_00_BIAS;
2535    
2536    
2537    /* Step 6: If MinSAD <= thresa goto Step 10.
2538       If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
2539    */
2540    
2541            if ((iMinSAD <= threshA) ||
2542                    (MVequal(*currMV, prevMB->i_mvs[0]) &&
2543                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2544    
2545                    if (MotionFlags & PMV_EARLYSTOP16)
2546                            goto PMVfastInt16_Terminate_with_Refine;
2547            }
2548    
2549    
2550    /************ (Diamond Search)  **************/
2551    /*
2552       Step 7: Perform Diamond search, with either the small or large diamond.
2553       If Found=2 only examine one Diamond pattern, and afterwards goto step 10
2554       Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond.
2555       If center then goto step 10.
2556       Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center.
2557       Refine by using small diamond and goto step 10.
2558    */
2559    
2560            if (MotionFlags & PMV_USESQUARES16)
2561                    MainSearchPtr = Square16_MainSearch;
2562            else if (MotionFlags & PMV_ADVANCEDDIAMOND16)
2563                    MainSearchPtr = AdvDiamond16_MainSearch;
2564            else
2565                    MainSearchPtr = Diamond16_MainSearch;
2566    
2567            backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
2568    
2569    
2570    /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2571            iSAD =
2572                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2573                                                      currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,
2574                                                      min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2575                                                      iQuant, iFound);
2576    
2577            if (iSAD < iMinSAD) {
2578                    *currMV = newMV;
2579                    iMinSAD = iSAD;
2580            }
2581    
2582            if (MotionFlags & PMV_EXTSEARCH16) {
2583    /* extended: search (up to) two more times: orignal prediction and (0,0) */
2584    
2585                    if (!(MVequal(pmv[0], backupMV))) {
2586                            iSAD =
2587                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2588                                                                      pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,
2589                                                                      min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2590                                                                      iDiamondSize, iFcode, iQuant, iFound);
2591    
2592                            if (iSAD < iMinSAD) {
2593                                    *currMV = newMV;
2594                                    iMinSAD = iSAD;
2595                            }
2596                    }
2597    
2598                    if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2599                            iSAD =
2600                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2601                                                                      iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,
2602                                                                      max_dy, iEdgedWidth, iDiamondSize, iFcode,
2603                                                                      iQuant, iFound);
2604    
2605                            if (iSAD < iMinSAD) {
2606                                    *currMV = newMV;
2607                                    iMinSAD = iSAD;
2608                            }
2609                    }
2610            }
2611    
2612    /*
2613       Step 10:  The motion vector is chosen according to the block corresponding to MinSAD.
2614    */
2615    
2616    PMVfastInt16_Terminate_with_Refine:
2617    
2618            pMB->i_mvs[0] = pMB->i_mvs[1] = pMB->i_mvs[2] = pMB->i_mvs[3] = pMB->i_mv16 = *currMV;
2619            pMB->i_sad8[0] = pMB->i_sad8[1] = pMB->i_sad8[2] = pMB->i_sad8[3] = pMB->i_sad16 = iMinSAD;
2620    
2621            if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2622                    iMinSAD =
2623                            Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2624                                                             iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
2625                                                             iFcode, iQuant, iEdgedWidth);
2626    
2627            pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)
2628    
2629    PMVfastInt16_Terminate_without_Refine:
2630            currPMV->x = currMV->x - pmv[0].x;
2631            currPMV->y = currMV->y - pmv[0].y;
2632            return iMinSAD;
2633    }
2634    
2635    
2636    
2637  /* ***********************************************************  /* ***********************************************************

Legend:
Removed from v.248  
changed lines
  Added in v.289

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