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

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

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

revision 344, Sat Jul 27 23:07:33 2002 UTC revision 504, Sat Sep 21 11:59:22 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      motion estimation   *  - Motion Estimation module -
5     *
6     *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>
7     *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>
8     *  Copyright(C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>
9   *   *
10   *      This program is an implementation of a part of one or more MPEG-4   *      This program is an implementation of a part of one or more MPEG-4
11   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
# Line 24  Line 28 
28   *   *
29   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
30   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
31   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
32   *   *
33   *************************************************************************/   *************************************************************************/
34    
 /**************************************************************************  
  *  
  *  Modifications:  
  *  
  *      01.05.2002      updated MotionEstimationBVOP  
  *      25.04.2002 partial prevMB conversion  
  *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>  
  *  14.04.2002 added MotionEstimationBVOP()  
  *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between  
  *             EPZS and EPZS^2  
  *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop  
  *             PMVFast_Refine to support multiple searches with different start points  
  *  07.01.2002 uv-block-based interpolation  
  *  06.01.2002 INTER/INTRA-decision is now done before any SEARCH8 (speedup)  
  *             changed INTER_BIAS to 150 (as suggested by suxen_drol)  
  *             removed halfpel refinement step in PMVfastSearch8 + quality=5  
  *             added new quality mode = 6 which performs halfpel refinement  
  *             filesize difference between quality 5 and 6 is smaller than 1%  
  *             (Isibaar)  
  *  31.12.2001 PMVfastSearch16 and PMVfastSearch8 (gruel)  
  *  30.12.2001 get_range/MotionSearchX simplified; blue/green bug fix  
  *  22.12.2001 commented best_point==99 check  
  *  19.12.2001 modified get_range (purple bug fix)  
  *  15.12.2001 moved pmv displacement from mbprediction  
  *  02.12.2001 motion estimation/compensation split (Isibaar)  
  *  16.11.2001 rewrote/tweaked search algorithms; pross@cs.rmit.edu.au  
  *  10.11.2001 support for sad16/sad8 functions  
  *  28.08.2001 reactivated MODE_INTER4V for EXT_MODE  
  *  24.08.2001 removed MODE_INTER4V_Q, disabled MODE_INTER4V for EXT_MODE  
  *  22.08.2001 added MODE_INTER4V_Q  
  *  20.08.2001 added pragma to get rid of internal compiler error with VC6  
  *             idea by Cyril. Thanks.  
  *  
  *  Michael Militzer <isibaar@videocoding.de>  
  *  
  **************************************************************************/  
   
35  #include <assert.h>  #include <assert.h>
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
# Line 174  Line 141 
141          static const VECTOR zeroMV = { 0, 0 };          static const VECTOR zeroMV = { 0, 0 };
142          VECTOR predMV;          VECTOR predMV;
143    
144          int32_t x, y;          uint32_t x, y;
145          int32_t iIntra = 0;          uint32_t iIntra = 0;
146          VECTOR pmv;          VECTOR pmv;
147    
148          if (sadInit)          if (sadInit)
# Line 389  Line 356 
356      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
357  }  }
358    
359    #if 0
360  /* too slow and not fully functional at the moment */  /* too slow and not fully functional at the moment */
 /*  
361  int32_t ZeroSearch16(  int32_t ZeroSearch16(
362                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
363                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 429  Line 396 
396          return iSAD;          return iSAD;
397    
398  }  }
399  */  #endif /* 0 */
400    
401  int32_t  int32_t
402  Diamond16_MainSearch(const uint8_t * const pRef,  Diamond16_MainSearch(const uint8_t * const pRef,
# Line 554  Line 521 
521                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
522    
523    
524          if (iDirection)          if (iDirection) {
525                  while (!iFound) {                  while (!iFound) {
526                          iFound = 1;                          iFound = 1;
527                          backupMV = *currMV;                          backupMV = *currMV;
# Line 563  Line 530 
530                          case 1:                          case 1:
531                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
532                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
533                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
534                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
535                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
536                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
537                                  break;                                  break;
538                          case 2:                          case 2:
539                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
540                                                                                   2);                                                                                   2);
541                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
542                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
543                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
544                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
545                                  break;                                  break;
546    
547                          case 3:                          case 3:
548                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
549                                                                                   4);                                                                                   4);
550                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
551                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
552                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
553                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
554                                  break;                                  break;
555    
556                          case 4:                          case 4:
557                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
558                                                                                   3);                                                                                   3);
559                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
560                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
561                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
562                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
563                                  break;                                  break;
564    
565                          case 5:                          case 5:
566                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
567                                                                                   1);                                                                                   1);
568                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
569                                                                                   3);                                                                                   3);
570                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
571                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
572                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
573                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
574                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
575                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
576                                  break;                                  break;
577    
578                          case 6:                          case 6:
579                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
580                                                                                   2);                                                                                   2);
581                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
582                                                                                   3);                                                                                   3);
583    
584                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
585                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
586                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
587                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
588                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
589                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
590    
591                                  break;                                  break;
# Line 626  Line 593 
593                          case 7:                          case 7:
594                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
595                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
596                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
597                                                                                   4);                                                                                   4);
598                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
599                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
600                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
601                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
602                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
603                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
604                                  break;                                  break;
605    
606                          case 8:                          case 8:
607                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
608                                                                                   2);                                                                                   2);
609                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
610                                                                                   4);                                                                                   4);
611                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
612                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
613                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
614                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
615                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
616                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
617                                  break;                                  break;
618                          default:                          default:
619                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
620                                                                                   1);                                                                                   1);
621                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
622                                                                                   2);                                                                                   2);
623                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
624                                                                                   3);                                                                                   3);
625                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
626                                                                                   4);                                                                                   4);
627    
628                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
629                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
630                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
631                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
632                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
633                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
634                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
635                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
636                                  break;                                  break;
637                          }                          }
638                    }
639          } else {          } else {
640                  currMV->x = start_x;                  currMV->x = start_x;
641                  currMV->y = start_y;                  currMV->y = start_y;
# Line 722  Line 690 
690                                                  const uint8_t * const cur,                                                  const uint8_t * const cur,
691                                                  const int x,                                                  const int x,
692                                                  const int y,                                                  const int y,
693                                             int start_x,                                                  const int start_xi,
694                                             int start_y,                                                  const int start_yi,
695                                             int iMinSAD,                                             int iMinSAD,
696                                             VECTOR * const currMV,                                             VECTOR * const currMV,
697                                             const int center_x,                                             const int center_x,
# Line 740  Line 708 
708  {  {
709    
710          int32_t iSAD;          int32_t iSAD;
711            int start_x = start_xi, start_y = start_yi;
712    
713  /* 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) */
714    
# Line 870  Line 839 
839                  }                  }
840                  while (1);                              //forever                  while (1);                              //forever
841          }          }
842    
843          return iMinSAD;          return iMinSAD;
844  }  }
845    
846    /* Disabled bframe specific code */
847    #if 0
848    
849  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \  #define CHECK_MV16_F_INTERPOL(X,Y) { \
850    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
851      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
852    { \    { \
853      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
854      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
855                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
856                            iEdgedWidth); \
857        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
858        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
859      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
860      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
861  }  }
862    
863  #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
864    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
865      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
866    { \    { \
867      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
868      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
869                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
870                            iEdgedWidth); \
871        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
872        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
873      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
874      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
875  }  }
876    
877  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  #define CHECK_MV16_B_INTERPOL(X,Y) { \
878    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
879      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
880    { \    { \
881      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
882      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
883                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
884                            iEdgedWidth); \
885        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
886        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
887      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
888      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
889  }  }
890    
891    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
892  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
893    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
894    { \    { \
895      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
896      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\                          get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \
897                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
898                            iEdgedWidth); \
899        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
900        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
901      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
902      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
903  }  }
904    
905    
 #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
   { \  
     iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \  
     iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \  
 }  
   
   
 #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
   { \  
     iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \  
     iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \  
 }  
   
   
 #if (0==1)  
