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

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

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

revision 132, Tue Apr 23 00:04:51 2002 UTC revision 181, Wed May 22 12:42:25 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      01.05.2002      updated MotionEstimationBVOP
6     *      25.04.2002 partial prevMB conversion
7   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
8   *  14.04.2002 added MotionEstimationBVOP()   *  14.04.2002 added MotionEstimationBVOP()
9   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between
# Line 52  Line 54 
54  #define MV16_THRESHOLD  192  #define MV16_THRESHOLD  192
55  #define MV8_THRESHOLD   56  #define MV8_THRESHOLD   56
56    
57    #define NEIGH_MOVE_THRESH 0
58    // how much a block's MV must differ from his neighbour
59    // to be search for INTER4V. The more, the faster...
60    
61  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
62  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
63  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
64    #define MV8_00_BIAS     (0)
65    
66  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
67  #define INTER_BIAS      512  #define MV16_INTER_BIAS 512
68    
69  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
70  #define IMV16X16                        5  #define IMV16X16                        5
# Line 66  Line 73 
73  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
74  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
75    
   
76  // fast ((A)/2)*2  // fast ((A)/2)*2
77  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
78    
79    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
80    #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
81    
82  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
83                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 79  Line 87 
87                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
88                                          const int x, const int y,                                          const int x, const int y,
89                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
90                                            const uint32_t iQuant,
91                                            const uint32_t iFcode,
92                                          const MBParam * const pParam,                                          const MBParam * const pParam,
93                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
94                                            const MACROBLOCK * const prevMBs,
95                                          VECTOR * const currMV,                                          VECTOR * const currMV,
96                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
97    
# Line 92  Line 103 
103                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
104                                          const int x, const int y,                                          const int x, const int y,
105                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
106                                            const uint32_t iQuant,
107                                            const uint32_t iFcode,
108                                          const MBParam * const pParam,                                          const MBParam * const pParam,
109                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
110                                            const MACROBLOCK * const prevMBs,
111                                          VECTOR * const currMV,                                          VECTOR * const currMV,
112                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
113    
# Line 105  Line 119 
119                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
120                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
121                                          const int x, const int y,                                          const int x, const int y,
122                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
123                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
124                                            const uint32_t iQuant,
125                                            const uint32_t iFcode,
126                                          const MBParam * const pParam,                                          const MBParam * const pParam,
127                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
128                                            const MACROBLOCK * const prevMBs,
129                                          VECTOR * const currMV,                                          VECTOR * const currMV,
130                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
131    
# Line 119  Line 136 
136                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
137                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
138                                          const int x, const int y,                                          const int x, const int y,
139                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
140                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
141                                            const uint32_t iQuant,
142                                            const uint32_t iFcode,
143                                          const MBParam * const pParam,                                          const MBParam * const pParam,
144                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
145                                            const MACROBLOCK * const prevMBs,
146                                          VECTOR * const currMV,                                          VECTOR * const currMV,
147                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
148    
# Line 170  Line 190 
190    
191  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
192    
193    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
194            {     0    ,(int)(1.00235+0.5), (int)(1.15582+0.5), (int)(1.31976+0.5), (int)(1.49591+0.5), (int)(1.68601+0.5),
195            (int)(1.89187+0.5), (int)(2.11542+0.5), (int)(2.35878+0.5), (int)(2.62429+0.5), (int)(2.91455+0.5),
196            (int)(3.23253+0.5), (int)(3.58158+0.5), (int)(3.96555+0.5), (int)(4.38887+0.5), (int)(4.85673+0.5),
197            (int)(5.37519+0.5), (int)(5.95144+0.5), (int)(6.59408+0.5), (int)(7.31349+0.5), (int)(8.12242+0.5),
198            (int)(9.03669+0.5), (int)(10.0763+0.5), (int)(11.2669+0.5), (int)(12.6426+0.5), (int)(14.2493+0.5),
199            (int)(16.1512+0.5), (int)(18.442+0.5),  (int)(21.2656+0.5), (int)(24.8580+0.5), (int)(29.6436+0.5),
200            (int)(36.4949+0.5)      };
201    
202    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
203    
204    
205    
206  // mv.length table  // mv.length table
207  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
208      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 205  Line 238 
238  }  }
239    
240    
241  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
242  {  {
243          return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
244  }  }
245    
246  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
247    
248  {  {
249      return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));      return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
250  }  }
251    
252    
# Line 232  Line 265 
265  #endif  #endif
266    
267  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
268          MBParam * const pParam,          MBParam * const pParam,
269          const IMAGE * const pRef,          FRAMEINFO * const current,
270            FRAMEINFO * const reference,
271          const IMAGE * const pRefH,          const IMAGE * const pRefH,
272          const IMAGE * const pRefV,          const IMAGE * const pRefV,
273          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
274          const uint32_t iLimit)          const uint32_t iLimit)
275    
276  {  {
277          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
278          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
279            MACROBLOCK * const pMBs = current->mbs;
280            MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
281    
282          uint32_t i, j, iIntra = 0;          const IMAGE * const pCurrent = &current->image;
283            const IMAGE * const pRef = &reference->image;
284    
285          VECTOR mv16;          const VECTOR zeroMV = {0,0};
         VECTOR pmv16;  
286    
287          int32_t sad8 = 0;          int32_t x, y;
288          int32_t sad16;          int32_t iIntra = 0;
289          int32_t deviation;          VECTOR pmv;
290    
291          if (sadInit)          if (sadInit)
292                  (*sadInit)();                  (*sadInit)();
293    
294          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
295          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
296                  {                  {
297                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
   
                         sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                          j, i, pParam->motion_flags,  
                                          pParam, pMBs, &mv16, &pmv16);  
                         pMB->sad16=sad16;  
298    
299                            pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                                             x, y, current->motion_flags, current->quant, current->fcode,
301                                             pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
302    
                         /* decide: MODE_INTER or MODE_INTRA  
                            if (dev_intra < sad_inter - 2 * nb) use_intra  
                         */  
303    
304                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
305                            {
306                                    int32_t deviation;
307                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
308                                                             pParam->edged_width);
309    
310                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
311                          {                          {
312                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
313                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1]
314                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
315                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
316                                                                 = pMB->sad8[2] = pMB->sad8[3] = 0;
317    
318                                  iIntra++;                                  iIntra++;
319                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 287  Line 321 
321    
322                                  continue;                                  continue;
323                          }                          }
324                            }
325                            pMB->mode = MODE_INTER;
326                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
327               pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
328                    }
329    
330                          if (pParam->global_flags & XVID_INTER4V)          // we try to do as few INTER4V-searches as possible. So we split ME in two parts, normal
331                          {          // SEARCH16 and only for special blocks SEARCH8. May this should be modified for quality
332                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,          // levels.
                                                        2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);  
