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

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

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

revision 312, Thu Jul 18 23:42:36 2002 UTC revision 370, Mon Aug 12 10:07:16 2002 UTC
# Line 171  Line 171 
171          const IMAGE *const pCurrent = &current->image;          const IMAGE *const pCurrent = &current->image;
172          const IMAGE *const pRef = &reference->image;          const IMAGE *const pRef = &reference->image;
173    
174          const VECTOR zeroMV = { 0, 0 };          static const VECTOR zeroMV = { 0, 0 };
175            VECTOR predMV;
176    
177          int32_t x, y;          int32_t x, y;
178          int32_t iIntra = 0;          int32_t iIntra = 0;
# Line 185  Line 186 
186    
187                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
188    
189                            if (pMB->mode == MODE_NOT_CODED)
190                                    continue;
191    
192                            predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
193    
194                          pMB->sad16 =                          pMB->sad16 =
195                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
196                                                   y, current->motion_flags, current->quant,                                                   x, y, predMV.x, predMV.y, predMV.x, predMV.y,
197                                                     current->motion_flags, current->quant,
198                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,
199                                                   &pMB->pmvs[0]);                                                   &pMB->pmvs[0]);
200    
# Line 219  Line 226 
226                                           pMB->dquant == NO_CHANGE)) {                                           pMB->dquant == NO_CHANGE)) {
227                                          int32_t sad8 = IMV16X16 * current->quant;                                          int32_t sad8 = IMV16X16 * current->quant;
228    
229                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
   
230                                                  sad8 += pMB->sad8[0] =                                                  sad8 += pMB->sad8[0] =
231                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
232                                                                          pCurrent, 2 * x, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y,
233                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
234                                                                            current->motion_flags,
235                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
236                                                                          pMBs, prevMBs, &pMB->mvs[0],                                                                          pMBs, prevMBs, &pMB->mvs[0],
237                                                                          &pMB->pmvs[0]);                                                                          &pMB->pmvs[0]);
238                                            }
239                                            if (sad8 < pMB->sad16) {
240    
241                                          if (sad8 < pMB->sad16)                                                  predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 1);
242                                                  sad8 += pMB->sad8[1] =                                                  sad8 += pMB->sad8[1] =
243                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
244                                                                          pCurrent, 2 * x + 1, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x + 1, 2 * y,
245                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
246                                                                            current->motion_flags,
247                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
248                                                                          pMBs, prevMBs, &pMB->mvs[1],                                                                          pMBs, prevMBs, &pMB->mvs[1],
249                                                                          &pMB->pmvs[1]);                                                                          &pMB->pmvs[1]);
250                                            }
251                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
252                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 2);
253                                                  sad8 += pMB->sad8[2] =                                                  sad8 += pMB->sad8[2] =
254                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
255                                                                          pCurrent, 2 * x, 2 * y + 1, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y + 1,
256                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
257                                                                            current->motion_flags,
258                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
259                                                                          pMBs, prevMBs, &pMB->mvs[2],                                                                          pMBs, prevMBs, &pMB->mvs[2],
260                                                                          &pMB->pmvs[2]);                                                                          &pMB->pmvs[2]);
261                                            }
262                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
263                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 3);
264                                                  sad8 += pMB->sad8[3] =                                                  sad8 += pMB->sad8[3] =
265                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
266                                                                          pCurrent, 2 * x + 1, 2 * y + 1,                                                                          pCurrent, 2 * x + 1, 2 * y + 1,
267                                                                          pMB->mv16.x, pMB->mv16.y,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
268                                                                          current->motion_flags, current->quant,                                                                          current->motion_flags,
269                                                                          current->fcode, pParam, pMBs, prevMBs,                                                                          current->quant, current->fcode, pParam,
270                                                                          &pMB->mvs[3], &pMB->pmvs[3]);                                                                          pMBs, prevMBs,
271                                                                            &pMB->mvs[3],
272                                                                            &pMB->pmvs[3]);
273                                            }
274    
275                                          /* decide: MODE_INTER or MODE_INTER4V                                          /* decide: MODE_INTER or MODE_INTER4V
276                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
# Line 282  Line 298 
298          return 0;          return 0;
299  }  }
300    
301    
302  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
303    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
304      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
305    { \    { \
306      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); \
307      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
308      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
309      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
310  }  }
311    
312  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
313      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); \
314      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
315      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
316      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
317  }  }
# Line 304  Line 321 
321      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
322    { \    { \
323      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); \
324      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
325      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
326      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
327  }  }
# Line 314  Line 331 
331      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
332    { \    { \
333      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); \
334      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
335      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
336      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
337  }  }
# Line 324  Line 341 
341      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
342    { \    { \
343      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); \
344      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
345      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
346      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
347  }  }
# Line 332  Line 349 
349    
350  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
351    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); \
352    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\    iSAD += calc_delta_8(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
353    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
354    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
355  }  }
# Line 340  Line 357 
357  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
358    { \    { \
359      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); \
360      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
361      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
362      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
363  }  }
# Line 350  Line 367 
367      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
368    { \    { \
369      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); \
370      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
371      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
372      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
373  }  }
# Line 360  Line 377 
377      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
378    { \    { \
379      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); \
380      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
381      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
382      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
383  }  }
# Line 370  Line 387 
387      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
388    { \    { \
389      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); \
390      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
391      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
392      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
393  }  }
# Line 425  Line 442 
442                                           const uint8_t * const cur,                                           const uint8_t * const cur,
443                                           const int x,                                           const int x,
444                                           const int y,                                           const int y,
445                                           int32_t startx,                                     const int start_x,
446                                           int32_t starty,                                     const int start_y,
447                                           int32_t iMinSAD,                                     int iMinSAD,
448                                           VECTOR * const currMV,                                           VECTOR * const currMV,
449                                           const VECTOR * const pmv,                                     const int center_x,
450                                       const int center_y,
451                                           const int32_t min_dx,                                           const int32_t min_dx,
452                                           const int32_t max_dx,                                           const int32_t max_dx,
453                                           const int32_t min_dy,                                           const int32_t min_dy,
# Line 443  Line 461 
461  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
462    
463          int32_t iDirection = 0;          int32_t iDirection = 0;
464            int32_t iDirectionBackup;
465          int32_t iSAD;          int32_t iSAD;
466          VECTOR backupMV;          VECTOR backupMV;
467    
468          backupMV.x = startx;          backupMV.x = start_x;
469          backupMV.y = starty;          backupMV.y = start_y;
470    
471  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
472    
# Line 456  Line 475 
475          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
476          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
477    
478          if (iDirection)          if (iDirection) {
479                  while (!iFound) {                  while (!iFound) {
480                          iFound = 1;                          iFound = 1;
481                          backupMV = *currMV;                          backupMV = *currMV;
482                            iDirectionBackup = iDirection;
483    
484                          if (iDirection != 2)                          if (iDirectionBackup != 2)
485                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
486                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
487                          if (iDirection != 1)                          if (iDirectionBackup != 1)
488                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
489                                                                                     backupMV.y, 2);                                                                                     backupMV.y, 2);
490                          if (iDirection != 4)                          if (iDirectionBackup != 4)
491                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
492                                                                                     backupMV.y - iDiamondSize, 3);                                                                                     backupMV.y - iDiamondSize, 3);
493                          if (iDirection != 3)                          if (iDirectionBackup != 3)
494                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
495                                                                                     backupMV.y + iDiamondSize, 4);                                                                                     backupMV.y + iDiamondSize, 4);
496                    }
497          } else {          } else {
498                  currMV->x = startx;                  currMV->x = start_x;
499                  currMV->y = starty;                  currMV->y = start_y;
500          }          }
501          return iMinSAD;          return iMinSAD;
502  }  }
# Line 488  Line 509 
509                                          const uint8_t * const cur,                                          const uint8_t * const cur,
510                                          const int x,                                          const int x,
511                                          const int y,                                          const int y,
512                                          int32_t startx,                                     const int start_x,
513                                          int32_t starty,                                     const int start_y,
514                                          int32_t iMinSAD,                                     int iMinSAD,
515                                          VECTOR * const currMV,                                          VECTOR * const currMV,
516                                          const VECTOR * const pmv,                                     const int center_x,
517                                       const int center_y,
518                                          const int32_t min_dx,                                          const int32_t min_dx,
519                                          const int32_t max_dx,                                          const int32_t max_dx,
520                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 509  Line 531 
531          int32_t iSAD;          int32_t iSAD;
532          VECTOR backupMV;          VECTOR backupMV;
533    
534          backupMV.x = startx;          backupMV.x = start_x;
535          backupMV.y = starty;          backupMV.y = start_y;
536    
537  /* It's one search with full square pattern, and new parts for all following diamonds */  /* It's one search with full square pattern, and new parts for all following diamonds */
538    
# Line 535  Line 557 
557                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
558    
559    
560          if (iDirection)          if (iDirection) {
561                  while (!iFound) {                  while (!iFound) {
562                          iFound = 1;                          iFound = 1;
563                          backupMV = *currMV;                          backupMV = *currMV;
# Line 544  Line 566 
566                          case 1:                          case 1:
567                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
568                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
569                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
570                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
571                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
572                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
573                                  break;                                  break;
574                          case 2:                          case 2:
575                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
576                                                                                   2);                                                                                   2);
577                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
578                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
579                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
580                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
581                                  break;                                  break;
582    
583                          case 3:                          case 3:
584                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
585                                                                                   4);                                                                                   4);
586                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
587                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
588                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
589                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
590                                  break;                                  break;
591    
592                          case 4:                          case 4:
593                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
594                                                                                   3);                                                                                   3);
595                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
596                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
597                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
598                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
599                                  break;                                  break;
600    
601                          case 5:                          case 5:
602                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
603                                                                                   1);                                                                                   1);
604                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
605                                                                                   3);                                                                                   3);
606                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
607                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
608                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
609                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
610                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
611                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
612                                  break;                                  break;
613    
614                          case 6:                          case 6:
615                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
616                                                                                   2);                                                                                   2);
617                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
618                                                                                   3);                                                                                   3);
619    
620                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
621                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
622                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
623                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
624                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
625                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
626    
627                                  break;                                  break;
# Line 607  Line 629 
629                          case 7:                          case 7:
630                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
631                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
632                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
633                                                                                   4);                                                                                   4);
634                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
635                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
636                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
637                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
638                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
639                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
640                                  break;                                  break;
641    
642                          case 8:                          case 8:
643                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
644                                                                                   2);                                                                                   2);
645                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
646                                                                                   4);                                                                                   4);
647                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
648                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
649                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
650                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
651                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
652                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
653                                  break;                                  break;
654                          default:                          default:
655                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
656                                                                                   1);                                                                                   1);
657                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
658                                                                                   2);                                                                                   2);
659                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
660                                                                                   3);                                                                                   3);
661                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
662                                                                                   4);                                                                                   4);
663    
664                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
665                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
666                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
667                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
668                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
669                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
670                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
671                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
672                                  break;                                  break;
673                          }                          }
674                    }
675          } else {          } else {
676                  currMV->x = startx;                  currMV->x = start_x;
677                  currMV->y = starty;                  currMV->y = start_y;
678          }          }
679          return iMinSAD;          return iMinSAD;
680  }  }
# Line 665  Line 688 
688                                    const uint8_t * const cur,                                    const uint8_t * const cur,
689                                    const int x,                                    const int x,
690                                    const int y,                                    const int y,
691                                    int32_t startx,                                     const int start_x,
692                                    int32_t starty,                                     const int start_y,
693                                    int32_t iMinSAD,                                     int iMinSAD,
694                                    VECTOR * const currMV,                                    VECTOR * const currMV,
695                                    const VECTOR * const pmv,                                     const int center_x,
696                                       const int center_y,
697                                    const int32_t min_dx,                                    const int32_t min_dx,
698                                    const int32_t max_dx,                                    const int32_t max_dx,
699                                    const int32_t min_dy,                                    const int32_t min_dy,
# Line 684  Line 708 
708          int32_t dx, dy;          int32_t dx, dy;
709          VECTOR backupMV;          VECTOR backupMV;
710    
711          backupMV.x = startx;          backupMV.x = start_x;
712          backupMV.y = starty;          backupMV.y = start_y;
713    
714          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
715                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 702  Line 726 
726                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
727                                                  const int x,                                                  const int x,
728                                                  const int y,                                                  const int y,
729                                                  int32_t startx,                                             int start_x,
730                                                  int32_t starty,                                             int start_y,
731                                                  int32_t iMinSAD,                                             int iMinSAD,
732                                                  VECTOR * const currMV,                                                  VECTOR * const currMV,
733                                                  const VECTOR * const pmv,                                             const int center_x,
734                                               const int center_y,
735                                                  const int32_t min_dx,                                                  const int32_t min_dx,
736                                                  const int32_t max_dx,                                                  const int32_t max_dx,
737                                                  const int32_t min_dy,                                                  const int32_t min_dy,
# Line 723  Line 748 
748  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
749    
750          if (iDirection) {          if (iDirection) {
751                  CHECK_MV16_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y);
752                  CHECK_MV16_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y);
753                  CHECK_MV16_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize);
754                  CHECK_MV16_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize);
755          } else {          } else {
756                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
757    
758                  do {                  do {
759                          iDirection = 0;                          iDirection = 0;
760                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
761                                  CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
762    
763                          if (bDirection & 2)                          if (bDirection & 2)
764                                  CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
765    
766                          if (bDirection & 4)                          if (bDirection & 4)
767                                  CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
768    
769                          if (bDirection & 8)                          if (bDirection & 8)
770                                  CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
771    
772                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
773    
# Line 750  Line 775 
775                          {                          {
776                                  bDirection = iDirection;                                  bDirection = iDirection;
777                                  iDirection = 0;                                  iDirection = 0;
778                                  startx = currMV->x;                                  start_x = currMV->x;
779                                  starty = currMV->y;                                  start_y = currMV->y;
780                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
781                                  {                                  {
782                                          CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
783                                          CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
784                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
785                                  {                                  {
786                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
787                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
788                                  }                                  }
789    
790                                  if (iDirection) {                                  if (iDirection) {
791                                          bDirection += iDirection;                                          bDirection += iDirection;
792                                          startx = currMV->x;                                          start_x = currMV->x;
793                                          starty = currMV->y;                                          start_y = currMV->y;
794                                  }                                  }
795                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
796                          {                          {
797                                  switch (bDirection) {                                  switch (bDirection) {
798                                  case 2:                                  case 2:
799                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
800                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
801                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
802                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
803                                          break;                                          break;
804                                  case 1:                                  case 1:
805                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,  
806                                                                                           starty - iDiamondSize, 1 + 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
807                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                                                                           start_y - iDiamondSize, 1 + 4);
808                                                                                           starty + iDiamondSize, 1 + 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
809                                                                                             start_y + iDiamondSize, 1 + 8);
810                                          break;                                          break;
811                                  case 2 + 4:                                  case 2 + 4:
812                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
813                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
814                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
815                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
816                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
817                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
818                                          break;                                          break;
819                                  case 4:                                  case 4:
820                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
821                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
822                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
823                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
824                                          break;                                          break;
825                                  case 8:                                  case 8:
826                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
827                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
828                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
829                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
830                                          break;                                          break;
831                                  case 1 + 4:                                  case 1 + 4:
832                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
833                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
834                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
835                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
836                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
837                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
838                                          break;                                          break;
839                                  case 2 + 8:                                  case 2 + 8:
840                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
841                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
842                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
843                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
844                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
845                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
846                                          break;                                          break;
847                                  case 1 + 8:                                  case 1 + 8:
848                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
849                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
850                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
851                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
852                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
853                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
854                                          break;                                          break;
855                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
856                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
857                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
858                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
859                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
860                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
861                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
862                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
863                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
864                                          break;                                          break;
865                                  }                                  }
866                                  if (!iDirection)                                  if (!iDirection)
867                                          break;          //ok, the end. really                                          break;          //ok, the end. really
868                                  else {                                  else {
869                                          bDirection = iDirection;                                          bDirection = iDirection;
870                                          startx = currMV->x;                                          start_x = currMV->x;
871                                          starty = currMV->y;                                          start_y = currMV->y;
872                                  }                                  }
873                          }                          }
874                  }                  }
# Line 851  Line 877 
877          return iMinSAD;          return iMinSAD;
878  }  }
879    
880    #define CHECK_MV16_F_INTERPOL(X,Y) { \
881      if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
882        && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
883      { \
884        iSAD = sad16bi( cur, \
885                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
886                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
887                            iEdgedWidth); \
888        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
889        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
890        if (iSAD < iMinSAD) \
891        {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
892    }
893    
894    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
895      if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
896        && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
897      { \
898        iSAD = sad16bi( cur, \
899                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
900                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
901                            iEdgedWidth); \
902        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
903        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
904        if (iSAD < iMinSAD) \
905        {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
906    }
907    
908    #define CHECK_MV16_B_INTERPOL(X,Y) { \
909      if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
910        && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
911      { \
912        iSAD = sad16bi( cur, \
913                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
914                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
915                            iEdgedWidth); \
916        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
917        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
918        if (iSAD < iMinSAD) \
919        {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
920    }
921    
922    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
923      if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
924        && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
925      { \
926        iSAD = sad16bi( cur, \
927                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
928                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
929                            iEdgedWidth); \
930        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
931        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
932        if (iSAD < iMinSAD) \
933        {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
934    }
935    
936    int32_t
937    Diamond16_InterpolMainSearch(
938                                            const uint8_t * const f_pRef,
939                                             const uint8_t * const f_pRefH,
940                                             const uint8_t * const f_pRefV,
941                                             const uint8_t * const f_pRefHV,
942    
943                                             const uint8_t * const cur,
944    
945                                            const uint8_t * const b_pRef,
946                                             const uint8_t * const b_pRefH,
947                                             const uint8_t * const b_pRefV,
948                                             const uint8_t * const b_pRefHV,
949    
950                                             const int x,
951                                             const int y,
952    
953                                       const int f_start_x,
954                                       const int f_start_y,
955                                       const int b_start_x,
956                                       const int b_start_y,
957    
958                                       int iMinSAD,
959                                       VECTOR * const f_currMV,
960                                       VECTOR * const b_currMV,
961    
962                                       const int f_center_x,
963                                       const int f_center_y,
964                                       const int b_center_x,
965                                       const int b_center_y,
966    
967                                        const int32_t f_min_dx,
968                                            const int32_t f_max_dx,
969                                            const int32_t f_min_dy,
970                                            const int32_t f_max_dy,
971    
972                                        const int32_t b_min_dx,
973                                            const int32_t b_max_dx,
974                                            const int32_t b_min_dy,
975                                            const int32_t b_max_dy,
976    
977                                            const int32_t iEdgedWidth,
978                                            const int32_t iDiamondSize,
979    
980                                            const int32_t f_iFcode,
981                                            const int32_t b_iFcode,
982    
983                                            const int32_t iQuant,
984                                            int iFound)
985    {
986    /* Do a diamond search around given starting point, return SAD of best */
987    
988            int32_t iSAD;
989    
990            VECTOR f_backupMV;
991            VECTOR b_backupMV;
992    
993            f_currMV->x = f_start_x;
994            f_currMV->y = f_start_y;
995            b_currMV->x = b_start_x;
996            b_currMV->y = b_start_y;
997    
998            do
999            {
1000                    iFound = 1;
1001    
1002                    f_backupMV = *f_currMV;
1003    
1004                    CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
1005                    CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
1006                    CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
1007                    CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
1008    
1009                    b_backupMV = *b_currMV;
1010    
1011                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
1012                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
1013                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
1014                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
1015    
1016            } while (!iFound);
1017    
1018            return iMinSAD;
1019    }
1020    
1021    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
1022    
1023    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
1024            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
1025            { int k;\
1026            VECTOR mvs,b_mvs;       \
1027            iSAD = 0;\
1028            for (k = 0; k < 4; k++) {       \
1029                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
1030                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
1031                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1032                                                : mvs.x - directmv[k].x);                           \
1033                                                                                                                                                                    \
1034                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1035                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1036                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1037                                                : mvs.y - directmv[k].y);                           \
1038                                                                                                                                                                    \
1039      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1040        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1041            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1042        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1043                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1044                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1045                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1046                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1047                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1048                            iEdgedWidth); \
1049                    }       \
1050            else    \
1051                    iSAD = 65535;   \
1052            } \
1053            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1054            if (iSAD < iMinSAD) \
1055                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1056    }
1057    
1058    
1059    
1060    int32_t
1061    Diamond16_DirectMainSearch(
1062                                            const uint8_t * const f_pRef,
1063                                            const uint8_t * const f_pRefH,
1064                                            const uint8_t * const f_pRefV,
1065                                            const uint8_t * const f_pRefHV,
1066    
1067                                            const uint8_t * const cur,
1068    
1069                                            const uint8_t * const b_pRef,
1070                                            const uint8_t * const b_pRefH,
1071                                            const uint8_t * const b_pRefV,
1072                                            const uint8_t * const b_pRefHV,
1073    
1074                                            const int x,
1075                                            const int y,
1076    
1077                                            const int TRB,
1078                                            const int TRD,
1079    
1080                                        const int start_x,
1081                                        const int start_y,
1082    
1083                                        int iMinSAD,
1084                                        VECTOR * const currMV,
1085                                            const VECTOR * const directmv,
1086    
1087                                        const int32_t min_dx,
1088                                            const int32_t max_dx,
1089                                            const int32_t min_dy,
1090                                            const int32_t max_dy,
1091    
1092                                            const int32_t iEdgedWidth,
1093                                            const int32_t iDiamondSize,
1094    
1095                                            const int32_t iQuant,
1096                                            int iFound)
1097    {
1098    /* Do a diamond search around given starting point, return SAD of best */
1099    
1100            int32_t iSAD;
1101    
1102            VECTOR backupMV;
1103    
1104            currMV->x = start_x;
1105            currMV->y = start_y;
1106    
1107    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1108    
1109            do
1110            {
1111                    iFound = 1;
1112    
1113                    backupMV = *currMV;
1114    
1115                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1116                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1117                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1118                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1119    
1120            } while (!iFound);
1121    
1122            return iMinSAD;
1123    }
1124    
1125    
1126  int32_t  int32_t
1127  AdvDiamond8_MainSearch(const uint8_t * const pRef,  AdvDiamond8_MainSearch(const uint8_t * const pRef,
1128                                             const uint8_t * const pRefH,                                             const uint8_t * const pRefH,
# Line 859  Line 1131 
1131                                             const uint8_t * const cur,                                             const uint8_t * const cur,
1132                                             const int x,                                             const int x,
1133                                             const int y,                                             const int y,
1134                                             int32_t startx,                                             int start_x,
1135                                             int32_t starty,                                             int start_y,
1136                                             int32_t iMinSAD,                                             int iMinSAD,
1137                                             VECTOR * const currMV,                                             VECTOR * const currMV,
1138                                             const VECTOR * const pmv,                                             const int center_x,
1139                                               const int center_y,
1140                                             const int32_t min_dx,                                             const int32_t min_dx,
1141                                             const int32_t max_dx,                                             const int32_t max_dx,
1142                                             const int32_t min_dy,                                             const int32_t min_dy,
# Line 880  Line 1153 
1153  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
1154    
1155          if (iDirection) {          if (iDirection) {
1156                  CHECK_MV8_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x - iDiamondSize, start_y);
1157                  CHECK_MV8_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x + iDiamondSize, start_y);
1158                  CHECK_MV8_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y - iDiamondSize);
1159                  CHECK_MV8_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y + iDiamondSize);
1160          } else {          } else {
1161                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
1162    
1163                  do {                  do {
1164                          iDirection = 0;                          iDirection = 0;
1165                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
1166                                  CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1167    
1168                          if (bDirection & 2)                          if (bDirection & 2)
1169                                  CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1170    
1171                          if (bDirection & 4)                          if (bDirection & 4)
1172                                  CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1173    
1174                          if (bDirection & 8)                          if (bDirection & 8)
1175                                  CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1176    
1177                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
1178    
# Line 907  Line 1180 
1180                          {                          {
1181                                  bDirection = iDirection;                                  bDirection = iDirection;
1182                                  iDirection = 0;                                  iDirection = 0;
1183                                  startx = currMV->x;                                  start_x = currMV->x;
1184                                  starty = currMV->y;                                  start_y = currMV->y;
1185                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
1186                                  {                                  {
1187                                          CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1188                                          CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1189                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
1190                                  {                                  {
1191                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1192                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1193                                  }                                  }
1194    
1195                                  if (iDirection) {                                  if (iDirection) {
1196                                          bDirection += iDirection;                                          bDirection += iDirection;
1197                                          startx = currMV->x;                                          start_x = currMV->x;
1198                                          starty = currMV->y;                                          start_y = currMV->y;
1199                                  }                                  }
1200                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
1201                          {                          {
1202                                  switch (bDirection) {                                  switch (bDirection) {
1203                                  case 2:                                  case 2:
1204                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1205                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1206                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1207                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1208                                          break;                                          break;
1209                                  case 1:                                  case 1:
1210                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1211                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1212                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1213                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1214                                          break;                                          break;
1215                                  case 2 + 4:                                  case 2 + 4:
1216                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1217                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1218                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1219                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1220                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1221                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1222                                          break;                                          break;
1223                                  case 4:                                  case 4:
1224                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1225                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1226                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1227                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1228                                          break;                                          break;
1229                                  case 8:                                  case 8:
1230                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1231                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1232                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1233                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1234                                          break;                                          break;
1235                                  case 1 + 4:                                  case 1 + 4:
1236                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1237                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1238                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1239                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1240                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1241                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1242                                          break;                                          break;
1243                                  case 2 + 8:                                  case 2 + 8:
1244                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1245                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1246                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1247                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1248                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1249                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1250                                          break;                                          break;
1251                                  case 1 + 8:                                  case 1 + 8:
1252                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1253                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1254                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1255                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1256                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1257                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1258                                          break;                                          break;
1259                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
1260                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1261                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1262                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1263                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1264                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1265                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1266                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1267                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1268                                          break;                                          break;
1269                                  }                                  }
1270                                  if (!(iDirection))                                  if (!(iDirection))
1271                                          break;          //ok, the end. really                                          break;          //ok, the end. really
1272                                  else {                                  else {
1273                                          bDirection = iDirection;                                          bDirection = iDirection;
1274                                          startx = currMV->x;                                          start_x = currMV->x;
1275                                          starty = currMV->y;                                          start_y = currMV->y;
1276                                  }                                  }
1277                          }                          }
1278                  }                  }
# Line 1017  Line 1290 
1290                                   const uint8_t * const cur,                                   const uint8_t * const cur,
1291                                   const int x,                                   const int x,
1292                                   const int y,                                   const int y,
1293                                   int32_t startx,                             const int start_x,
1294                                   int32_t starty,                             const int start_y,
1295                                   int32_t iMinSAD,                             int iMinSAD,
1296                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1297                                   const VECTOR * const pmv,                             const int center_x,
1298                               const int center_y,
1299                                   const int32_t min_dx,                                   const int32_t min_dx,
1300                                   const int32_t max_dx,                                   const int32_t max_dx,
1301                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1036  Line 1310 
1310          int32_t dx, dy;          int32_t dx, dy;
1311          VECTOR backupMV;          VECTOR backupMV;
1312    
1313          backupMV.x = startx;          backupMV.x = start_x;
1314          backupMV.y = starty;          backupMV.y = start_y;
1315    
1316          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
1317                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 1058  Line 1332 
1332                                   const int y,                                   const int y,
1333                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1334                                   int32_t iMinSAD,                                   int32_t iMinSAD,
1335                                   const VECTOR * const pmv,                             const int center_x,
1336                               const int center_y,
1337                                   const int32_t min_dx,                                   const int32_t min_dx,
1338                                   const int32_t max_dx,                                   const int32_t max_dx,
1339                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1087  Line 1362 
1362  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1363    
1364    
1365    
1366  int32_t  int32_t
1367  PMVfastSearch16(const uint8_t * const pRef,  PMVfastSearch16(const uint8_t * const pRef,
1368                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1095  Line 1371 
1371                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1372                                  const int x,                                  const int x,
1373                                  const int y,                                  const int y,
1374                                    const int start_x,      /* start is searched first, so it should contain the most */
1375                                    const int start_y,  /* likely motion vector for this block */
1376                                    const int center_x,     /* center is from where length of MVs is measured */
1377                                    const int center_y,
1378                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1379                                  const uint32_t iQuant,                                  const uint32_t iQuant,
1380                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 1151  Line 1431 
1431          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1432          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1433    
 /*      fprintf(stderr,"pmv: %d %d / %d --- %d %d   %d %d   %d %d - %d %d %d\n",  
                 pmv[0].x,pmv[0].y,psad[0],  
                 pmv[1].x,pmv[1].y,pmv[2].x,pmv[2].y,pmv[3].x,pmv[3].y,  
                 psad[1],psad[2],psad[3]);  
 */  
1434          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1435                  threshA = 512;                  threshA = 512;
1436                  threshB = 1024;                  threshB = 1024;
# Line 1179  Line 1454 
1454     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1455  */  */
1456    
1457          *currMV = pmv[0];                       /* current best := prediction */          currMV->x = start_x;
1458            currMV->y = start_y;
1459    
1460          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
1461                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1462                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1203  Line 1480 
1480                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1481                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1482          iMinSAD +=          iMinSAD +=
1483                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
1484                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
1485    
1486          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 1340  Line 1617 
1617          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
1618    
1619    
 //      fprintf(stderr,"Entering Diamond %d %d (%d):\n",x,y,iMinSAD);  
   
1620  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1621          iSAD =          iSAD =
1622                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1623                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y,
1624                                                      min_dx, max_dx,
1625                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1626                                                    iQuant, iFound);                                                    iQuant, iFound);
1627    
# Line 1360  Line 1636 
1636                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1637                          iSAD =                          iSAD =
1638                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1639                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    center_x, center_y, iMinSAD, &newMV, center_x, center_y,
1640                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1641                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1642    
# Line 1373  Line 1649 
1649                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1650                          iSAD =                          iSAD =
1651                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1652                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y,
1653                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    min_dx, max_dx, min_dy, max_dy,
1654                                                                      iEdgedWidth, iDiamondSize, iFcode,
1655                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1656    
1657                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 1392  Line 1669 
1669          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
1670                  iMinSAD =                  iMinSAD =
1671                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1672                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1673                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1674    
 /*fprintf(stderr,"Chosen for %d %d: %d %d - %d %d\n",x,y,currMV->x,currMV->y,pmv[0].x,pmv[0].y);  
 */  
1675    PMVfast16_Terminate_without_Refine:    PMVfast16_Terminate_without_Refine:
1676          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
1677          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
1678          return iMinSAD;          return iMinSAD;
1679  }  }
1680    
# Line 1416  Line 1691 
1691                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1692                                          const int x,                                          const int x,
1693                                          const int y,                                          const int y,
1694                                          int32_t startx,                                          int32_t start_x,
1695                                          int32_t starty,                                          int32_t start_y,
1696                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1697                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1698                                          const VECTOR * const pmv,                                     const int center_x,
1699                                       const int center_y,
1700                                          const int32_t min_dx,                                          const int32_t min_dx,
1701                                          const int32_t max_dx,                                          const int32_t max_dx,
1702                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 1434  Line 1710 
1710  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
1711    
1712          int32_t iDirection = 0;          int32_t iDirection = 0;
1713            int32_t iDirectionBackup;
1714          int32_t iSAD;          int32_t iSAD;
1715          VECTOR backupMV;          VECTOR backupMV;
1716    
1717          backupMV.x = startx;          backupMV.x = start_x;
1718          backupMV.y = starty;          backupMV.y = start_y;
1719    
1720  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1721    
# Line 1447  Line 1724 
1724          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1725          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1726    
1727          if (iDirection)          if (iDirection) {
1728                  while (!iFound) {                  while (!iFound) {
1729                          iFound = 1;                          iFound = 1;
1730                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     // since iDirection!=0, this is well defined!
1731                            iDirectionBackup = iDirection;
1732    
1733                          if (iDirection != 2)                          if (iDirectionBackup != 2)
1734                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1735                                                                                    backupMV.y, 1);                                                                                    backupMV.y, 1);
1736                          if (iDirection != 1)                          if (iDirectionBackup != 1)
1737                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1738                                                                                    backupMV.y, 2);                                                                                    backupMV.y, 2);
1739                          if (iDirection != 4)                          if (iDirectionBackup != 4)
1740                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1741                                                                                    backupMV.y - iDiamondSize, 3);                                                                                    backupMV.y - iDiamondSize, 3);
1742                          if (iDirection != 3)                          if (iDirectionBackup != 3)
1743                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1744                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1745                    }
1746          } else {          } else {
1747                  currMV->x = startx;                  currMV->x = start_x;
1748                  currMV->y = starty;                  currMV->y = start_y;
1749          }          }
1750          return iMinSAD;          return iMinSAD;
1751  }  }
1752    
1753    
1754    
1755    
1756    int32_t
1757    Square8_MainSearch(const uint8_t * const pRef,
1758                                            const uint8_t * const pRefH,
1759                                            const uint8_t * const pRefV,
1760                                            const uint8_t * const pRefHV,
1761                                            const uint8_t * const cur,
1762                                            const int x,
1763                                            const int y,
1764                                            int32_t start_x,
1765                                            int32_t start_y,
1766                                            int32_t iMinSAD,
1767                                            VECTOR * const currMV,
1768                                       const int center_x,
1769                                       const int center_y,
1770                                            const int32_t min_dx,
1771                                            const int32_t max_dx,
1772                                            const int32_t min_dy,
1773                                            const int32_t max_dy,
1774                                            const int32_t iEdgedWidth,
1775                                            const int32_t iDiamondSize,
1776                                            const int32_t iFcode,
1777                                            const int32_t iQuant,
1778                                            int iFound)
1779    {
1780    /* Do a square search around given starting point, return SAD of best */
1781    
1782            int32_t iDirection = 0;
1783            int32_t iSAD;
1784            VECTOR backupMV;
1785    
1786            backupMV.x = start_x;
1787            backupMV.y = start_y;
1788    
1789    /* It's one search with full square pattern, and new parts for all following diamonds */
1790    
1791    /*   new direction are extra, so 1-4 is normal diamond
1792          537
1793          1*2
1794          648
1795    */
1796    
1797            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1798            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1799            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1800            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1801    
1802            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1803                                                             backupMV.y - iDiamondSize, 5);
1804            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1805                                                             backupMV.y + iDiamondSize, 6);
1806            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1807                                                             backupMV.y - iDiamondSize, 7);
1808            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1809                                                             backupMV.y + iDiamondSize, 8);
1810    
1811    
1812            if (iDirection) {
1813                    while (!iFound) {
1814                            iFound = 1;
1815                            backupMV = *currMV;
1816    
1817                            switch (iDirection) {
1818                            case 1:
1819                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1820                                                                                       backupMV.y, 1);
1821                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1822                                                                                     backupMV.y - iDiamondSize, 5);
1823                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1824                                                                                     backupMV.y - iDiamondSize, 7);
1825                                    break;
1826                            case 2:
1827                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1828                                                                                     2);
1829                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1830                                                                                     backupMV.y + iDiamondSize, 6);
1831                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1832                                                                                     backupMV.y + iDiamondSize, 8);
1833                                    break;
1834    
1835                            case 3:
1836                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1837                                                                                     4);
1838                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1839                                                                                     backupMV.y - iDiamondSize, 7);
1840                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1841                                                                                     backupMV.y + iDiamondSize, 8);
1842                                    break;
1843    
1844                            case 4:
1845                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1846                                                                                     3);
1847                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1848                                                                                     backupMV.y - iDiamondSize, 5);
1849                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1850                                                                                     backupMV.y + iDiamondSize, 6);
1851                                    break;
1852    
1853                            case 5:
1854                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1855                                                                                     1);
1856                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1857                                                                                     3);
1858                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1859                                                                                     backupMV.y - iDiamondSize, 5);
1860                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1861                                                                                     backupMV.y + iDiamondSize, 6);
1862                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1863                                                                                     backupMV.y - iDiamondSize, 7);
1864                                    break;
1865    
1866                            case 6:
1867                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1868                                                                                     2);
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1870                                                                                     3);
1871    
1872                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1873                                                                                     backupMV.y - iDiamondSize, 5);
1874                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1875                                                                                     backupMV.y + iDiamondSize, 6);
1876                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1877                                                                                     backupMV.y + iDiamondSize, 8);
1878    
1879                                    break;
1880    
1881                            case 7:
1882                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1883                                                                                       backupMV.y, 1);
1884                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1885                                                                                     4);
1886                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1887                                                                                     backupMV.y - iDiamondSize, 5);
1888                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1889                                                                                     backupMV.y - iDiamondSize, 7);
1890                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1891                                                                                     backupMV.y + iDiamondSize, 8);
1892                                    break;
1893    
1894                            case 8:
1895                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1896                                                                                     2);
1897                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1898                                                                                     4);
1899                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1900                                                                                     backupMV.y + iDiamondSize, 6);
1901                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1902                                                                                     backupMV.y - iDiamondSize, 7);
1903                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1904                                                                                     backupMV.y + iDiamondSize, 8);
1905                                    break;
1906                            default:
1907                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1908                                                                                     1);
1909                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1910                                                                                     2);
1911                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1912                                                                                     3);
1913                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1914                                                                                     4);
1915    
1916                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1917                                                                                     backupMV.y - iDiamondSize, 5);
1918                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1919                                                                                     backupMV.y + iDiamondSize, 6);
1920                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1921                                                                                     backupMV.y - iDiamondSize, 7);
1922                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1923                                                                                     backupMV.y + iDiamondSize, 8);
1924                                    break;
1925                            }
1926                    }
1927            } else {
1928                    currMV->x = start_x;
1929                    currMV->y = start_y;
1930            }
1931            return iMinSAD;
1932    }
1933    
1934    
1935    
1936    
1937    
1938  int32_t  int32_t
1939  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1940                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1481  Line 1945 
1945                                  const int y,                                  const int y,
1946                                  VECTOR * const currMV,                                  VECTOR * const currMV,
1947                                  int32_t iMinSAD,                                  int32_t iMinSAD,
1948                                  const VECTOR * const pmv,                             const int center_x,
1949                               const int center_y,
1950                                  const int32_t min_dx,                                  const int32_t min_dx,
1951                                  const int32_t max_dx,                                  const int32_t max_dx,
1952                                  const int32_t min_dy,                                  const int32_t min_dy,
# Line 1520  Line 1985 
1985                             const int y,                             const int y,
1986                             const int start_x,                             const int start_x,
1987                             const int start_y,                             const int start_y,
1988                                    const int center_x,
1989                                    const int center_y,
1990                             const uint32_t MotionFlags,                             const uint32_t MotionFlags,
1991                             const uint32_t iQuant,                             const uint32_t iQuant,
1992                             const uint32_t iFcode,                             const uint32_t iFcode,
# Line 1584  Line 2051 
2051                  threshB = 1024 / 4;                  threshB = 1024 / 4;
2052    
2053          } else {          } else {
2054                  threshA = psad[0] / 4;  /* good estimate */                  threshA = psad[0] / 4;  /* good estimate? */
2055                  threshB = threshA + 256 / 4;                  threshB = threshA + 256 / 4;
2056                  if (threshA < 512 / 4)                  if (threshA < 512 / 4)
2057                          threshA = 512 / 4;                          threshA = 512 / 4;
# Line 1606  Line 2073 
2073    
2074  // Prepare for main loop  // Prepare for main loop
2075    
2076  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2077  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2078  //  else    else
2079    
2080          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2081                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 1623  Line 2090 
2090                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2091                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
2092          iMinSAD +=          iMinSAD +=
2093                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2094                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2095    
2096          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
# Line 1666  Line 2133 
2133  // the median prediction might be even better than mv16  // the median prediction might be even better than mv16
2134    
2135          if (!MVequal(pmv[0], startMV))          if (!MVequal(pmv[0], startMV))
2136                  CHECK_MV8_CANDIDATE(pmv[0].x, pmv[0].y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
2137    
2138  // (0,0) if needed  // (0,0) if needed
2139          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
# Line 1763  Line 2230 
2230  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2231          iSAD =          iSAD =
2232                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2233                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2234                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2235                                                    iQuant, iFound);                                                    iQuant, iFound);
2236    
# Line 1778  Line 2245 
2245                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2246                          iSAD =                          iSAD =
2247                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2248                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2249                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2250                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
2251    
# Line 1791  Line 2258 
2258                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2259                          iSAD =                          iSAD =
2260                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2261                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2262                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2263                                                                    iQuant, iFound);                                                                    iQuant, iFound);
2264    
# Line 1810  Line 2277 
2277          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2278                  iMinSAD =                  iMinSAD =
2279                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2280                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2281                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2282    
2283    
2284    PMVfast8_Terminate_without_Refine:    PMVfast8_Terminate_without_Refine:
2285          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2286          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2287    
2288          return iMinSAD;          return iMinSAD;
2289  }  }
# Line 1829  Line 2296 
2296                           const IMAGE * const pCur,                           const IMAGE * const pCur,
2297                           const int x,                           const int x,
2298                           const int y,                           const int y,
2299                            const int start_x,
2300                            const int start_y,
2301                            const int center_x,
2302                            const int center_y,
2303                           const uint32_t MotionFlags,                           const uint32_t MotionFlags,
2304                           const uint32_t iQuant,                           const uint32_t iQuant,
2305                           const uint32_t iFcode,                           const uint32_t iFcode,
# Line 1899  Line 2370 
2370    
2371  // Prepare for main loop  // Prepare for main loop
2372    
2373          *currMV = pmv[0];                       /* current best := median prediction */          currMV->x = start_x;
2374            currMV->y = start_y;
2375    
2376          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
2377                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2378                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1921  Line 2394 
2394                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2395                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2396          iMinSAD +=          iMinSAD +=
2397                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2398                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2399    
2400  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 2045  Line 2518 
2518    
2519          iSAD =          iSAD =
2520                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2521                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2522                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2523    
2524          if (iSAD < iMinSAD) {          if (iSAD < iMinSAD) {
# Line 2060  Line 2533 
2533                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2534                          iSAD =                          iSAD =
2535                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2536                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2537                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2538                                                                    2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2539                  }                  }
# Line 2073  Line 2546 
2546                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2547                          iSAD =                          iSAD =
2548                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2549                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2550                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2551    
2552                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 2089  Line 2562 
2562          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2563                  iMinSAD =                  iMinSAD =
2564                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2565                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2566                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2567    
2568    EPZS16_Terminate_without_Refine:    EPZS16_Terminate_without_Refine:
2569    
2570          *oldMB = *prevMB;          *oldMB = *prevMB;
2571    
2572          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2573          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2574          return iMinSAD;          return iMinSAD;
2575  }  }
2576    
# Line 2112  Line 2585 
2585                          const int y,                          const int y,
2586                          const int start_x,                          const int start_x,
2587                          const int start_y,                          const int start_y,
2588                            const int center_x,
2589                            const int center_y,
2590                          const uint32_t MotionFlags,                          const uint32_t MotionFlags,
2591                          const uint32_t iQuant,                          const uint32_t iQuant,
2592                          const uint32_t iFcode,                          const uint32_t iFcode,
# Line 2166  Line 2641 
2641                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2642          }          }
2643          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
2644          //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv[0].x, pmv[0].y, psad);
2645          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2646    
2647    
# Line 2202  Line 2677 
2677                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2678                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
2679          iMinSAD +=          iMinSAD +=
2680                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2681                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2682    
2683    
# Line 2278  Line 2753 
2753    
2754  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2755    
2756  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2757  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2758  //  else    else
2759    
2760          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2761                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2289  Line 2764 
2764    
2765          iSAD =          iSAD =
2766                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2767                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2768                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2769                                                    iQuant, 0);                                                    iQuant, 0);
2770    
# Line 2305  Line 2780 
2780                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2781                          iSAD =                          iSAD =
2782                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2783                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2784                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2785                                                                    iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2786    
# Line 2318  Line 2793 
2793                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2794                          iSAD =                          iSAD =
2795                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2796                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2797                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2798                                                                    iQuant, 0);                                                                    iQuant, 0);
2799    
# Line 2335  Line 2810 
2810          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2811                  iMinSAD =                  iMinSAD =
2812                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2813                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2814                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2815    
2816    EPZS8_Terminate_without_Refine:    EPZS8_Terminate_without_Refine:
2817    
2818          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2819          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2820          return iMinSAD;          return iMinSAD;
2821  }  }
2822    
# Line 2355  Line 2830 
2830                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2831                                  const int x,                                  const int x,
2832                                  const int y,                                  const int y,
2833                                    const int start_x,              /* start should be most likely vector */
2834                                    const int start_y,
2835                                    const int center_x,             /* center is from where length of MVs is measured */
2836                                    const int center_y,
2837                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2838                                  const uint32_t iQuant,                                  const uint32_t iQuant,
2839                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 2382  Line 2861 
2861          int32_t iFound;          int32_t iFound;
2862    
2863          VECTOR newMV;          VECTOR newMV;
2864          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2865    
2866          VECTOR pmv[4];          VECTOR pmv[4];
2867          int32_t psad[4];          int32_t psad[4];
# Line 2396  Line 2875 
2875          int32_t bPredEq;          int32_t bPredEq;
2876          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
2877    
2878    
2879  /* Get maximum range */  /* Get maximum range */
2880          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
2881                            iFcode);                            iFcode);
# Line 2411  Line 2891 
2891                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2892    
2893          } else {          } else {
2894    
2895                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2896    
2897                  threshA = psad[0];                  threshA = psad[0];
2898                  threshB = threshA + 256;                  threshB = threshA + 256;
2899                  if (threshA < 512)                  if (threshA < 512)
# Line 2420  Line 2903 
2903                  if (threshB > 1792)                  if (threshB > 1792)
2904                          threshB = 1792;                          threshB = 1792;
2905    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2906                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2907          }          }
2908    
# Line 2451  Line 2933 
2933                            get_iref_mv(pRef, x, y, 16, currMV,                            get_iref_mv(pRef, x, y, 16, currMV,
2934                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2935          iMinSAD +=          iMinSAD +=
2936                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2937                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2938    
2939          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 2570  Line 3052 
3052  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
3053          iSAD =          iSAD =
3054                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
3055                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
3056                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
3057                                                    iQuant, iFound);                                                    iQuant, iFound);
3058    
# Line 2585  Line 3067 
3067                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
3068                          iSAD =                          iSAD =
3069                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
3070                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
3071                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
3072                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
3073    
# Line 2598  Line 3080 
3080                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
3081                          iSAD =                          iSAD =
3082                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
3083                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
3084                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
3085                                                                    iQuant, iFound);                                                                    iQuant, iFound);
3086    
# Line 2621  Line 3103 
3103          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
3104                  iMinSAD =                  iMinSAD =
3105                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
3106                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
3107                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
3108    
3109          pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)          pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)
3110    
3111  PMVfastInt16_Terminate_without_Refine:  PMVfastInt16_Terminate_without_Refine:
3112          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
3113          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
3114          return iMinSAD;          return iMinSAD;
3115  }  }
3116    
# Line 2636  Line 3118 
3118    
3119  /* ***********************************************************  /* ***********************************************************
3120          bvop motion estimation          bvop motion estimation
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
3121  ***************************************************************/  ***************************************************************/
3122    
   
