[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 341, Thu Jul 25 00:43:19 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 305  Line 171 
171          const IMAGE *const pCurrent = &current->image;          const IMAGE *const pCurrent = &current->image;
172          const IMAGE *const pRef = &reference->image;          const IMAGE *const pRef = &reference->image;
173    
174          const VECTOR zeroMV = { 0, 0 };          static const VECTOR zeroMV = { 0, 0 };
175            VECTOR predMV;
176    
177          int32_t x, y;          int32_t x, y;
178          int32_t iIntra = 0;          int32_t iIntra = 0;
# Line 314  Line 181 
181          if (sadInit)          if (sadInit)
182                  (*sadInit) ();                  (*sadInit) ();
183    
184          for (y = 0; y < iHcount; y++)          for (y = 0; y < iHcount; y++)   {
185                  for (x = 0; x < iWcount; x++) {                  for (x = 0; x < iWcount; x++) {
186    
187                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
188    
189                            predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
190    
191                          pMB->sad16 =                          pMB->sad16 =
192                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
193                                                   y, current->motion_flags, current->quant,                                                   x, y, predMV.x, predMV.y, predMV.x, predMV.y,
194                                                     current->motion_flags, current->quant,
195                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,
196                                                   &pMB->pmvs[0]);                                                   &pMB->pmvs[0]);
197    
# Line 352  Line 223 
223                                           pMB->dquant == NO_CHANGE)) {                                           pMB->dquant == NO_CHANGE)) {
224                                          int32_t sad8 = IMV16X16 * current->quant;                                          int32_t sad8 = IMV16X16 * current->quant;
225    
226                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
   
227                                                  sad8 += pMB->sad8[0] =                                                  sad8 += pMB->sad8[0] =
228                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
229                                                                          pCurrent, 2 * x, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y,
230                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
231                                                                            current->motion_flags,
232                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
233                                                                          pMBs, prevMBs, &pMB->mvs[0],                                                                          pMBs, prevMBs, &pMB->mvs[0],
234                                                                          &pMB->pmvs[0]);                                                                          &pMB->pmvs[0]);
235                                            }
236                                            if (sad8 < pMB->sad16) {
237    
238                                          if (sad8 < pMB->sad16)                                                  predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 1);
239                                                  sad8 += pMB->sad8[1] =                                                  sad8 += pMB->sad8[1] =
240                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
241                                                                          pCurrent, 2 * x + 1, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x + 1, 2 * y,
242                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
243                                                                            current->motion_flags,
244                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
245                                                                          pMBs, prevMBs, &pMB->mvs[1],                                                                          pMBs, prevMBs, &pMB->mvs[1],
246                                                                          &pMB->pmvs[1]);                                                                          &pMB->pmvs[1]);
247                                            }
248                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
249                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 2);
250                                                  sad8 += pMB->sad8[2] =                                                  sad8 += pMB->sad8[2] =
251                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
252                                                                          pCurrent, 2 * x, 2 * y + 1, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y + 1,
253                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
254                                                                            current->motion_flags,
255                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
256                                                                          pMBs, prevMBs, &pMB->mvs[2],                                                                          pMBs, prevMBs, &pMB->mvs[2],
257                                                                          &pMB->pmvs[2]);                                                                          &pMB->pmvs[2]);
258                                            }
259                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
260                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 3);
261                                                  sad8 += pMB->sad8[3] =                                                  sad8 += pMB->sad8[3] =
262                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
263                                                                          pCurrent, 2 * x + 1, 2 * y + 1,                                                                          pCurrent, 2 * x + 1, 2 * y + 1,
264                                                                          pMB->mv16.x, pMB->mv16.y,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
265                                                                          current->motion_flags, current->quant,                                                                          current->motion_flags,
266                                                                          current->fcode, pParam, pMBs, prevMBs,                                                                          current->quant, current->fcode, pParam,
267                                                                          &pMB->mvs[3], &pMB->pmvs[3]);                                                                          pMBs, prevMBs,
268                                                                            &pMB->mvs[3],
269                                                                            &pMB->pmvs[3]);
270                                            }
271    
272                                          /* decide: MODE_INTER or MODE_INTER4V                                          /* decide: MODE_INTER or MODE_INTER4V
273                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
# Line 409  Line 289 
289                          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;
290                          pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =                          pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =
291                                  pMB->sad16;                                  pMB->sad16;
   
292                  }                  }
293                            }
294    
295          return 0;          return 0;
296  }  }
297    
298    
299  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
300    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
301      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
302    { \    { \
303      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \
304      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
305      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
306      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
307  }  }
308    
309  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
310      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
311      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
312      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
313      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
314  }  }
# Line 436  Line 318 
318      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
319    { \    { \
320      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
321      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
322      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
323      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
324  }  }
# Line 446  Line 328 
328      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
329    { \    { \
330      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
331      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
332      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
333      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
334  }  }
# Line 456  Line 338 
338      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
339    { \    { \
340      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
341      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
342      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
343      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
344  }  }
# Line 464  Line 346 
346    
347  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
348    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \
349    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\    iSAD += calc_delta_8(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
350    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
351    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
352  }  }
# Line 472  Line 354 
354  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
355    { \    { \
356      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
357      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
358      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
359      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
360  }  }
# Line 482  Line 364 
364      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
365    { \    { \
366      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
367      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
368      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
369      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
370  }  }
# Line 492  Line 374 
374      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
375    { \    { \
376      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
377      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
378      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
379      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
380  }  }
# Line 502  Line 384 
384      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
385    { \    { \
386      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
387      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
388      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
389      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
390  }  }
# Line 528  Line 410 
410          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
411          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
412          int32_t iSAD;          int32_t iSAD;
413          int32_t pred_x,pred_y;          VECTOR pred;
414    
415    
416          get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y);          pred = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
417    
418          iSAD = sad16( cur,          iSAD = sad16( cur,
419                  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 423 
423    
424          currMV->x = 0;          currMV->x = 0;
425          currMV->y = 0;          currMV->y = 0;
426          currPMV->x = -pred_x;          currPMV->x = -pred.x;
427          currPMV->y = -pred_y;          currPMV->y = -pred.y;
428    
429          return iSAD;          return iSAD;
430    
# Line 556  Line 439 
439                                           const uint8_t * const cur,                                           const uint8_t * const cur,
440                                           const int x,                                           const int x,
441                                           const int y,                                           const int y,
442                                           int32_t startx,                                     const int start_x,
443                                           int32_t starty,                                     const int start_y,
444                                           int32_t iMinSAD,                                     int iMinSAD,
445                                           VECTOR * const currMV,                                           VECTOR * const currMV,
446                                           const VECTOR * const pmv,                                     const int center_x,
447                                       const int center_y,
448                                           const int32_t min_dx,                                           const int32_t min_dx,
449                                           const int32_t max_dx,                                           const int32_t max_dx,
450                                           const int32_t min_dy,                                           const int32_t min_dy,
# Line 577  Line 461 
461          int32_t iSAD;          int32_t iSAD;
462          VECTOR backupMV;          VECTOR backupMV;
463    
464          backupMV.x = startx;          backupMV.x = start_x;
465          backupMV.y = starty;          backupMV.y = start_y;
466    
467  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
468    
# Line 605  Line 489 
489                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
490                                                                                     backupMV.y + iDiamondSize, 4);                                                                                     backupMV.y + iDiamondSize, 4);
491          } else {          } else {
492                  currMV->x = startx;                  currMV->x = start_x;
493                  currMV->y = starty;                  currMV->y = start_y;
494          }          }
495          return iMinSAD;          return iMinSAD;
496  }  }
# Line 619  Line 503 
503                                          const uint8_t * const cur,                                          const uint8_t * const cur,
504                                          const int x,                                          const int x,
505                                          const int y,                                          const int y,
506                                          int32_t startx,                                     const int start_x,
507                                          int32_t starty,                                     const int start_y,
508                                          int32_t iMinSAD,                                     int iMinSAD,
509                                          VECTOR * const currMV,                                          VECTOR * const currMV,
510                                          const VECTOR * const pmv,                                     const int center_x,
511                                       const int center_y,
512                                          const int32_t min_dx,                                          const int32_t min_dx,
513                                          const int32_t max_dx,                                          const int32_t max_dx,
514                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 640  Line 525 
525          int32_t iSAD;          int32_t iSAD;
526          VECTOR backupMV;          VECTOR backupMV;
527    
528          backupMV.x = startx;          backupMV.x = start_x;
529          backupMV.y = starty;          backupMV.y = start_y;
530    
531  /* It's one search with full square pattern, and new parts for all following diamonds */  /* It's one search with full square pattern, and new parts for all following diamonds */
532    
# Line 781  Line 666 
666                                  break;                                  break;
667                          }                          }
668          } else {          } else {
669                  currMV->x = startx;                  currMV->x = start_x;
670                  currMV->y = starty;                  currMV->y = start_y;
671          }          }
672          return iMinSAD;          return iMinSAD;
673  }  }
# Line 796  Line 681 
681                                    const uint8_t * const cur,                                    const uint8_t * const cur,
682                                    const int x,                                    const int x,
683                                    const int y,                                    const int y,
684                                    int32_t startx,                                     const int start_x,
685                                    int32_t starty,                                     const int start_y,
686                                    int32_t iMinSAD,                                     int iMinSAD,
687                                    VECTOR * const currMV,                                    VECTOR * const currMV,
688                                    const VECTOR * const pmv,                                     const int center_x,
689                                       const int center_y,
690                                    const int32_t min_dx,                                    const int32_t min_dx,
691                                    const int32_t max_dx,                                    const int32_t max_dx,
692                                    const int32_t min_dy,                                    const int32_t min_dy,
# Line 815  Line 701 
701          int32_t dx, dy;          int32_t dx, dy;
702          VECTOR backupMV;          VECTOR backupMV;
703    
704          backupMV.x = startx;          backupMV.x = start_x;
705          backupMV.y = starty;          backupMV.y = start_y;
706    
707          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
708                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 833  Line 719 
719                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
720                                                  const int x,                                                  const int x,
721                                                  const int y,                                                  const int y,
722                                                  int32_t startx,                                             int start_x,
723                                                  int32_t starty,                                             int start_y,
724                                                  int32_t iMinSAD,                                             int iMinSAD,
725                                                  VECTOR * const currMV,                                                  VECTOR * const currMV,
726                                                  const VECTOR * const pmv,                                             const int center_x,
727                                               const int center_y,
728                                                  const int32_t min_dx,                                                  const int32_t min_dx,
729                                                  const int32_t max_dx,                                                  const int32_t max_dx,
730                                                  const int32_t min_dy,                                                  const int32_t min_dy,
# Line 854  Line 741 
741  /* 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) */
742    
743          if (iDirection) {          if (iDirection) {
744                  CHECK_MV16_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y);
745                  CHECK_MV16_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y);
746                  CHECK_MV16_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize);
747                  CHECK_MV16_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize);
748          } else {          } else {
749                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
750    
751                  do {                  do {
752                          iDirection = 0;                          iDirection = 0;
753                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
754                                  CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
755    
756                          if (bDirection & 2)                          if (bDirection & 2)
757                                  CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
758    
759                          if (bDirection & 4)                          if (bDirection & 4)
760                                  CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
761    
762                          if (bDirection & 8)                          if (bDirection & 8)
763                                  CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
764    
765                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
766    
# Line 881  Line 768 
768                          {                          {
769                                  bDirection = iDirection;                                  bDirection = iDirection;
770                                  iDirection = 0;                                  iDirection = 0;
771                                  startx = currMV->x;                                  start_x = currMV->x;
772                                  starty = currMV->y;                                  start_y = currMV->y;
773                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
774                                  {                                  {
775                                          CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
776                                          CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
777                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
778                                  {                                  {
779                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
780                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
781                                  }                                  }
782    
783                                  if (iDirection) {                                  if (iDirection) {
784                                          bDirection += iDirection;                                          bDirection += iDirection;
785                                          startx = currMV->x;                                          start_x = currMV->x;
786                                          starty = currMV->y;                                          start_y = currMV->y;
787                                  }                                  }
788                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
789                          {                          {
790                                  switch (bDirection) {                                  switch (bDirection) {
791                                  case 2:                                  case 2:
792                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
793                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
794                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
795                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
796                                          break;                                          break;
797                                  case 1:                                  case 1:
798                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,  
799                                                                                           starty - iDiamondSize, 1 + 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
800                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                                                                           start_y - iDiamondSize, 1 + 4);
801                                                                                           starty + iDiamondSize, 1 + 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
802                                                                                             start_y + iDiamondSize, 1 + 8);
803                                          break;                                          break;
804                                  case 2 + 4:                                  case 2 + 4:
805                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
806                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
807                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
808                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
809                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
810                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
811                                          break;                                          break;
812                                  case 4:                                  case 4:
813                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
814                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
815                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
816                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
817                                          break;                                          break;
818                                  case 8:                                  case 8:
819                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
820                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
821                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
822                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
823                                          break;                                          break;
824                                  case 1 + 4:                                  case 1 + 4:
825                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
826                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
827                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
828                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
829                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
830                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
831                                          break;                                          break;
832                                  case 2 + 8:                                  case 2 + 8:
833                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
834                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
835                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
836                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
837                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
838                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
839                                          break;                                          break;
840                                  case 1 + 8:                                  case 1 + 8:
841                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
842                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
843                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
844                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
845                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
846                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
847                                          break;                                          break;
848                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
849                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
850                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
851                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
852                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
853                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
854                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
855                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
856                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
857                                          break;                                          break;
858                                  }                                  }
859                                  if (!iDirection)                                  if (!iDirection)
860                                          break;          //ok, the end. really                                          break;          //ok, the end. really
861                                  else {                                  else {
862                                          bDirection = iDirection;                                          bDirection = iDirection;
863                                          startx = currMV->x;                                          start_x = currMV->x;
864                                          starty = currMV->y;                                          start_y = currMV->y;
865                                  }                                  }
866                          }                          }
867                  }                  }
# Line 982  Line 870 
870          return iMinSAD;          return iMinSAD;
871  }  }
872    
873    
874    #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \
875      if ( ((X) <= max_dx) && ((X) >= min_dx) \
876        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
877      { \
878        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
879        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
880        if (iSAD < iMinSAD) \
881        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
882    }
883    
884    #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \
885      if ( ((X) <= max_dx) && ((X) >= min_dx) \
886        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
887      { \
888        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
889        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
890        if (iSAD < iMinSAD) \
891        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
892    }
893    
894    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \
895      if ( ((X) <= max_dx) && ((X) >= min_dx) \
896        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
897      { \
898        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
899        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
900        if (iSAD < iMinSAD) \
901        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
902    }
903    
904    
905    #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \
906      if ( ((X) <= max_dx) && ((X) >= min_dx) \
907        && ((Y) <= max_dy) && ((Y) >= 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);\
911        if (iSAD < iMinSAD) \
912        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
913    }
914    
915    
916    #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \
917      if ( ((X) <= max_dx) && ((X) >= min_dx) \
918        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
919      { \
920        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
921        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
922        if (iSAD < iMinSAD) \
923        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
924    }
925    
926    
927    #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \
928      if ( ((X) <= max_dx) && ((X) >= min_dx) \
929        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
930      { \
931        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
932        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
933        if (iSAD < iMinSAD) \
934        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
935    }
936    
937    
938    #if (0==1)
939  int32_t  int32_t
940  AdvDiamond8_MainSearch(const uint8_t * const pRef,  Diamond16_InterpolMainSearch(
941                                             const uint8_t * const pRefH,                                          const uint8_t * const f_pRef,
942                                             const uint8_t * const pRefV,                                           const uint8_t * const f_pRefH,
943                                             const uint8_t * const pRefHV,                                           const uint8_t * const f_pRefV,
944                                             const uint8_t * const f_pRefHV,
945                                             const uint8_t * const cur,                                             const uint8_t * const cur,
946    
947                                            const uint8_t * const b_pRef,
948                                             const uint8_t * const b_pRefH,
949                                             const uint8_t * const b_pRefV,
950                                             const uint8_t * const b_pRefHV,
951    
952                                             const int x,                                             const int x,
953                                             const int y,                                             const int y,
954                                             int32_t startx,  
955                                             int32_t starty,                                     const int f_start_x,
956                                             int32_t iMinSAD,                                     const int f_start_y,
957                                             VECTOR * const currMV,                                     const int b_start_x,
958                                             const VECTOR * const pmv,                                     const int b_start_y,
959    
960                                       int iMinSAD,
961                                       VECTOR * const f_currMV,
962                                       VECTOR * const b_currMV,
963    
964                                       const int f_center_x,
965                                       const int f_center_y,
966                                       const int b_center_x,
967                                       const int b_center_y,
968    
969                                             const int32_t min_dx,                                             const int32_t min_dx,
970                                             const int32_t max_dx,                                             const int32_t max_dx,
971                                             const int32_t min_dy,                                             const int32_t min_dy,
972                                             const int32_t max_dy,                                             const int32_t max_dy,
973                                             const int32_t iEdgedWidth,                                             const int32_t iEdgedWidth,
974                                             const int32_t iDiamondSize,                                             const int32_t iDiamondSize,
975                                             const int32_t iFcode,  
976                                             const int32_t f_iFcode,
977                                             const int32_t b_iFcode,
978    
979                                             const int32_t iQuant,                                             const int32_t iQuant,
980                                             int iDirection)                                           int iFound)
981  {  {
982    /* Do a diamond search around given starting point, return SAD of best */
983    
984            int32_t f_iDirection = 0;
985            int32_t b_iDirection = 0;
986          int32_t iSAD;          int32_t iSAD;
987    
988  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */          VECTOR f_backupMV;
989            VECTOR b_backupMV;
         if (iDirection) {  
                 CHECK_MV8_CANDIDATE(startx - iDiamondSize, starty);  
                 CHECK_MV8_CANDIDATE(startx + iDiamondSize, starty);  
                 CHECK_MV8_CANDIDATE(startx, starty - iDiamondSize);  
                 CHECK_MV8_CANDIDATE(startx, starty + iDiamondSize);  
         } else {  
                 int bDirection = 1 + 2 + 4 + 8;  
   
                 do {  
                         iDirection = 0;  
                         if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)  
                                 CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);  
   
                         if (bDirection & 2)  
                                 CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);  
990    
991                          if (bDirection & 4)          f_backupMV.x = start_x;
992                                  CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);          f_backupMV.y = start_y;
993            b_backupMV.x = start_x;
994            b_backupMV.y = start_y;
995    
996                          if (bDirection & 8)  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
                                 CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);  
997    
998                          /* now we're doing diagonal checks near our candidate */          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
999            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1000            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1001            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1002    
1003                          if (iDirection)         //checking if anything found          if (iDirection)
1004                          {                  while (!iFound) {
1005                                  bDirection = iDirection;                          iFound = 1;
1006                                  iDirection = 0;                          backupMV = *currMV;
1007                                  startx = currMV->x;  
1008                                  starty = currMV->y;                          if (iDirection != 2)
1009                                  if (bDirection & 3)     //our candidate is left or right                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1010                                  {                                                                                     backupMV.y, 1);
1011                                          CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                          if (iDirection != 1)
1012                                          CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1013                                  } else                  // what remains here is up or down                                                                                     backupMV.y, 2);
1014                                  {                          if (iDirection != 4)
1015                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1016                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                                                                     backupMV.y - iDiamondSize, 3);
1017                                  }                          if (iDirection != 3)
1018                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1019                                                                                       backupMV.y + iDiamondSize, 4);
1020            } else {
1021                    currMV->x = start_x;
1022                    currMV->y = start_y;
1023            }
1024            return iMinSAD;
1025    }
1026    #endif
1027    
1028    
1029    int32_t
1030    AdvDiamond8_MainSearch(const uint8_t * const pRef,
1031                                               const uint8_t * const pRefH,
1032                                               const uint8_t * const pRefV,
1033                                               const uint8_t * const pRefHV,
1034                                               const uint8_t * const cur,
1035                                               const int x,
1036                                               const int y,
1037                                               int start_x,
1038                                               int start_y,
1039                                               int iMinSAD,
1040                                               VECTOR * const currMV,
1041                                               const int center_x,
1042                                               const int center_y,
1043                                               const int32_t min_dx,
1044                                               const int32_t max_dx,
1045                                               const int32_t min_dy,
1046                                               const int32_t max_dy,
1047                                               const int32_t iEdgedWidth,
1048                                               const int32_t iDiamondSize,
1049                                               const int32_t iFcode,
1050                                               const int32_t iQuant,
1051                                               int iDirection)
1052    {
1053    
1054            int32_t iSAD;
1055    
1056    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
1057    
1058            if (iDirection) {
1059                    CHECK_MV8_CANDIDATE(start_x - iDiamondSize, start_y);
1060                    CHECK_MV8_CANDIDATE(start_x + iDiamondSize, start_y);
1061                    CHECK_MV8_CANDIDATE(start_x, start_y - iDiamondSize);
1062                    CHECK_MV8_CANDIDATE(start_x, start_y + iDiamondSize);
1063            } else {
1064                    int bDirection = 1 + 2 + 4 + 8;
1065    
1066                    do {
1067                            iDirection = 0;
1068                            if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
1069                                    CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1070    
1071                            if (bDirection & 2)
1072                                    CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1073    
1074                            if (bDirection & 4)
1075                                    CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1076    
1077                            if (bDirection & 8)
1078                                    CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1079    
1080                            /* now we're doing diagonal checks near our candidate */
1081    
1082                            if (iDirection)         //checking if anything found
1083                            {
1084                                    bDirection = iDirection;
1085                                    iDirection = 0;
1086                                    start_x = currMV->x;
1087                                    start_y = currMV->y;
1088                                    if (bDirection & 3)     //our candidate is left or right
1089                                    {
1090                                            CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1091                                            CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1092                                    } else                  // what remains here is up or down
1093                                    {
1094                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1095                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1096                                    }
1097    
1098                                  if (iDirection) {                                  if (iDirection) {
1099                                          bDirection += iDirection;                                          bDirection += iDirection;
1100                                          startx = currMV->x;                                          start_x = currMV->x;
1101                                          starty = currMV->y;                                          start_y = currMV->y;
1102                                  }                                  }
1103                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
1104                          {                          {
1105                                  switch (bDirection) {                                  switch (bDirection) {
1106                                  case 2:                                  case 2:
1107                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1108                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1109                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1110                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1111                                          break;                                          break;
1112                                  case 1:                                  case 1:
1113                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1114                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1115                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1116                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1117                                          break;                                          break;
1118                                  case 2 + 4:                                  case 2 + 4:
1119                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1120                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1121                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1122                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1123                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1124                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1125                                          break;                                          break;
1126                                  case 4:                                  case 4:
1127                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1128                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1129                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1130                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1131                                          break;                                          break;
1132                                  case 8:                                  case 8:
1133                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1134                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1135                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1136                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1137                                          break;                                          break;
1138                                  case 1 + 4:                                  case 1 + 4:
1139                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1140                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1141                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1142                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1143                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1144                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1145                                          break;                                          break;
1146                                  case 2 + 8:                                  case 2 + 8:
1147                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1148                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1149                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1150                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1151                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1152                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1153                                          break;                                          break;
1154                                  case 1 + 8:                                  case 1 + 8:
1155                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1156                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1157                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1158                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1159                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1160                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1161                                          break;                                          break;
1162                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
1163                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1164                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1165                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1166                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1167                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1168                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1169                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1170                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1171                                          break;                                          break;
1172                                  }                                  }
1173                                  if (!(iDirection))                                  if (!(iDirection))
1174                                          break;          //ok, the end. really                                          break;          //ok, the end. really
1175                                  else {                                  else {
1176                                          bDirection = iDirection;                                          bDirection = iDirection;
1177                                          startx = currMV->x;                                          start_x = currMV->x;
1178                                          starty = currMV->y;                                          start_y = currMV->y;
1179                                  }                                  }
1180                          }                          }
1181                  }                  }
# Line 1148  Line 1193 
1193                                   const uint8_t * const cur,                                   const uint8_t * const cur,
1194                                   const int x,                                   const int x,
1195                                   const int y,                                   const int y,
1196                                   int32_t startx,                             const int start_x,
1197                                   int32_t starty,                             const int start_y,
1198                                   int32_t iMinSAD,                             int iMinSAD,
1199                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1200                                   const VECTOR * const pmv,                             const int center_x,
1201                               const int center_y,
1202                                   const int32_t min_dx,                                   const int32_t min_dx,
1203                                   const int32_t max_dx,                                   const int32_t max_dx,
1204                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1167  Line 1213 
1213          int32_t dx, dy;          int32_t dx, dy;
1214          VECTOR backupMV;          VECTOR backupMV;
1215    
1216          backupMV.x = startx;          backupMV.x = start_x;
1217          backupMV.y = starty;          backupMV.y = start_y;
1218    
1219          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
1220                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 1177  Line 1223 
1223          return iMinSAD;          return iMinSAD;
1224  }  }
1225    
1226    Halfpel8_RefineFuncPtr Halfpel8_Refine;
1227    
1228  int32_t  int32_t
1229  Halfpel16_Refine(const uint8_t * const pRef,  Halfpel16_Refine(const uint8_t * const pRef,
# Line 1189  Line 1235 
1235                                   const int y,                                   const int y,
1236                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1237                                   int32_t iMinSAD,                                   int32_t iMinSAD,
1238                                   const VECTOR * const pmv,                             const int center_x,
1239                               const int center_y,
1240                                   const int32_t min_dx,                                   const int32_t min_dx,
1241                                   const int32_t max_dx,                                   const int32_t max_dx,
1242                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1218  Line 1265 
1265  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1266    
1267    
1268    
1269  int32_t  int32_t
1270  PMVfastSearch16(const uint8_t * const pRef,  PMVfastSearch16(const uint8_t * const pRef,
1271                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1226  Line 1274 
1274                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1275                                  const int x,                                  const int x,
1276                                  const int y,                                  const int y,
1277                                    const int start_x,
1278                                    const int start_y,
1279                                    const int center_x,
1280                                    const int center_y,
1281                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1282                                  const uint32_t iQuant,                                  const uint32_t iQuant,
1283                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 1259  Line 1311 
1311    
1312          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1313    
 //  const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  
1314          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
1315    
1316          static int32_t threshA, threshB;          int32_t threshA, threshB;
1317          int32_t bPredEq;          int32_t bPredEq;
1318          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
1319    
# Line 1280  Line 1331 
1331          }          }
1332    
1333          /* 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; */
1334          bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad, 0, 0);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1335            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1336    
1337          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1338                  threshA = 512;                  threshA = 512;
1339                  threshB = 1024;                  threshB = 1024;
   
1340          } else {          } else {
1341                  threshA = psad[0];                  threshA = psad[0];
1342                  threshB = threshA + 256;                  threshB = threshA + 256;
# Line 1306  Line 1357 
1357     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1358  */  */
1359    
1360          *currMV = pmv[0];                       /* current best := prediction */          currMV->x = start_x;
1361            currMV->y = start_y;
1362    
1363          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
1364                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1365                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1330  Line 1383 
1383                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1384                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1385          iMinSAD +=          iMinSAD +=
1386                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
1387                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
1388    
1389          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1390                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1391                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1392                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
1393                  {                  {
1394                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
# Line 1439  Line 1492 
1492    
1493          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1494                  (MVequal(*currMV, prevMB->mvs[0]) &&                  (MVequal(*currMV, prevMB->mvs[0]) &&
1495                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1496                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1497                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
1498                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1466  Line 1519 
1519    
1520          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
1521    
1522    
1523  /* 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 */
1524          iSAD =          iSAD =
1525                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1526                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y,
1527                                                      min_dx, max_dx,
1528                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1529                                                    iQuant, iFound);                                                    iQuant, iFound);
1530    
# Line 1484  Line 1539 
1539                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1540                          iSAD =                          iSAD =
1541                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1542                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    center_x, center_y, iMinSAD, &newMV, center_x, center_y,
1543                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1544                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1545    
# Line 1497  Line 1552 
1552                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1553                          iSAD =                          iSAD =
1554                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1555                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y,
1556                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    min_dx, max_dx, min_dy, max_dy,
1557                                                                      iEdgedWidth, iDiamondSize, iFcode,
1558                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1559    
1560                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 1516  Line 1572 
1572          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
1573                  iMinSAD =                  iMinSAD =
1574                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1575                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1576                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1577    
1578    PMVfast16_Terminate_without_Refine:    PMVfast16_Terminate_without_Refine:
1579          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
1580          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
1581          return iMinSAD;          return iMinSAD;
1582  }  }
1583    
# Line 1538  Line 1594 
1594                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1595                                          const int x,                                          const int x,
1596                                          const int y,                                          const int y,
1597                                          int32_t startx,                                          int32_t start_x,
1598                                          int32_t starty,                                          int32_t start_y,
1599                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1600                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1601                                          const VECTOR * const pmv,                                     const int center_x,
1602                                       const int center_y,
1603                                          const int32_t min_dx,                                          const int32_t min_dx,
1604                                          const int32_t max_dx,                                          const int32_t max_dx,
1605                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 1559  Line 1616 
1616          int32_t iSAD;          int32_t iSAD;
1617          VECTOR backupMV;          VECTOR backupMV;
1618    
1619          backupMV.x = startx;          backupMV.x = start_x;
1620          backupMV.y = starty;          backupMV.y = start_y;
1621    
1622  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1623    
# Line 1587  Line 1644 
1644                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1645                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1646          } else {          } else {
1647                  currMV->x = startx;                  currMV->x = start_x;
1648                  currMV->y = starty;                  currMV->y = start_y;
1649          }          }
1650          return iMinSAD;          return iMinSAD;
1651  }  }
1652    
1653  int32_t  int32_t
1654  Halfpel8_Refine(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1655                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
1656                                  const uint8_t * const pRefV,                                  const uint8_t * const pRefV,
1657                                  const uint8_t * const pRefHV,                                  const uint8_t * const pRefHV,
# Line 1603  Line 1660 
1660                                  const int y,                                  const int y,
1661                                  VECTOR * const currMV,                                  VECTOR * const currMV,
1662                                  int32_t iMinSAD,                                  int32_t iMinSAD,
1663                                  const VECTOR * const pmv,                             const int center_x,
1664                               const int center_y,
1665                                  const int32_t min_dx,                                  const int32_t min_dx,
1666                                  const int32_t max_dx,                                  const int32_t max_dx,
1667                                  const int32_t min_dy,                                  const int32_t min_dy,
# Line 1642  Line 1700 
1700                             const int y,                             const int y,
1701                             const int start_x,                             const int start_x,
1702                             const int start_y,                             const int start_y,
1703                                    const int center_x,
1704                                    const int center_y,
1705                             const uint32_t MotionFlags,                             const uint32_t MotionFlags,
1706                             const uint32_t iQuant,                             const uint32_t iQuant,
1707                             const uint32_t iFcode,                             const uint32_t iFcode,
# Line 1674  Line 1734 
1734  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1735          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
1736    
1737          static int32_t threshA, threshB;           int32_t threshA, threshB;
1738          int32_t iFound, bPredEq;          int32_t iFound, bPredEq;
1739          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
1740    
# Line 1698  Line 1758 
1758          }          }
1759    
1760          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
1761          bPredEq =          //bPredEq = get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad);
1762                  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);
1763    
1764          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1765                  threshA = 512 / 4;                  threshA = 512 / 4;
1766                  threshB = 1024 / 4;                  threshB = 1024 / 4;
1767    
1768          } else {          } else {
1769                  threshA = psad[0] / 4;  /* good estimate */                  threshA = psad[0] / 4;  /* good estimate? */
1770                  threshB = threshA + 256 / 4;                  threshB = threshA + 256 / 4;
1771                  if (threshA < 512 / 4)                  if (threshA < 512 / 4)
1772                          threshA = 512 / 4;                          threshA = 512 / 4;
# Line 1745  Line 1805 
1805                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
1806                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
1807          iMinSAD +=          iMinSAD +=
1808                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
1809                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
1810    
1811          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
1812                                                                  && ((uint32_t) iMinSAD <                                                                  && ((int32_t) iMinSAD <
1813                                                                          prevMB->sad8[iSubBlock]))) {                                                                          prevMB->sad8[iSubBlock]))) {
1814                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1815                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1788  Line 1848 
1848  // the median prediction might be even better than mv16  // the median prediction might be even better than mv16
1849    
1850          if (!MVequal(pmv[0], startMV))          if (!MVequal(pmv[0], startMV))
1851                  CHECK_MV8_CANDIDATE(pmv[0].x, pmv[0].y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
1852    
1853  // (0,0) if needed  // (0,0) if needed
1854          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
# Line 1804  Line 1864 
1864    
1865          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1866                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1867                   ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {                   ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1868                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1869                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1870                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1863  Line 1923 
1923    
1924          if ((iMinSAD <= threshA) ||          if ((iMinSAD <= threshA) ||
1925                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1926                   ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {                   ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1927                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1928                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1929                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1885  Line 1945 
1945  /* 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 */
1946          iSAD =          iSAD =
1947                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
1948                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
1949                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1950                                                    iQuant, iFound);                                                    iQuant, iFound);
1951    
# Line 1900  Line 1960 
1960                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1961                          iSAD =                          iSAD =
1962                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1963                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
1964                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1965                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1966    
# Line 1913  Line 1973 
1973                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1974                          iSAD =                          iSAD =
1975                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1976                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
1977                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
1978                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1979    
# Line 1932  Line 1992 
1992          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
1993                  iMinSAD =                  iMinSAD =
1994                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1995                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1996                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
1997    
1998    
1999    PMVfast8_Terminate_without_Refine:    PMVfast8_Terminate_without_Refine:
2000          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2001          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2002    
2003          return iMinSAD;          return iMinSAD;
2004  }  }
# Line 1951  Line 2011 
2011                           const IMAGE * const pCur,                           const IMAGE * const pCur,
2012                           const int x,                           const int x,
2013                           const int y,                           const int y,
2014                            const int start_x,
2015                            const int start_y,
2016                            const int center_x,
2017                            const int center_y,
2018                           const uint32_t MotionFlags,                           const uint32_t MotionFlags,
2019                           const uint32_t iQuant,                           const uint32_t iQuant,
2020                           const uint32_t iFcode,                           const uint32_t iFcode,
# Line 1986  Line 2050 
2050          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
2051          MACROBLOCK *oldMB = NULL;          MACROBLOCK *oldMB = NULL;
2052    
2053          static int32_t thresh2;           int32_t thresh2;
2054          int32_t bPredEq;          int32_t bPredEq;
2055          int32_t iMinSAD, iSAD = 9999;          int32_t iMinSAD, iSAD = 9999;
2056    
# Line 2009  Line 2073 
2073                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2074          }          }
2075          /* 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; */
2076          bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad, 0, 0);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
2077            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2078    
2079  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
2080          MinSAD=SAD          MinSAD=SAD
# Line 2020  Line 2085 
2085    
2086  // Prepare for main loop  // Prepare for main loop
2087    
2088          *currMV = pmv[0];                       /* current best := median prediction */          currMV->x = start_x;
2089            currMV->y = start_y;
2090    
2091          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
2092                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2093                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 2042  Line 2109 
2109                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2110                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2111          iMinSAD +=          iMinSAD +=
2112                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2113                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2114    
2115  // thresh1 is fixed to 256  // thresh1 is fixed to 256
2116          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
2117                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
2118                   ((uint32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
2119                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
2120                          goto EPZS16_Terminate_without_Refine;                          goto EPZS16_Terminate_without_Refine;
2121                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 2108  Line 2175 
2175    
2176          if ((iMinSAD <= thresh2)          if ((iMinSAD <= thresh2)
2177                  || (MVequal(*currMV, prevMB->mvs[0]) &&                  || (MVequal(*currMV, prevMB->mvs[0]) &&
2178                          ((uint32_t) iMinSAD <= prevMB->sad16))) {                          ((int32_t) iMinSAD <= prevMB->sad16))) {
2179                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
2180                          goto EPZS16_Terminate_without_Refine;                          goto EPZS16_Terminate_without_Refine;
2181                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 2154  Line 2221 
2221    
2222          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
2223    
2224          if (MotionFlags & PMV_USESQUARES8)          if (MotionFlags & PMV_USESQUARES16)
2225                  MainSearchPtr = Square16_MainSearch;                  MainSearchPtr = Square16_MainSearch;
2226          else          else
2227           if (MotionFlags & PMV_ADVANCEDDIAMOND8)           if (MotionFlags & PMV_ADVANCEDDIAMOND16)
2228                  MainSearchPtr = AdvDiamond16_MainSearch;                  MainSearchPtr = AdvDiamond16_MainSearch;
2229          else          else
2230                  MainSearchPtr = Diamond16_MainSearch;                  MainSearchPtr = Diamond16_MainSearch;
# Line 2166  Line 2233 
2233    
2234          iSAD =          iSAD =
2235                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2236                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2237                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2238    
2239          if (iSAD < iMinSAD) {          if (iSAD < iMinSAD) {
# Line 2181  Line 2248 
2248                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2249                          iSAD =                          iSAD =
2250                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2251                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2252                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2253                                                                    2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2254                  }                  }
# Line 2194  Line 2261 
2261                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2262                          iSAD =                          iSAD =
2263                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2264                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2265                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2266    
2267                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 2210  Line 2277 
2277          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2278                  iMinSAD =                  iMinSAD =
2279                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2280                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2281                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2282    
2283    EPZS16_Terminate_without_Refine:    EPZS16_Terminate_without_Refine:
2284    
2285          *oldMB = *prevMB;          *oldMB = *prevMB;
2286    
2287          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2288          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2289          return iMinSAD;          return iMinSAD;
2290  }  }
2291    
# Line 2233  Line 2300 
2300                          const int y,                          const int y,
2301                          const int start_x,                          const int start_x,
2302                          const int start_y,                          const int start_y,
2303                            const int center_x,
2304                            const int center_y,
2305                          const uint32_t MotionFlags,                          const uint32_t MotionFlags,
2306                          const uint32_t iQuant,                          const uint32_t iQuant,
2307                          const uint32_t iFcode,                          const uint32_t iFcode,
# Line 2287  Line 2356 
2356                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2357          }          }
2358          /* 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; */
2359          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[0].x, pmv[0].y, psad);
2360            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2361    
2362    
2363  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2322  Line 2392 
2392                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2393                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
2394          iMinSAD +=          iMinSAD +=
2395                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2396                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2397    
2398    
# Line 2409  Line 2479 
2479    
2480          iSAD =          iSAD =
2481                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2482                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2483                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2484                                                    iQuant, 0);                                                    iQuant, 0);
2485    
# Line 2425  Line 2495 
2495                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2496                          iSAD =                          iSAD =
2497                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2498                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2499                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2500                                                                    iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2501    
# Line 2438  Line 2508 
2508                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2509                          iSAD =                          iSAD =
2510                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2511                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2512                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2513                                                                    iQuant, 0);                                                                    iQuant, 0);
2514    
# Line 2455  Line 2525 
2525          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2526                  iMinSAD =                  iMinSAD =
2527                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2528                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2529                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2530    
2531    EPZS8_Terminate_without_Refine:    EPZS8_Terminate_without_Refine:
2532    
2533          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2534          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2535          return iMinSAD;          return iMinSAD;
2536  }  }
2537    
2538    
2539    
2540    int32_t
2541    PMVfastIntSearch16(const uint8_t * const pRef,
2542                                    const uint8_t * const pRefH,
2543                                    const uint8_t * const pRefV,
2544                                    const uint8_t * const pRefHV,
2545                                    const IMAGE * const pCur,
2546                                    const int x,
2547                                    const int y,
2548                            const int start_x,
2549                            const int start_y,
2550                            const int center_x,
2551                            const int center_y,
2552                                    const uint32_t MotionFlags,
2553                                    const uint32_t iQuant,
2554                                    const uint32_t iFcode,
2555                                    const MBParam * const pParam,
2556                                    const MACROBLOCK * const pMBs,
2557                                    const MACROBLOCK * const prevMBs,
2558                                    VECTOR * const currMV,
2559                                    VECTOR * const currPMV)
2560    {
2561            const uint32_t iWcount = pParam->mb_width;
2562            const int32_t iWidth = pParam->width;
2563            const int32_t iHeight = pParam->height;
2564            const int32_t iEdgedWidth = pParam->edged_width;
2565    
2566            const uint8_t *cur = pCur->y + x * 16 + y * 16 * iEdgedWidth;
2567            const VECTOR zeroMV = { 0, 0 };
2568    
2569            int32_t iDiamondSize;
2570    
2571            int32_t min_dx;
2572            int32_t max_dx;
2573            int32_t min_dy;
2574            int32_t max_dy;
2575    
2576            int32_t iFound;
2577    
2578            VECTOR newMV;
2579            VECTOR backupMV;                        /* just for PMVFAST */
2580    
2581            VECTOR pmv[4];
2582            int32_t psad[4];
2583    
2584            MainSearch16FuncPtr MainSearchPtr;
2585    
2586            const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
2587            MACROBLOCK *const pMB = pMBs + x + y * iWcount;
2588    
2589            int32_t threshA, threshB;
2590            int32_t bPredEq;
2591            int32_t iMinSAD, iSAD;
2592    
2593    
2594    /* Get maximum range */
2595            get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
2596                              iFcode);
2597    
2598    /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */
2599    
2600            if ((x == 0) && (y == 0)) {
2601                    threshA = 512;
2602                    threshB = 1024;
2603    
2604                    bPredEq = 0;
2605                    psad[0] = psad[1] = psad[2] = psad[3] = 0;
2606                    *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2607    
2608            } else {
2609                    threshA = psad[0];
2610                    threshB = threshA + 256;
2611                    if (threshA < 512)
2612                            threshA = 512;
2613                    if (threshA > 1024)
2614                            threshA = 1024;
2615                    if (threshB > 1792)
2616                            threshB = 1792;
2617    
2618                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2619                    *currMV = pmv[0];                       /* current best := prediction */
2620            }
2621    
2622            iFound = 0;
2623    
2624    /* Step 4: Calculate SAD around the Median prediction.
2625       MinSAD=SAD
2626       If Motion Vector equal to Previous frame motion vector
2627       and MinSAD<PrevFrmSAD goto Step 10.
2628       If SAD<=256 goto Step 10.
2629    */
2630    
2631            if (currMV->x > max_dx) {
2632                    currMV->x = EVEN(max_dx);
2633            }
2634            if (currMV->x < min_dx) {
2635                    currMV->x = EVEN(min_dx);
2636            }
2637            if (currMV->y > max_dy) {
2638                    currMV->y = EVEN(max_dy);
2639            }
2640            if (currMV->y < min_dy) {
2641                    currMV->y = EVEN(min_dy);
2642            }
2643    
2644            iMinSAD =
2645                    sad16(cur,
2646                              get_iref_mv(pRef, x, y, 16, currMV,
2647                                                     iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2648            iMinSAD +=
2649                    calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2650                                              (uint8_t) iFcode, iQuant);
2651    
2652            if ((iMinSAD < 256) ||
2653                    ((MVequal(*currMV, prevMB->i_mvs[0])) &&
2654                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2655                    if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
2656                    {
2657                            if (!MVzero(*currMV)) {
2658                                    iMinSAD += MV16_00_BIAS;
2659                                    CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures
2660                                    iMinSAD -= MV16_00_BIAS;
2661                            }
2662                    }
2663    
2664                    if (MotionFlags & PMV_EARLYSTOP16)
2665                            goto PMVfastInt16_Terminate_with_Refine;
2666            }
2667    
2668    
2669    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
2670       vector of the median.
2671       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
2672    */
2673    
2674            if ((bPredEq) && (MVequal(pmv[0], prevMB->i_mvs[0])))
2675                    iFound = 2;
2676    
2677    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
2678       Otherwise select large Diamond Search.
2679    */
2680    
2681            if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))
2682                    iDiamondSize = 2;               // halfpel units!
2683            else
2684                    iDiamondSize = 4;               // halfpel units!
2685    
2686    /*
2687       Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
2688       Also calculate (0,0) but do not subtract offset.
2689       Let MinSAD be the smallest SAD up to this point.
2690       If MV is (0,0) subtract offset.
2691    */
2692    
2693    // (0,0) is often a good choice
2694    
2695            if (!MVzero(pmv[0]))
2696                    CHECK_MV16_ZERO;
2697    
2698    // previous frame MV is always possible
2699    
2700            if (!MVzero(prevMB->i_mvs[0]))
2701                    if (!MVequal(prevMB->i_mvs[0], pmv[0]))
2702                            CHECK_MV16_CANDIDATE(prevMB->i_mvs[0].x, prevMB->i_mvs[0].y);
2703    
2704    // left neighbour, if allowed
2705    
2706            if (!MVzero(pmv[1]))
2707                    if (!MVequal(pmv[1], prevMB->i_mvs[0]))
2708                            if (!MVequal(pmv[1], pmv[0]))
2709                                    CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);
2710    
2711    // top neighbour, if allowed
2712            if (!MVzero(pmv[2]))
2713                    if (!MVequal(pmv[2], prevMB->i_mvs[0]))
2714                            if (!MVequal(pmv[2], pmv[0]))
2715                                    if (!MVequal(pmv[2], pmv[1]))
2716                                            CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);
2717    
2718    // top right neighbour, if allowed
2719                                            if (!MVzero(pmv[3]))
2720                                                    if (!MVequal(pmv[3], prevMB->i_mvs[0]))
2721                                                            if (!MVequal(pmv[3], pmv[0]))
2722                                                                    if (!MVequal(pmv[3], pmv[1]))
2723                                                                            if (!MVequal(pmv[3], pmv[2]))
2724                                                                                    CHECK_MV16_CANDIDATE(pmv[3].x,
2725                                                                                                                             pmv[3].y);
2726    
2727            if ((MVzero(*currMV)) &&
2728                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
2729                    iMinSAD -= MV16_00_BIAS;
2730    
2731    
2732    /* Step 6: If MinSAD <= thresa goto Step 10.
2733       If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
2734    */
2735    
2736            if ((iMinSAD <= threshA) ||
2737                    (MVequal(*currMV, prevMB->i_mvs[0]) &&
2738                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2739    
2740                    if (MotionFlags & PMV_EARLYSTOP16)
2741                            goto PMVfastInt16_Terminate_with_Refine;
2742            }
2743    
2744    
2745    /************ (Diamond Search)  **************/
2746    /*
2747       Step 7: Perform Diamond search, with either the small or large diamond.
2748       If Found=2 only examine one Diamond pattern, and afterwards goto step 10
2749       Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond.
2750       If center then goto step 10.
2751       Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center.
2752       Refine by using small diamond and goto step 10.
2753    */
2754    
2755            if (MotionFlags & PMV_USESQUARES16)
2756                    MainSearchPtr = Square16_MainSearch;
2757            else if (MotionFlags & PMV_ADVANCEDDIAMOND16)
2758                    MainSearchPtr = AdvDiamond16_MainSearch;
2759            else
2760                    MainSearchPtr = Diamond16_MainSearch;
2761    
2762            backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
2763    
2764    
2765    /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2766            iSAD =
2767                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2768                                                      currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2769                                                      min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2770                                                      iQuant, iFound);
2771    
2772            if (iSAD < iMinSAD) {
2773                    *currMV = newMV;
2774                    iMinSAD = iSAD;
2775            }
2776    
2777            if (MotionFlags & PMV_EXTSEARCH16) {
2778    /* extended: search (up to) two more times: orignal prediction and (0,0) */
2779    
2780                    if (!(MVequal(pmv[0], backupMV))) {
2781                            iSAD =
2782                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2783                                                                      pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2784                                                                      min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2785                                                                      iDiamondSize, iFcode, iQuant, iFound);
2786    
2787                            if (iSAD < iMinSAD) {
2788                                    *currMV = newMV;
2789                                    iMinSAD = iSAD;
2790                            }
2791                    }
2792    
2793                    if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2794                            iSAD =
2795                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2796                                                                      iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2797                                                                      max_dy, iEdgedWidth, iDiamondSize, iFcode,
2798                                                                      iQuant, iFound);
2799    
2800                            if (iSAD < iMinSAD) {
2801                                    *currMV = newMV;
2802                                    iMinSAD = iSAD;
2803                            }
2804                    }
2805            }
2806    
2807    /*
2808       Step 10:  The motion vector is chosen according to the block corresponding to MinSAD.
2809    */
2810    
2811    PMVfastInt16_Terminate_with_Refine:
2812    
2813            pMB->i_mvs[0] = pMB->i_mvs[1] = pMB->i_mvs[2] = pMB->i_mvs[3] = pMB->i_mv16 = *currMV;
2814            pMB->i_sad8[0] = pMB->i_sad8[1] = pMB->i_sad8[2] = pMB->i_sad8[3] = pMB->i_sad16 = iMinSAD;
2815    
2816            if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2817                    iMinSAD =
2818                            Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2819                                                             iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2820                                                             iFcode, iQuant, iEdgedWidth);
2821    
2822            pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)
2823    
2824    PMVfastInt16_Terminate_without_Refine:
2825            currPMV->x = currMV->x - center_x;
2826            currPMV->y = currMV->y - center_y;
2827            return iMinSAD;
2828    }
2829    
2830    
2831    
2832  /* ***********************************************************  /* ***********************************************************
# Line 2475  Line 2835 
2835  ***************************************************************/  ***************************************************************/
2836    
2837    
2838    #define DIRECT_PENALTY 0
2839    #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this
2840    
2841  void  void
2842  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
2843                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
2844                                             const int32_t time_bp,
2845                                             const int32_t time_pp,
2846                                           // forward (past) reference                                           // forward (past) reference
2847                                           const MACROBLOCK * const f_mbs,                                           const MACROBLOCK * const f_mbs,
2848                                           const IMAGE * const f_ref,                                           const IMAGE * const f_ref,
# Line 2491  Line 2856 
2856                                           const IMAGE * const b_refV,                                           const IMAGE * const b_refV,
2857                                           const IMAGE * const b_refHV)                                           const IMAGE * const b_refHV)
2858  {  {
2859          const uint32_t mb_width = pParam->mb_width;          const int mb_width = pParam->mb_width;
2860          const uint32_t mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
2861          const int32_t edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
2862    
2863          uint32_t i, j;          int i, j, k;
2864    
2865          int32_t f_sad16;          static const VECTOR zeroMV={0,0};
2866          int32_t b_sad16;  
2867          int32_t i_sad16;          int f_sad16;    /* forward (as usual) search */
2868          int32_t d_sad16;          int b_sad16;    /* backward (only in b-frames) search */
2869          int32_t best_sad;          int i_sad16;    /* interpolated (both direction, b-frames only) */
2870            int d_sad16;    /* direct mode (assume linear motion) */
2871    
2872            int best_sad;
2873    
2874            VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
2875          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
2876    
2877            int f_count=0;
2878            int b_count=0;
2879            int i_count=0;
2880            int d_count=0;
2881            int s_count=0;
2882    
2883            const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
2884        const int64_t TRD = (int32_t)time_pp;
2885    
2886            // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);
2887          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
2888          for (j = 0; j < mb_height; j++) {          for (j = 0; j < mb_height; j++) {
2889    
2890                    f_predMV = zeroMV;      /* prediction is reset at left boundary */
2891                    b_predMV = zeroMV;
2892    
2893                  for (i = 0; i < mb_width; i++) {                  for (i = 0; i < mb_width; i++) {
2894                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];
2895                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
2896                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
2897    
2898                            mb->deltamv=zeroMV;
2899    
2900    /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
2901    
2902    #ifndef _DISABLE_SKIP
2903                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
2904                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
2905                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
# Line 2521  Line 2909 
2909                                  mb->b_mvs[0].y = 0;                                  mb->b_mvs[0].y = 0;
2910                                  continue;                                  continue;
2911                          }                          }
2912                  /* force F_SAD16  #endif
                         f_sad16 = 100;  
                         b_sad16 = 65535;  
2913    
2914                          mb->mode = MODE_FORWARD;                          d_sad16 = DIRECT_PENALTY;
                         mb->mvs[0].x = 1;  
                         mb->mvs[0].y = 1;  
                         mb->b_mvs[0].x = 1;  
                         mb->b_mvs[0].y = 1;  
                         continue;  
                  ^^ force F_SAD16 */  
2915    
2916                            if (b_mb->mode == MODE_INTER4V)
2917                            {
2918    
2919                            /* same method of scaling as in decoder.c, so we copy from there */
2920                        for (k = 0; k < 4; k++) {
2921    
2922                                            mb->directmv[k] = b_mb->mvs[k];
2923    
2924                                            mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
2925                        mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
2926                                                                                    ? ((TRB - TRD) * mb->directmv[k].x) / TRD
2927                                                : mb->mvs[k].x - mb->directmv[k].x);
2928    
2929                        mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
2930                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
2931                                                                                    ? ((TRB - TRD) * mb->directmv[k].y) / TRD
2932                                                : mb->mvs[k].y - mb->directmv[k].y);
2933    
2934                                            d_sad16 +=
2935                                                    sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
2936                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2937                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
2938                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2939                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
2940                                                      edged_width);
2941                                    }
2942                            }
2943                            else
2944                            {
2945                                    mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
2946                                    mb->directmv[0] = b_mb->mvs[0];
2947    
2948                                    mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
2949                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
2950                                                                            ? ((TRB - TRD) * mb->directmv[0].x) / TRD
2951                                        : mb->mvs[0].x - mb->directmv[0].x);
2952    
2953                        mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
2954                    mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
2955                                                                            ? ((TRB - TRD) * mb->directmv[0].y) / TRD
2956                                        : mb->mvs[0].y - mb->directmv[0].y);
2957    
2958                                    d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2959                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2960                                                                    i, j, 16, &mb->mvs[0], edged_width),
2961                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2962                                                                    i, j, 16, &mb->b_mvs[0], edged_width),
2963                                                      edged_width);
2964    
2965                }
2966                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
2967    
2968                          // forward search                          // forward search
2969                          f_sad16 =                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2970                                  SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                  &frame->image, i, j,
2971                                                   &frame->image, i, j, frame->motion_flags,                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
2972                                                    f_predMV.x, f_predMV.y,                         /* center is f-prediction */
2973                                                    frame->motion_flags,
2974                                                   frame->quant, frame->fcode, pParam,                                                   frame->quant, frame->fcode, pParam,
2975                                                   f_mbs,  f_mbs, /* todo */                                                  f_mbs, f_mbs,
2976                                                   &mb->mvs[0], &pmv_dontcare);   // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);
2977    
2978    
2979                          // backward search                          // backward search
2980                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2981                                                  &frame->image, i, j, frame->motion_flags,                                                  &frame->image, i, j,
2982                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
2983                                                    b_predMV.x, b_predMV.y,                         /* center is b-prediction */
2984                                                    frame->motion_flags,
2985                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
2986                                                  b_mbs, b_mbs,   /* todo */                                                  b_mbs, b_mbs,
2987                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);
   
                         // interpolate search (simple, but effective)  
                         i_sad16 = 65535;  