333    
                                 pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);  
334    
                                 pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);  
335    
336                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,          if (current->global_flags & XVID_INTER4V)
337                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                  for (y = 0; y < iHcount; y++)
338                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                          for (x = 0; x < iWcount; x++)
339                            {
340                                    MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
341    
342                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];                                  if (pMB->mode == MODE_INTRA)
343                          }                                          continue;
344    
345    
346                                    if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) )
347                                    {
348                                    int32_t neigh=0;
349    
350                                    if (x>0)
351                                    {       neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x));
352                                            neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y));
353                                    }
354                                    if (y>0)
355                                    {       neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x));
356                                            neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y));
357                                    }
358                                    if (x<(iWcount-1))
359                                    {       neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x));
360                                            neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y));
361                                    }
362                                    if (y<(iHcount-1))
363                                    {       neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x));
364                                            neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y));
365                                    }
366    
367                                    if (neigh > NEIGH_MOVE_THRESH)
368                                    {
369                                            int32_t sad8 = IMV16X16 * current->quant;
370    
371                                            if (sad8 < pMB->sad16)
372                                            sad8 += pMB->sad8[0]
373                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
374                                                                   2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
375                                                                       current->motion_flags, current->quant, current->fcode,
376                                                                   pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
377    
378                                            if (sad8 < pMB->sad16)
379                                            sad8 += pMB->sad8[1]
380                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
381                                           2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
382                                                            current->motion_flags, current->quant, current->fcode,
383                                                            pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
384    
385                                            if (sad8 < pMB->sad16)
386                                            sad8 += pMB->sad8[2]
387                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
388                                                            2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
389                                                            current->motion_flags, current->quant, current->fcode,
390                                                            pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
391    
392                                            if (sad8 < pMB->sad16)
393                                            sad8 += pMB->sad8[3]
394                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
395                                                            2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
396                                                            current->motion_flags, current->quant, current->fcode,
397                                                            pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
398    
399                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
400                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
401                          */                          */
402    
403                          if (pMB->dquant == NO_CHANGE) {                                          if (sad8 < pMB->sad16)
                                 if (((pParam->global_flags & XVID_INTER4V)==0) ||  
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {  
   
                                         sad8 = sad16;  
                                         pMB->mode = MODE_INTER;  
                                         pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;  
                                         pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;  
                                         pMB->pmvs[0].x = pmv16.x;  
                                         pMB->pmvs[0].y = pmv16.y;  
                                 }  
                                 else  
                                         pMB->mode = MODE_INTER4V;  
                         }  
                         else  
404                          {                          {
405                                  sad8 = sad16;                                                  pMB->mode = MODE_INTER4V;
406                                  pMB->mode = MODE_INTER;                        pMB->sad8[0] *= 4;
407                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                                  pMB->sad8[1] *= 4;
408                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                                  pMB->sad8[2] *= 4;
409                                  pMB->pmvs[0].x = pmv16.x;                                                  pMB->sad8[3] *= 4;
410                                  pMB->pmvs[0].y = pmv16.y;                                                  continue;
411                          }                          }
412    
413                                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
414                  }                  }
415    
         return 0;  