906  int32_t  int32_t
907  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(const uint8_t * const f_pRef,
                                         const uint8_t * const f_pRef,  
908                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
909                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
910                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
911    
912                                           const uint8_t * const cur,                                           const uint8_t * const cur,
913    
914                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 969  Line 933 
933                                     const int b_center_x,                                     const int b_center_x,
934                                     const int b_center_y,                                     const int b_center_y,
935    
936                                           const int32_t min_dx,                                                           const int32_t f_min_dx,
937                                           const int32_t max_dx,                                                           const int32_t f_max_dx,
938                                           const int32_t min_dy,                                                           const int32_t f_min_dy,
939                                           const int32_t max_dy,                                                           const int32_t f_max_dy,
940    
941                                                             const int32_t b_min_dx,
942                                                             const int32_t b_max_dx,
943                                                             const int32_t b_min_dy,
944                                                             const int32_t b_max_dy,
945    
946                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
947                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
948    
# Line 984  Line 954 
954  {  {
955  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
956    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
957          int32_t iSAD;          int32_t iSAD;
958    
959          VECTOR f_backupMV;          VECTOR f_backupMV;
960          VECTOR b_backupMV;          VECTOR b_backupMV;
961    
962          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
963          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
964          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
965          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
966    
967  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
968            {
969                    iFound = 1;
970    
971          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);                  f_backupMV = *f_currMV;
         CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);  
         CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);  
         CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);  