3123  void  void
3124  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3125                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
3126                                  //       const float scalefactor,                                           const int32_t time_bp,
3127                                             const int32_t time_pp,
3128                                           // forward (past) reference                                           // forward (past) reference
3129                                           const MACROBLOCK * const f_mbs,                                           const MACROBLOCK * const f_mbs,
3130                                           const IMAGE * const f_ref,                                           const IMAGE * const f_ref,
# Line 2661  Line 3142 
3142          const int mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3143          const int edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
3144    
3145          const float scalefactor=0.666;          const int32_t iWidth = pParam->width;
3146          int i, j;          const int32_t iHeight = pParam->height;
3147    
3148            int i, j, k;
3149    
3150  //      static const VECTOR zeroMV={0,0};          static const VECTOR zeroMV={0,0};
3151    
3152          int f_sad16;    /* forward (as usual) search */          int f_sad16;    /* forward (as usual) search */
3153          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
3154          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
3155          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume almost linear motion) */
3156    
3157          int best_sad;          int best_sad;
3158    
3159            VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3160            VECTOR f_interpolMV, b_interpolMV;
3161          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3162    
3163            int min_dx, max_dx, min_dy, max_dy;
3164            int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3165            int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3166    
3167          int f_count=0;          int f_count=0;
3168          int b_count=0;          int b_count=0;
3169          int i_count=0;          int i_count=0;
3170          int d_count=0;          int d_count=0;
         int dnv_count=0;  
         int s_count=0;  
