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

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

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

revision 300, Tue Jul 16 12:02:27 2002 UTC revision 345, Sat Jul 27 23:47:01 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                            predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
190    
191                          pMB->sad16 =                          pMB->sad16 =
192                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
193                                                   y, current->motion_flags, current->quant,                                                   x, y, predMV.x, predMV.y, predMV.x, predMV.y,
194                                                     current->motion_flags, current->quant,
195                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,
196                                                   &pMB->pmvs[0]);                                                   &pMB->pmvs[0]);
197    
# Line 219  Line 223 
223                                           pMB->dquant == NO_CHANGE)) {                                           pMB->dquant == NO_CHANGE)) {
224                                          int32_t sad8 = IMV16X16 * current->quant;                                          int32_t sad8 = IMV16X16 * current->quant;
225    
226                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
   
227                                                  sad8 += pMB->sad8[0] =                                                  sad8 += pMB->sad8[0] =
228                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
229                                                                          pCurrent, 2 * x, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y,
230                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
231                                                                            current->motion_flags,
232                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
233                                                                          pMBs, prevMBs, &pMB->mvs[0],                                                                          pMBs, prevMBs, &pMB->mvs[0],
234                                                                          &pMB->pmvs[0]);                                                                          &pMB->pmvs[0]);
235                                            }
236                                            if (sad8 < pMB->sad16) {
237    
238                                          if (sad8 < pMB->sad16)                                                  predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 1);
239                                                  sad8 += pMB->sad8[1] =                                                  sad8 += pMB->sad8[1] =
240                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
241                                                                          pCurrent, 2 * x + 1, 2 * y, pMB->mv16.x,                                                                          pCurrent, 2 * x + 1, 2 * y,
242                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
243                                                                            current->motion_flags,
244                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
245                                                                          pMBs, prevMBs, &pMB->mvs[1],                                                                          pMBs, prevMBs, &pMB->mvs[1],
246                                                                          &pMB->pmvs[1]);                                                                          &pMB->pmvs[1]);
247                                            }
248                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
249                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 2);
250                                                  sad8 += pMB->sad8[2] =                                                  sad8 += pMB->sad8[2] =
251                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
252                                                                          pCurrent, 2 * x, 2 * y + 1, pMB->mv16.x,                                                                          pCurrent, 2 * x, 2 * y + 1,
253                                                                          pMB->mv16.y, current->motion_flags,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
254                                                                            current->motion_flags,
255                                                                          current->quant, current->fcode, pParam,                                                                          current->quant, current->fcode, pParam,
256                                                                          pMBs, prevMBs, &pMB->mvs[2],                                                                          pMBs, prevMBs, &pMB->mvs[2],
257                                                                          &pMB->pmvs[2]);                                                                          &pMB->pmvs[2]);
258                                            }
259                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
260                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 3);
261                                                  sad8 += pMB->sad8[3] =                                                  sad8 += pMB->sad8[3] =
262                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
263                                                                          pCurrent, 2 * x + 1, 2 * y + 1,                                                                          pCurrent, 2 * x + 1, 2 * y + 1,
264                                                                          pMB->mv16.x, pMB->mv16.y,                                                                          pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
265                                                                          current->motion_flags, current->quant,                                                                          current->motion_flags,
266                                                                          current->fcode, pParam, pMBs, prevMBs,                                                                          current->quant, current->fcode, pParam,
267                                                                          &pMB->mvs[3], &pMB->pmvs[3]);                                                                          pMBs, prevMBs,
268                                                                            &pMB->mvs[3],
269                                                                            &pMB->pmvs[3]);
270                                            }
271    
272                                          /* decide: MODE_INTER or MODE_INTER4V                                          /* decide: MODE_INTER or MODE_INTER4V
273                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
# Line 282  Line 295 
295          return 0;          return 0;
296  }  }
297    
298    
299  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
300    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
301      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
302    { \    { \
303      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); \
304      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);\
305      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
306      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
307  }  }
308    
309  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
310      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); \
311      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);\
312      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
313      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
314  }  }
# Line 304  Line 318 
318      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
319    { \    { \
320      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); \
321      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);\
322      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
323      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
324  }  }
# Line 314  Line 328 
328      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
329    { \    { \
330      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); \
331      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);\
332      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
333      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
334  }  }
# Line 324  Line 338 
338      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
339    { \    { \
340      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); \
341      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);\
342      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
343      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
344  }  }
# Line 332  Line 346 
346    
347  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
348    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); \
349    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);\
350    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
351    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
352  }  }
# Line 340  Line 354 
354  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
355    { \    { \
356      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); \
357      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);\
358      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
359      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
360  }  }
# Line 350  Line 364 
364      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
365    { \    { \
366      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); \
367      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);\
368      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
369      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
370  }  }
# Line 360  Line 374 
374      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
375    { \    { \
376      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); \
377      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);\
378      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
379      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
380  }  }
# Line 370  Line 384 
384      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
385    { \    { \
386      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); \
387      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);\
388      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
389      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
390  }  }
# Line 425  Line 439 
439                                           const uint8_t * const cur,                                           const uint8_t * const cur,
440                                           const int x,                                           const int x,
441                                           const int y,                                           const int y,
442                                           int32_t startx,                                     const int start_x,
443                                           int32_t starty,                                     const int start_y,
444                                           int32_t iMinSAD,                                     int iMinSAD,
445                                           VECTOR * const currMV,                                           VECTOR * const currMV,
446                                           const VECTOR * const pmv,                                     const int center_x,
447                                       const int center_y,
448                                           const int32_t min_dx,                                           const int32_t min_dx,
449                                           const int32_t max_dx,                                           const int32_t max_dx,
450                                           const int32_t min_dy,                                           const int32_t min_dy,
# Line 443  Line 458 
458  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
459    
460          int32_t iDirection = 0;          int32_t iDirection = 0;
461            int32_t iDirectionBackup;
462          int32_t iSAD;          int32_t iSAD;
463          VECTOR backupMV;          VECTOR backupMV;
464    
465          backupMV.x = startx;          backupMV.x = start_x;
466          backupMV.y = starty;          backupMV.y = start_y;
467    
468  /* 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 */
469    
# Line 456  Line 472 
472          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
473          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
474    
475          if (iDirection)          if (iDirection) {
476                  while (!iFound) {                  while (!iFound) {
477                          iFound = 1;                          iFound = 1;
478                          backupMV = *currMV;                          backupMV = *currMV;
479                            iDirectionBackup = iDirection;
480    
481                          if (iDirection != 2)                          if (iDirectionBackup != 2)
482                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
483                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
484                          if (iDirection != 1)                          if (iDirectionBackup != 1)
485                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
486                                                                                     backupMV.y, 2);                                                                                     backupMV.y, 2);
487                          if (iDirection != 4)                          if (iDirectionBackup != 4)
488                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
489                                                                                     backupMV.y - iDiamondSize, 3);                                                                                     backupMV.y - iDiamondSize, 3);
490                          if (iDirection != 3)                          if (iDirectionBackup != 3)
491                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
492                                                                                     backupMV.y + iDiamondSize, 4);                                                                                     backupMV.y + iDiamondSize, 4);
493                    }
494          } else {          } else {
495                  currMV->x = startx;                  currMV->x = start_x;
496                  currMV->y = starty;                  currMV->y = start_y;
497          }          }
498          return iMinSAD;          return iMinSAD;
499  }  }
# Line 488  Line 506 
506                                          const uint8_t * const cur,                                          const uint8_t * const cur,
507                                          const int x,                                          const int x,
508                                          const int y,                                          const int y,
509                                          int32_t startx,                                     const int start_x,
510                                          int32_t starty,                                     const int start_y,
511                                          int32_t iMinSAD,                                     int iMinSAD,
512                                          VECTOR * const currMV,                                          VECTOR * const currMV,
513                                          const VECTOR * const pmv,                                     const int center_x,
514                                       const int center_y,
515                                          const int32_t min_dx,                                          const int32_t min_dx,
516                                          const int32_t max_dx,                                          const int32_t max_dx,
517                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 509  Line 528 
528          int32_t iSAD;          int32_t iSAD;
529          VECTOR backupMV;          VECTOR backupMV;
530    
531          backupMV.x = startx;          backupMV.x = start_x;
532          backupMV.y = starty;          backupMV.y = start_y;
533    
534  /* 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 */
535    
# Line 535  Line 554 
554                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
555    
556    
557          if (iDirection)          if (iDirection) {
558                  while (!iFound) {                  while (!iFound) {
559                          iFound = 1;                          iFound = 1;
560                          backupMV = *currMV;                          backupMV = *currMV;
# Line 544  Line 563 
563                          case 1:                          case 1:
564                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
565                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
566                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
567                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
568                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
569                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
570                                  break;                                  break;
571                          case 2:                          case 2:
572                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
573                                                                                   2);                                                                                   2);
574                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
575                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
576                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
577                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
578                                  break;                                  break;
579    
580                          case 3:                          case 3:
581                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
582                                                                                   4);                                                                                   4);
583                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
584                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
585                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
586                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
587                                  break;                                  break;
588    
589                          case 4:                          case 4:
590                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
591                                                                                   3);                                                                                   3);
592                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
593                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
594                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
595                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
596                                  break;                                  break;
597    
598                          case 5:                          case 5:
599                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
600                                                                                   1);                                                                                   1);
601                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
602                                                                                   3);                                                                                   3);
603                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
604                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
605                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
606                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
607                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
608                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
609                                  break;                                  break;
610    
611                          case 6:                          case 6:
612                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
613                                                                                   2);                                                                                   2);
614                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
615                                                                                   3);                                                                                   3);
616    
617                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
618                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
619                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
620                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
621                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
622                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
623    
624                                  break;                                  break;
# Line 607  Line 626 
626                          case 7:                          case 7:
627                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
628                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
629                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
630                                                                                   4);                                                                                   4);
631                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
632                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
633                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
634                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
635                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
636                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
637                                  break;                                  break;
638    
639                          case 8:                          case 8:
640                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
641                                                                                   2);                                                                                   2);
642                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
643                                                                                   4);                                                                                   4);
644                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
645                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
646                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
647                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
648                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
649                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
650                                  break;                                  break;
651                          default:                          default:
652                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
653                                                                                   1);                                                                                   1);
654                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
655                                                                                   2);                                                                                   2);
656                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
657                                                                                   3);                                                                                   3);
658                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
659                                                                                   4);                                                                                   4);
660    
661                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
662                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
663                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
664                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
665                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
666                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
667                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
668                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
669                                  break;                                  break;
670                          }                          }
671                    }
672          } else {          } else {
673                  currMV->x = startx;                  currMV->x = start_x;
674                  currMV->y = starty;                  currMV->y = start_y;
675          }          }
676          return iMinSAD;          return iMinSAD;
677  }  }
# Line 665  Line 685 
685                                    const uint8_t * const cur,                                    const uint8_t * const cur,
686                                    const int x,                                    const int x,
687                                    const int y,                                    const int y,
688                                    int32_t startx,                                     const int start_x,
689                                    int32_t starty,                                     const int start_y,
690                                    int32_t iMinSAD,                                     int iMinSAD,
691                                    VECTOR * const currMV,                                    VECTOR * const currMV,
692                                    const VECTOR * const pmv,                                     const int center_x,
693                                       const int center_y,
694                                    const int32_t min_dx,                                    const int32_t min_dx,
695                                    const int32_t max_dx,                                    const int32_t max_dx,
696                                    const int32_t min_dy,                                    const int32_t min_dy,
# Line 684  Line 705 
705          int32_t dx, dy;          int32_t dx, dy;
706          VECTOR backupMV;          VECTOR backupMV;
707    
708          backupMV.x = startx;          backupMV.x = start_x;
709          backupMV.y = starty;          backupMV.y = start_y;
710    
711          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
712                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 702  Line 723 
723                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
724                                                  const int x,                                                  const int x,
725                                                  const int y,                                                  const int y,
726                                                  int32_t startx,                                             int start_x,
727                                                  int32_t starty,                                             int start_y,
728                                                  int32_t iMinSAD,                                             int iMinSAD,
729                                                  VECTOR * const currMV,                                                  VECTOR * const currMV,
730                                                  const VECTOR * const pmv,                                             const int center_x,
731                                               const int center_y,
732                                                  const int32_t min_dx,                                                  const int32_t min_dx,
733                                                  const int32_t max_dx,                                                  const int32_t max_dx,
734                                                  const int32_t min_dy,                                                  const int32_t min_dy,
# Line 723  Line 745 
745  /* 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) */
746    
747          if (iDirection) {          if (iDirection) {
748                  CHECK_MV16_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y);
749                  CHECK_MV16_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y);
750                  CHECK_MV16_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize);
751                  CHECK_MV16_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize);
752          } else {          } else {
753                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
754    
755                  do {                  do {
756                          iDirection = 0;                          iDirection = 0;
757                          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)
758                                  CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
759    
760                          if (bDirection & 2)                          if (bDirection & 2)
761                                  CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
762    
763                          if (bDirection & 4)                          if (bDirection & 4)
764                                  CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
765    
766                          if (bDirection & 8)                          if (bDirection & 8)
767                                  CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
768    
769                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
770    
# Line 750  Line 772 
772                          {                          {
773                                  bDirection = iDirection;                                  bDirection = iDirection;
774                                  iDirection = 0;                                  iDirection = 0;
775                                  startx = currMV->x;                                  start_x = currMV->x;
776                                  starty = currMV->y;                                  start_y = currMV->y;
777                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
778                                  {                                  {
779                                          CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
780                                          CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
781                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
782                                  {                                  {
783                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
784                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
785                                  }                                  }
786    
787                                  if (iDirection) {                                  if (iDirection) {
788                                          bDirection += iDirection;                                          bDirection += iDirection;
789                                          startx = currMV->x;                                          start_x = currMV->x;
790                                          starty = currMV->y;                                          start_y = currMV->y;
791                                  }                                  }
792                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
793                          {                          {
794                                  switch (bDirection) {                                  switch (bDirection) {
795                                  case 2:                                  case 2:
796                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
797                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
798                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
799                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
800                                          break;                                          break;
801                                  case 1:                                  case 1:
802                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,  
803                                                                                           starty - iDiamondSize, 1 + 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
804                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                                                                           start_y - iDiamondSize, 1 + 4);
805                                                                                           starty + iDiamondSize, 1 + 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
806                                                                                             start_y + iDiamondSize, 1 + 8);
807                                          break;                                          break;
808                                  case 2 + 4:                                  case 2 + 4:
809                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
810                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
811                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
812                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
813                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
814                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
815                                          break;                                          break;
816                                  case 4:                                  case 4:
817                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
818                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
819                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
820                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
821                                          break;                                          break;
822                                  case 8:                                  case 8:
823                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
824                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
825                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
826                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
827                                          break;                                          break;
828                                  case 1 + 4:                                  case 1 + 4:
829                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
830                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
831                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
832                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
833                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
834                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
835                                          break;                                          break;
836                                  case 2 + 8:                                  case 2 + 8:
837                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
838                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
839                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
840                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
841                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
842                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
843                                          break;                                          break;
844                                  case 1 + 8:                                  case 1 + 8:
845                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
846                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
847                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
848                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
849                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
850                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
851                                          break;                                          break;
852                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
853                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
854                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
855                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
856                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
857                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
858                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
859                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
860                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
861                                          break;                                          break;
862                                  }                                  }
863                                  if (!iDirection)                                  if (!iDirection)
864                                          break;          //ok, the end. really                                          break;          //ok, the end. really
865                                  else {                                  else {
866                                          bDirection = iDirection;                                          bDirection = iDirection;
867                                          startx = currMV->x;                                          start_x = currMV->x;
868                                          starty = currMV->y;                                          start_y = currMV->y;
869                                  }                                  }
870                          }                          }
871                  }                  }
# Line 851  Line 874 
874          return iMinSAD;          return iMinSAD;
875  }  }
876    
877    
878    #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \
879      if ( ((X) <= max_dx) && ((X) >= min_dx) \
880        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
881      { \
882        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
883        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
884        if (iSAD < iMinSAD) \
885        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
886    }
887    
888    #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \
889      if ( ((X) <= max_dx) && ((X) >= min_dx) \
890        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
891      { \
892        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
893        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
894        if (iSAD < iMinSAD) \
895        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
896    }
897    
898    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \
899      if ( ((X) <= max_dx) && ((X) >= min_dx) \
900        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
901      { \
902        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
903        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
904        if (iSAD < iMinSAD) \
905        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
906    }
907    
908    
909    #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \
910      if ( ((X) <= max_dx) && ((X) >= min_dx) \
911        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
912      { \
913        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
914        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
915        if (iSAD < iMinSAD) \
916        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
917    }
918    
919    
920    #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \
921      if ( ((X) <= max_dx) && ((X) >= min_dx) \
922        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
923      { \
924        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
925        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
926        if (iSAD < iMinSAD) \
927        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
928    }
929    
930    
931    #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \
932      if ( ((X) <= max_dx) && ((X) >= min_dx) \
933        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
934      { \
935        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
936        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
937        if (iSAD < iMinSAD) \
938        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
939    }
940    
941    
942    #if (0==1)
943    int32_t
944    Diamond16_InterpolMainSearch(
945                                            const uint8_t * const f_pRef,
946                                             const uint8_t * const f_pRefH,
947                                             const uint8_t * const f_pRefV,
948                                             const uint8_t * const f_pRefHV,
949                                             const uint8_t * const cur,
950    
951                                            const uint8_t * const b_pRef,
952                                             const uint8_t * const b_pRefH,
953                                             const uint8_t * const b_pRefV,
954                                             const uint8_t * const b_pRefHV,
955    
956                                             const int x,
957                                             const int y,
958    
959                                       const int f_start_x,
960                                       const int f_start_y,
961                                       const int b_start_x,
962                                       const int b_start_y,
963    
964                                       int iMinSAD,
965                                       VECTOR * const f_currMV,
966                                       VECTOR * const b_currMV,
967    
968                                       const int f_center_x,
969                                       const int f_center_y,
970                                       const int b_center_x,
971                                       const int b_center_y,
972    
973                                             const int32_t min_dx,
974                                             const int32_t max_dx,
975                                             const int32_t min_dy,
976                                             const int32_t max_dy,
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 f_iDirection = 0;
989            int32_t b_iDirection = 0;
990            int32_t iSAD;
991    
992            VECTOR f_backupMV;
993            VECTOR b_backupMV;
994    
995            f_backupMV.x = start_x;
996            f_backupMV.y = start_y;
997            b_backupMV.x = start_x;
998            b_backupMV.y = start_y;
999    
1000    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1001    
1002            CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1003            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1004            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1005            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1006    
1007            if (iDirection)
1008                    while (!iFound) {
1009                            iFound = 1;
1010                            backupMV = *currMV;
1011    
1012                            if (iDirection != 2)
1013                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1014                                                                                       backupMV.y, 1);
1015                            if (iDirection != 1)
1016                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1017                                                                                       backupMV.y, 2);
1018                            if (iDirection != 4)
1019                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1020                                                                                       backupMV.y - iDiamondSize, 3);
1021                            if (iDirection != 3)
1022                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1023                                                                                       backupMV.y + iDiamondSize, 4);
1024            } else {
1025                    currMV->x = start_x;
1026                    currMV->y = start_y;
1027            }
1028            return iMinSAD;
1029    }
1030    #endif
1031    
1032    
1033  int32_t  int32_t
1034  AdvDiamond8_MainSearch(const uint8_t * const pRef,  AdvDiamond8_MainSearch(const uint8_t * const pRef,
1035                                             const uint8_t * const pRefH,                                             const uint8_t * const pRefH,
# Line 859  Line 1038 
1038                                             const uint8_t * const cur,                                             const uint8_t * const cur,
1039                                             const int x,                                             const int x,
1040                                             const int y,                                             const int y,
1041                                             int32_t startx,                                             int start_x,
1042                                             int32_t starty,                                             int start_y,
1043                                             int32_t iMinSAD,                                             int iMinSAD,
1044                                             VECTOR * const currMV,                                             VECTOR * const currMV,
1045                                             const VECTOR * const pmv,                                             const int center_x,
1046                                               const int center_y,
1047                                             const int32_t min_dx,                                             const int32_t min_dx,
1048                                             const int32_t max_dx,                                             const int32_t max_dx,
1049                                             const int32_t min_dy,                                             const int32_t min_dy,
# Line 880  Line 1060 
1060  /* 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) */
1061    
1062          if (iDirection) {          if (iDirection) {
1063                  CHECK_MV8_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x - iDiamondSize, start_y);
1064                  CHECK_MV8_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x + iDiamondSize, start_y);
1065                  CHECK_MV8_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y - iDiamondSize);
1066                  CHECK_MV8_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y + iDiamondSize);
1067          } else {          } else {
1068                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
1069    
1070                  do {                  do {
1071                          iDirection = 0;                          iDirection = 0;
1072                          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)
1073                                  CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1074    
1075                          if (bDirection & 2)                          if (bDirection & 2)
1076                                  CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1077    
1078                          if (bDirection & 4)                          if (bDirection & 4)
1079                                  CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1080    
1081                          if (bDirection & 8)                          if (bDirection & 8)
1082                                  CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1083    
1084                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
1085    
# Line 907  Line 1087 
1087                          {                          {
1088                                  bDirection = iDirection;                                  bDirection = iDirection;
1089                                  iDirection = 0;                                  iDirection = 0;
1090                                  startx = currMV->x;                                  start_x = currMV->x;
1091                                  starty = currMV->y;                                  start_y = currMV->y;
1092                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
1093                                  {                                  {
1094                                          CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1095                                          CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1096                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
1097                                  {                                  {
1098                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1099                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1100                                  }                                  }
1101    
1102                                  if (iDirection) {                                  if (iDirection) {
1103                                          bDirection += iDirection;                                          bDirection += iDirection;
1104                                          startx = currMV->x;                                          start_x = currMV->x;
1105                                          starty = currMV->y;                                          start_y = currMV->y;
1106                                  }                                  }
1107                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
1108                          {                          {
1109                                  switch (bDirection) {                                  switch (bDirection) {
1110                                  case 2:                                  case 2:
1111                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1112                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1113                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1114                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1115                                          break;                                          break;
1116                                  case 1:                                  case 1:
1117                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1118                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1119                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1120                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1121                                          break;                                          break;
1122                                  case 2 + 4:                                  case 2 + 4:
1123                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1124                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1125                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1126                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1127                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1128                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1129                                          break;                                          break;
1130                                  case 4:                                  case 4:
1131                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1132                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1133                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1134                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1135                                          break;                                          break;
1136                                  case 8:                                  case 8:
1137                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1138                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1139                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1140                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1141                                          break;                                          break;
1142                                  case 1 + 4:                                  case 1 + 4:
1143                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1144                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1145                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1146                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1147                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1148                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1149                                          break;                                          break;
1150                                  case 2 + 8:                                  case 2 + 8:
1151                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1152                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1153                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1154                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1155                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1156                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1157                                          break;                                          break;
1158                                  case 1 + 8:                                  case 1 + 8:
1159                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1160                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1161                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1162                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1163                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1164                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1165                                          break;                                          break;
1166                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
1167                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1168                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1169                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1170                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1171                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1172                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1173                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1174                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1175                                          break;                                          break;
1176                                  }                                  }
1177                                  if (!(iDirection))                                  if (!(iDirection))
1178                                          break;          //ok, the end. really                                          break;          //ok, the end. really
1179                                  else {                                  else {
1180                                          bDirection = iDirection;                                          bDirection = iDirection;
1181                                          startx = currMV->x;                                          start_x = currMV->x;
1182                                          starty = currMV->y;                                          start_y = currMV->y;
1183                                  }                                  }
1184                          }                          }
1185                  }                  }
# Line 1017  Line 1197 
1197                                   const uint8_t * const cur,                                   const uint8_t * const cur,
1198                                   const int x,                                   const int x,
1199                                   const int y,                                   const int y,
1200                                   int32_t startx,                             const int start_x,
1201                                   int32_t starty,                             const int start_y,
1202                                   int32_t iMinSAD,                             int iMinSAD,
1203                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1204                                   const VECTOR * const pmv,                             const int center_x,
1205                               const int center_y,
1206                                   const int32_t min_dx,                                   const int32_t min_dx,
1207                                   const int32_t max_dx,                                   const int32_t max_dx,
1208                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1036  Line 1217 
1217          int32_t dx, dy;          int32_t dx, dy;
1218          VECTOR backupMV;          VECTOR backupMV;
1219    
1220          backupMV.x = startx;          backupMV.x = start_x;
1221          backupMV.y = starty;          backupMV.y = start_y;
1222    
1223          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
1224                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 1058  Line 1239 
1239                                   const int y,                                   const int y,
1240                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1241                                   int32_t iMinSAD,                                   int32_t iMinSAD,
1242                                   const VECTOR * const pmv,                             const int center_x,
1243                               const int center_y,
1244                                   const int32_t min_dx,                                   const int32_t min_dx,
1245                                   const int32_t max_dx,                                   const int32_t max_dx,
1246                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1087  Line 1269 
1269  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1270    
1271    
1272    
1273  int32_t  int32_t
1274  PMVfastSearch16(const uint8_t * const pRef,  PMVfastSearch16(const uint8_t * const pRef,
1275                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1095  Line 1278 
1278                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1279                                  const int x,                                  const int x,
1280                                  const int y,                                  const int y,
1281                                    const int start_x,
1282                                    const int start_y,
1283                                    const int center_x,
1284                                    const int center_y,
1285                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1286                                  const uint32_t iQuant,                                  const uint32_t iQuant,
1287                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 1151  Line 1338 
1338          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1339          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1340    
 /*      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]);  
 */  
1341          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1342                  threshA = 512;                  threshA = 512;
1343                  threshB = 1024;                  threshB = 1024;
# Line 1179  Line 1361 
1361     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1362  */  */
1363    
1364          *currMV = pmv[0];                       /* current best := prediction */          currMV->x = start_x;
1365            currMV->y = start_y;
1366    
1367          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
1368                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1369                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1203  Line 1387 
1387                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1388                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1389          iMinSAD +=          iMinSAD +=
1390                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
1391                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
1392    
1393          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 1340  Line 1524 
1524          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
1525    
1526    
 //      fprintf(stderr,"Entering Diamond %d %d (%d):\n",x,y,iMinSAD);  
   
1527  /* 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 */
1528          iSAD =          iSAD =
1529                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1530                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y,
1531                                                      min_dx, max_dx,
1532                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1533                                                    iQuant, iFound);                                                    iQuant, iFound);
1534    
# Line 1360  Line 1543 
1543                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1544                          iSAD =                          iSAD =
1545                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1546                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    center_x, center_y, iMinSAD, &newMV, center_x, center_y,
1547                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1548                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1549    
# Line 1373  Line 1556 
1556                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1557                          iSAD =                          iSAD =
1558                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1559                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y,
1560                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    min_dx, max_dx, min_dy, max_dy,
1561                                                                      iEdgedWidth, iDiamondSize, iFcode,
1562                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1563    
1564                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 1392  Line 1576 
1576          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
1577                  iMinSAD =                  iMinSAD =
1578                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1579                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1580                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1581    
 /*fprintf(stderr,"Chosen for %d %d: %d %d - %d %d\n",x,y,currMV->x,currMV->y,pmv[0].x,pmv[0].y);  
 */  
1582    PMVfast16_Terminate_without_Refine:    PMVfast16_Terminate_without_Refine:
1583          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
1584          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
1585          return iMinSAD;          return iMinSAD;
1586  }  }
1587    
# Line 1416  Line 1598 
1598                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1599                                          const int x,                                          const int x,
1600                                          const int y,                                          const int y,
1601                                          int32_t startx,                                          int32_t start_x,
1602                                          int32_t starty,                                          int32_t start_y,
1603                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1604                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1605                                          const VECTOR * const pmv,                                     const int center_x,
1606                                       const int center_y,
1607                                          const int32_t min_dx,                                          const int32_t min_dx,
1608                                          const int32_t max_dx,                                          const int32_t max_dx,
1609                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 1434  Line 1617 
1617  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
1618    
1619          int32_t iDirection = 0;          int32_t iDirection = 0;
1620            int32_t iDirectionBackup;
1621          int32_t iSAD;          int32_t iSAD;
1622          VECTOR backupMV;          VECTOR backupMV;
1623    
1624          backupMV.x = startx;          backupMV.x = start_x;
1625          backupMV.y = starty;          backupMV.y = start_y;
1626    
1627  /* 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 */
1628    
# Line 1447  Line 1631 
1631          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1632          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1633    
1634          if (iDirection)          if (iDirection) {
1635                  while (!iFound) {                  while (!iFound) {
1636                          iFound = 1;                          iFound = 1;
1637                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     // since iDirection!=0, this is well defined!
1638                            iDirectionBackup = iDirection;
1639    
1640                          if (iDirection != 2)                          if (iDirectionBackup != 2)
1641                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1642                                                                                    backupMV.y, 1);                                                                                    backupMV.y, 1);
1643                          if (iDirection != 1)                          if (iDirectionBackup != 1)
1644                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1645                                                                                    backupMV.y, 2);                                                                                    backupMV.y, 2);
1646                          if (iDirection != 4)                          if (iDirectionBackup != 4)
1647                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1648                                                                                    backupMV.y - iDiamondSize, 3);                                                                                    backupMV.y - iDiamondSize, 3);
1649                          if (iDirection != 3)                          if (iDirectionBackup != 3)
1650                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1651                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1652                    }
1653            } else {
1654                    currMV->x = start_x;
1655                    currMV->y = start_y;
1656            }
1657            return iMinSAD;
1658    }
1659    
1660    
1661    
1662    
1663    int32_t
1664    Square8_MainSearch(const uint8_t * const pRef,
1665                                            const uint8_t * const pRefH,
1666                                            const uint8_t * const pRefV,
1667                                            const uint8_t * const pRefHV,
1668                                            const uint8_t * const cur,
1669                                            const int x,
1670                                            const int y,
1671                                            int32_t start_x,
1672                                            int32_t start_y,
1673                                            int32_t iMinSAD,
1674                                            VECTOR * const currMV,
1675                                       const int center_x,
1676                                       const int center_y,
1677                                            const int32_t min_dx,
1678                                            const int32_t max_dx,
1679                                            const int32_t min_dy,
1680                                            const int32_t max_dy,
1681                                            const int32_t iEdgedWidth,
1682                                            const int32_t iDiamondSize,
1683                                            const int32_t iFcode,
1684                                            const int32_t iQuant,
1685                                            int iFound)
1686    {
1687    /* Do a square search around given starting point, return SAD of best */
1688    
1689            int32_t iDirection = 0;
1690            int32_t iSAD;
1691            VECTOR backupMV;
1692    
1693            backupMV.x = start_x;
1694            backupMV.y = start_y;
1695    
1696    /* It's one search with full square pattern, and new parts for all following diamonds */
1697    
1698    /*   new direction are extra, so 1-4 is normal diamond
1699          537
1700          1*2
1701          648
1702    */
1703    
1704            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1705            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1706            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1707            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1708    
1709            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1710                                                             backupMV.y - iDiamondSize, 5);
1711            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1712                                                             backupMV.y + iDiamondSize, 6);
1713            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1714                                                             backupMV.y - iDiamondSize, 7);
1715            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1716                                                             backupMV.y + iDiamondSize, 8);
1717    
1718    
1719            if (iDirection) {
1720                    while (!iFound) {
1721                            iFound = 1;
1722                            backupMV = *currMV;
1723    
1724                            switch (iDirection) {
1725                            case 1:
1726                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1727                                                                                       backupMV.y, 1);
1728                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1729                                                                                     backupMV.y - iDiamondSize, 5);
1730                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1731                                                                                     backupMV.y - iDiamondSize, 7);
1732                                    break;
1733                            case 2:
1734                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1735                                                                                     2);
1736                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1737                                                                                     backupMV.y + iDiamondSize, 6);
1738                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1739                                                                                     backupMV.y + iDiamondSize, 8);
1740                                    break;
1741    
1742                            case 3:
1743                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1744                                                                                     4);
1745                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1746                                                                                     backupMV.y - iDiamondSize, 7);
1747                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1748                                                                                     backupMV.y + iDiamondSize, 8);
1749                                    break;
1750    
1751                            case 4:
1752                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1753                                                                                     3);
1754                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1755                                                                                     backupMV.y - iDiamondSize, 5);
1756                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1757                                                                                     backupMV.y + iDiamondSize, 6);
1758                                    break;
1759    
1760                            case 5:
1761                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1762                                                                                     1);
1763                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1764                                                                                     3);
1765                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1766                                                                                     backupMV.y - iDiamondSize, 5);
1767                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1768                                                                                     backupMV.y + iDiamondSize, 6);
1769                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1770                                                                                     backupMV.y - iDiamondSize, 7);
1771                                    break;
1772    
1773                            case 6:
1774                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1775                                                                                     2);
1776                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1777                                                                                     3);
1778    
1779                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1780                                                                                     backupMV.y - iDiamondSize, 5);
1781                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1782                                                                                     backupMV.y + iDiamondSize, 6);
1783                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1784                                                                                     backupMV.y + iDiamondSize, 8);
1785    
1786                                    break;
1787    
1788                            case 7:
1789                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1790                                                                                       backupMV.y, 1);
1791                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1792                                                                                     4);
1793                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1794                                                                                     backupMV.y - iDiamondSize, 5);
1795                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1796                                                                                     backupMV.y - iDiamondSize, 7);
1797                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1798                                                                                     backupMV.y + iDiamondSize, 8);
1799                                    break;
1800    
1801                            case 8:
1802                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1803                                                                                     2);
1804                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1805                                                                                     4);
1806                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1807                                                                                     backupMV.y + iDiamondSize, 6);
1808                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1809                                                                                     backupMV.y - iDiamondSize, 7);
1810                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1811                                                                                     backupMV.y + iDiamondSize, 8);
1812                                    break;
1813                            default:
1814                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1815                                                                                     1);
1816                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1817                                                                                     2);
1818                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1819                                                                                     3);
1820                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1821                                                                                     4);
1822    
1823                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1824                                                                                     backupMV.y - iDiamondSize, 5);
1825                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1826                                                                                     backupMV.y + iDiamondSize, 6);
1827                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1828                                                                                     backupMV.y - iDiamondSize, 7);
1829                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1830                                                                                     backupMV.y + iDiamondSize, 8);
1831                                    break;
1832                            }
1833                    }
1834          } else {          } else {
1835                  currMV->x = startx;                  currMV->x = start_x;
1836                  currMV->y = starty;                  currMV->y = start_y;
1837          }          }
1838          return iMinSAD;          return iMinSAD;
1839  }  }
1840    
1841    
1842    
1843    
1844    
1845  int32_t  int32_t
1846  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1847                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1481  Line 1852 
1852                                  const int y,                                  const int y,
1853                                  VECTOR * const currMV,                                  VECTOR * const currMV,
1854                                  int32_t iMinSAD,                                  int32_t iMinSAD,
1855                                  const VECTOR * const pmv,                             const int center_x,
1856                               const int center_y,
1857                                  const int32_t min_dx,                                  const int32_t min_dx,
1858                                  const int32_t max_dx,                                  const int32_t max_dx,
1859                                  const int32_t min_dy,                                  const int32_t min_dy,
# Line 1520  Line 1892 
1892                             const int y,                             const int y,
1893                             const int start_x,                             const int start_x,
1894                             const int start_y,                             const int start_y,
1895                                    const int center_x,
1896                                    const int center_y,
1897                             const uint32_t MotionFlags,                             const uint32_t MotionFlags,
1898                             const uint32_t iQuant,                             const uint32_t iQuant,
1899                             const uint32_t iFcode,                             const uint32_t iFcode,
# Line 1584  Line 1958 
1958                  threshB = 1024 / 4;                  threshB = 1024 / 4;
1959    
1960          } else {          } else {
1961                  threshA = psad[0] / 4;  /* good estimate */                  threshA = psad[0] / 4;  /* good estimate? */
1962                  threshB = threshA + 256 / 4;                  threshB = threshA + 256 / 4;
1963                  if (threshA < 512 / 4)                  if (threshA < 512 / 4)
1964                          threshA = 512 / 4;                          threshA = 512 / 4;
# Line 1606  Line 1980 
1980    
1981  // Prepare for main loop  // Prepare for main loop
1982    
1983  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
1984  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
1985  //  else    else
1986    
1987          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1988                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 1623  Line 1997 
1997                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
1998                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
1999          iMinSAD +=          iMinSAD +=
2000                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2001                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2002    
2003          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
# Line 1666  Line 2040 
2040  // the median prediction might be even better than mv16  // the median prediction might be even better than mv16
2041    
2042          if (!MVequal(pmv[0], startMV))          if (!MVequal(pmv[0], startMV))
2043                  CHECK_MV8_CANDIDATE(pmv[0].x, pmv[0].y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
2044    
2045  // (0,0) if needed  // (0,0) if needed
2046          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
# Line 1763  Line 2137 
2137  /* 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 */
2138          iSAD =          iSAD =
2139                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2140                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2141                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2142                                                    iQuant, iFound);                                                    iQuant, iFound);
2143    
# Line 1778  Line 2152 
2152                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2153                          iSAD =                          iSAD =
2154                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2155                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2156                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2157                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
2158    
# Line 1791  Line 2165 
2165                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2166                          iSAD =                          iSAD =
2167                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2168                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2169                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2170                                                                    iQuant, iFound);                                                                    iQuant, iFound);
2171    
# Line 1810  Line 2184 
2184          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2185                  iMinSAD =                  iMinSAD =
2186                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2187                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2188                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2189    
2190    
2191    PMVfast8_Terminate_without_Refine:    PMVfast8_Terminate_without_Refine:
2192          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2193          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2194    
2195          return iMinSAD;          return iMinSAD;
2196  }  }
# Line 1829  Line 2203 
2203                           const IMAGE * const pCur,                           const IMAGE * const pCur,
2204                           const int x,                           const int x,
2205                           const int y,                           const int y,
2206                            const int start_x,
2207                            const int start_y,
2208                            const int center_x,
2209                            const int center_y,
2210                           const uint32_t MotionFlags,                           const uint32_t MotionFlags,
2211                           const uint32_t iQuant,                           const uint32_t iQuant,
2212                           const uint32_t iFcode,                           const uint32_t iFcode,
# Line 1899  Line 2277 
2277    
2278  // Prepare for main loop  // Prepare for main loop
2279    
2280          *currMV = pmv[0];                       /* current best := median prediction */          currMV->x = start_x;
2281            currMV->y = start_y;
2282    
2283          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
2284                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2285                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1921  Line 2301 
2301                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2302                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2303          iMinSAD +=          iMinSAD +=
2304                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2305                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2306    
2307  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 2045  Line 2425 
2425    
2426          iSAD =          iSAD =
2427                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2428                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2429                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2430    
2431          if (iSAD < iMinSAD) {          if (iSAD < iMinSAD) {
# Line 2060  Line 2440 
2440                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2441                          iSAD =                          iSAD =
2442                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2443                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2444                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2445                                                                    2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2446                  }                  }
# Line 2073  Line 2453 
2453                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2454                          iSAD =                          iSAD =
2455                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2456                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2457                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2458    
2459                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 2089  Line 2469 
2469          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2470                  iMinSAD =                  iMinSAD =
2471                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2472                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2473                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2474    
2475    EPZS16_Terminate_without_Refine:    EPZS16_Terminate_without_Refine:
2476    
2477          *oldMB = *prevMB;          *oldMB = *prevMB;
2478    
2479          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2480          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2481          return iMinSAD;          return iMinSAD;
2482  }  }
2483    
# Line 2112  Line 2492 
2492                          const int y,                          const int y,
2493                          const int start_x,                          const int start_x,
2494                          const int start_y,                          const int start_y,
2495                            const int center_x,
2496                            const int center_y,
2497                          const uint32_t MotionFlags,                          const uint32_t MotionFlags,
2498                          const uint32_t iQuant,                          const uint32_t iQuant,
2499                          const uint32_t iFcode,                          const uint32_t iFcode,
# Line 2166  Line 2548 
2548                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2549          }          }
2550          /* 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; */
2551          //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);
2552          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);
2553    
2554    
# Line 2202  Line 2584 
2584                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2585                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
2586          iMinSAD +=          iMinSAD +=
2587                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2588                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2589    
2590    
# Line 2278  Line 2660 
2660    
2661  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2662    
2663  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2664  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2665  //  else    else
2666    
2667          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2668                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2289  Line 2671 
2671    
2672          iSAD =          iSAD =
2673                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2674                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2675                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2676                                                    iQuant, 0);                                                    iQuant, 0);
2677    
# Line 2305  Line 2687 
2687                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2688                          iSAD =                          iSAD =
2689                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2690                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2691                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2692                                                                    iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2693    
# Line 2318  Line 2700 
2700                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2701                          iSAD =                          iSAD =
2702                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2703                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2704                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2705                                                                    iQuant, 0);                                                                    iQuant, 0);
2706    
# Line 2335  Line 2717 
2717          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2718                  iMinSAD =                  iMinSAD =
2719                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2720                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2721                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2722    
2723    EPZS8_Terminate_without_Refine:    EPZS8_Terminate_without_Refine:
2724    
2725          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2726          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2727          return iMinSAD;          return iMinSAD;
2728  }  }
2729    
# Line 2355  Line 2737 
2737                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2738                                  const int x,                                  const int x,
2739                                  const int y,                                  const int y,
2740                            const int start_x,
2741                            const int start_y,
2742                            const int center_x,
2743                            const int center_y,
2744                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2745                                  const uint32_t iQuant,                                  const uint32_t iQuant,
2746                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 2396  Line 2782 
2782          int32_t bPredEq;          int32_t bPredEq;
2783          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
2784    
2785    
2786  /* Get maximum range */  /* Get maximum range */
2787          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,
2788                            iFcode);                            iFcode);
# Line 2448  Line 2835 
2835    
2836          iMinSAD =          iMinSAD =
2837                  sad16(cur,                  sad16(cur,
2838                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_iref_mv(pRef, x, y, 16, currMV,
2839                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2840          iMinSAD +=          iMinSAD +=
2841                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2842                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2843    
2844          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 2570  Line 2957 
2957  /* 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 */
2958          iSAD =          iSAD =
2959                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2960                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2961                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2962                                                    iQuant, iFound);                                                    iQuant, iFound);
2963    
# Line 2585  Line 2972 
2972                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2973                          iSAD =                          iSAD =
2974                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2975                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2976                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2977                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
2978    
# Line 2598  Line 2985 
2985                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2986                          iSAD =                          iSAD =
2987                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2988                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2989                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2990                                                                    iQuant, iFound);                                                                    iQuant, iFound);
2991    
# Line 2621  Line 3008 
3008          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
3009                  iMinSAD =                  iMinSAD =
3010                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
3011                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
3012                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
3013    
3014          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)
3015    
3016  PMVfastInt16_Terminate_without_Refine:  PMVfastInt16_Terminate_without_Refine:
3017          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
3018          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
3019          return iMinSAD;          return iMinSAD;
3020  }  }
3021    
# Line 2640  Line 3027 
3027  ***************************************************************/  ***************************************************************/
3028    
3029    
3030    #define DIRECT_PENALTY 0
3031    #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this
3032    
3033  void  void
3034  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3035                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
3036                                             const int32_t time_bp,
3037                                             const int32_t time_pp,
3038                                           // forward (past) reference                                           // forward (past) reference
3039                                           const MACROBLOCK * const f_mbs,                                           const MACROBLOCK * const f_mbs,
3040                                           const IMAGE * const f_ref,                                           const IMAGE * const f_ref,
# Line 2656  Line 3048 
3048                                           const IMAGE * const b_refV,                                           const IMAGE * const b_refV,
3049                                           const IMAGE * const b_refHV)                                           const IMAGE * const b_refHV)
3050  {  {
3051          const uint32_t mb_width = pParam->mb_width;          const int mb_width = pParam->mb_width;
3052          const uint32_t mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3053          const int32_t edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
   
         uint32_t i, j;  
   
         int32_t f_sad16;  
         int32_t b_sad16;  
         int32_t i_sad16;  
         int32_t d_sad16;  
         int32_t best_sad;  
3054    
3055            int i, j, k;
3056    
3057            static const VECTOR zeroMV={0,0};
3058    
3059            int f_sad16;    /* forward (as usual) search */
3060            int b_sad16;    /* backward (only in b-frames) search */
3061            int i_sad16;    /* interpolated (both direction, b-frames only) */
3062            int d_sad16;    /* direct mode (assume linear motion) */
3063    
3064            int best_sad;
3065    
3066            VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3067          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3068    
3069            int f_count=0;
3070            int b_count=0;
3071            int i_count=0;
3072            int d_count=0;
3073            int s_count=0;
3074    
3075            const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3076        const int64_t TRD = (int32_t)time_pp;
3077    
3078            // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);
3079          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
3080          for (j = 0; j < mb_height; j++) {          for (j = 0; j < mb_height; j++) {
3081    
3082                    f_predMV = zeroMV;      /* prediction is reset at left boundary */
3083                    b_predMV = zeroMV;
3084    
3085                  for (i = 0; i < mb_width; i++) {                  for (i = 0; i < mb_width; i++) {
3086                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];
3087                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
3088                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
3089    
3090                            mb->deltamv=zeroMV;
3091    
3092    /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
3093    
3094    #ifndef _DISABLE_SKIP
3095                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3096                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3097                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
# Line 2686  Line 3101 
3101                                  mb->b_mvs[0].y = 0;                                  mb->b_mvs[0].y = 0;
3102                                  continue;                                  continue;
3103                          }                          }
3104                  /* force F_SAD16  #endif
                         f_sad16 = 100;  
                         b_sad16 = 65535;  
3105    
3106                          mb->mode = MODE_FORWARD;                          d_sad16 = DIRECT_PENALTY;
3107                          mb->mvs[0].x = 1;  
3108                          mb->mvs[0].y = 1;                          if (b_mb->mode == MODE_INTER4V)
3109                          mb->b_mvs[0].x = 1;                          {
3110                          mb->b_mvs[0].y = 1;  
3111                          continue;                          /* same method of scaling as in decoder.c, so we copy from there */
3112                   ^^ force F_SAD16 */                      for (k = 0; k < 4; k++) {
3113    
3114                                            mb->directmv[k] = b_mb->mvs[k];
3115    
3116                                            mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3117                        mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3118                                                                                    ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3119                                                : mb->mvs[k].x - mb->directmv[k].x);
3120    
3121                        mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3122                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3123                                                                                    ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3124                                                : mb->mvs[k].y - mb->directmv[k].y);
3125    
3126                                            d_sad16 +=
3127                                                    sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
3128                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3129                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
3130                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3131                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
3132                                                      edged_width);
3133                                    }
3134                            }
3135                            else
3136                            {
3137                                    mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
3138                                    mb->directmv[0] = b_mb->mvs[0];
3139    
3140                                    mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3141                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3142                                                                            ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3143                                        : mb->mvs[0].x - mb->directmv[0].x);
3144    
3145                        mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3146                    mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3147                                                                            ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3148                                        : mb->mvs[0].y - mb->directmv[0].y);
3149    
3150                                    d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3151                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3152                                                                    i, j, 16, &mb->mvs[0], edged_width),
3153                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3154                                                                    i, j, 16, &mb->b_mvs[0], edged_width),
3155                                                      edged_width);
3156    
3157                }
3158                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
3159    
3160                          // forward search                          // forward search
3161                          f_sad16 =                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3162                                  SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                  &frame->image, i, j,
3163                                                   &frame->image, i, j, frame->motion_flags,                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
3164                                                    f_predMV.x, f_predMV.y,                         /* center is f-prediction */
3165                                                    frame->motion_flags,
3166                                                   frame->quant, frame->fcode, pParam,                                                   frame->quant, frame->fcode, pParam,
3167                                                   f_mbs,  f_mbs, /* todo */                                                  f_mbs, f_mbs,
3168                                                   &mb->mvs[0], &pmv_dontcare);   // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);
3169    
3170    
3171                          // backward search                          // backward search
3172                          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,
3173                                                  &frame->image, i, j, frame->motion_flags,                                                  &frame->image, i, j,
3174                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
3175                                                    b_predMV.x, b_predMV.y,                         /* center is b-prediction */
3176                                                    frame->motion_flags,
3177                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
3178                                                  b_mbs, b_mbs,   /* todo */                                                  b_mbs, b_mbs,
3179                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);
   
                         // interpolate search (simple, but effective)  
                         i_sad16 = 65535;  