972    
973          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
974                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
975                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
976                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
977    
978                    b_backupMV = *b_currMV;
979    
980                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
981                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
982                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
983                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
984    
985            } while (!iFound);
986    
987            return iMinSAD;
988    }
989    
990    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
991    
992    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
993            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
994            { int k;\
995            VECTOR mvs,b_mvs;       \
996            iSAD = 0;\
997            for (k = 0; k < 4; k++) {       \
998                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
999                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
1000                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1001                                                : mvs.x - directmv[k].x);                           \
1002                                                                                                                                                                    \
1003                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1004                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1005                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1006                                                : mvs.y - directmv[k].y);                           \
1007                                                                                                                                                                    \
1008      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1009        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1010            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1011        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1012                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1013                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1014                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1015                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1016                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1017                            iEdgedWidth); \
1018                    }       \
1019            else    \
1020                    iSAD = 65535;   \
1021            } \
1022            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1023            if (iSAD < iMinSAD) \
1024                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1025    }
1026    
1027    
1028    
1029    int32_t
1030    Diamond16_DirectMainSearch(
1031                                            const uint8_t * const f_pRef,
1032                                            const uint8_t * const f_pRefH,
1033                                            const uint8_t * const f_pRefV,
1034                                            const uint8_t * const f_pRefHV,
1035    
1036                                            const uint8_t * const cur,
1037    
1038                                            const uint8_t * const b_pRef,
1039                                            const uint8_t * const b_pRefH,
1040                                            const uint8_t * const b_pRefV,
1041                                            const uint8_t * const b_pRefHV,
1042    
1043                                            const int x,
1044                                            const int y,
1045    
1046                                            const int TRB,
1047                                            const int TRD,
1048    
1049                                        const int start_x,
1050                                        const int start_y,
1051    
1052                                        int iMinSAD,
1053                                        VECTOR * const currMV,
1054                                            const VECTOR * const directmv,
1055    
1056                                        const int32_t min_dx,
1057                                            const int32_t max_dx,
1058                                            const int32_t min_dy,
1059                                            const int32_t max_dy,
1060    
1061                                            const int32_t iEdgedWidth,
1062                                            const int32_t iDiamondSize,
1063    
1064                                            const int32_t iQuant,
1065                                            int iFound)
1066    {
1067    /* Do a diamond search around given starting point, return SAD of best */
1068    
1069            int32_t iSAD;
1070    
1071            VECTOR backupMV;
1072    
                         if (iDirection != 2)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,  
                                                                                    backupMV.y, 1);  
                         if (iDirection != 1)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,  
                                                                                    backupMV.y, 2);  
                         if (iDirection != 4)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x,  
                                                                                    backupMV.y - iDiamondSize, 3);  
                         if (iDirection != 3)  
                                 CHECK_MV16_CANDIDATE_FOUND(backupMV.x,  
                                                                                    backupMV.y + iDiamondSize, 4);  
         } else {  
1073                  currMV->x = start_x;                  currMV->x = start_x;
1074                  currMV->y = start_y;                  currMV->y = start_y;
1075          }  
1076    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1077    
1078            do
1079            {
1080                    iFound = 1;
1081    
1082                    backupMV = *currMV;
1083    
1084                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1085                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1086                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1087                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1088    
1089            } while (!iFound);
1090    
1091          return iMinSAD;          return iMinSAD;
1092  }  }
 #endif  