3171    
3172            const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3173        const int64_t TRD = (int32_t)time_pp;
3174    
3175            // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);
3176          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
3177          for (j = 0; j < mb_height; j++) {          for (j = 0; j < mb_height; j++) {
3178    
3179                    f_predMV = zeroMV;      /* prediction is reset at left boundary */
3180                    b_predMV = zeroMV;
3181    
3182                  for (i = 0; i < mb_width; i++) {                  for (i = 0; i < mb_width; i++) {
3183                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];
3184                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
3185                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
3186    
3187                          VECTOR directMV=b_mb->mvs[0];           /* direct mode: presume linear motion */                          mb->deltamv=zeroMV;
3188    
3189  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  /* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */
3190    
3191                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3192                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3193                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
3194                                  mb->mvs[0].x = 0;                                  mb->b_mvs[0] = mb->mvs[0] = zeroMV;
                                 mb->mvs[0].y = 0;  
                                 mb->b_mvs[0].x = 0;  
                                 mb->b_mvs[0].y = 0;  
3195                                  continue;                                  continue;
3196                          }                          }
3197    
3198                          /* candidates for best MV assumes linear motion */                          if (b_mb->mode == MODE_INTER4V)
3199                          /* next vector is linearly scaled (factor depends on distance to that frame) */                          {
3200                                    d_sad16 = 0;
3201                          mb->mvs[0].x = (int)(directMV.x * scalefactor + 0.75);                          /* same method of scaling as in decoder.c, so we copy from there */
3202                          mb->mvs[0].y = (int)(directMV.y * scalefactor + 0.75);                      for (k = 0; k < 4; k++) {
3203    
3204                                            mb->directmv[k] = b_mb->mvs[k];
3205    
3206                                            mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3207                        mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3208                                                                                    ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3209                                                : mb->mvs[k].x - mb->directmv[k].x);
3210    
3211                        mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3212                            mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3213                                                                                    ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3214                                                : mb->mvs[k].y - mb->directmv[k].y);
3215    
3216                          mb->b_mvs[0].x = (int)(directMV.x * (scalefactor-1.) + 0.75); /* opposite direction! */                                          d_sad16 +=
3217                          mb->b_mvs[0].y = (int)(directMV.y * (scalefactor-1.) + 0.75);                                                  sad8bi(frame->image.y + (2*i+(k&1))*8 + (2*j+(k>>1))*8*edged_width,
3218                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3219                                                                    (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->mvs[k], edged_width),
3220                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3221                                                                    (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
3222                                                      edged_width);
3223                                    }
3224                            }
3225                            else
3226                            {
3227                                    mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
3228                                            mb->directmv[0] = b_mb->mvs[0];
3229    
3230                          DEBUG2("last: ",f_mb->mvs[0].x,f_mb->mvs[0].y);                                  mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3231                          DEBUG2("next: ",b_mb->mvs[0].x,b_mb->mvs[0].y);                      mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3232                          DEBUG2("directF: ",mb->mvs[0].x,mb->mvs[0].y);                                                                          ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3233                          DEBUG2("directB: ",mb->b_mvs[0].x,mb->b_mvs[0].y);                                      : mb->mvs[0].x - mb->directmv[0].x);
3234    
3235                        mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3236                    mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3237                                                                            ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3238                                        : mb->mvs[0].y - mb->directmv[0].y);
3239    
3240                          d_sad16 =                                  d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
                                 sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
