[svn] / trunk / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/motion_est.c

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

revision 132, Tue Apr 23 00:04:51 2002 UTC revision 175, Sun May 12 17:21:30 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 780  Line 859 
859                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
860                                          const int x, const int y,                                          const int x, const int y,
861                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
862                                            const uint32_t iQuant,
863                                            const uint32_t iFcode,
864                                          const MBParam * const pParam,                                          const MBParam * const pParam,
865                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
866                                            const MACROBLOCK * const prevMBs,
867                                          VECTOR * const currMV,                                          VECTOR * const currMV,
868                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
869  {  {
870      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;  
871          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
872          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
873          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 809  Line 889 
889          VECTOR pmv[4];          VECTOR pmv[4];
890          int32_t psad[4];          int32_t psad[4];
891    
892          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
893            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
894    
895          static int32_t threshA,threshB;          static int32_t threshA,threshB;
896          int32_t bPredEq;          int32_t bPredEq;
# Line 848  Line 929 
929    
930          iFound=0;          iFound=0;
931    
 /* 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;  
   
932  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
933     MinSAD=SAD     MinSAD=SAD
934     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 875  Line 936 
936     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
937  */  */
938    
   
 // Prepare for main loop  
   
939          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
940          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
941          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 905  Line 963 
963          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
964                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
965                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
966          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);
967    
968          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) ) )
969            {
970                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
971          {          {
972                            if (!MVzero(*currMV))
973                            {
974                                    iMinSAD += MV16_00_BIAS;
975                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
976                                    iMinSAD -= MV16_00_BIAS;
977                            }
978                    }
979    
980                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
981                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 916  Line 983 
983                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
984          }          }
985    
986    
987    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
988       vector of the median.
989       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
990    */
991    
992            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
993                    iFound=2;
994    
995    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
996       Otherwise select large Diamond Search.
997    */
998    
999            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1000                    iDiamondSize=1; // halfpel!
1001            else
1002                    iDiamondSize=2; // halfpel!
1003    
1004            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1005                    iDiamondSize*=2;
1006    
1007  /*  /*
1008     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.
1009     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1010     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1011     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1012  */  */
1013    
1014  // (0,0) is always possible  // (0,0) is always possible
1015    
1016            if (!MVzero(pmv[0]))
1017          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1018    
1019  // previous frame MV is always possible  // previous frame MV is always possible
1020          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1021            if (!MVzero(prevMB->mvs[0]))
1022            if (!MVequal(prevMB->mvs[0],pmv[0]))
1023                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1024    
1025  // left neighbour, if allowed  // left neighbour, if allowed
1026          if (x != 0)  
1027            if (!MVzero(pmv[1]))
1028            if (!MVequal(pmv[1],prevMB->mvs[0]))
1029            if (!MVequal(pmv[1],pmv[0]))
1030          {          {
1031                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1032                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1033                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1034                  }                  }
1035    
1036                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1037          }          }
1038    
1039  // top neighbour, if allowed  // top neighbour, if allowed
1040          if (y != 0)          if (!MVzero(pmv[2]))
1041            if (!MVequal(pmv[2],prevMB->mvs[0]))
1042            if (!MVequal(pmv[2],pmv[0]))
1043            if (!MVequal(pmv[2],pmv[1]))
1044          {          {
1045                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1046                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 950  Line 1049 
1049                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1050    
1051  // top right neighbour, if allowed  // top right neighbour, if allowed
1052                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1053                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1054                    if (!MVequal(pmv[3],pmv[0]))
1055                    if (!MVequal(pmv[3],pmv[1]))
1056                    if (!MVequal(pmv[3],pmv[2]))
1057                  {                  {
1058                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1059                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 960  Line 1063 
1063                  }                  }
1064          }          }
1065    
1066            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1067                    iMinSAD -= MV16_00_BIAS;
1068    
1069    
1070  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1071     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.
1072  */  */
1073    
1074          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) ) )
1075          {          {
1076                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1077                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1150  Line 1257 
1257                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1258                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1259                                          const int x, const int y,                                          const int x, const int y,
1260                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1261                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1262                                            const uint32_t iQuant,
1263                                            const uint32_t iFcode,
1264                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1265                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1266                                            const MACROBLOCK * const prevMBs,
1267                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1268                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1269  {  {
1270          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;  
1271          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1272          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1273          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1178  Line 1285 
1285          int32_t psad[4];          int32_t psad[4];
1286          VECTOR newMV;          VECTOR newMV;
1287          VECTOR backupMV;          VECTOR backupMV;
1288            VECTOR startMV;
1289    
1290          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1291            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1292    
1293          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1294          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1295          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1296    
1297          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1298    
1299            /* Init variables */
1300            startMV.x = start_x;
1301            startMV.y = start_y;
1302    
1303  /* Get maximum range */  /* Get maximum range */
1304          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1305                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1306    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1307          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1308          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1309          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1220  Line 1331 
1331    
1332          iFound=0;          iFound=0;
1333    
 /* 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;  
   
1334  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1335     MinSAD=SAD     MinSAD=SAD
1336     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1250  Line 1341 
1341    
1342  // Prepare for main loop  // Prepare for main loop
1343    
1344          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1345    
1346          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1347                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1348                          iEdgedWidth);                          iEdgedWidth);
1349          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);
1350    
1351          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1352                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1353          {          {
1354                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1355                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1266  Line 1357 
1357                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1358          }          }
1359    
1360    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1361       vector of the median.
1362       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1363    */
1364    
1365            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1366                    iFound=2;
1367    
1368    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1369       Otherwise select large Diamond Search.
1370    */
1371    
1372            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1373                    iDiamondSize=1; // 1 halfpel!
1374            else
1375                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1376    
1377            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1378                    iDiamondSize*=2;
1379    
1380    
1381  /*  /*
1382     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.
1383     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1384     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1385     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1386  */  */
1387    
1388  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1389    
1390            if (!MVequal(pmv[0],startMV))
1391          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1392    
1393  // (0,0) is always possible  // (0,0) if needed
1394            if (!MVzero(pmv[0]))
1395            if (!MVzero(startMV))
1396          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1397    
1398  // previous frame MV is always possible  // previous frame MV if needed
1399          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1400            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1401            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1402            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1403    
1404  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1405          if (psad[1] != MV_MAX_ERROR)          {
1406                    if (MotionFlags & PMV_QUICKSTOP16)
1407                            goto PMVfast8_Terminate_without_Refine;
1408                    if (MotionFlags & PMV_EARLYSTOP16)
1409                            goto PMVfast8_Terminate_with_Refine;
1410            }
1411    
1412    
1413    // left neighbour, if allowed and needed
1414            if (!MVzero(pmv[1]))
1415            if (!MVequal(pmv[1],startMV))
1416            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1417            if (!MVequal(pmv[1],pmv[0]))
1418          {          {
1419                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1420                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1293  Line 1423 
1423                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1424          }          }
1425    
1426  // top neighbour, if allowed  // top neighbour, if allowed and needed
1427          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1428            if (!MVequal(pmv[2],startMV))
1429            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1430            if (!MVequal(pmv[2],pmv[0]))
1431            if (!MVequal(pmv[2],pmv[1]))
1432          {          {
1433                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1434                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1302  Line 1436 
1436                  }                  }
1437                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1438    
1439  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1440                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1441            if (!MVequal(pmv[3],startMV))
1442            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1443            if (!MVequal(pmv[3],pmv[0]))
1444            if (!MVequal(pmv[3],pmv[1]))
1445            if (!MVequal(pmv[3],pmv[2]))
1446                  {                  {
1447                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1448                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1313  Line 1452 
1452                  }                  }
1453          }          }
1454    
1455            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1456                    iMinSAD -= MV8_00_BIAS;
1457    
1458    
1459  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1460     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.
1461  */  */
1462    
1463          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]) ) )
1464          {          {
1465                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1466                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1407  Line 1550 
1550                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1551                                          const int x, const int y,                                          const int x, const int y,
1552                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1553                                            const uint32_t iQuant,
1554                                            const uint32_t iFcode,
1555                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1556                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1557                                            const MACROBLOCK * const prevMBs,
1558                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1559                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1560  {  {
1561      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1562      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;  
1563    
1564          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1565          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1435  Line 1579 
1579          int32_t psad[8];          int32_t psad[8];
1580    
1581          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1582          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1583            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1584          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1585    
1586          static int32_t thresh2;          static int32_t thresh2;
# Line 1445  Line 1590 
1590          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1591    
1592          if (oldMBs == NULL)          if (oldMBs == NULL)
1593          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1594                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1595          }          }
1596          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1597    
# Line 1454  Line 1599 
1599          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1600                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1601    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1602          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1603          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1604            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1495  Line 1638 
1638          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1639                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1640                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1641          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);
1642    
1643  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1644          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) ) )
1645                  {                  {
1646                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1647                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1509  Line 1652 
1652  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1653    
1654  // previous frame MV  // previous frame MV
1655          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1656    
1657  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1658  // 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 1708 
1708  */  */
1709    
1710          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1711                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1712                  {                  {
1713                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1714                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1575  Line 1718 
1718    
1719  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1720    
1721          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1722          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1723          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1724    
1725          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1726    
1727  // left neighbour  // left neighbour
1728          if (x != 0)          if (x != 0)
1729                  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);
1730    
1731  // top neighbour  // top neighbour
1732          if (y != 0)          if (y != 0)
1733                  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);
1734    
1735  // 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
1736    
1737          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1738                  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);
1739    
1740  // bottom neighbour, dito  // bottom neighbour, dito
1741          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1742                  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);
1743    
1744  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1745          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1653  Line 1796 
1796                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1797                                  x, y,                                  x, y,
1798                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1799                          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);
1800    
1801                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1802                          {                          {
# Line 1674  Line 1817 
1817    
1818  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1819    
1820          *oldMB = *pMB;          *oldMB = *prevMB;
1821    
1822          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1823          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1691  Line 1834 
1834                                          const int x, const int y,                                          const int x, const int y,
1835                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1836                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1837                                            const uint32_t iQuant,
1838                                            const uint32_t iFcode,
1839                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1840                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1841                                            const MACROBLOCK * const prevMBs,
1842                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1843                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1844  {  {
1845      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;  
1846    
1847            const uint32_t iWcount = pParam->mb_width;
1848          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1849          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1850          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1721  Line 1866 
1866    
1867          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1868    
1869          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1870            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1871    
1872          int32_t bPredEq;          int32_t bPredEq;
1873          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1775  Line 1921 
1921          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1922                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1923                  iEdgedWidth);                  iEdgedWidth);
1924          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);
1925    
1926    
1927  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1789  Line 1935 
1935    
1936  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1937    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1938    
1939  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1940          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1941    
1942    // previous frame MV
1943            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1944    
1945    // left neighbour, if allowed
1946            if (psad[1] != MV_MAX_ERROR)
1947            {
1948                    if (!(MotionFlags & PMV_HALFPEL8 ))
1949                    {       pmv[1].x = EVEN(pmv[1].x);
1950                            pmv[1].y = EVEN(pmv[1].y);
1951                    }
1952                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1953            }
1954    
1955    // top neighbour, if allowed
1956            if (psad[2] != MV_MAX_ERROR)
1957            {
1958                    if (!(MotionFlags & PMV_HALFPEL8 ))
1959                    {       pmv[2].x = EVEN(pmv[2].x);
1960                            pmv[2].y = EVEN(pmv[2].y);
1961                    }
1962                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1963    
1964    // top right neighbour, if allowed
1965                    if (psad[3] != MV_MAX_ERROR)
1966                    {
1967                            if (!(MotionFlags & PMV_HALFPEL8 ))
1968                            {       pmv[3].x = EVEN(pmv[3].x);
1969                                    pmv[3].y = EVEN(pmv[3].y);
1970                            }
1971                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1972                    }
1973            }
1974    
1975    /*  // this bias is zero anyway, at the moment!
1976    
1977            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1978                    iMinSAD -= MV8_00_BIAS;
1979    
1980    */
1981    
1982  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1983     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]
1984  */  */
# Line 1808  Line 1991 
1991                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1992                  }                  }
1993    
1994  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1995    
1996          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1997    
1998          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1999                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2000    
2001  /* 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 */
2002    
2003    /* // there is no EPZS^2 for inter4v at the moment
2004    
2005            if (MotionFlags & PMV_USESQUARES8)
2006                    EPZSMainSearchPtr = Square8_MainSearch;
2007            else
2008    */
2009    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
2010                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
2011    
2012          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2013                  x, y,                  x, y,
2014                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2015                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2016                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2017    
2018    
2019          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1893  Line 2080 
2080  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2081  ***************************************************************/  ***************************************************************/
2082    
2083  /*  
2084  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2085                          MBParam * const pParam,                          MBParam * const pParam,
2086                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 1915  Line 2102 
2102      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2103          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2104    
2105          int32_t i,j;          uint32_t i,j;
2106    
2107          int32_t f_sad16;          int32_t f_sad16;
2108          int32_t b_sad16;          int32_t b_sad16;
# Line 1939  Line 2126 
2126                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2127                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2128                          {                          {
2129                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2130                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2131                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2132                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 1954  Line 2141 
2141                                                  i, j,                                                  i, j,
2142                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2143                                                  pParam,                                                  pParam,
2144                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2145                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2146    
2147                          // backward search                          // backward search
# Line 1963  Line 2150 
2150                                                  i, j,                                                  i, j,
2151                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2152                                                  pParam,                                                  pParam,
2153                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2154                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2155    
2156                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 1983  Line 2170 
2170                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2171                          {                          {
2172                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2173                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2174                          }                          }
2175                          else                          else
2176                          {                          {
2177                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2178                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2179                          }                          }
2180    
2181                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2182                          {                          {
2183                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2184                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2185                          }                          }
2186    
2187                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2188                          {                          {
2189                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2190                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2191                          }                          }
2192    
2193                  }                  }
2194          }          }
2195  }  }
   
 */  

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

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