[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 136, Thu Apr 25 06:55:00 2002 UTC revision 170, Thu May 9 21:47:51 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 56  Line 57 
57  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
58  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
59  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
60    #define MV8_00_BIAS     (0)
61    
62  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
63  #define INTER_BIAS      512  #define INTER_BIAS      512
# Line 183  Line 185 
185    
186  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
187    
188    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
189            {     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),
190            (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),
191            (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),
192            (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),
193            (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),
194            (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),
195            (int)(36.4949+0.5)      };
196    
197    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
198    
199    
200    
201  // mv.length table  // mv.length table
202  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
203      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 218  Line 233 
233  }  }
234    
235    
236  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)
237  {  {
238          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));
239  }  }
240    
241  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)
242    
243  {  {
244      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));
245  }  }
246    
247    
# Line 275  Line 290 
290          if (sadInit)          if (sadInit)
291                  (*sadInit)();                  (*sadInit)();
292    
   
         /* eventhough we have a seperate prevMBs,  
            pmvfast/epsz does something "funny" with the previous frames data */  
   
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
                 {  
                         pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];  
                         pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];  
                         pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];  
                         pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];  
                 }  
   
         /*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);  
                 }  
         */  
   
293          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
294          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
295                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
# Line 381  Line 364 
364                                          pMB->mode = MODE_INTER;                                          pMB->mode = MODE_INTER;
365                                          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;
366                                          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;
367                                            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16;
368                                          pMB->pmvs[0].x = pmv16.x;                                          pMB->pmvs[0].x = pmv16.x;
369                                          pMB->pmvs[0].y = pmv16.y;                                          pMB->pmvs[0].y = pmv16.y;
370                                  }                                  }
371                                  else                                  else
372                                    {
373                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
374                                            pMB->sad8[0] *= 4;
375                                            pMB->sad8[1] *= 4;
376                                            pMB->sad8[2] *= 4;
377                                            pMB->sad8[3] *= 4;
378                                    }
379                          }                          }
380                          else                          else
381                          {                          {
# Line 393  Line 383 
383                                  pMB->mode = MODE_INTER;                                  pMB->mode = MODE_INTER;
384                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;
385                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;
386                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16;
387    
388                                  pMB->pmvs[0].x = pmv16.x;                                  pMB->pmvs[0].x = pmv16.x;
389                                  pMB->pmvs[0].y = pmv16.y;                                  pMB->pmvs[0].y = pmv16.y;
390                          }                          }
391                  }                  }
392    
 /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);  
         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],  
                                 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);  
                 }  
         */  
   
393          return 0;          return 0;
394  }  }
395    
# Line 430  Line 403 
403      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
404    { \    { \
405      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); \
406      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; \  
407      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
408      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
409  }  }
410    
411  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
412      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); \
413      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);\
414      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
415      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
416  }  }
# Line 449  Line 420 
420      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
421    { \    { \
422      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); \
423      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);\
424      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
425      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
426  }  }
# Line 459  Line 430 
430      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
431    { \    { \
432      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); \
433      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);\
434      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
435      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
436  }  }
# Line 469  Line 440 
440      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
441    { \    { \
442      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); \
443      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);\
444      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
445      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
446  }  }
# Line 477  Line 448 
448    
449  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
450    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); \
451    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);\
452    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
453    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
454  }  }
# Line 485  Line 456 
456  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
457    { \    { \
458      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); \
459      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);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
462  }  }
# Line 495  Line 466 
466      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
467    { \    { \
468      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); \
469      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);\
470      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
471      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
472  }  }
# Line 505  Line 476 
476      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
477    { \    { \
478      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); \
479      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);\
480      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
481      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
482  }  }
# Line 515  Line 486 
486      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
487    { \    { \
488      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); \
489      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);\
490      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
491      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
492  }  }
# Line 930  Line 901 
901    
902          iFound=0;          iFound=0;
903    
 /* 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;  
   
904  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
905     MinSAD=SAD     MinSAD=SAD
906     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 957  Line 908 
908     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
909  */  */
910    
   
 // Prepare for main loop  
   
