[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 289, Wed Jul 10 20:11:05 2002 UTC revision 344, Sat Jul 27 23:07:33 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 650  Line 669 
669                                  break;                                  break;
670                          }                          }
671          } else {          } else {
672                  currMV->x = startx;                  currMV->x = start_x;
673                  currMV->y = starty;                  currMV->y = start_y;
674          }          }
675          return iMinSAD;          return iMinSAD;
676  }  }
# Line 665  Line 684 
684                                    const uint8_t * const cur,                                    const uint8_t * const cur,
685                                    const int x,                                    const int x,
686                                    const int y,                                    const int y,
687                                    int32_t startx,                                     const int start_x,
688                                    int32_t starty,                                     const int start_y,
689                                    int32_t iMinSAD,                                     int iMinSAD,
690                                    VECTOR * const currMV,                                    VECTOR * const currMV,
691                                    const VECTOR * const pmv,                                     const int center_x,
692                                       const int center_y,
693                                    const int32_t min_dx,                                    const int32_t min_dx,
694                                    const int32_t max_dx,                                    const int32_t max_dx,
695                                    const int32_t min_dy,                                    const int32_t min_dy,
# Line 684  Line 704 
704          int32_t dx, dy;          int32_t dx, dy;
705          VECTOR backupMV;          VECTOR backupMV;
706    
707          backupMV.x = startx;          backupMV.x = start_x;
708          backupMV.y = starty;          backupMV.y = start_y;
709    
710          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
711                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 702  Line 722 
722                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
723                                                  const int x,                                                  const int x,
724                                                  const int y,                                                  const int y,
725                                                  int32_t startx,                                             int start_x,
726                                                  int32_t starty,                                             int start_y,
727                                                  int32_t iMinSAD,                                             int iMinSAD,
728                                                  VECTOR * const currMV,                                                  VECTOR * const currMV,
729                                                  const VECTOR * const pmv,                                             const int center_x,
730                                               const int center_y,
731                                                  const int32_t min_dx,                                                  const int32_t min_dx,
732                                                  const int32_t max_dx,                                                  const int32_t max_dx,
733                                                  const int32_t min_dy,                                                  const int32_t min_dy,
# Line 723  Line 744 
744  /* 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) */
745    
746          if (iDirection) {          if (iDirection) {
747                  CHECK_MV16_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y);
748                  CHECK_MV16_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y);
749                  CHECK_MV16_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize);
750                  CHECK_MV16_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize);
751          } else {          } else {
752                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
753    
754                  do {                  do {
755                          iDirection = 0;                          iDirection = 0;
756                          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)
757                                  CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
758    
759                          if (bDirection & 2)                          if (bDirection & 2)
760                                  CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
761    
762                          if (bDirection & 4)                          if (bDirection & 4)
763                                  CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
764    
765                          if (bDirection & 8)                          if (bDirection & 8)
766                                  CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
767    
768                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
769    
# Line 750  Line 771 
771                          {                          {
772                                  bDirection = iDirection;                                  bDirection = iDirection;
773                                  iDirection = 0;                                  iDirection = 0;
774                                  startx = currMV->x;                                  start_x = currMV->x;
775                                  starty = currMV->y;                                  start_y = currMV->y;
776                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
777                                  {                                  {
778                                          CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
779                                          CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
780                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
781                                  {                                  {
782                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
783                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
784                                  }                                  }
785    
786                                  if (iDirection) {                                  if (iDirection) {
787                                          bDirection += iDirection;                                          bDirection += iDirection;
788                                          startx = currMV->x;                                          start_x = currMV->x;
789                                          starty = currMV->y;                                          start_y = currMV->y;
790                                  }                                  }
791                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
792                          {                          {
793                                  switch (bDirection) {                                  switch (bDirection) {
794                                  case 2:                                  case 2:
795                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
796                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
797                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
798                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
799                                          break;                                          break;
800                                  case 1:                                  case 1:
801                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,  
802                                                                                           starty - iDiamondSize, 1 + 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
803                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                                                                           start_y - iDiamondSize, 1 + 4);
804                                                                                           starty + iDiamondSize, 1 + 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
805                                                                                             start_y + iDiamondSize, 1 + 8);
806                                          break;                                          break;
807                                  case 2 + 4:                                  case 2 + 4:
808                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
809                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
810                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
811                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
812                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
813                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
814                                          break;                                          break;
815                                  case 4:                                  case 4:
816                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
817                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
818                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
819                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
820                                          break;                                          break;
821                                  case 8:                                  case 8:
822                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
823                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
824                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
825                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
826                                          break;                                          break;
827                                  case 1 + 4:                                  case 1 + 4:
828                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
829                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
830                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
831                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
832                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
833                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
834                                          break;                                          break;
835                                  case 2 + 8:                                  case 2 + 8:
836                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
837                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
838                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
839                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
840                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
841                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
842                                          break;                                          break;
843                                  case 1 + 8:                                  case 1 + 8:
844                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
845                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
846                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
847                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
848                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
849                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
850                                          break;                                          break;
851                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
852                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
853                                                                                           starty - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
854                                          CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
855                                                                                           starty + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
856                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
857                                                                                           starty - iDiamondSize, 2 + 4);                                                                                           start_y - iDiamondSize, 2 + 4);
858                                          CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
859                                                                                           starty + iDiamondSize, 2 + 8);                                                                                           start_y + iDiamondSize, 2 + 8);
860                                          break;                                          break;
861                                  }                                  }
862                                  if (!iDirection)                                  if (!iDirection)
863                                          break;          //ok, the end. really                                          break;          //ok, the end. really
864                                  else {                                  else {
865                                          bDirection = iDirection;                                          bDirection = iDirection;
866                                          startx = currMV->x;                                          start_x = currMV->x;
867                                          starty = currMV->y;                                          start_y = currMV->y;
868                                  }                                  }
869                          }                          }
870                  }                  }
# Line 851  Line 873 
873          return iMinSAD;          return iMinSAD;
874  }  }
875    
876    
877    #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \
878      if ( ((X) <= max_dx) && ((X) >= min_dx) \
879        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
880      { \
881        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
882        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
883        if (iSAD < iMinSAD) \
884        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
885    }
886    
887    #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \
888      if ( ((X) <= max_dx) && ((X) >= min_dx) \
889        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
890      { \
891        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
892        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
893        if (iSAD < iMinSAD) \
894        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
895    }
896    
897    #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \
898      if ( ((X) <= max_dx) && ((X) >= min_dx) \
899        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
900      { \
901        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
902        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
903        if (iSAD < iMinSAD) \
904        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
905    }
906    
907    
908    #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \
909      if ( ((X) <= max_dx) && ((X) >= min_dx) \
910        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
911      { \
912        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
913        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
914        if (iSAD < iMinSAD) \
915        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
916    }
917    
918    
919    #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \
920      if ( ((X) <= max_dx) && ((X) >= min_dx) \
921        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
922      { \
923        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
924        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
925        if (iSAD < iMinSAD) \
926        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
927    }
928    
929    
930    #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \
931      if ( ((X) <= max_dx) && ((X) >= min_dx) \
932        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
933      { \
934        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
935        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
936        if (iSAD < iMinSAD) \
937        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
938    }
939    
940    
941    #if (0==1)
942    int32_t
943    Diamond16_InterpolMainSearch(
944                                            const uint8_t * const f_pRef,
945                                             const uint8_t * const f_pRefH,
946                                             const uint8_t * const f_pRefV,
947                                             const uint8_t * const f_pRefHV,
948                                             const uint8_t * const cur,
949    
950                                            const uint8_t * const b_pRef,
951                                             const uint8_t * const b_pRefH,
952                                             const uint8_t * const b_pRefV,
953                                             const uint8_t * const b_pRefHV,
954    
955                                             const int x,
956                                             const int y,
957    
958                                       const int f_start_x,
959                                       const int f_start_y,
960                                       const int b_start_x,
961                                       const int b_start_y,
962    
963                                       int iMinSAD,
964                                       VECTOR * const f_currMV,
965                                       VECTOR * const b_currMV,
966    
967                                       const int f_center_x,
968                                       const int f_center_y,
969                                       const int b_center_x,
970                                       const int b_center_y,
971    
972                                             const int32_t min_dx,
973                                             const int32_t max_dx,
974                                             const int32_t min_dy,
975                                             const int32_t max_dy,
976                                             const int32_t iEdgedWidth,
977                                             const int32_t iDiamondSize,
978    
979                                             const int32_t f_iFcode,
980                                             const int32_t b_iFcode,
981    
982                                             const int32_t iQuant,
983                                             int iFound)
984    {
985    /* Do a diamond search around given starting point, return SAD of best */
986    
987            int32_t f_iDirection = 0;
988            int32_t b_iDirection = 0;
989            int32_t iSAD;
990    
991            VECTOR f_backupMV;
992            VECTOR b_backupMV;
993    
994            f_backupMV.x = start_x;
995            f_backupMV.y = start_y;
996            b_backupMV.x = start_x;
997            b_backupMV.y = start_y;
998    
999    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1000    
1001            CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1002            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1003            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1004            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1005    
1006            if (iDirection)
1007                    while (!iFound) {
1008                            iFound = 1;
1009                            backupMV = *currMV;
1010    
1011                            if (iDirection != 2)
1012                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1013                                                                                       backupMV.y, 1);
1014                            if (iDirection != 1)
1015                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1016                                                                                       backupMV.y, 2);
1017                            if (iDirection != 4)
1018                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1019                                                                                       backupMV.y - iDiamondSize, 3);
1020                            if (iDirection != 3)
1021                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1022                                                                                       backupMV.y + iDiamondSize, 4);
1023            } else {
1024                    currMV->x = start_x;
1025                    currMV->y = start_y;
1026            }
1027            return iMinSAD;
1028    }
1029    #endif
1030    
1031    
1032  int32_t  int32_t
1033  AdvDiamond8_MainSearch(const uint8_t * const pRef,  AdvDiamond8_MainSearch(const uint8_t * const pRef,
1034                                             const uint8_t * const pRefH,                                             const uint8_t * const pRefH,
# Line 859  Line 1037 
1037                                             const uint8_t * const cur,                                             const uint8_t * const cur,
1038                                             const int x,                                             const int x,
1039                                             const int y,                                             const int y,
1040                                             int32_t startx,                                             int start_x,
1041                                             int32_t starty,                                             int start_y,
1042                                             int32_t iMinSAD,                                             int iMinSAD,
1043                                             VECTOR * const currMV,                                             VECTOR * const currMV,
1044                                             const VECTOR * const pmv,                                             const int center_x,
1045                                               const int center_y,
1046                                             const int32_t min_dx,                                             const int32_t min_dx,
1047                                             const int32_t max_dx,                                             const int32_t max_dx,
1048                                             const int32_t min_dy,                                             const int32_t min_dy,
# Line 880  Line 1059 
1059  /* 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) */
1060    
1061          if (iDirection) {          if (iDirection) {
1062                  CHECK_MV8_CANDIDATE(startx - iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x - iDiamondSize, start_y);
1063                  CHECK_MV8_CANDIDATE(startx + iDiamondSize, starty);                  CHECK_MV8_CANDIDATE(start_x + iDiamondSize, start_y);
1064                  CHECK_MV8_CANDIDATE(startx, starty - iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y - iDiamondSize);
1065                  CHECK_MV8_CANDIDATE(startx, starty + iDiamondSize);                  CHECK_MV8_CANDIDATE(start_x, start_y + iDiamondSize);
1066          } else {          } else {
1067                  int bDirection = 1 + 2 + 4 + 8;                  int bDirection = 1 + 2 + 4 + 8;
1068    
1069                  do {                  do {
1070                          iDirection = 0;                          iDirection = 0;
1071                          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)
1072                                  CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                  CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1073    
1074                          if (bDirection & 2)                          if (bDirection & 2)
1075                                  CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                  CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1076    
1077                          if (bDirection & 4)                          if (bDirection & 4)
1078                                  CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1079    
1080                          if (bDirection & 8)                          if (bDirection & 8)
1081                                  CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                  CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1082    
1083                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
1084    
# Line 907  Line 1086 
1086                          {                          {
1087                                  bDirection = iDirection;                                  bDirection = iDirection;
1088                                  iDirection = 0;                                  iDirection = 0;
1089                                  startx = currMV->x;                                  start_x = currMV->x;
1090                                  starty = currMV->y;                                  start_y = currMV->y;
1091                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     //our candidate is left or right
1092                                  {                                  {
1093                                          CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1094                                          CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1095                                  } else                  // what remains here is up or down                                  } else                  // what remains here is up or down
1096                                  {                                  {
1097                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1098                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1099                                  }                                  }
1100    
1101                                  if (iDirection) {                                  if (iDirection) {
1102                                          bDirection += iDirection;                                          bDirection += iDirection;
1103                                          startx = currMV->x;                                          start_x = currMV->x;
1104                                          starty = currMV->y;                                          start_y = currMV->y;
1105                                  }                                  }
1106                          } else                          //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
1107                          {                          {
1108                                  switch (bDirection) {                                  switch (bDirection) {
1109                                  case 2:                                  case 2:
1110                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1111                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1112                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1113                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1114                                          break;                                          break;
1115                                  case 1:                                  case 1:
1116                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1117                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1118                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1119                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1120                                          break;                                          break;
1121                                  case 2 + 4:                                  case 2 + 4:
1122                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1123                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1124                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1125                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1126                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1127                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1128                                          break;                                          break;
1129                                  case 4:                                  case 4:
1130                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1131                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1132                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1133                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1134                                          break;                                          break;
1135                                  case 8:                                  case 8:
1136                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1137                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1138                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1139                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1140                                          break;                                          break;
1141                                  case 1 + 4:                                  case 1 + 4:
1142                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1143                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1144                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1145                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1146                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1147                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1148                                          break;                                          break;
1149                                  case 2 + 8:                                  case 2 + 8:
1150                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1151                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1152                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1153                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1154                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1155                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1156                                          break;                                          break;
1157                                  case 1 + 8:                                  case 1 + 8:
1158                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1159                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1160                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1161                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1162                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1163                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1164                                          break;                                          break;
1165                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                //1+2+4+8 == we didn't find anything at all
1166                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1167                                                                                          starty - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1168                                          CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1169                                                                                          starty + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1170                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1171                                                                                          starty - iDiamondSize, 2 + 4);                                                                                          start_y - iDiamondSize, 2 + 4);
1172                                          CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1173                                                                                          starty + iDiamondSize, 2 + 8);                                                                                          start_y + iDiamondSize, 2 + 8);
1174                                          break;                                          break;
1175                                  }                                  }
1176                                  if (!(iDirection))                                  if (!(iDirection))
1177                                          break;          //ok, the end. really                                          break;          //ok, the end. really
1178                                  else {                                  else {
1179                                          bDirection = iDirection;                                          bDirection = iDirection;
1180                                          startx = currMV->x;                                          start_x = currMV->x;
1181                                          starty = currMV->y;                                          start_y = currMV->y;
1182                                  }                                  }
1183                          }                          }
1184                  }                  }
# Line 1017  Line 1196 
1196                                   const uint8_t * const cur,                                   const uint8_t * const cur,
1197                                   const int x,                                   const int x,
1198                                   const int y,                                   const int y,
1199                                   int32_t startx,                             const int start_x,
1200                                   int32_t starty,                             const int start_y,
1201                                   int32_t iMinSAD,                             int iMinSAD,
1202                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1203                                   const VECTOR * const pmv,                             const int center_x,
1204                               const int center_y,
1205                                   const int32_t min_dx,                                   const int32_t min_dx,
1206                                   const int32_t max_dx,                                   const int32_t max_dx,
1207                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1036  Line 1216 
1216          int32_t dx, dy;          int32_t dx, dy;
1217          VECTOR backupMV;          VECTOR backupMV;
1218    
1219          backupMV.x = startx;          backupMV.x = start_x;
1220          backupMV.y = starty;          backupMV.y = start_y;
1221    
1222          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)          for (dx = min_dx; dx <= max_dx; dx += iDiamondSize)
1223                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)                  for (dy = min_dy; dy <= max_dy; dy += iDiamondSize)
# Line 1046  Line 1226 
1226          return iMinSAD;          return iMinSAD;
1227  }  }
1228    
1229    Halfpel8_RefineFuncPtr Halfpel8_Refine;
1230    
1231  int32_t  int32_t
1232  Halfpel16_Refine(const uint8_t * const pRef,  Halfpel16_Refine(const uint8_t * const pRef,
# Line 1058  Line 1238 
1238                                   const int y,                                   const int y,
1239                                   VECTOR * const currMV,                                   VECTOR * const currMV,
1240                                   int32_t iMinSAD,                                   int32_t iMinSAD,
1241                                   const VECTOR * const pmv,                             const int center_x,
1242                               const int center_y,
1243                                   const int32_t min_dx,                                   const int32_t min_dx,
1244                                   const int32_t max_dx,                                   const int32_t max_dx,
1245                                   const int32_t min_dy,                                   const int32_t min_dy,
# Line 1087  Line 1268 
1268  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1269    
1270    
1271    
1272  int32_t  int32_t
1273  PMVfastSearch16(const uint8_t * const pRef,  PMVfastSearch16(const uint8_t * const pRef,
1274                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1095  Line 1277 
1277                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1278                                  const int x,                                  const int x,
1279                                  const int y,                                  const int y,
1280                                    const int start_x,
1281                                    const int start_y,
1282                                    const int center_x,
1283                                    const int center_y,
1284                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1285                                  const uint32_t iQuant,                                  const uint32_t iQuant,
1286                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 1151  Line 1337 
1337          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1338          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1339    
 /*      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]);  
 */  
1340          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
1341                  threshA = 512;                  threshA = 512;
1342                  threshB = 1024;                  threshB = 1024;
# Line 1179  Line 1360 
1360     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1361  */  */
1362    
1363          *currMV = pmv[0];                       /* current best := prediction */          currMV->x = start_x;
1364            currMV->y = start_y;
1365    
1366          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
1367                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1368                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1203  Line 1386 
1386                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1387                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1388          iMinSAD +=          iMinSAD +=
1389                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
1390                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
1391    
1392          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 1340  Line 1523 
1523          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
1524    
1525    
 //      fprintf(stderr,"Entering Diamond %d %d (%d):\n",x,y,iMinSAD);  
   
1526  /* 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 */
1527          iSAD =          iSAD =
1528                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1529                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y,
1530                                                      min_dx, max_dx,
1531                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1532                                                    iQuant, iFound);                                                    iQuant, iFound);
1533    
# Line 1360  Line 1542 
1542                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1543                          iSAD =                          iSAD =
1544                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1545                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    center_x, center_y, iMinSAD, &newMV, center_x, center_y,
1546                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1547                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1548    
# Line 1373  Line 1555 
1555                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1556                          iSAD =                          iSAD =
1557                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1558                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y,
1559                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    min_dx, max_dx, min_dy, max_dy,
1560                                                                      iEdgedWidth, iDiamondSize, iFcode,
1561                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1562    
1563                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 1392  Line 1575 
1575          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
1576                  iMinSAD =                  iMinSAD =
1577                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1578                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1579                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1580    
 /*fprintf(stderr,"Chosen for %d %d: %d %d - %d %d\n",x,y,currMV->x,currMV->y,pmv[0].x,pmv[0].y);  
 */  
1581    PMVfast16_Terminate_without_Refine:    PMVfast16_Terminate_without_Refine:
1582          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
1583          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
1584          return iMinSAD;          return iMinSAD;
1585  }  }
1586    
# Line 1416  Line 1597 
1597                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1598                                          const int x,                                          const int x,
1599                                          const int y,                                          const int y,
1600                                          int32_t startx,                                          int32_t start_x,
1601                                          int32_t starty,                                          int32_t start_y,
1602                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1603                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1604                                          const VECTOR * const pmv,                                     const int center_x,
1605                                       const int center_y,
1606                                          const int32_t min_dx,                                          const int32_t min_dx,
1607                                          const int32_t max_dx,                                          const int32_t max_dx,
1608                                          const int32_t min_dy,                                          const int32_t min_dy,
# Line 1434  Line 1616 
1616  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
1617    
1618          int32_t iDirection = 0;          int32_t iDirection = 0;
1619            int32_t iDirectionBackup;
1620          int32_t iSAD;          int32_t iSAD;
1621          VECTOR backupMV;          VECTOR backupMV;
1622    
1623          backupMV.x = startx;          backupMV.x = start_x;
1624          backupMV.y = starty;          backupMV.y = start_y;
1625    
1626  /* 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 */
1627    
# Line 1447  Line 1630 
1630          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1631          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1632    
1633          if (iDirection)          if (iDirection) {
1634                  while (!iFound) {                  while (!iFound) {
1635                          iFound = 1;                          iFound = 1;
1636                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     // since iDirection!=0, this is well defined!
1637                            iDirectionBackup = iDirection;
1638    
1639                          if (iDirection != 2)                          if (iDirectionBackup != 2)
1640                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1641                                                                                    backupMV.y, 1);                                                                                    backupMV.y, 1);
1642                          if (iDirection != 1)                          if (iDirectionBackup != 1)
1643                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1644                                                                                    backupMV.y, 2);                                                                                    backupMV.y, 2);
1645                          if (iDirection != 4)                          if (iDirectionBackup != 4)
1646                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1647                                                                                    backupMV.y - iDiamondSize, 3);                                                                                    backupMV.y - iDiamondSize, 3);
1648                          if (iDirection != 3)                          if (iDirectionBackup != 3)
1649                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1650                                                                                    backupMV.y + iDiamondSize, 4);                                                                                    backupMV.y + iDiamondSize, 4);
1651                    }
1652          } else {          } else {
1653                  currMV->x = startx;                  currMV->x = start_x;
1654                  currMV->y = starty;                  currMV->y = start_y;
1655          }          }
1656          return iMinSAD;          return iMinSAD;
1657  }  }
1658    
1659  int32_t  int32_t
1660  Halfpel8_Refine(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1661                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
1662                                  const uint8_t * const pRefV,                                  const uint8_t * const pRefV,
1663                                  const uint8_t * const pRefHV,                                  const uint8_t * const pRefHV,
# Line 1481  Line 1666 
1666                                  const int y,                                  const int y,
1667                                  VECTOR * const currMV,                                  VECTOR * const currMV,
1668                                  int32_t iMinSAD,                                  int32_t iMinSAD,
1669                                  const VECTOR * const pmv,                             const int center_x,
1670                               const int center_y,
1671                                  const int32_t min_dx,                                  const int32_t min_dx,
1672                                  const int32_t max_dx,                                  const int32_t max_dx,
1673                                  const int32_t min_dy,                                  const int32_t min_dy,
# Line 1520  Line 1706 
1706                             const int y,                             const int y,
1707                             const int start_x,                             const int start_x,
1708                             const int start_y,                             const int start_y,
1709                                    const int center_x,
1710                                    const int center_y,
1711                             const uint32_t MotionFlags,                             const uint32_t MotionFlags,
1712                             const uint32_t iQuant,                             const uint32_t iQuant,
1713                             const uint32_t iFcode,                             const uint32_t iFcode,
# Line 1584  Line 1772 
1772                  threshB = 1024 / 4;                  threshB = 1024 / 4;
1773    
1774          } else {          } else {
1775                  threshA = psad[0] / 4;  /* good estimate */                  threshA = psad[0] / 4;  /* good estimate? */
1776                  threshB = threshA + 256 / 4;                  threshB = threshA + 256 / 4;
1777                  if (threshA < 512 / 4)                  if (threshA < 512 / 4)
1778                          threshA = 512 / 4;                          threshA = 512 / 4;
# Line 1623  Line 1811 
1811                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
1812                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
1813          iMinSAD +=          iMinSAD +=
1814                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
1815                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
1816    
1817          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))          if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
# Line 1666  Line 1854 
1854  // the median prediction might be even better than mv16  // the median prediction might be even better than mv16
1855    
1856          if (!MVequal(pmv[0], startMV))          if (!MVequal(pmv[0], startMV))
1857                  CHECK_MV8_CANDIDATE(pmv[0].x, pmv[0].y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
1858    
1859  // (0,0) if needed  // (0,0) if needed
1860          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
# Line 1763  Line 1951 
1951  /* 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 */
1952          iSAD =          iSAD =
1953                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
1954                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
1955                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1956                                                    iQuant, iFound);                                                    iQuant, iFound);
1957    
# Line 1778  Line 1966 
1966                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
1967                          iSAD =                          iSAD =
1968                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1969                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
1970                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1971                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
1972    
# Line 1791  Line 1979 
1979                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1980                          iSAD =                          iSAD =
1981                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1982                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
1983                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
1984                                                                    iQuant, iFound);                                                                    iQuant, iFound);
1985    
# Line 1810  Line 1998 
1998          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
1999                  iMinSAD =                  iMinSAD =
2000                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2001                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2002                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2003    
2004    
2005    PMVfast8_Terminate_without_Refine:    PMVfast8_Terminate_without_Refine:
2006          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2007          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2008    
2009          return iMinSAD;          return iMinSAD;
2010  }  }
# Line 1829  Line 2017 
2017                           const IMAGE * const pCur,                           const IMAGE * const pCur,
2018                           const int x,                           const int x,
2019                           const int y,                           const int y,
2020                            const int start_x,
2021                            const int start_y,
2022                            const int center_x,
2023                            const int center_y,
2024                           const uint32_t MotionFlags,                           const uint32_t MotionFlags,
2025                           const uint32_t iQuant,                           const uint32_t iQuant,
2026                           const uint32_t iFcode,                           const uint32_t iFcode,
# Line 1899  Line 2091 
2091    
2092  // Prepare for main loop  // Prepare for main loop
2093    
2094          *currMV = pmv[0];                       /* current best := median prediction */          currMV->x = start_x;
2095            currMV->y = start_y;
2096    
2097          if (!(MotionFlags & PMV_HALFPEL16)) {          if (!(MotionFlags & PMV_HALFPEL16)) {
2098                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2099                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
# Line 1921  Line 2115 
2115                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2116                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2117          iMinSAD +=          iMinSAD +=
2118                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2119                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2120    
2121  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 2045  Line 2239 
2239    
2240          iSAD =          iSAD =
2241                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2242                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2243                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2244    
2245          if (iSAD < iMinSAD) {          if (iSAD < iMinSAD) {
# Line 2060  Line 2254 
2254                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2255                          iSAD =                          iSAD =
2256                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2257                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2258                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2259                                                                    2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2260                  }                  }
# Line 2073  Line 2267 
2267                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2268                          iSAD =                          iSAD =
2269                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2270                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2271                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2272    
2273                          if (iSAD < iMinSAD) {                          if (iSAD < iMinSAD) {
# Line 2089  Line 2283 
2283          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2284                  iMinSAD =                  iMinSAD =
2285                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2286                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2287                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2288    
2289    EPZS16_Terminate_without_Refine:    EPZS16_Terminate_without_Refine:
2290    
2291          *oldMB = *prevMB;          *oldMB = *prevMB;
2292    
2293          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2294          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2295          return iMinSAD;          return iMinSAD;
2296  }  }
2297    
# Line 2112  Line 2306 
2306                          const int y,                          const int y,
2307                          const int start_x,                          const int start_x,
2308                          const int start_y,                          const int start_y,
2309                            const int center_x,
2310                            const int center_y,
2311                          const uint32_t MotionFlags,                          const uint32_t MotionFlags,
2312                          const uint32_t iQuant,                          const uint32_t iQuant,
2313                          const uint32_t iFcode,                          const uint32_t iFcode,
# Line 2166  Line 2362 
2362                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2363          }          }
2364          /* 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; */
2365          //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);
2366          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);
2367    
2368    
# Line 2202  Line 2398 
2398                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2399                                                  iEdgedWidth), iEdgedWidth);                                                  iEdgedWidth), iEdgedWidth);
2400          iMinSAD +=          iMinSAD +=
2401                  calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2402                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2403    
2404    
# Line 2289  Line 2485 
2485    
2486          iSAD =          iSAD =
2487                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2488                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2489                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2490                                                    iQuant, 0);                                                    iQuant, 0);
2491    
# Line 2305  Line 2501 
2501                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2502                          iSAD =                          iSAD =
2503                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2504                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2505                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2506                                                                    iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2507    
# Line 2318  Line 2514 
2514                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2515                          iSAD =                          iSAD =
2516                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2517                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2518                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2519                                                                    iQuant, 0);                                                                    iQuant, 0);
2520    
# Line 2335  Line 2531 
2531          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step
2532                  iMinSAD =                  iMinSAD =
2533                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2534                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2535                                                          iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2536    
2537    EPZS8_Terminate_without_Refine:    EPZS8_Terminate_without_Refine:
2538    
2539          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2540          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2541          return iMinSAD;          return iMinSAD;
2542  }  }
2543    
# Line 2355  Line 2551 
2551                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2552                                  const int x,                                  const int x,
2553                                  const int y,                                  const int y,
2554                            const int start_x,
2555                            const int start_y,
2556                            const int center_x,
2557                            const int center_y,
2558                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2559                                  const uint32_t iQuant,                                  const uint32_t iQuant,
2560                                  const uint32_t iFcode,                                  const uint32_t iFcode,
# Line 2396  Line 2596 
2596          int32_t bPredEq;          int32_t bPredEq;
2597          int32_t iMinSAD, iSAD;          int32_t iMinSAD, iSAD;
2598    
2599    
2600  /* Get maximum range */  /* Get maximum range */
2601          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,
2602                            iFcode);                            iFcode);
# Line 2448  Line 2649 
2649    
2650          iMinSAD =          iMinSAD =
2651                  sad16(cur,                  sad16(cur,
2652                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,                            get_iref_mv(pRef, x, y, 16, currMV,
2653                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2654          iMinSAD +=          iMinSAD +=
2655                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2656                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2657    
2658          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
# Line 2570  Line 2771 
2771  /* 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 */
2772          iSAD =          iSAD =
2773                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2774                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2775                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2776                                                    iQuant, iFound);                                                    iQuant, iFound);
2777    
# Line 2585  Line 2786 
2786                  if (!(MVequal(pmv[0], backupMV))) {                  if (!(MVequal(pmv[0], backupMV))) {
2787                          iSAD =                          iSAD =
2788                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2789                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2790                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2791                                                                    iDiamondSize, iFcode, iQuant, iFound);                                                                    iDiamondSize, iFcode, iQuant, iFound);
2792    
# Line 2598  Line 2799 
2799                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2800                          iSAD =                          iSAD =
2801                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2802                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2803                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2804                                                                    iQuant, iFound);                                                                    iQuant, iFound);
2805    
# Line 2621  Line 2822 
2822          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2823                  iMinSAD =                  iMinSAD =
2824                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2825                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2826                                                           iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2827    
2828          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)
2829    
2830  PMVfastInt16_Terminate_without_Refine:  PMVfastInt16_Terminate_without_Refine:
2831          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2832          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2833          return iMinSAD;          return iMinSAD;
2834  }  }
2835    
# Line 2640  Line 2841 
2841  ***************************************************************/  ***************************************************************/
2842    
2843    
2844    #define DIRECT_PENALTY 0
2845    #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this
2846    
2847  void  void
2848  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
2849                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
2850                                             const int32_t time_bp,
2851                                             const int32_t time_pp,
2852                                           // forward (past) reference                                           // forward (past) reference
2853                                           const MACROBLOCK * const f_mbs,                                           const MACROBLOCK * const f_mbs,
2854                                           const IMAGE * const f_ref,                                           const IMAGE * const f_ref,
# Line 2656  Line 2862 
2862                                           const IMAGE * const b_refV,                                           const IMAGE * const b_refV,
2863                                           const IMAGE * const b_refHV)                                           const IMAGE * const b_refHV)
2864  {  {
2865          const uint32_t mb_width = pParam->mb_width;          const int mb_width = pParam->mb_width;
2866          const uint32_t mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
2867          const int32_t edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
2868    
2869          uint32_t i, j;          int i, j, k;
2870    
2871          int32_t f_sad16;          static const VECTOR zeroMV={0,0};
2872          int32_t b_sad16;  
2873          int32_t i_sad16;          int f_sad16;    /* forward (as usual) search */
2874          int32_t d_sad16;          int b_sad16;    /* backward (only in b-frames) search */
2875          int32_t best_sad;          int i_sad16;    /* interpolated (both direction, b-frames only) */
2876            int d_sad16;    /* direct mode (assume linear motion) */
2877    
2878            int best_sad;
2879    
2880            VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
2881          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
2882    
2883            int f_count=0;
2884            int b_count=0;
2885            int i_count=0;
2886            int d_count=0;
2887            int s_count=0;
2888    
2889            const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
2890        const int64_t TRD = (int32_t)time_pp;
2891    
2892            // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);
2893          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
2894          for (j = 0; j < mb_height; j++) {          for (j = 0; j < mb_height; j++) {
2895    
2896                    f_predMV = zeroMV;      /* prediction is reset at left boundary */
2897                    b_predMV = zeroMV;
2898    
2899                  for (i = 0; i < mb_width; i++) {                  for (i = 0; i < mb_width; i++) {
2900                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j * mb_width];
2901                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];
2902                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];
2903    
2904                            mb->deltamv=zeroMV;
2905    
2906    /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
2907    
2908    #ifndef _DISABLE_SKIP
2909                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
2910                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
2911                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
# Line 2686  Line 2915 
2915                                  mb->b_mvs[0].y = 0;                                  mb->b_mvs[0].y = 0;
2916                                  continue;                                  continue;
2917                          }                          }
2918                  /* force F_SAD16  #endif
                         f_sad16 = 100;  
                         b_sad16 = 65535;  
2919    
2920                          mb->mode = MODE_FORWARD;                          d_sad16 = DIRECT_PENALTY;
2921                          mb->mvs[0].x = 1;  
2922                          mb->mvs[0].y = 1;                          if (b_mb->mode == MODE_INTER4V)
2923                          mb->b_mvs[0].x = 1;                          {
2924                          mb->b_mvs[0].y = 1;  
2925                          continue;                          /* same method of scaling as in decoder.c, so we copy from there */
2926                   ^^ force F_SAD16 */                      for (k = 0; k < 4; k++) {
2927    
2928                                            mb->directmv[k] = b_mb->mvs[k];
2929    
2930                                            mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
2931                        mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
2932                                                                                    ? ((TRB - TRD) * mb->directmv[k].x) / TRD
2933                                                : mb->mvs[k].x - mb->directmv[k].x);
2934    
2935                        mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
2936                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
2937                                                                                    ? ((TRB - TRD) * mb->directmv[k].y) / TRD
2938                                                : mb->mvs[k].y - mb->directmv[k].y);
2939    
2940                                            d_sad16 +=
2941                                                    sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
2942                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2943                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
2944                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2945                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
2946                                                      edged_width);
2947                                    }
2948                            }
2949                            else
2950                            {
2951                                    mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =
2952                                    mb->directmv[0] = b_mb->mvs[0];
2953    
2954                                    mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
2955                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
2956                                                                            ? ((TRB - TRD) * mb->directmv[0].x) / TRD
2957                                        : mb->mvs[0].x - mb->directmv[0].x);
2958    
2959                        mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
2960                    mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
2961                                                                            ? ((TRB - TRD) * mb->directmv[0].y) / TRD
2962                                        : mb->mvs[0].y - mb->directmv[0].y);
2963    
2964                                    d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2965                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2966                                                                    i, j, 16, &mb->mvs[0], edged_width),
2967                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2968                                                                    i, j, 16, &mb->b_mvs[0], edged_width),
2969                                                      edged_width);
2970    
2971                }
2972                        d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);
2973    
2974                          // forward search                          // forward search
2975                          f_sad16 =                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2976                                  SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                  &frame->image, i, j,
2977                                                   &frame->image, i, j, frame->motion_flags,                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
2978                                                    f_predMV.x, f_predMV.y,                         /* center is f-prediction */
2979                                                    frame->motion_flags,
2980                                                   frame->quant, frame->fcode, pParam,                                                   frame->quant, frame->fcode, pParam,
2981                                                   f_mbs,  f_mbs, /* todo */                                                  f_mbs, f_mbs,
2982                                                   &mb->mvs[0], &pmv_dontcare);   // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);
2983    
2984    
2985                          // backward search                          // backward search
2986                          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,
2987                                                  &frame->image, i, j, frame->motion_flags,                                                  &frame->image, i, j,
2988                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
2989                                                    b_predMV.x, b_predMV.y,                         /* center is b-prediction */
2990                                                    frame->motion_flags,
2991                                                  frame->quant, frame->bcode, pParam,                                                  frame->quant, frame->bcode, pParam,
2992                                                  b_mbs, b_mbs,   /* todo */                                                  b_mbs, b_mbs,
2993                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);
2994    
                         // interpolate search (simple, but effective)  
                         i_sad16 = 65535;  
   
                         /*  
                         x/y range somewhat buggy  
2995                          i_sad16 =                          i_sad16 =
2996                                  sad16bi_c(frame->image.y + i * 16 + j * 16 * edged_width,                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2997                                                    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,
2998                                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y,                                                                  i, j, 16, &mb->mvs[0], edged_width),
2999                                                                    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,
3000                                                                                                                  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),  
3001                                                    edged_width);                                                    edged_width);
3002                          */                      i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3003                                                                    frame->fcode, frame->quant);
3004                        i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3005                                                                    frame->bcode, frame->quant);
3006    
3007                          // TODO: direct search                          // TODO: direct search
3008                          // predictor + range of [-32,32]                          // predictor + delta vector in range [-32,32] (fcode=1)
                         d_sad16 = 65535;  