1093    
1094    #endif /* 0 */
1095    
1096  int32_t  int32_t
1097  AdvDiamond8_MainSearch(const uint8_t * const pRef,  AdvDiamond8_MainSearch(const uint8_t * const pRef,
# Line 1037  Line 1101 
1101                                             const uint8_t * const cur,                                             const uint8_t * const cur,
1102                                             const int x,                                             const int x,
1103                                             const int y,                                             const int y,
1104                                             int start_x,                                             const int start_xi,
1105                                             int start_y,                                             const int start_yi,
1106                                             int iMinSAD,                                             int iMinSAD,
1107                                             VECTOR * const currMV,                                             VECTOR * const currMV,
1108                                             const int center_x,                                             const int center_x,
# Line 1055  Line 1119 
1119  {  {
1120    
1121          int32_t iSAD;          int32_t iSAD;
1122            int start_x = start_xi, start_y = start_yi;
1123    
1124  /* 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) */
1125    
# Line 1277  Line 1342 
1342                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1343                                  const int x,                                  const int x,
1344                                  const int y,                                  const int y,
1345                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1346                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1347                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1348                                  const int center_y,                                  const int center_y,
1349                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1350                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1334  Line 1399 
1399          }          }
1400    
1401          /* 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; */
         //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);  
1402          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1403    
1404          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 1392  Line 1456 
1456          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1457                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1458                   ((int32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1459                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode
1460                  {                  {
1461                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
1462                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
# Line 1597  Line 1661 
1661                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1662                                          const int x,                                          const int x,
1663                                          const int y,                                          const int y,
1664                                          int32_t start_x,                                          const int32_t start_x,
1665                                          int32_t start_y,                                          const int32_t start_y,
1666                                          int32_t iMinSAD,                                          int32_t iMinSAD,
1667                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1668                                     const int center_x,                                     const int center_x,
# Line 1656  Line 1720 
1720          return iMinSAD;          return iMinSAD;
1721  }  }
1722    
1723    
1724    
1725    
1726    int32_t
1727    Square8_MainSearch(const uint8_t * const pRef,
1728                                       const uint8_t * const pRefH,
1729                                       const uint8_t * const pRefV,
1730                                       const uint8_t * const pRefHV,
1731                                       const uint8_t * const cur,
1732                                       const int x,
1733                                       const int y,
1734                                       const int32_t start_x,
1735                                       const int32_t start_y,
1736                                       int32_t iMinSAD,
1737                                       VECTOR * const currMV,
1738                                       const int center_x,
1739                                       const int center_y,
1740                                       const int32_t min_dx,
1741                                       const int32_t max_dx,
1742                                       const int32_t min_dy,
1743                                       const int32_t max_dy,
1744                                       const int32_t iEdgedWidth,
1745                                       const int32_t iDiamondSize,
1746                                       const int32_t iFcode,
1747                                       const int32_t iQuant,
1748                                       int iFound)
1749    {
1750    /* Do a square search around given starting point, return SAD of best */
1751    
1752            int32_t iDirection = 0;
1753            int32_t iSAD;
1754            VECTOR backupMV;
1755    
1756            backupMV.x = start_x;
1757            backupMV.y = start_y;
1758    
1759    /* It's one search with full square pattern, and new parts for all following diamonds */
1760    
1761    /*   new direction are extra, so 1-4 is normal diamond
1762          537
1763          1*2
1764          648
1765    */
1766    
1767            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1768            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1769            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1770            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1771    
1772            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1773                                                             backupMV.y - iDiamondSize, 5);
1774            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1775                                                             backupMV.y + iDiamondSize, 6);
1776            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1777                                                             backupMV.y - iDiamondSize, 7);
1778            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1779                                                             backupMV.y + iDiamondSize, 8);
1780    
1781    
1782            if (iDirection) {
1783                    while (!iFound) {
1784                            iFound = 1;
1785                            backupMV = *currMV;
1786    
1787                            switch (iDirection) {
1788                            case 1:
1789                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1790                                                                                       backupMV.y, 1);
1791                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1792                                                                                     backupMV.y - iDiamondSize, 5);
1793                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1794                                                                                     backupMV.y - iDiamondSize, 7);
1795                                    break;
1796                            case 2:
1797                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1798                                                                                     2);
1799                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1800                                                                                     backupMV.y + iDiamondSize, 6);
1801                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1802                                                                                     backupMV.y + iDiamondSize, 8);
1803                                    break;
1804    
1805                            case 3:
1806                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1807                                                                                     4);
1808                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1809                                                                                     backupMV.y - iDiamondSize, 7);
1810                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1811                                                                                     backupMV.y + iDiamondSize, 8);
1812                                    break;
1813    
1814                            case 4:
1815                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1816                                                                                     3);
1817                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1818                                                                                     backupMV.y - iDiamondSize, 5);
1819                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1820                                                                                     backupMV.y + iDiamondSize, 6);
1821                                    break;
1822    
1823                            case 5:
1824                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1825                                                                                     1);
1826                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1827                                                                                     3);
1828                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1829                                                                                     backupMV.y - iDiamondSize, 5);
1830                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1831                                                                                     backupMV.y + iDiamondSize, 6);
1832                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1833                                                                                     backupMV.y - iDiamondSize, 7);
1834                                    break;
1835    
1836                            case 6:
1837                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1838                                                                                     2);
1839                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1840                                                                                     3);
1841    
1842                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1843                                                                                     backupMV.y - iDiamondSize, 5);
1844                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1845                                                                                     backupMV.y + iDiamondSize, 6);
1846                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1847                                                                                     backupMV.y + iDiamondSize, 8);
1848    
1849                                    break;
1850    
1851                            case 7:
1852                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1853                                                                                       backupMV.y, 1);
1854                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1855                                                                                     4);
1856                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1857                                                                                     backupMV.y - iDiamondSize, 5);
1858                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1859                                                                                     backupMV.y - iDiamondSize, 7);
1860                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1861                                                                                     backupMV.y + iDiamondSize, 8);
1862                                    break;
1863    
1864                            case 8:
1865                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1866                                                                                     2);
1867                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1868                                                                                     4);
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1870                                                                                     backupMV.y + iDiamondSize, 6);
1871                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1872                                                                                     backupMV.y - iDiamondSize, 7);
1873                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1874                                                                                     backupMV.y + iDiamondSize, 8);
1875                                    break;
1876                            default:
1877                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1878                                                                                     1);
1879                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1880                                                                                     2);
1881                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1882                                                                                     3);
1883                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1884                                                                                     4);
1885    
1886                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1887                                                                                     backupMV.y - iDiamondSize, 5);
1888                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1889                                                                                     backupMV.y + iDiamondSize, 6);
1890                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1891                                                                                     backupMV.y - iDiamondSize, 7);
1892                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1893                                                                                     backupMV.y + iDiamondSize, 8);
1894                                    break;
1895                            }
1896                    }
1897            } else {
1898                    currMV->x = start_x;
1899                    currMV->y = start_y;
1900            }
1901            return iMinSAD;
1902    }
1903    
1904    
1905    
1906    
1907    
1908  int32_t  int32_t
1909  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1910                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1764  Line 2013 
2013          }          }
2014    
2015          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
         //bPredEq = get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad);  
