[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 140, Thu Apr 25 21:32:05 2002 UTC revision 174, Sat May 11 23:54: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   *      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()
# Line 53  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 8
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)  #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 68  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 184  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 219  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 257  Line 276 
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 * pMBs = current->mbs;          MACROBLOCK * const pMBs = current->mbs;
280          IMAGE * pCurrent = &current->image;          MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
   
         MACROBLOCK * prevMBs = reference->mbs;  // previous frame  
         IMAGE * pRef = &reference->image;  
281    
282            const IMAGE * const pCurrent = &current->image;
283            const IMAGE * const pRef = &reference->image;
284    
285          uint32_t i, j, iIntra = 0;          const VECTOR zeroMV = {0,0};
286    
287          VECTOR mv16;          int32_t x, y;
288          VECTOR pmv16;          int32_t iIntra = 0;
289            VECTOR pmv;
         int32_t sad8 = 0;  
         int32_t sad16;  
         int32_t deviation;  
290    
291          if (sadInit)          if (sadInit)
292                  (*sadInit)();                  (*sadInit)();
293    
294            for (y = 0; y < iHcount; y++)
295          /* eventhough we have a seperate prevMBs,                  for (x = 0; x < iWcount; x++)
            pmvfast/epsz does something "funny" with the previous frames data */  
   
 /*      for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
296                  {                  {
297                          pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
298                          pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];  
299                          pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];                          pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                          pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];                                           x, y, current->motion_flags, current->quant, current->fcode,
301                  }                                           pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
 */  
         /*dprintf("*** BEFORE ***");  
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
                 {  
                         dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,  
                                 pMBs[j + i * iWcount].mode,  
                                 pMBs[j + i * iWcount].dquant,  
                                 pMBs[j + i * iWcount].mvs[0],  
                                 pMBs[j + i * iWcount].mvs[1],  
                                 pMBs[j + i * iWcount].mvs[2],  
                                 pMBs[j + i * iWcount].mvs[3],  
                                 prevMBs[j + i * iWcount].sad8[0],  
                                 prevMBs[j + i * iWcount].sad8[1],  
                                 prevMBs[j + i * iWcount].sad8[2],  
                                 prevMBs[j + i * iWcount].sad8[3],  
                                 prevMBs[j + i * iWcount].sad16);  
302                  }                  }
         */  
303    
304          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
305          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
306                  {                  {
307                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
                         MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];  
   
                         sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                          j, i, current->motion_flags, current->quant, current->fcode,  
                                          pParam, pMBs, prevMBs, &mv16, &pmv16);  
                         pMB->sad16=sad16;  
   
308    
309                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
310                             if (dev_intra < sad_inter - 2 * nb) use_intra                          {
311                          */                                  int32_t deviation;
312                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
313                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                                                           pParam->edged_width);
314    
315                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
316                          {                          {
317                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
318                                  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]
319                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
320                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
321                                  pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;                                                               = pMB->sad8[2] = pMB->sad8[3] = 0;
322    
323                                  iIntra++;                                  iIntra++;
324                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 341  Line 326 
326    
327                                  continue;                                  continue;
328                          }                          }
329                            }
330    
331                          if (current->global_flags & XVID_INTER4V)                          if ( (current->global_flags & XVID_INTER4V)
332                                    && (!(current->global_flags & XVID_LUMIMASKING)
333                                            || pMB->dquant == NO_CHANGE) )
334                          {                          {
335                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  int32_t neigh=0;
336                                                         2 * j, 2 * i, mv16.x, mv16.y,  
337                                    if (x>0)
338                                    {       neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x));
339                                            neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y));
340                                    }
341                                    if (y>0)
342                                    {       neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x));
343                                            neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y));
344                                    }
345                                    if (x<(iWcount-1))
346                                    {       neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x));
347                                            neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y));
348                                    }
349                                    if (y<(iHcount-1))
350                                    {       neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x));
351                                            neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y));
352                                    }
353    
354                                    if (neigh > NEIGH_MOVE_THRESH)
355                                    {
356                                            int32_t sad8 = 129; //IMV16X16 * current->quant;
357    
358                                    if (sad8 < pMB->sad16)
359                                    sad8 += pMB->sad8[0]
360                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
361                                                           2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
362                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
363                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
364    
365                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
366                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,                                  sad8 += pMB->sad8[1]
367                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
368                                   2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
369                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
370                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
371    
372                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
373                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,                                  sad8 += pMB->sad8[2]
374                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
375                                                    2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
376                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
377                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
378    
379                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
380                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,                                  sad8 += pMB->sad8[3]
381                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
382                                                    2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
383                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
384                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
385    
                                 sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];  
                         }  
   
   