3009    
3010                            i_sad16 = 65535;
3011                            f_sad16 = 65535;
3012                            b_sad16 = 65535;
3013    //                      d_sad16 = 65535;
3014    
3015                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
3016                                  best_sad = f_sad16;                                  best_sad = f_sad16;
# Line 2751  Line 3026 
3026                          }                          }
3027    
3028                          if (d_sad16 < best_sad) {                          if (d_sad16 < best_sad) {
3029    
3030                                    if (b_mb->mode == MODE_INTER4V)
3031                                    {
3032    
3033                                    /* same method of scaling as in decoder.c, so we copy from there */
3034                                for (k = 0; k < 4; k++) {
3035    
3036                                                    mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
3037                                mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)
3038                                                                                            ? ((TRB - TRD) * mb->directmv[k].x) / TRD
3039                                                        : mb->mvs[k].x - mb->directmv[k].x);
3040    
3041                                mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3042                            mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)
3043                                                                                            ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3044                                                : mb->mvs[k].y - mb->directmv[k].y);
3045                                            }
3046                                    }
3047                                    else
3048                                    {
3049                                            mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);
3050    
3051                        mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)
3052                                                                                    ? ((TRB - TRD) * mb->directmv[0].x) / TRD
3053                                            : mb->mvs[0].x - mb->directmv[0].x);
3054    
3055                                mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3056    
3057                            mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)
3058                                                                                    ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3059                                                : mb->mvs[0].y - mb->directmv[0].y);
3060    
3061                                            mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];
3062                                            mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];
3063                    }
3064    
3065                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3066                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
3067                                    mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(
3068                            }
3069    
3070                            switch (mb->mode)
3071                            {
3072                                    case MODE_FORWARD:
3073                                            f_count++;
3074                                            f_predMV = mb->mvs[0];
3075                                            break;
3076                                    case MODE_BACKWARD:
3077                                            b_count++;
3078                                            b_predMV = mb->b_mvs[0];
3079    
3080                                            break;
3081                                    case MODE_INTERPOLATE:
3082                                            i_count++;
3083                                            f_predMV = mb->mvs[0];
3084                                            b_predMV = mb->b_mvs[0];
3085                                            break;
3086                                    case MODE_DIRECT:
3087                                            d_count++;
3088                                            break;
3089                                    default:
3090                                            s_count++;              // ???
3091                                            break;
3092                          }                          }
3093    
3094                  }                  }
3095          }          }
3096    
3097    #ifdef _DEBUG_BFRAME_STAT
3098            fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",
3099                                    f_count,b_count,i_count,d_count,s_count);
3100    #endif
3101    
3102  }  }

Legend:
Removed from v.289  
changed lines
  Added in v.344

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