3241                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3242                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3243                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3244                                                                  i, j, 16, &mb->b_mvs[0], edged_width),                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
3245                                                    edged_width);                                                    edged_width);
3246    
3247                }
3248                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
3249    
3250                          // forward search                          // forward search
3251                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3252                                                  &frame->image, i, j, frame->motion_flags,                                                  &frame->image, i, j,
3253                                                    mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
3254                                                    f_predMV.x, f_predMV.y,                         /* center is f-prediction */
3255                                                    frame->motion_flags,
3256                                                  frame->quant, frame->fcode, pParam,                                                  frame->quant, frame->fcode, pParam,
3257                                                  f_mbs, f_mbs, /* todo */                                                  f_mbs, f_mbs,
3258                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv (why?)                                                  &mb->mvs[0], &pmv_dontcare);
3259    
3260    
3261                          // backward search                          // backward search
3262                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3263                                                  &frame->image, i, j, frame->motion_flags,                                                  &frame->image, i, j,
3264                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
3265                                                    b_predMV.x, b_predMV.y,                         /* center is b-prediction */
3266                                                    frame->motion_flags,
3267                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
3268                                                  b_mbs, b_mbs,   /* todo */                                                  b_mbs, b_mbs,
3269                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);
3270    
3271                          i_sad16 =                          i_sad16 =
3272                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3273                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3274                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3275                                                    get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3276                                                                  i, j, 16, -mb->b_mvs[0].x, -mb->b_mvs[0].y, edged_width),                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
3277                                                    edged_width);                                                    edged_width);
3278                        i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3279                                                                    frame->fcode, frame->quant);
3280                        i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3281                                                                    frame->bcode, frame->quant);
3282    
3283                            get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3284                              frame->fcode);
3285                            get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3286                              frame->bcode);
3287    
3288    /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3289       two values for everything, always one for backward and one for forward ME. Still, we don't gain
3290       much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3291       as "optimal". */
3292    
3293                            i_sad16 = Diamond16_InterpolMainSearch(
3294                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3295                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3296                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3297                                                    i, j,
3298                                                    mb->mvs[0].x, mb->mvs[0].y,
3299                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,
3300                                                    i_sad16,
3301                                                    &f_interpolMV, &b_interpolMV,
3302                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3303                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3304                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3305                                                    edged_width,  2,
3306                                                    frame->fcode, frame->bcode,frame->quant,0);
3307    
3308                            i_sad16 = Diamond16_InterpolMainSearch(
3309                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3310                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3311                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3312                                                    i, j,
3313                                                    f_interpolMV.x, f_interpolMV.y,
3314                                                    b_interpolMV.x, b_interpolMV.y,
3315                                                    i_sad16,
3316                                                    &f_interpolMV, &b_interpolMV,
3317                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3318                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3319                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3320                                                    edged_width,  1,
3321                                                    frame->fcode, frame->bcode,frame->quant,0);             // equiv to halfpel refine
3322    
3323    
3324    /*  DIRECT MODE DELTA VECTOR SEARCH.
3325        This has to be made more effective, but at the moment I'm happy it's running at all */
3326    
3327    /* There are two range restrictions for direct mode: deltaMV is limited to [-32,31] in halfpel units, and
3328       absolute vector must not lie outside of image dimensions. Constraint one is dealt with by CHECK_MV16_DIRECT
3329       and for constraint two we need distance to boundary. This is done by get_range very large fcode (hack!) */
3330    
3331                            get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3332    
3333                            d_sad16 = Diamond16_DirectMainSearch(
3334                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3335                                                    frame->image.y + i*16 + j*16*edged_width,
3336                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3337                                                    i, j,
3338                                                    TRB,TRD,
3339                                                    0,0,
3340                                                    d_sad16,
3341                                                    &mb->deltamv,
3342                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3343                                            min_dx, max_dx, min_dy, max_dy,
3344                                                    edged_width, 2, frame->quant, 0);
3345    
3346                            d_sad16 = Diamond16_DirectMainSearch(
3347                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3348                                                    frame->image.y + i*16 + j*16*edged_width,
3349                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3350                                                    i, j,
3351                                                    TRB,TRD,
3352                                                    mb->deltamv.x, mb->deltamv.y,
3353                                                    d_sad16,
3354                                                    &mb->deltamv,
3355                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3356                                            min_dx, max_dx, min_dy, max_dy,
3357                                                    edged_width, 1, frame->quant, 0);               // equiv to halfpel refine
3358    
                         // TODO: direct search  
                         // predictor + range of [-32,32]  
   
                         DEBUG2("f_MV: ",mb->mvs[0].x,mb->mvs[0].y);  
                         DEBUG2("b_MV: ",mb->b_mvs[0].x,mb->b_mvs[0].y);  