386                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
387                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
388                          */                          */
389    
390                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)                                  if (sad8 < pMB->sad16)
                         {  
                                 if (((current->global_flags & XVID_INTER4V)==0) ||  
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))  
391                                  {                                  {
   
                                         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  
392                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
393                   pMB->sad8[0] *= 4;
394                                            pMB->sad8[1] *= 4;
395                                            pMB->sad8[2] *= 4;
396                                            pMB->sad8[3] *= 4;
397                                            continue;
398                          }                          }
                         else  
                         {  
                                 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;  
399                          }                          }
400                  }                  }
401    
402  /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);                          pMB->mode = MODE_INTER;
403          for (i = 0; i < iHcount; i++)                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
404                  for (j = 0; j < iWcount; j++)           pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
405                  {  
406                          dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,                          pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
407                                  pMBs[j + i * iWcount].mode,                          // get_pmv has to be called again.
408                                  pMBs[j + i * iWcount].dquant,                          // intra-decision and inter4v change predictors
409                                  pMBs[j + i * iWcount].mvs[0],  
410                                  pMBs[j + i * iWcount].mvs[1],                                  pMB->pmvs[0].x = pMB->mv16.x - pmv.x;
411                                  pMBs[j + i * iWcount].mvs[2],                                  pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
                                 pMBs[j + i * iWcount].mvs[3],  
                                 pMBs[j + i * iWcount].sad8[0],  
                                 pMBs[j + i * iWcount].sad8[1],  
                                 pMBs[j + i * iWcount].sad8[2],  
                                 pMBs[j + i * iWcount].sad8[3],  
                                 pMBs[j + i * iWcount].sad16);  
412                  }                  }
         */  
413    
414          return 0;          return 0;
415  }  }
416    
 #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )  
   
 #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )  
   
   
417  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
418    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
419      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
420    { \    { \
421      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); \
422      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);\
423      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
424      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
425  }  }
426    
427  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
428      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); \
429      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);\
430      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
431      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
432  }  }
# Line 448  Line 436 
436      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
437    { \    { \
438      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); \
439      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);\
440      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
441      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
442  }  }
# Line 458  Line 446 
446      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
447    { \    { \
448      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); \
449      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);\
450      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
451      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
452  }  }
# Line 468  Line 456 
456      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
457    { \    { \
458      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); \
459      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);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
462  }  }
# Line 476  Line 464 
464    
465  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
466    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); \
467    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);\
468    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
469    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
470  }  }
# Line 484  Line 472 
472  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
473    { \    { \
474      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); \
475      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);\
476      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
477      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
478  }  }
# Line 494  Line 482 
482      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
483    { \    { \
484      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); \
485      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);\
486      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
487      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
488  }  }
# Line 504  Line 492 
492      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
493    { \    { \
494      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); \
495      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);\
496      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
497      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
498  }  }
# Line 514  Line 502 
502      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
503    { \    { \
504      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); \
505      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);\
506      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
507      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
508  }  }
# Line 889  Line 877 
877          VECTOR pmv[4];          VECTOR pmv[4];
878          int32_t psad[4];          int32_t psad[4];
879    
880          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
881          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
882    
883          static int32_t threshA,threshB;          static int32_t threshA,threshB;
# Line 929  Line 917 
917    
918          iFound=0;          iFound=0;
919    
 /* 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],prevMB->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;  
   
920  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
921     MinSAD=SAD     MinSAD=SAD
922     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 956  Line 924 
924     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
925  */  */
926    
   
 // Prepare for main loop  
   