3180    
                         /*  
                         x/y range somewhat buggy  
3181                          i_sad16 =                          i_sad16 =
3182                                  sad16bi_c(frame->image.y + i * 16 + j * 16 * edged_width,                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3183                                                    get_ref(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,
3184                                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y,                                                                  i, j, 16, &mb->mvs[0], edged_width),
3185                                                                    edged_width), get_ref(b_ref->y, b_refH->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3186                                                                                                                  b_refV->y, b_refHV->y,                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
                                                                                                                 i, j, 16,  
                                                                                                                 mb->b_mvs[0].x,  
                                                                                                                 mb->b_mvs[0].x,  
                                                                                                                 edged_width),  
3187                                                    edged_width);                                                    edged_width);
3188                          */                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3189                                                                    frame->fcode, frame->quant);
3190                        i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3191                                                                    frame->bcode, frame->quant);
3192    
3193                          // TODO: direct search                          // TODO: direct search
3194                          // predictor + range of [-32,32]                          // predictor + delta vector in range [-32,32] (fcode=1)
                         d_sad16 = 65535;  
3195    
3196                            i_sad16 = 65535;
3197                            f_sad16 = 65535;
3198                            b_sad16 = 65535;
3199    //                      d_sad16 = 65535;
3200    
3201                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3202                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 2751  Line 3212 
3212                          }                          }
3213    
3214                          if (d_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3215    
3216                                    if (b_mb->mode == MODE_INTER4V)
3217                                    {
3218    
3219                                    /* same method of scaling as in decoder.c, so we copy from there */
3220                                for (k = 0; k < 4; k++) {
3221    
3222                                                    mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3223                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3224                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3225                                                        : mb->mvs[k].x - mb->directmv[k].x);
3226    
3227                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3228                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3229                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3230                                                : mb->mvs[k].y - mb->directmv[k].y);
3231                                            }
3232                                    }
3233                                    else
3234                                    {
3235                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3236    
3237                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3238                                                                                    ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3239                                            : mb->mvs[0].x - mb->directmv[0].x);
3240    
3241                                mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3242    
3243                            mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3244                                                                                    ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3245                                                : mb->mvs[0].y - mb->directmv[0].y);
3246    
3247                                            mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3248                                            mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
3249                    }
3250    
3251                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3252                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
3253                                    mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(
3254                            }
3255    
3256                            switch (mb->mode)
3257                            {
3258                                    case MODE_FORWARD:
3259                                            f_count++;
3260                                            f_predMV = mb->mvs[0];
3261                                            break;
3262                                    case MODE_BACKWARD:
3263                                            b_count++;
3264                                            b_predMV = mb->b_mvs[0];
3265    
3266                                            break;
3267                                    case MODE_INTERPOLATE:
3268                                            i_count++;
3269                                            f_predMV = mb->mvs[0];
3270                                            b_predMV = mb->b_mvs[0];
3271                                            break;
3272                                    case MODE_DIRECT:
3273                                            d_count++;
3274                                            break;
3275                                    default:
3276                                            s_count++;              // ???
3277                                            break;
3278                          }                          }
3279    
3280                  }                  }
3281          }          }
3282    
3283    #ifdef _DEBUG_BFRAME_STAT
3284            fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",
3285                                    f_count,b_count,i_count,d_count,s_count);
3286    #endif
3287    
3288  }  }

Legend:
Removed from v.300  
changed lines
  Added in v.345

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