911          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
912          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
913          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 987  Line 935 
935          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
936                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
937                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
938          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);
939    
940          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) ) )
941          {          {
942                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
943                    {
944                            if (!MVzero(*currMV))
945                            {
946                                    iMinSAD += MV16_00_BIAS;
947                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
948                                    iMinSAD -= MV16_00_BIAS;
949                            }
950                    }
951    
952                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
953                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 998  Line 955 
955                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
956          }          }
957    
958    
959    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
960       vector of the median.
961       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
962    */
963    
964            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
965                    iFound=2;
966    
967    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
968       Otherwise select large Diamond Search.
969    */
970    
971            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
972                    iDiamondSize=1; // halfpel!
973            else
974                    iDiamondSize=2; // halfpel!
975    
976            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
977                    iDiamondSize*=2;
978    
979  /*  /*
980     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.
981     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
982     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
983     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
984  */  */
985    
986  // (0,0) is always possible  // (0,0) is always possible
987    
988            if (!MVzero(pmv[0]))
989          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
990    
991  // previous frame MV is always possible  // previous frame MV is always possible
992    
993            if (!MVzero(prevMB->mvs[0]))
994            if (!MVequal(prevMB->mvs[0],pmv[0]))
995          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
996    
997  // left neighbour, if allowed  // left neighbour, if allowed
998          if (x != 0)  
999            if (!MVzero(pmv[1]))
1000            if (!MVequal(pmv[1],prevMB->mvs[0]))
1001            if (!MVequal(pmv[1],pmv[0]))
1002          {          {
1003                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1004                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1005                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1006                  }                  }
1007    
1008                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1009          }          }
1010    
1011  // top neighbour, if allowed  // top neighbour, if allowed
1012          if (y != 0)          if (!MVzero(pmv[2]))
1013            if (!MVequal(pmv[2],prevMB->mvs[0]))
1014            if (!MVequal(pmv[2],pmv[0]))
1015            if (!MVequal(pmv[2],pmv[1]))
1016          {          {
1017                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1018                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1032  Line 1021 
1021                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1022    
1023  // top right neighbour, if allowed  // top right neighbour, if allowed
1024                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1025                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1026                    if (!MVequal(pmv[3],pmv[0]))
1027                    if (!MVequal(pmv[3],pmv[1]))
1028                    if (!MVequal(pmv[3],pmv[2]))
1029                  {                  {
1030                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1031                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1042  Line 1035 
1035                  }                  }
1036          }          }
1037    
1038            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1039                    iMinSAD -= MV16_00_BIAS;
1040    
1041    
1042  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1043     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.
1044  */  */
# Line 1260  Line 1257 
1257          int32_t psad[4];          int32_t psad[4];
1258          VECTOR newMV;          VECTOR newMV;
1259          VECTOR backupMV;          VECTOR backupMV;
1260            VECTOR startMV;
1261    
1262          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1263          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
# Line 1268  Line 1266 
1266          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1267          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1268    
1269          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1270    
1271            /* Init variables */
1272            startMV.x = start_x;
1273            startMV.y = start_y;
1274    
1275  /* Get maximum range */  /* Get maximum range */
1276          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1277                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1278    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1279          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1280          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1281          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1303  Line 1303 
1303    
1304          iFound=0;          iFound=0;
1305    
 /* 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;  
   
1306  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1307     MinSAD=SAD     MinSAD=SAD
1308     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1333  Line 1313 
1313    
1314  // Prepare for main loop  // Prepare for main loop
1315    
1316          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1317    
1318          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1319                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1320                          iEdgedWidth);                          iEdgedWidth);
1321          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);
1322    
1323          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1324                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1325          {          {
1326                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1327                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1349  Line 1329 
1329                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1330          }          }
1331    
1332    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1333       vector of the median.
1334       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1335    */
1336    
1337            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1338                    iFound=2;
1339    
1340    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1341       Otherwise select large Diamond Search.
1342    */
1343    
1344            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1345                    iDiamondSize=1; // 1 halfpel!
1346            else
1347                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1348    
1349            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1350                    iDiamondSize*=2;
1351    
1352    
1353  /*  /*
1354     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.
1355     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1356     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1357     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1358  */  */
1359    
1360  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1361    
1362            if (!MVequal(pmv[0],startMV))
1363          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1364    
1365  // (0,0) is always possible  // (0,0) if needed
1366            if (!MVzero(pmv[0]))
1367            if (!MVzero(startMV))
1368          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1369    
1370  // previous frame MV is always possible  // previous frame MV if needed
1371          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1372            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1373            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1374            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1375    
1376  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1377          if (psad[1] != MV_MAX_ERROR)          {
1378                    if (MotionFlags & PMV_QUICKSTOP16)
1379                            goto PMVfast8_Terminate_without_Refine;
1380                    if (MotionFlags & PMV_EARLYSTOP16)
1381                            goto PMVfast8_Terminate_with_Refine;
1382            }
1383    
1384    
1385    // left neighbour, if allowed and needed
1386            if (!MVzero(pmv[1]))
1387            if (!MVequal(pmv[1],startMV))
1388            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1389            if (!MVequal(pmv[1],pmv[0]))
1390          {          {
1391                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1392                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1376  Line 1395 
1395                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1396          }          }
1397    
1398  // top neighbour, if allowed  // top neighbour, if allowed and needed
1399          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1400            if (!MVequal(pmv[2],startMV))
1401            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1402            if (!MVequal(pmv[2],pmv[0]))
1403            if (!MVequal(pmv[2],pmv[1]))
1404          {          {
1405                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1406                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1385  Line 1408 
1408                  }                  }
1409                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1410    
1411  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1412                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1413            if (!MVequal(pmv[3],startMV))
1414            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1415            if (!MVequal(pmv[3],pmv[0]))
1416            if (!MVequal(pmv[3],pmv[1]))
1417            if (!MVequal(pmv[3],pmv[2]))
1418                  {                  {
1419                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1420                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1396  Line 1424 
1424                  }                  }
1425          }          }
1426    
1427            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1428                    iMinSAD -= MV8_00_BIAS;
1429    
1430    
1431  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1432     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.
1433  */  */
1434    
1435          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1436          {          {
1437                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1438                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1530  Line 1562 
1562          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1563    
1564          if (oldMBs == NULL)          if (oldMBs == NULL)
1565          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1566                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1567          }          }
1568          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1569    
# Line 1539  Line 1571 
1571          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1572                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1573    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1574          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1575          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1576            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1580  Line 1610 
1610          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1611                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1612                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1613          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);
1614    
1615  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1616          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) ) )
1617                  {                  {
1618                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1619                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1594  Line 1624 
1624  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1625    
1626  // previous frame MV  // previous frame MV
1627          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1628    
1629  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1630  // 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 1650  Line 1680 
1680  */  */
1681    
1682          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1683                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1684                  {                  {
1685                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1686                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1660  Line 1690 
1690    
1691  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1692    
1693          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1694          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1695          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1696    
1697          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1698    
1699  // left neighbour  // left neighbour
1700          if (x != 0)          if (x != 0)
1701                  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);
1702    
1703  // top neighbour  // top neighbour
1704          if (y != 0)          if (y != 0)
1705                  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);
1706    
1707  // 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
1708    
1709          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1710                  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);
1711    
1712  // bottom neighbour, dito  // bottom neighbour, dito
1713          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1714                  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);
1715    
1716  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1717          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1738  Line 1768 
1768                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1769                                  x, y,                                  x, y,
1770                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1771                          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);
1772    
1773                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1774                          {                          {
# Line 1759  Line 1789 
1789    
1790  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1791    
1792          *oldMB = *pMB;          *oldMB = *prevMB;
1793    
1794          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1795          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1784  Line 1814 
1814                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1815                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1816  {  {
1817    /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
1818    
1819      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1820          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1821          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1861  Line 1893 
1893          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1894                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1895                  iEdgedWidth);                  iEdgedWidth);
1896          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);
1897    
1898    
1899  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1907 
1907    
1908  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1909    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1910    
1911  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1912          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1913    
1914    // previous frame MV
1915            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1916    
1917    // left neighbour, if allowed
1918            if (psad[1] != MV_MAX_ERROR)
1919            {
1920                    if (!(MotionFlags & PMV_HALFPEL8 ))
1921                    {       pmv[1].x = EVEN(pmv[1].x);
1922                            pmv[1].y = EVEN(pmv[1].y);
1923                    }
1924                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1925            }
1926    
1927    // top neighbour, if allowed
1928            if (psad[2] != MV_MAX_ERROR)
1929            {
1930                    if (!(MotionFlags & PMV_HALFPEL8 ))
1931                    {       pmv[2].x = EVEN(pmv[2].x);
1932                            pmv[2].y = EVEN(pmv[2].y);
1933                    }
1934                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1935    
1936    // top right neighbour, if allowed
1937                    if (psad[3] != MV_MAX_ERROR)
1938                    {
1939                            if (!(MotionFlags & PMV_HALFPEL8 ))
1940                            {       pmv[3].x = EVEN(pmv[3].x);
1941                                    pmv[3].y = EVEN(pmv[3].y);
1942                            }
1943                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1944                    }
1945            }
1946    
1947    /*  // this bias is zero anyway, at the moment!
1948    
1949            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1950                    iMinSAD -= MV8_00_BIAS;
1951    
1952    */
1953    
1954  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1955     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]
1956  */  */
# Line 1894  Line 1963 
1963                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1964                  }                  }
1965    
1966  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1967    
1968          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1969    
1970          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1971                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1972    
1973  /* 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 */
1974    
1975    /* // there is no EPZS^2 for inter4v at the moment
1976    
1977            if (MotionFlags & PMV_USESQUARES8)
1978                    EPZSMainSearchPtr = Square8_MainSearch;
1979            else
1980    */
1981    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1982                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1983    
1984          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1985                  x, y,                  x, y,
1986                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1987                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1988                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1989    
1990    
1991          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1979  Line 2052 
2052  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2053  ***************************************************************/  ***************************************************************/
2054    
2055  /*  
2056  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2057                          MBParam * const pParam,                          MBParam * const pParam,
2058                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2001  Line 2074 
2074      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2075          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2076    
2077          int32_t i,j;          uint32_t i,j;
2078    
2079          int32_t f_sad16;          int32_t f_sad16;
2080          int32_t b_sad16;          int32_t b_sad16;
# Line 2025  Line 2098 
2098                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2099                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2100                          {                          {
2101                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2102                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2103                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2104                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2040  Line 2113 
2113                                                  i, j,                                                  i, j,
2114                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2115                                                  pParam,                                                  pParam,
2116                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2117                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2118    
2119                          // backward search                          // backward search
# Line 2049  Line 2122 
2122                                                  i, j,                                                  i, j,
2123                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2124                                                  pParam,                                                  pParam,
2125                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2126                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2127    
2128                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2069  Line 2142 
2142                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2143                          {                          {
2144                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2145                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2146                          }                          }
2147                          else                          else
2148                          {                          {
2149                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2150                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2151                          }                          }
2152    
2153                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2154                          {                          {
2155                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2156                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2157                          }                          }
2158    
2159                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2160                          {                          {
2161                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2162                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2163                          }                          }
2164    
2165                  }                  }
2166          }          }
2167  }  }
   
 */  

Legend:
Removed from v.136  
changed lines
  Added in v.170

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