416  }  }
417    
418  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                  // get_pmv has to be called again, because inter4v changes predictors
419    
420  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )                          pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
421                            pMB->pmvs[0].x = pMB->mv16.x - pmv.x;   /* the other pmvs are only needed in INTER4V-mode */
422                            pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
423    
424                            }
425    
426            return 0;
427    }
428    
429  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
430    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
431      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
432    { \    { \
433      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); \
434      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
     if (iSAD <= iQuant * 96)    \  
         iSAD -= MV16_00_BIAS; \  
435      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
436      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
437  }  }
438    
439  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
440      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); \
441      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
442      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
443      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
444  }  }
# Line 371  Line 448 
448      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
449    { \    { \
450      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); \
451      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
452      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
453      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
454  }  }
# Line 381  Line 458 
458      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
459    { \    { \
460      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); \
461      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
462      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
463      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
464  }  }
# Line 391  Line 468 
468      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
469    { \    { \
470      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); \
471      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
472      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
473      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
474  }  }
# Line 399  Line 476 
476    
477  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
478    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); \
479    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
480    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
481    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
482  }  }
# Line 407  Line 484 
484  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
485    { \    { \
486      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); \
487      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
488      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
489      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
490  }  }
# Line 417  Line 494 
494      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
495    { \    { \
496      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); \
497      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
498      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
499      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
500  }  }
# Line 427  Line 504 
504      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
505    { \    { \
506      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); \
507      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
508      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
509      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
510  }  }
# Line 437  Line 514 
514      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
515    { \    { \
516      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); \
517      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
518      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
519      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
520  }  }
# Line 452  Line 529 
529                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
530                                          const int x, const int y,                                          const int x, const int y,
531                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
532                                            const uint32_t iQuant,
533                                            const uint32_t iFcode,
534                                          MBParam * const pParam,                                          MBParam * const pParam,
535                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
536                                            const MACROBLOCK * const prevMBs,
537                                          VECTOR * const currMV,                                          VECTOR * const currMV,
538                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
539  {  {
540          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
541          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
542          int32_t iSAD;          int32_t iSAD;
543          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 702  Line 781 
781          return iMinSAD;          return iMinSAD;
782  }  }
783    
784    int32_t AdvDiamond16_MainSearch(
785            const uint8_t * const pRef,
786            const uint8_t * const pRefH,
787            const uint8_t * const pRefV,
788            const uint8_t * const pRefHV,
789            const uint8_t * const cur,
790            const int x, const int y,
791            int32_t startx, int32_t starty,
792            int32_t iMinSAD,
793            VECTOR * const currMV,
794            const VECTOR * const pmv,
795            const int32_t min_dx, const int32_t max_dx,
796            const int32_t min_dy, const int32_t max_dy,
797            const int32_t iEdgedWidth,
798            const int32_t iDiamondSize,
799            const int32_t iFcode,
800            const int32_t iQuant,
801            int iDirection)
802    {
803    
804            int32_t iSAD;
805    
806    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
807    
808            if (iDirection)
809            {
810                    CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty);
811                    CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty);
812                    CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize);
813                    CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize);
814            }
815            else
816            {
817                    int bDirection = 1+2+4+8;
818                    do
819                    {
820                            iDirection = 0;
821                            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)
822                                    CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
823    
824                            if (bDirection&2)
825                                    CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
826    
827                            if (bDirection&4)
828                                    CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
829    
830                            if (bDirection&8)
831                                    CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
832    
833                            /* now we're doing diagonal checks near our candidate */
834    
835                            if (iDirection) //checking if anything found
836                            {
837                                    bDirection = iDirection;
838                                    iDirection = 0;
839                                    startx=currMV->x; starty=currMV->y;
840                                    if (bDirection & 3) //our candidate is left or right
841                                    {
842                                            CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
843                                            CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
844                                    }
845                                    else // what remains here is up or down
846                                    {
847                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
848                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
849                                    }
850    
851                                    if (iDirection)
852                                    {       bDirection+=iDirection;
853                                            startx=currMV->x; starty=currMV->y;
854                                    }
855                            }
856                            else //about to quit, eh? not so fast....
857                            {
858                                    switch (bDirection)
859                                    {
860                                    case 2:
861                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
862                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
863                                            break;
864                                    case 1:
865                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
866                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
867                                            break;
868                                    case 2+4:
869                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
870                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
871                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
872                                            break;
873                                    case 4:
874                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
875                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
876                                            break;
877                                    case 8:
878                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
879                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
880                                            break;
881                                    case 1+4:
882                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
883                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
884                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
885                                            break;
886                                    case 2+8:
887                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
888                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
889                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
890                                            break;
891                                    case 1+8:
892                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
893                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
894                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
895                                            break;
896                                    default: //1+2+4+8 == we didn't find anything at all
897                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
898                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
899                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
900                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
901                                            break;
902                                    }
903                                    if (!iDirection) break; //ok, the end. really
904                                    else
905                                    {       bDirection=iDirection;
906                                            startx=currMV->x; starty=currMV->y;
907                                    }
908                            }
909                    }
910                    while (1); //forever
911            }
912            return iMinSAD;
913    }
914    
915    int32_t AdvDiamond8_MainSearch(
916            const uint8_t * const pRef,
917            const uint8_t * const pRefH,
918            const uint8_t * const pRefV,
919            const uint8_t * const pRefHV,
920            const uint8_t * const cur,
921            const int x, const int y,
922            int32_t startx, int32_t starty,
923            int32_t iMinSAD,
924            VECTOR * const currMV,
925            const VECTOR * const pmv,
926            const int32_t min_dx, const int32_t max_dx,
927            const int32_t min_dy, const int32_t max_dy,
928            const int32_t iEdgedWidth,
929            const int32_t iDiamondSize,
930            const int32_t iFcode,
931            const int32_t iQuant,
932            int iDirection)
933    {
934    
935            int32_t iSAD;
936    
937    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
938    
939            if (iDirection)
940            {
941                    CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty);
942                    CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty);
943                    CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize);
944                    CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize);
945            }
946            else
947            {
948                    int bDirection = 1+2+4+8;
949                    do
950                    {
951                            iDirection = 0;
952                            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)
953                                    CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
954    
955                            if (bDirection&2)
956                                    CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
957    
958                            if (bDirection&4)
959                                    CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
960    
961                            if (bDirection&8)
962                                    CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
963    
964                            /* now we're doing diagonal checks near our candidate */
965    
966                            if (iDirection) //checking if anything found
967                            {
968                                    bDirection = iDirection;
969                                    iDirection = 0;
970                                    startx=currMV->x; starty=currMV->y;
971                                    if (bDirection & 3) //our candidate is left or right
972                                    {
973                                            CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
974                                            CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
975                                    }
976                                    else // what remains here is up or down
977                                    {
978                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
979                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
980                                    }
981    
982                                    if (iDirection)
983                                    {       bDirection+=iDirection;
984                                            startx=currMV->x; starty=currMV->y;
985                                    }
986                            }
987                            else //about to quit, eh? not so fast....
988                            {
989                                    switch (bDirection)
990                                    {
991                                    case 2:
992                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
993                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
994                                            break;
995                                    case 1:
996                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
997                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
998                                            break;
999                                    case 2+4:
1000                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1001                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1002                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1003                                            break;
1004                                    case 4:
1005                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1006                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1007                                            break;
1008                                    case 8:
1009                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1010                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1011                                            break;
1012                                    case 1+4:
1013                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1014                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1015                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1016                                            break;
1017                                    case 2+8:
1018                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1019                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1020                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1021                                            break;
1022                                    case 1+8:
1023                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1024                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1025                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1026                                            break;
1027                                    default: //1+2+4+8 == we didn't find anything at all
1028                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1029                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1030                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1031                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1032                                            break;
1033                                    }
1034                                    if (!(iDirection)) break; //ok, the end. really
1035                                    else
1036                                    {       bDirection=iDirection;
1037                                            startx=currMV->x; starty=currMV->y;
1038                                    }
1039                            }
1040                    }
1041                    while (1); //forever
1042            }
1043            return iMinSAD;
1044    }
1045    
1046    
1047  int32_t Full8_MainSearch(  int32_t Full8_MainSearch(
1048                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
1049                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 780  Line 1122 
1122                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1123                                          const int x, const int y,                                          const int x, const int y,
1124                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1125                                            const uint32_t iQuant,
1126                                            const uint32_t iFcode,
1127                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1128                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1129                                            const MACROBLOCK * const prevMBs,
1130                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1131                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1132  {  {
1133      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1134          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1135          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1136          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 809  Line 1152 
1152          VECTOR pmv[4];          VECTOR pmv[4];
1153          int32_t psad[4];          int32_t psad[4];
1154    
1155          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          MainSearch16FuncPtr MainSearchPtr;
1156    
1157    //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1158            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1159    
1160          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1161          int32_t bPredEq;          int32_t bPredEq;
# Line 848  Line 1194 
1194    
1195          iFound=0;          iFound=0;
1196    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536) || (bPredEq) )  
                 iDiamondSize=1; // halfpel!  
         else  
                 iDiamondSize=2; // halfpel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND16) )  
                 iDiamondSize*=2;  
   
1197  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1198     MinSAD=SAD     MinSAD=SAD
1199     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 875  Line 1201 
1201     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1202  */  */
1203    
   
 // Prepare for main loop  
   
1204          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
1205          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1206          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 905  Line 1228 
1228          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1229                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1230                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
1231          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1232    
1233          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1234            {
1235                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
1236                    {
1237                            if (!MVzero(*currMV))
1238          {          {
1239                                    iMinSAD += MV16_00_BIAS;
1240                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
1241                                    iMinSAD -= MV16_00_BIAS;
1242                            }
1243                    }
1244    
1245                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1246                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 916  Line 1248 
1248                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
1249          }          }
1250    
1251    
1252    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1253       vector of the median.
1254       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1255    */
1256    
1257            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
1258                    iFound=2;
1259    
1260    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1261       Otherwise select large Diamond Search.
1262    */
1263    
1264            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1265                    iDiamondSize=1; // halfpel!
1266            else
1267                    iDiamondSize=2; // halfpel!
1268    
1269            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1270                    iDiamondSize*=2;
1271    
1272  /*  /*
1273     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
1274     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1275     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1276     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1277  */  */
1278    
1279  // (0,0) is always possible  // (0,0) is always possible
1280    
1281            if (!MVzero(pmv[0]))
1282          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1283    
1284  // previous frame MV is always possible  // previous frame MV is always possible
1285          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1286            if (!MVzero(prevMB->mvs[0]))
1287            if (!MVequal(prevMB->mvs[0],pmv[0]))
1288                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1289    
1290  // left neighbour, if allowed  // left neighbour, if allowed
1291          if (x != 0)  
1292            if (!MVzero(pmv[1]))
1293            if (!MVequal(pmv[1],prevMB->mvs[0]))
1294            if (!MVequal(pmv[1],pmv[0]))
1295          {          {
1296                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1297                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1298                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1299                  }                  }
1300    
1301                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1302          }          }
1303    
1304  // top neighbour, if allowed  // top neighbour, if allowed
1305          if (y != 0)          if (!MVzero(pmv[2]))
1306            if (!MVequal(pmv[2],prevMB->mvs[0]))
1307            if (!MVequal(pmv[2],pmv[0]))
1308            if (!MVequal(pmv[2],pmv[1]))
1309          {          {
1310                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1311                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 950  Line 1314 
1314                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1315    
1316  // top right neighbour, if allowed  // top right neighbour, if allowed
1317                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1318                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1319                    if (!MVequal(pmv[3],pmv[0]))
1320                    if (!MVequal(pmv[3],pmv[1]))
1321                    if (!MVequal(pmv[3],pmv[2]))
1322                  {                  {
1323                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1324                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 960  Line 1328 
1328                  }                  }
1329          }          }
1330    
1331            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1332                    iMinSAD -= MV16_00_BIAS;
1333    
1334    
1335  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1336     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1337  */  */
1338    
1339          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1340          {          {
1341                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1342                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 983  Line 1355 
1355     Refine by using small diamond and goto step 10.     Refine by using small diamond and goto step 10.
1356  */  */
1357    
1358            if (MotionFlags & PMV_USESQUARES16)
1359                    MainSearchPtr = Square16_MainSearch;
1360            else
1361                    if (MotionFlags & PMV_ADVANCEDDIAMOND16)
1362                            MainSearchPtr = AdvDiamond16_MainSearch;
1363                    else
1364                            MainSearchPtr = Diamond16_MainSearch;
1365    
1366          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1367    
1368  /* 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 */
1369          iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1370                                            x, y,                                            x, y,
1371                                            currMV->x, currMV->y, iMinSAD, &newMV,                                            currMV->x, currMV->y, iMinSAD, &newMV,
1372                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1002  Line 1382 
1382  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1383    
1384                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1385                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1386                                                            x, y,                                                            x, y,
1387                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1388                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1015  Line 1395 
1395                  }                  }
1396    
1397                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1398                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1399                                                            x, y,                                                            x, y,
1400                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1401                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1150  Line 1530 
1530                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1531                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1532                                          const int x, const int y,                                          const int x, const int y,
1533                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1534                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1535                                            const uint32_t iQuant,
1536                                            const uint32_t iFcode,
1537                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1538                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1539                                            const MACROBLOCK * const prevMBs,
1540                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1541                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1542  {  {
1543          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
   
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1544          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1545          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1546          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1178  Line 1558 
1558          int32_t psad[4];          int32_t psad[4];
1559          VECTOR newMV;          VECTOR newMV;
1560          VECTOR backupMV;          VECTOR backupMV;
1561            VECTOR startMV;
1562    
1563          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1564            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1565    
1566          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1567          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1568          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1569    
1570          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1571    
1572            MainSearch8FuncPtr MainSearchPtr;
1573    
1574            /* Init variables */
1575            startMV.x = start_x;
1576            startMV.y = start_y;
1577    
1578  /* Get maximum range */  /* Get maximum range */
1579          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1580                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1581    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1582          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1583          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1584          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1220  Line 1606 
1606    
1607          iFound=0;          iFound=0;
1608    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536/4) || (bPredEq) )  
                 iDiamondSize=1; // 1 halfpel!  
         else  
                 iDiamondSize=2; // 2 halfpel = 1 full pixel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND8) )  
                 iDiamondSize*=2;  
   