2016          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);
2017    
2018          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 1794  Line 2042 
2042    
2043  // Prepare for main loop  // Prepare for main loop
2044    
2045  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2046  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2047  //  else    else
2048    
2049          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2050                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2079  Line 2327 
2327                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2328          }          }
2329          /* 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; */
         //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);  
2330          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2331    
2332  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2362  Line 2609 
2609                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2610          }          }
2611          /* 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; */
         //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv[0].x, pmv[0].y, psad);  
2612          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);
2613    
2614    
# Line 2474  Line 2720 
2720    
2721  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2722    
2723  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2724  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2725  //  else    else
2726    
2727          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2728                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2542  Line 2788 
2788  }  }
2789    
2790    
2791    /* Disabled bframe specific code */
2792    # if 0
2793  int32_t  int32_t
2794  PMVfastIntSearch16(const uint8_t * const pRef,  PMVfastIntSearch16(const uint8_t * const pRef,
2795                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 2551  Line 2798 
2798                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2799                                  const int x,                                  const int x,
2800                                  const int y,                                  const int y,
2801                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2802                          const int start_y,                          const int start_y,
2803                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2804                          const int center_y,                          const int center_y,
2805                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2806                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2582  Line 2829 
2829          int32_t iFound;          int32_t iFound;
2830    
2831          VECTOR newMV;          VECTOR newMV;
2832          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2833    
2834          VECTOR pmv[4];          VECTOR pmv[4];
2835          int32_t psad[4];          int32_t psad[4];
2836    
2837          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
2838    
2839          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          MACROBLOCK *const prevMB = (MACROBLOCK *const)prevMBs + x + y * iWcount;
2840          MACROBLOCK *const pMB = pMBs + x + y * iWcount;          MACROBLOCK *const pMB = (MACROBLOCK *const)(pMBs + x + y * iWcount);
2841    
2842          int32_t threshA, threshB;          int32_t threshA, threshB;
2843          int32_t bPredEq;          int32_t bPredEq;
# Line 2612  Line 2859 
2859                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2860    
2861          } else {          } else {
2862    
2863                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2864    
2865                  threshA = psad[0];                  threshA = psad[0];
2866                  threshB = threshA + 256;                  threshB = threshA + 256;
2867                  if (threshA < 512)                  if (threshA < 512)
# Line 2621  Line 2871 
2871                  if (threshB > 1792)                  if (threshB > 1792)
2872                          threshB = 1792;                          threshB = 1792;
2873    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2874                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2875          }          }
2876    
# Line 2658  Line 2907 
2907          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
2908                  ((MVequal(*currMV, prevMB->i_mvs[0])) &&                  ((MVequal(*currMV, prevMB->i_mvs[0])) &&
2909                   ((int32_t) iMinSAD < prevMB->i_sad16))) {                   ((int32_t) iMinSAD < prevMB->i_sad16))) {
2910                  if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode                  if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode
2911                  {                  {
2912                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
2913                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
# Line 2827  Line 3076 
3076    
3077          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)
3078    
 PMVfastInt16_Terminate_without_Refine:  
3079          currPMV->x = currMV->x - center_x;          currPMV->x = currMV->x - center_x;
3080          currPMV->y = currMV->y - center_y;          currPMV->y = currMV->y - center_y;
3081          return iMinSAD;          return iMinSAD;
3082  }  }
3083    #endif /* 0 */
   
   
 /* ***********************************************************  
         bvop motion estimation  
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
 ***************************************************************/  
   
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
 void  
 MotionEstimationBVOP(MBParam * const pParam,  
                                          FRAMEINFO * const frame,  
                                          const int32_t time_bp,  
                                          const int32_t time_pp,  
                                          // forward (past) reference  
                                          const MACROBLOCK * const f_mbs,  
                                          const IMAGE * const f_ref,  
                                          const IMAGE * const f_refH,  
                                          const IMAGE * const f_refV,  
                                          const IMAGE * const f_refHV,  
                                          // backward (future) reference  
                                          const MACROBLOCK * const b_mbs,  
                                          const IMAGE * const b_ref,  
                                          const IMAGE * const b_refH,  
                                          const IMAGE * const b_refV,  
                                          const IMAGE * const b_refHV)  
 {  
         const int mb_width = pParam->mb_width;  
         const int mb_height = pParam->mb_height;  
         const int edged_width = pParam->edged_width;  
   
         int i, j, k;  
   
         static const VECTOR zeroMV={0,0};  
   
         int f_sad16;    /* forward (as usual) search */  
         int b_sad16;    /* backward (only in b-frames) search */  
         int i_sad16;    /* interpolated (both direction, b-frames only) */  
         int d_sad16;    /* direct mode (assume linear motion) */  
   
         int best_sad;  
   
         VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/  
         VECTOR pmv_dontcare;  
   
         int f_count=0;  
         int b_count=0;  
         int i_count=0;  
         int d_count=0;  
         int s_count=0;  
   
         const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;  
     const int64_t TRD = (int32_t)time_pp;  
   
         // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);  
         // note: i==horizontal, j==vertical  
         for (j = 0; j < mb_height; j++) {  
   
                 f_predMV = zeroMV;      /* prediction is reset at left boundary */  
                 b_predMV = zeroMV;  
   
                 for (i = 0; i < mb_width; i++) {  
                         MACROBLOCK *mb = &frame->mbs[i + j * mb_width];  
                         const MACROBLOCK *f_mb = &f_mbs[i + j * mb_width];  
                         const MACROBLOCK *b_mb = &b_mbs[i + j * mb_width];  
   
                         mb->deltamv=zeroMV;  
   
 /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  
   
 #ifndef _DISABLE_SKIP  
                         if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&  
                                 b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {  
                                 mb->mode = MODE_NOT_CODED;  
                                 mb->mvs[0].x = 0;  
                                 mb->mvs[0].y = 0;  
                                 mb->b_mvs[0].x = 0;  
                                 mb->b_mvs[0].y = 0;  
                                 continue;  
                         }  
 #endif  
   
                         d_sad16 = DIRECT_PENALTY;  
   
                         if (b_mb->mode == MODE_INTER4V)  
                         {  
   
                         /* same method of scaling as in decoder.c, so we copy from there */  
                     for (k = 0; k < 4; k++) {  
   
                                         mb->directmv[k] = b_mb->mvs[k];  
   
                                         mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);  
                     mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[k].x) / TRD  
                                             : mb->mvs[k].x - mb->directmv[k].x);  
   
                     mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);  
                         mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[k].y) / TRD  
                                             : mb->mvs[k].y - mb->directmv[k].y);  
   
                                         d_sad16 +=  
                                                 sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),  
                                                   edged_width);  
                                 }  
                         }  
                         else  
                         {  
                                 mb->directmv[3] = mb->directmv[2] = mb->directmv[1] =  
                                 mb->directmv[0] = b_mb->mvs[0];  
   
                                 mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);  
                     mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                         ? ((TRB - TRD) * mb->directmv[0].x) / TRD  
                                     : mb->mvs[0].x - mb->directmv[0].x);  
   
                     mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);  
                 mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)  
                                                                         ? ((TRB - TRD) * mb->directmv[0].y) / TRD  
                                     : mb->mvs[0].y - mb->directmv[0].y);  
   
                                 d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
   
             }  
                     d_sad16 += calc_delta_16(mb->deltamv.x, mb->deltamv.y, 1, frame->quant);  
   
                         // forward search  
                         f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                 &frame->image, i, j,  
                                                 mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */  
                                                 f_predMV.x, f_predMV.y,                         /* center is f-prediction */  
                                                 frame->motion_flags,  
                                                 frame->quant, frame->fcode, pParam,  
                                                 f_mbs, f_mbs,  
                                                 &mb->mvs[0], &pmv_dontcare);  
   
   
                         // backward search  
                         b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                 &frame->image, i, j,  
                                                 mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */  
                                                 b_predMV.x, b_predMV.y,                         /* center is b-prediction */  
                                                 frame->motion_flags,  
                                                 frame->quant, frame->bcode, pParam,  
                                                 b_mbs, b_mbs,  
                                                 &mb->b_mvs[0], &pmv_dontcare);  
   
                         i_sad16 =  
                                 sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,  
                                                   get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,  
                                                                 i, j, 16, &mb->mvs[0], edged_width),  
                                                   get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,  
                                                                 i, j, 16, &mb->b_mvs[0], edged_width),  
                                                   edged_width);  
                     i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,  
                                                                 frame->fcode, frame->quant);  
                     i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,  
                                                                 frame->bcode, frame->quant);  
   
                         // TODO: direct search  
                         // predictor + delta vector in range [-32,32] (fcode=1)  
   
                         i_sad16 = 65535;  
                         f_sad16 = 65535;  
                         b_sad16 = 65535;  
 //                      d_sad16 = 65535;  
   
                         if (f_sad16 < b_sad16) {  
                                 best_sad = f_sad16;  
                                 mb->mode = MODE_FORWARD;  
                         } else {  
                                 best_sad = b_sad16;  
                                 mb->mode = MODE_BACKWARD;  
                         }  
   
                         if (i_sad16 < best_sad) {  
                                 best_sad = i_sad16;  
                                 mb->mode = MODE_INTERPOLATE;  
                         }  
   
                         if (d_sad16 < best_sad) {  
   
                                 if (b_mb->mode == MODE_INTER4V)  
                                 {  
   
                                 /* same method of scaling as in decoder.c, so we copy from there */  
                             for (k = 0; k < 4; k++) {  
   
                                                 mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);  
                             mb->b_mvs[k].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                         ? ((TRB - TRD) * mb->directmv[k].x) / TRD  
                                                     : mb->mvs[k].x - mb->directmv[k].x);  
   
                             mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);  
                         mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)  
                                                                                         ? ((TRB - TRD) * mb->directmv[k].y) / TRD  
                                             : mb->mvs[k].y - mb->directmv[k].y);  
                                         }  
                                 }  
                                 else  
                                 {  
                                         mb->mvs[0].x = (int32_t) ((TRB * mb->directmv[0].x) / TRD + mb->deltamv.x);  
   
                     mb->b_mvs[0].x = (int32_t) ((mb->deltamv.x == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[0].x) / TRD  
                                         : mb->mvs[0].x - mb->directmv[0].x);  
   
                             mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);  
   
                         mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)  
                                                                                 ? ((TRB - TRD) * mb->directmv[0].y) / TRD  
                                             : mb->mvs[0].y - mb->directmv[0].y);  
   
                                         mb->mvs[3] = mb->mvs[2] = mb->mvs[1] = mb->mvs[0];  
                                         mb->b_mvs[3] = mb->b_mvs[2] = mb->b_mvs[1] = mb->b_mvs[0];  
                 }  
   
                                 best_sad = d_sad16;  
                                 mb->mode = MODE_DIRECT;  
                                 mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(  
                         }  
   
                         switch (mb->mode)  
                         {  
                                 case MODE_FORWARD:  
                                         f_count++;  
                                         f_predMV = mb->mvs[0];  
                                         break;  
                                 case MODE_BACKWARD:  
                                         b_count++;  
                                         b_predMV = mb->b_mvs[0];  
   
                                         break;  
                                 case MODE_INTERPOLATE:  
                                         i_count++;  
                                         f_predMV = mb->mvs[0];  
                                         b_predMV = mb->b_mvs[0];  
                                         break;  
                                 case MODE_DIRECT:  
                                         d_count++;  
                                         break;  
                                 default:  
                                         s_count++;              // ???  
                                         break;  
                         }  
   
                 }  
         }  
   
 #ifdef _DEBUG_BFRAME_STAT  
         fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",  
                                 f_count,b_count,i_count,d_count,s_count);  
 #endif  
   
 }  

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

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