2988    
                         /*  
                         x/y range somewhat buggy  
2989                          i_sad16 =                          i_sad16 =
2990                                  sad16bi_c(frame->image.y + i * 16 + j * 16 * edged_width,                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2991                                                    get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2992                                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y,                                                                  i, j, 16, &mb->mvs[0], edged_width),
2993                                                                    edged_width), get_ref(b_ref->y, b_refH->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2994                                                                                                                  b_refV->y, b_refHV->y,                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
                                                                                                                 i, j, 16,  
                                                                                                                 mb->b_mvs[0].x,  
                                                                                                                 mb->b_mvs[0].x,  
                                                                                                                 edged_width),  
2995                                                    edged_width);                                                    edged_width);
2996                          */                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
2997                                                                    frame->fcode, frame->quant);
2998                        i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
2999                                                                    frame->bcode, frame->quant);
3000    
3001                          // TODO: direct search                          // TODO: direct search
3002                          // predictor + range of [-32,32]                          // predictor + delta vector in range [-32,32] (fcode=1)
                         d_sad16 = 65535;  
3003    
3004                            i_sad16 = 65535;
3005                            f_sad16 = 65535;
3006                            b_sad16 = 65535;
3007    //                      d_sad16 = 65535;
3008    
3009                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3010                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 2586  Line 3020 
3020                          }                          }
3021    
3022                          if (d_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3023    
3024                                    if (b_mb->mode == MODE_INTER4V)
3025                                    {
3026    
3027                                    /* same method of scaling as in decoder.c, so we copy from there */
3028                                for (k = 0; k < 4; k++) {
3029    
3030                                                    mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3031                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3032                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3033                                                        : mb->mvs[k].x - mb->directmv[k].x);
3034    
3035                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3036                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3037                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3038                                                : mb->mvs[k].y - mb->directmv[k].y);
3039                                            }
3040                                    }
3041                                    else
3042                                    {
3043                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3044    
3045                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3046                                                                                    ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3047                                            : mb->mvs[0].x - mb->directmv[0].x);
3048    
3049                                mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3050    
3051                            mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3052                                                                                    ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3053                                                : mb->mvs[0].y - mb->directmv[0].y);
3054    
3055                                            mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3056                                            mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
3057                    }
3058    
3059                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3060                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
3061                                    mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(
3062                            }
3063    
3064                            switch (mb->mode)
3065                            {
3066                                    case MODE_FORWARD:
3067                                            f_count++;
3068                                            f_predMV = mb->mvs[0];
3069                                            break;
3070                                    case MODE_BACKWARD:
3071                                            b_count++;
3072                                            b_predMV = mb->b_mvs[0];
3073    
3074                                            break;
3075                                    case MODE_INTERPOLATE:
3076                                            i_count++;
3077                                            f_predMV = mb->mvs[0];
3078                                            b_predMV = mb->b_mvs[0];
3079                                            break;
3080                                    case MODE_DIRECT:
3081                                            d_count++;
3082                                            break;
3083                                    default:
3084                                            s_count++;              // ???
3085                                            break;
3086                          }                          }
3087    
3088                  }                  }
3089          }          }
3090    
3091    #ifdef _DEBUG_BFRAME_STAT
3092            fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",
3093                                    f_count,b_count,i_count,d_count,s_count);
3094    #endif
3095    
3096  }  }

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

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