[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 152, Wed May 1 13:00:02 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 279  Line 294 
294          /* eventhough we have a seperate prevMBs,          /* eventhough we have a seperate prevMBs,
295             pmvfast/epsz does something "funny" with the previous frames data */             pmvfast/epsz does something "funny" with the previous frames data */
296    
297          for (i = 0; i < iHcount; i++)  /*      for (i = 0; i < iHcount; i++)
298                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
299                  {                  {
300                          pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];                          pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];
# Line 287  Line 302 
302                          pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];                          pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];
303                          pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];                          pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];
304                  }                  }
305    */
306          /*dprintf("*** BEFORE ***");          /*dprintf("*** BEFORE ***");
307          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
308                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
# Line 430  Line 445 
445      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
446    { \    { \
447      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); \
448      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; \  
449      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
450      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
451  }  }
452    
453  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
454      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); \
455      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);\
456      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
457      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
458  }  }
# Line 449  Line 462 
462      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
463    { \    { \
464      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); \
465      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);\
466      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
467      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
468  }  }
# Line 459  Line 472 
472      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
473    { \    { \
474      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); \
475      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);\
476      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
477      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
478  }  }
# Line 469  Line 482 
482      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
483    { \    { \
484      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); \
485      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);\
486      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
487      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
488  }  }
# Line 477  Line 490 
490    
491  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
492    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); \
493    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);\
494    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
495    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
496  }  }
# Line 485  Line 498 
498  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
499    { \    { \
500      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); \
501      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);\
502      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
503      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
504  }  }
# Line 495  Line 508 
508      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
509    { \    { \
510      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); \
511      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);\
512      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
513      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
514  }  }
# Line 505  Line 518 
518      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
519    { \    { \
520      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); \
521      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);\
522      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
523      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
524  }  }
# Line 515  Line 528 
528      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
529    { \    { \
530      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); \
531      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);\
532      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
533      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
534  }  }
# Line 987  Line 1000 
1000          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1001                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1002                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
1003          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);
1004    
1005          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) ) )
1006          {          {
# Line 1002  Line 1015 
1015     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.
1016     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1017     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1018     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1019  */  */
1020    
1021  // (0,0) is always possible  // (0,0) is always possible
# Line 1042  Line 1055 
1055                  }                  }
1056          }          }
1057    
1058            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1059                    iMinSAD -= MV16_00_BIAS;
1060    
1061    
1062  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1063     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.
1064  */  */
# Line 1274  Line 1291 
1291          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1292                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1293    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1294          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1295          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1296          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1308  Line 1323 
1323     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1324  */  */
1325    
1326          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1327                  iFound=2;                  iFound=2;
1328    
1329  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
# Line 1339  Line 1354 
1354          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1355                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1356                          iEdgedWidth);                          iEdgedWidth);
1357          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);
1358    
1359          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1360          {          {
1361                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1362                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1354  Line 1369 
1369     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.
1370     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1371     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1372     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1373  */  */
1374    
1375  // the prediction might be even better than mv16  // the prediction might be even better than mv16
# Line 1364  Line 1379 
1379          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1380    
1381  // previous frame MV is always possible  // previous frame MV is always possible
1382          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1383    
1384  // left neighbour, if allowed  // left neighbour, if allowed
1385          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR)
# Line 1396  Line 1411 
1411                  }                  }
1412          }          }
1413    
1414            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1415                    iMinSAD -= MV8_00_BIAS;
1416    
1417    
1418  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1419     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.
1420  */  */
1421    
1422          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]) ) )
1423          {          {
1424                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1425                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1530  Line 1549 
1549          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1550    
1551          if (oldMBs == NULL)          if (oldMBs == NULL)
1552          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1553                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1554          }          }
1555          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1556    
# Line 1539  Line 1558 
1558          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1559                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1560    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1561          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1562          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1563            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1580  Line 1597 
1597          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1598                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1599                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1600          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);
1601    
1602  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1603          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) ) )
1604                  {                  {
1605                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1606                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1594  Line 1611 
1611  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1612    
1613  // previous frame MV  // previous frame MV
1614          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1615    
1616  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1617  // 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 1667 
1667  */  */
1668    
1669          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1670                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1671                  {                  {
1672                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1673                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1660  Line 1677 
1677    
1678  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1679    
1680          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1681          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1682          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1683    
1684          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1685    
1686  // left neighbour  // left neighbour
1687          if (x != 0)          if (x != 0)
1688                  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);
1689    
1690  // top neighbour  // top neighbour
1691          if (y != 0)          if (y != 0)
1692                  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);
1693    
1694  // 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
1695    
1696          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1697                  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);
1698    
1699  // bottom neighbour, dito  // bottom neighbour, dito
1700          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1701                  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);
1702    
1703  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1704          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1738  Line 1755 
1755                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1756                                  x, y,                                  x, y,
1757                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1758                          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);
1759    
1760                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1761                          {                          {
# Line 1759  Line 1776 
1776    
1777  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1778    
1779          *oldMB = *pMB;          *oldMB = *prevMB;
1780    
1781          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1782          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1784  Line 1801 
1801                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1802                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1803  {  {
1804    /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
1805    
1806      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1807          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1808          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1861  Line 1880 
1880          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1881                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1882                  iEdgedWidth);                  iEdgedWidth);
1883          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);
1884    
1885    
1886  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1894 
1894    
1895  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1896    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1897    
1898  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1899          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1900    
1901    // previous frame MV
1902            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1903    
1904    // left neighbour, if allowed
1905            if (psad[1] != MV_MAX_ERROR)
1906            {
1907                    if (!(MotionFlags & PMV_HALFPEL8 ))
1908                    {       pmv[1].x = EVEN(pmv[1].x);
1909                            pmv[1].y = EVEN(pmv[1].y);
1910                    }
1911                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1912            }
1913    
1914    // top neighbour, if allowed
1915            if (psad[2] != MV_MAX_ERROR)
1916            {
1917                    if (!(MotionFlags & PMV_HALFPEL8 ))
1918                    {       pmv[2].x = EVEN(pmv[2].x);
1919                            pmv[2].y = EVEN(pmv[2].y);
1920                    }
1921                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1922    
1923    // top right neighbour, if allowed
1924                    if (psad[3] != MV_MAX_ERROR)
1925                    {
1926                            if (!(MotionFlags & PMV_HALFPEL8 ))
1927                            {       pmv[3].x = EVEN(pmv[3].x);
1928                                    pmv[3].y = EVEN(pmv[3].y);
1929                            }
1930                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1931                    }
1932            }
1933    
1934    /*  // this bias is zero anyway, at the moment!
1935    
1936            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1937                    iMinSAD -= MV8_00_BIAS;
1938    
1939    */
1940    
1941  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1942     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]
1943  */  */
# Line 1894  Line 1950 
1950                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1951                  }                  }
1952    
1953  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1954    
1955          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1956    
1957          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1958                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1959    
1960  /* 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 */
1961    
1962    /* // there is no EPZS^2 for inter4v at the moment
1963    
1964            if (MotionFlags & PMV_USESQUARES8)
1965                    EPZSMainSearchPtr = Square8_MainSearch;
1966            else
1967    */
1968    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1969                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1970    
1971          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1972                  x, y,                  x, y,
1973                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1974                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1975                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1976    
1977    
1978          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1979  Line 2039 
2039  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2040  ***************************************************************/  ***************************************************************/
2041    
2042  /*  
2043  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2044                          MBParam * const pParam,                          MBParam * const pParam,
2045                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2001  Line 2061 
2061      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2062          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2063    
2064          int32_t i,j;          uint32_t i,j;
2065    
2066          int32_t f_sad16;          int32_t f_sad16;
2067          int32_t b_sad16;          int32_t b_sad16;
# Line 2025  Line 2085 
2085                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2086                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2087                          {                          {
2088                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2089                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2090                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2091                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2040  Line 2100 
2100                                                  i, j,                                                  i, j,
2101                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2102                                                  pParam,                                                  pParam,
2103                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2104                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2105    
2106                          // backward search                          // backward search
# Line 2049  Line 2109 
2109                                                  i, j,                                                  i, j,
2110                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2111                                                  pParam,                                                  pParam,
2112                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2113                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2114    
2115                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2069  Line 2129 
2129                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2130                          {                          {
2131                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2132                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2133                          }                          }
2134                          else                          else
2135                          {                          {
2136                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2137                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2138                          }                          }
2139    
2140                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2141                          {                          {
2142                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2143                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2144                          }                          }
2145    
2146                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2147                          {                          {
2148                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2149                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2150                          }                          }
2151    
2152                  }                  }
2153          }          }
2154  }  }
   
 */  

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

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