3359    
3360  /*                      fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, d_sad16 = %d\n",  //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3361                                  f_sad16,b_sad16,i_sad16,d_sad16);  //                      f_sad16 = 65535;
 */  
   
 //                      d_sad16 -= 50;  
 //                      d_sad16 = 65535;  
 //                      i_sad16 = 65535;  
3362  //                      b_sad16 = 65535;  //                      b_sad16 = 65535;
3363    //                      d_sad16 = 65535;
3364    
3365                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3366                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 2777  Line 3376 
3376                          }                          }
3377    
3378                          if (d_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3379    
3380                                    if (b_mb->mode == MODE_INTER4V)
3381                                    {
3382    
3383                                    /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */
3384                                    /* for the bitstream, the value mb->deltamv is read directly */
3385    
3386                                for (k = 0; k < 4; k++) {
3387    
3388                                                    mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3389                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3390                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3391                                                        : mb->mvs[k].x - mb->directmv[k].x);
3392    
3393                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3394                            mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3395                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3396                                                : mb->mvs[k].y - mb->directmv[k].y);
3397                                            }
3398                                    }
3399                                    else
3400                                    {
3401                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3402    
3403                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3404                                                                                    ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3405                                            : mb->mvs[0].x - mb->directmv[0].x);
3406    
3407                                mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3408    
3409                            mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3410                                                                                    ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3411                                                : mb->mvs[0].y - mb->directmv[0].y);
3412    
3413                                            mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3414                                            mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
3415                    }
3416    
3417                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3418                                  mb->mode = MODE_DIRECT_NONE_MV;                                  mb->mode = MODE_DIRECT;
3419                          }                          }
3420    
3421                          switch (mb->mode)                          switch (mb->mode)
3422                          {                          {
3423                                  case MODE_FORWARD:                                  case MODE_FORWARD:
3424                                          f_count++; break;                                          f_count++;
3425                                            f_predMV = mb->mvs[0];
3426                                            break;
3427                                  case MODE_BACKWARD:                                  case MODE_BACKWARD:
3428                                          b_count++; break;                                          b_count++;
3429                                            b_predMV = mb->b_mvs[0];
3430    
3431                                            break;
3432                                  case MODE_INTERPOLATE:                                  case MODE_INTERPOLATE:
3433                                          i_count++; break;                                          i_count++;
3434                                            mb->mvs[0] = f_interpolMV;
3435                                            mb->b_mvs[0] = b_interpolMV;
3436                                            f_predMV = mb->mvs[0];
3437                                            b_predMV = mb->b_mvs[0];
3438                                            break;
3439                                  case MODE_DIRECT:                                  case MODE_DIRECT:
3440                                          d_count++; break;                                          d_count++;
3441                                  case MODE_DIRECT_NONE_MV:                                          break;
                                         dnv_count++; break;  
3442                                  default:                                  default:
3443                                          s_count++; break;                                          break;
3444                          }                          }
3445    
3446                  }                  }
3447          }          }
3448    
3449  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3450          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D0: %04d   D: %04d   S: %04d\n",          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d\n",
3451                                  f_count,b_count,i_count,dnv_count,d_count,s_count);                                  f_count,b_count,i_count,d_count);
3452  #endif  #endif
3453    
3454  }  }

Legend:
Removed from v.312  
changed lines
  Added in v.370

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