1609  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1610     MinSAD=SAD     MinSAD=SAD
1611     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1250  Line 1616 
1616    
1617  // Prepare for main loop  // Prepare for main loop
1618    
1619          currMV->x=start_x;              /* start with mv16 */  //      if (MotionFlags & PMV_USESQUARES8)
1620          currMV->y=start_y;  //              MainSearchPtr = Square8_MainSearch;
1621    //      else
1622    
1623            if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1624                    MainSearchPtr = AdvDiamond8_MainSearch;
1625            else
1626                    MainSearchPtr = Diamond8_MainSearch;
1627    
1628    
1629            *currMV = startMV;
1630    
1631          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1632                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1633                          iEdgedWidth);                          iEdgedWidth);
1634          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode, iQuant);
1635    
1636          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1637                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1638          {          {
1639                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1640                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1266  Line 1642 
1642                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1643          }          }
1644    
1645    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1646       vector of the median.
1647       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1648    */
1649    
1650            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1651                    iFound=2;
1652    
1653    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1654       Otherwise select large Diamond Search.
1655    */
1656    
1657            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1658                    iDiamondSize=1; // 1 halfpel!
1659            else
1660                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1661    
1662            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1663                    iDiamondSize*=2;
1664    
1665    
1666  /*  /*
1667     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
1668     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1669     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1670     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1671  */  */
1672    
1673  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1674    
1675            if (!MVequal(pmv[0],startMV))
1676          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1677    
1678  // (0,0) is always possible  // (0,0) if needed
1679            if (!MVzero(pmv[0]))
1680            if (!MVzero(startMV))
1681          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1682    
1683  // previous frame MV is always possible  // previous frame MV if needed
1684          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1685            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1686            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1687            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1688    
1689  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1690          if (psad[1] != MV_MAX_ERROR)          {
1691                    if (MotionFlags & PMV_QUICKSTOP16)
1692                            goto PMVfast8_Terminate_without_Refine;
1693                    if (MotionFlags & PMV_EARLYSTOP16)
1694                            goto PMVfast8_Terminate_with_Refine;
1695            }
1696    
1697    
1698    // left neighbour, if allowed and needed
1699            if (!MVzero(pmv[1]))
1700            if (!MVequal(pmv[1],startMV))
1701            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1702            if (!MVequal(pmv[1],pmv[0]))
1703          {          {
1704                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1705                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1293  Line 1708 
1708                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1709          }          }
1710    
1711  // top neighbour, if allowed  // top neighbour, if allowed and needed
1712          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1713            if (!MVequal(pmv[2],startMV))
1714            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1715            if (!MVequal(pmv[2],pmv[0]))
1716            if (!MVequal(pmv[2],pmv[1]))
1717          {          {
1718                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1719                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1302  Line 1721 
1721                  }                  }
1722                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1723    
1724  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1725                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1726            if (!MVequal(pmv[3],startMV))
1727            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1728            if (!MVequal(pmv[3],pmv[0]))
1729            if (!MVequal(pmv[3],pmv[1]))
1730            if (!MVequal(pmv[3],pmv[2]))
1731                  {                  {
1732                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1733                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1313  Line 1737 
1737                  }                  }
1738          }          }
1739    
1740            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1741                    iMinSAD -= MV8_00_BIAS;
1742    
1743    
1744  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1745     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1746  */  */
1747    
1748          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1749          {          {
1750                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1751                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1338  Line 1766 
1766          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1767    
1768  /* 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 */
1769          iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1770                                           x, y,                                           x, y,
1771                                           currMV->x, currMV->y, iMinSAD, &newMV,                                           currMV->x, currMV->y, iMinSAD, &newMV,
1772                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1354  Line 1782 
1782  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1783    
1784                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1785                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1786                                                            x, y,                                                            x, y,
1787                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1788                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1367  Line 1795 
1795                  }                  }
1796    
1797                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1798                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1799                                                            x, y,                                                            x, y,
1800                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1801                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1407  Line 1835 
1835                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1836                                          const int x, const int y,                                          const int x, const int y,
1837                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1838                                            const uint32_t iQuant,
1839                                            const uint32_t iFcode,
1840                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1841                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1842                                            const MACROBLOCK * const prevMBs,
1843                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1844                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1845  {  {
1846      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1847      const uint32_t iHcount = pParam->mb_height;      const uint32_t iHcount = pParam->mb_height;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1848    
1849          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1850          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1435  Line 1864 
1864          int32_t psad[8];          int32_t psad[8];
1865    
1866          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1867          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1868            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1869          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1870    
1871          static int32_t thresh2;          static int32_t thresh2;
1872          int32_t bPredEq;          int32_t bPredEq;
1873          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
1874    
1875          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1876    
1877          if (oldMBs == NULL)          if (oldMBs == NULL)
1878          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1879                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1880          }          }
1881          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1882    
# Line 1454  Line 1884 
1884          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1885                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1886    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1887          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1888          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1889            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1495  Line 1923 
1923          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1924                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1925                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1926          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1927    
1928  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1929          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1930                  {                  {
1931                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1932                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1509  Line 1937 
1937  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1938    
1939  // previous frame MV  // previous frame MV
1940          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1941    
1942  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1943  // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want  // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want
# Line 1565  Line 1993 
1993  */  */
1994    
1995          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1996                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1997                  {                  {
1998                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1999                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1575  Line 2003 
2003    
2004  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
2005    
2006          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
2007          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
2008          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
2009    
2010          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
2011    
2012  // left neighbour  // left neighbour
2013          if (x != 0)          if (x != 0)
2014                  CHECK_MV16_CANDIDATE((oldMB-1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB-1)->mvs[0].x,(prevMB-1)->mvs[0].y);
2015    
2016  // top neighbour  // top neighbour
2017          if (y != 0)          if (y != 0)
2018                  CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB-iWcount)->mvs[0].x,(prevMB-iWcount)->mvs[0].y);
2019    
2020  // right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs  // right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs
2021    
2022          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
2023                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB+1)->mvs[0].x,(prevMB+1)->mvs[0].y);
2024    
2025  // bottom neighbour, dito  // bottom neighbour, dito
2026          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
2027                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB+iWcount)->mvs[0].x,(prevMB+iWcount)->mvs[0].y);
2028    
2029  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
2030          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1613  Line 2041 
2041    
2042  /* 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 */
2043    
2044          if (MotionFlags & PMV_USESQUARES16)          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
                 EPZSMainSearchPtr = Square16_MainSearch;  
         else  
                 EPZSMainSearchPtr = Diamond16_MainSearch;  
   
         iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,  