927          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
928          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
929          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 986  Line 951 
951          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
952                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
953                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
954          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);
955    
956          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
957          {          {
958                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
959                    {
960                            if (!MVzero(*currMV))
961                            {
962                                    iMinSAD += MV16_00_BIAS;
963                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
964                                    iMinSAD -= MV16_00_BIAS;
965                            }
966                    }
967    
968                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
969                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 997  Line 971 
971                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
972          }          }
973    
974    
975    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
976       vector of the median.
977       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
978    */
979    
980            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
981                    iFound=2;
982    
983    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
984       Otherwise select large Diamond Search.
985    */
986    
987            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
988                    iDiamondSize=1; // halfpel!
989            else
990                    iDiamondSize=2; // halfpel!
991    
992            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
993                    iDiamondSize*=2;
994    
995  /*  /*
996     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.
997     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
# Line 1006  Line 1001 
1001    
1002  // (0,0) is always possible  // (0,0) is always possible
1003    
1004            if (!MVzero(pmv[0]))
1005          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1006    
1007  // previous frame MV is always possible  // previous frame MV is always possible
1008    
1009            if (!MVzero(prevMB->mvs[0]))
1010            if (!MVequal(prevMB->mvs[0],pmv[0]))
1011          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1012    
1013  // left neighbour, if allowed  // left neighbour, if allowed
1014          if (x != 0)  
1015            if (!MVzero(pmv[1]))
1016            if (!MVequal(pmv[1],prevMB->mvs[0]))
1017            if (!MVequal(pmv[1],pmv[0]))
1018          {          {
1019                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1020                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1021                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1022                  }                  }
1023    
1024                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1025          }          }
1026    
1027  // top neighbour, if allowed  // top neighbour, if allowed
1028          if (y != 0)          if (!MVzero(pmv[2]))
1029            if (!MVequal(pmv[2],prevMB->mvs[0]))
1030            if (!MVequal(pmv[2],pmv[0]))
1031            if (!MVequal(pmv[2],pmv[1]))
1032          {          {
1033                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1034                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1031  Line 1037 
1037                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1038    
1039  // top right neighbour, if allowed  // top right neighbour, if allowed
1040                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1041                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1042                    if (!MVequal(pmv[3],pmv[0]))
1043                    if (!MVequal(pmv[3],pmv[1]))
1044                    if (!MVequal(pmv[3],pmv[2]))
1045                  {                  {
1046                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1047                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1041  Line 1051 
1051                  }                  }
1052          }          }
1053    
1054          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) && (iSAD <= iQuant * 96) )          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1055                  iMinSAD -= MV16_00_BIAS;                  iMinSAD -= MV16_00_BIAS;
1056    
1057    
# Line 1263  Line 1273 
1273          int32_t psad[4];          int32_t psad[4];
1274          VECTOR newMV;          VECTOR newMV;
1275          VECTOR backupMV;          VECTOR backupMV;
1276            VECTOR startMV;
1277    
1278          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1279          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1280    
1281          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1282          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1283          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1284    
1285          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1286    
1287            /* Init variables */
1288            startMV.x = start_x;
1289            startMV.y = start_y;
1290    
1291  /* Get maximum range */  /* Get maximum range */
1292          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
# Line 1304  Line 1319 
1319    
1320          iFound=0;          iFound=0;
1321    
 /* 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],prevMB->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;  
   
1322  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1323     MinSAD=SAD     MinSAD=SAD
1324     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1334  Line 1329 
1329    
1330  // Prepare for main loop  // Prepare for main loop
1331    
1332          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1333    
1334          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1335                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1336                          iEdgedWidth);                          iEdgedWidth);
1337          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);
1338    
1339          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1340                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1341          {          {
1342                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1343                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1350  Line 1345 
1345                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1346          }          }
1347    
1348    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1349       vector of the median.
1350       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1351    */
1352    
1353            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1354                    iFound=2;
1355    
1356    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1357       Otherwise select large Diamond Search.
1358    */
1359    
1360            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1361                    iDiamondSize=1; // 1 halfpel!
1362            else
1363                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1364    
1365            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1366                    iDiamondSize*=2;
1367    
1368    
1369  /*  /*
1370     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.
# Line 1358  Line 1373 
1373     If MV is (0,0) subtract offset.     If MV is (0,0) subtract offset.
1374  */  */
1375    
1376  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1377    
1378            if (!MVequal(pmv[0],startMV))
1379          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1380    
1381  // (0,0) is always possible  // (0,0) if needed
1382            if (!MVzero(pmv[0]))
1383            if (!MVzero(startMV))
1384          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1385    
1386  // previous frame MV is always possible  // previous frame MV if needed
1387            if (!MVzero(prevMB->mvs[iSubBlock]))
1388            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1389            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1390          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1391    
1392  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1393          if (psad[1] != MV_MAX_ERROR)          {
1394                    if (MotionFlags & PMV_QUICKSTOP16)
1395                            goto PMVfast8_Terminate_without_Refine;
1396                    if (MotionFlags & PMV_EARLYSTOP16)
1397                            goto PMVfast8_Terminate_with_Refine;
1398            }
1399    
1400    
1401    // left neighbour, if allowed and needed
1402            if (!MVzero(pmv[1]))
1403            if (!MVequal(pmv[1],startMV))
1404            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1405            if (!MVequal(pmv[1],pmv[0]))
1406          {          {
1407                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1408                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1377  Line 1411 
1411                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1412          }          }
1413    
1414  // top neighbour, if allowed  // top neighbour, if allowed and needed
1415          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1416            if (!MVequal(pmv[2],startMV))
1417            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1418            if (!MVequal(pmv[2],pmv[0]))
1419            if (!MVequal(pmv[2],pmv[1]))
1420          {          {
1421                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1422                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1386  Line 1424 
1424                  }                  }
1425                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1426    
1427  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1428                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1429            if (!MVequal(pmv[3],startMV))
1430            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1431            if (!MVequal(pmv[3],pmv[0]))
1432            if (!MVequal(pmv[3],pmv[1]))
1433            if (!MVequal(pmv[3],pmv[2]))
1434                  {                  {
1435                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1436                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1397  Line 1440 
1440                  }                  }
1441          }          }
1442    
1443          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) && (iSAD <= iQuant * 96) )          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1444                  iMinSAD -= MV8_00_BIAS;                  iMinSAD -= MV8_00_BIAS;
1445    
1446    
# Line 1524  Line 1567 
1567          int32_t psad[8];          int32_t psad[8];
1568    
1569          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1570          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1571          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1572          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1573    
# Line 1535  Line 1578 
1578          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1579    
1580          if (oldMBs == NULL)          if (oldMBs == NULL)
1581          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1582  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1583          }          }
1584          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
# Line 1583  Line 1626 
1626          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1627                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1628                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1629          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);
1630    
1631  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1632          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1633                  {                  {
1634                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1635                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1597  Line 1640 
1640  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1641    
1642  // previous frame MV  // previous frame MV
1643          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1644    
1645  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1646  // 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 1653  Line 1696 
1696  */  */
1697    
1698          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1699                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1700                  {                  {
1701                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1702                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1663  Line 1706 
1706    
1707  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1708    
1709          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1710          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1711          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1712    
1713          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1714    
1715  // left neighbour  // left neighbour
1716          if (x != 0)          if (x != 0)
1717                  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);
1718    
1719  // top neighbour  // top neighbour
1720          if (y != 0)          if (y != 0)
1721                  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);
1722    
1723  // 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
1724    
1725          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1726                  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);
1727    
1728  // bottom neighbour, dito  // bottom neighbour, dito
1729          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1730                  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);
1731    
1732  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1733          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1741  Line 1784 
1784                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1785                                  x, y,                                  x, y,
1786                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1787                          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);
1788    
1789                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1790                          {                          {
# Line 1762  Line 1805 
1805    
1806  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1807    
1808          *oldMB = *pMB;          *oldMB = *prevMB;
1809    
1810          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1811          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1787  Line 1830 
1830                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1831                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1832  {  {
1833    /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
1834    
1835      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1836          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1837          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1809  Line 1854 
1854    
1855          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1856    
1857          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1858          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1859    
1860          int32_t bPredEq;          int32_t bPredEq;
# Line 1864  Line 1909 
1909          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1910                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1911                  iEdgedWidth);                  iEdgedWidth);
1912          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);
1913    
1914    
1915  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1878  Line 1923 
1923    
1924  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1925    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1926    
1927  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1928          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1929    
1930    // previous frame MV
1931            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1932    
1933    // left neighbour, if allowed
1934            if (psad[1] != MV_MAX_ERROR)
1935            {
1936                    if (!(MotionFlags & PMV_HALFPEL8 ))
1937                    {       pmv[1].x = EVEN(pmv[1].x);
1938                            pmv[1].y = EVEN(pmv[1].y);
1939                    }
1940                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1941            }
1942    
1943    // top neighbour, if allowed
1944            if (psad[2] != MV_MAX_ERROR)
1945            {
1946                    if (!(MotionFlags & PMV_HALFPEL8 ))
1947                    {       pmv[2].x = EVEN(pmv[2].x);
1948                            pmv[2].y = EVEN(pmv[2].y);
1949                    }
1950                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1951    
1952    // top right neighbour, if allowed
1953                    if (psad[3] != MV_MAX_ERROR)
1954                    {
1955                            if (!(MotionFlags & PMV_HALFPEL8 ))
1956                            {       pmv[3].x = EVEN(pmv[3].x);
1957                                    pmv[3].y = EVEN(pmv[3].y);
1958                            }
1959                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1960                    }
1961            }
1962    
1963    /*  // this bias is zero anyway, at the moment!
1964    
1965            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1966                    iMinSAD -= MV8_00_BIAS;
1967    
1968    */
1969    
1970  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1971     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]
1972  */  */
# Line 1897  Line 1979 
1979                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1980                  }                  }
1981    
1982  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1983    
1984          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1985    
1986          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1987                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1988    
1989  /* 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 */
1990    
1991    /* // there is no EPZS^2 for inter4v at the moment
1992    
1993            if (MotionFlags & PMV_USESQUARES8)
1994                    EPZSMainSearchPtr = Square8_MainSearch;
1995            else
1996    */
1997    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1998                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1999    
2000          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2001                  x, y,                  x, y,
2002                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2003                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2004                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2005    
2006    
2007          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1982  Line 2068 
2068  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2069  ***************************************************************/  ***************************************************************/
2070    
2071  /*  
2072  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2073                          MBParam * const pParam,                          MBParam * const pParam,
2074                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2004  Line 2090 
2090      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2091          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2092    
2093          int32_t i,j;          uint32_t i,j;
2094    
2095          int32_t f_sad16;          int32_t f_sad16;
2096          int32_t b_sad16;          int32_t b_sad16;
# Line 2028  Line 2114 
2114                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2115                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2116                          {                          {
2117                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2118                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2119                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2120                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2043  Line 2129 
2129                                                  i, j,                                                  i, j,
2130                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2131                                                  pParam,                                                  pParam,
2132                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2133                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2134    
2135                          // backward search                          // backward search
# Line 2052  Line 2138 
2138                                                  i, j,                                                  i, j,
2139                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2140                                                  pParam,                                                  pParam,
2141                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2142                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2143    
2144                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2072  Line 2158 
2158                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2159                          {                          {
2160                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2161                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2162                          }                          }
2163                          else                          else
2164                          {                          {
2165                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2166                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2167                          }                          }
2168    
2169                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2170                          {                          {
2171                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2172                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2173                          }                          }
2174    
2175                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2176                          {                          {
2177                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2178                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2179                          }                          }
2180    
2181                  }                  }
2182          }          }
2183  }  }
   
 */  

Legend:
Removed from v.140  
changed lines
  Added in v.174

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