2045                          x, y,                          x, y,
2046                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2047                          2, iFcode, iQuant, 0);                          2, iFcode, iQuant, 0);
# Line 1636  Line 2059 
2059    
2060                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2061                  {                  {
2062                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2063                                  x, y,                                  x, y,
2064                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2065                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
# Line 1650  Line 2073 
2073    
2074                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2075                  {                  {
2076                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2077                                  x, y,                                  x, y,
2078                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2079                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2080    
2081                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
2082                          {                          {
# Line 1674  Line 2097 
2097    
2098  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
2099    
2100          *oldMB = *pMB;          *oldMB = *prevMB;
2101    
2102          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
2103          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1691  Line 2114 
2114                                          const int x, const int y,                                          const int x, const int y,
2115                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
2116                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
2117                                            const uint32_t iQuant,
2118                                            const uint32_t iFcode,
2119                                          const MBParam * const pParam,                                          const MBParam * const pParam,
2120                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
2121                                            const MACROBLOCK * const prevMBs,
2122                                          VECTOR * const currMV,                                          VECTOR * const currMV,
2123                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
2124  {  {
2125      const uint32_t iWcount = pParam->mb_width;  /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
2126    
2127            const uint32_t iWcount = pParam->mb_width;
2128          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
2129          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
2130          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1721  Line 2146 
2146    
2147          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
2148    
2149          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
2150            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
2151    
2152          int32_t bPredEq;          int32_t bPredEq;
2153          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
2154    
2155          MainSearch8FuncPtr EPZSMainSearchPtr;          MainSearch8FuncPtr MainSearchPtr;
2156    
2157  /* Get maximum range */  /* Get maximum range */
2158          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
# Line 1775  Line 2201 
2201          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
2202                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
2203                  iEdgedWidth);                  iEdgedWidth);
2204          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
2205    
2206    
2207  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1789  Line 2215 
2215    
2216  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2217    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
2218    
2219  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
2220          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
2221    
2222    // previous frame MV
2223            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
2224    
2225    // left neighbour, if allowed
2226            if (psad[1] != MV_MAX_ERROR)
2227            {
2228                    if (!(MotionFlags & PMV_HALFPEL8 ))
2229                    {       pmv[1].x = EVEN(pmv[1].x);
2230                            pmv[1].y = EVEN(pmv[1].y);
2231                    }
2232                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
2233            }
2234    
2235    // top neighbour, if allowed
2236            if (psad[2] != MV_MAX_ERROR)
2237            {
2238                    if (!(MotionFlags & PMV_HALFPEL8 ))
2239                    {       pmv[2].x = EVEN(pmv[2].x);
2240                            pmv[2].y = EVEN(pmv[2].y);
2241                    }
2242                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
2243    
2244    // top right neighbour, if allowed
2245                    if (psad[3] != MV_MAX_ERROR)
2246                    {
2247                            if (!(MotionFlags & PMV_HALFPEL8 ))
2248                            {       pmv[3].x = EVEN(pmv[3].x);
2249                                    pmv[3].y = EVEN(pmv[3].y);
2250                            }
2251                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
2252                    }
2253            }
2254    
2255    /*  // this bias is zero anyway, at the moment!
2256    
2257            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
2258                    iMinSAD -= MV8_00_BIAS;
2259    
2260    */
2261    
2262  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
2263     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]
2264  */  */
# Line 1808  Line 2271 
2271                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
2272                  }                  }
2273    
2274  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
2275    
2276          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
2277    
2278          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
2279                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2280    
2281  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of EPZS_MainSearch */
2282    
2283    /* // there is no EPZS^2 for inter4v at the moment
2284    
2285            if (MotionFlags & PMV_USESQUARES8)
2286                    MainSearchPtr = Square8_MainSearch;
2287            else
2288    */
2289    
2290  //      if (MotionFlags & PMV_USESQUARES8)  //      if (MotionFlags & PMV_USESQUARES8)
2291  //              EPZSMainSearchPtr = Square8_MainSearch;  //              MainSearchPtr = Square8_MainSearch;
2292  //      else  //      else
                 EPZSMainSearchPtr = Diamond8_MainSearch;  
2293    
2294          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2295                    MainSearchPtr = AdvDiamond8_MainSearch;
2296            else
2297                    MainSearchPtr = Diamond8_MainSearch;
2298    
2299            iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2300                  x, y,                  x, y,
2301                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2302                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2303                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2304    
2305    
2306          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1841  Line 2315 
2315    
2316                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2317                  {                  {
2318                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2319                                  x, y,                                  x, y,
2320                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2321                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 1855  Line 2329 
2329    
2330                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2331                  {                  {
2332                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2333                                  x, y,                                  x, y,
2334                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2335                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 1893  Line 2367 
2367  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2368  ***************************************************************/  ***************************************************************/
2369    
2370  /*  
2371  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2372                          MBParam * const pParam,                          MBParam * const pParam,
2373                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 1915  Line 2389 
2389      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2390          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2391    
2392          int32_t i,j;          uint32_t i,j;
2393    
2394          int32_t f_sad16;          int32_t f_sad16;
2395          int32_t b_sad16;          int32_t b_sad16;
# Line 1939  Line 2413 
2413                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2414                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2415                          {                          {
2416                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2417                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2418                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2419                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 1954  Line 2428 
2428                                                  i, j,                                                  i, j,
2429                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2430                                                  pParam,                                                  pParam,
2431                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2432                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2433    
2434                          // backward search                          // backward search
# Line 1963  Line 2437 
2437                                                  i, j,                                                  i, j,
2438                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2439                                                  pParam,                                                  pParam,
2440                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2441                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2442    
2443                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 1983  Line 2457 
2457                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2458                          {                          {
2459                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2460                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2461                          }                          }
2462                          else                          else
2463                          {                          {
2464                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2465                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2466                          }                          }
2467    
2468                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2469                          {                          {
2470                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2471                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2472                          }                          }
2473    
2474                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2475                          {                          {
2476                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2477                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2478                          }                          }
2479    
2480                  }                  }
2481          }          }
2482  }  }
   
 */  

Legend:
Removed from v.132  
changed lines
  Added in v.181

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