[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 344, Sat Jul 27 23:07:33 2002 UTC revision 430, Fri Sep 6 16:59:47 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     *  Copyright(C) 2002 chenm001 <chenm001@163.com>
10   *   *
11   *      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
12   *      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 29 
29   *   *
30   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
31   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
32   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
33   *   *
34   *************************************************************************/   *************************************************************************/
35    
 /**************************************************************************  
  *  
  *  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>  
  *  
  **************************************************************************/  
   
36  #include <assert.h>  #include <assert.h>
37  #include <stdio.h>  #include <stdio.h>
38  #include <stdlib.h>  #include <stdlib.h>
# Line 186  Line 154 
154    
155                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
156    
157                            if (pMB->mode == MODE_NOT_CODED)
158                                    continue;
159    
160                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
161    
162                          pMB->sad16 =                          pMB->sad16 =
# Line 554  Line 525 
525                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
526    
527    
528          if (iDirection)          if (iDirection) {
529                  while (!iFound) {                  while (!iFound) {
530                          iFound = 1;                          iFound = 1;
531                          backupMV = *currMV;                          backupMV = *currMV;
# Line 563  Line 534 
534                          case 1:                          case 1:
535                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
536                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
537                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
538                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
539                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
540                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
541                                  break;                                  break;
542                          case 2:                          case 2:
543                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
544                                                                                   2);                                                                                   2);
545                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
546                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
547                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
548                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
549                                  break;                                  break;
550    
551                          case 3:                          case 3:
552                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
553                                                                                   4);                                                                                   4);
554                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
555                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
556                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
557                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
558                                  break;                                  break;
559    
560                          case 4:                          case 4:
561                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
562                                                                                   3);                                                                                   3);
563                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
564                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
565                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
566                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
567                                  break;                                  break;
568    
569                          case 5:                          case 5:
570                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
571                                                                                   1);                                                                                   1);
572                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
573                                                                                   3);                                                                                   3);
574                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
575                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
576                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
577                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
578                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
579                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
580                                  break;                                  break;
581    
582                          case 6:                          case 6:
583                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
584                                                                                   2);                                                                                   2);
585                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
586                                                                                   3);                                                                                   3);
587    
588                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
589                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
590                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
591                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
592                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
593                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
594    
595                                  break;                                  break;
# Line 626  Line 597 
597                          case 7:                          case 7:
598                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
599                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
600                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
601                                                                                   4);                                                                                   4);
602                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
603                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
604                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
605                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
606                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
607                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
608                                  break;                                  break;
609    
610                          case 8:                          case 8:
611                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
612                                                                                   2);                                                                                   2);
613                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
614                                                                                   4);                                                                                   4);
615                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
616                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
617                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
618                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
619                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
620                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
621                                  break;                                  break;
622                          default:                          default:
623                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
624                                                                                   1);                                                                                   1);
625                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
626                                                                                   2);                                                                                   2);
627                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
628                                                                                   3);                                                                                   3);
629                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
630                                                                                   4);                                                                                   4);
631    
632                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
633                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
634                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
635                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
636                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
637                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
638                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
639                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
640                                  break;                                  break;
641                          }                          }
642                    }
643          } else {          } else {
644                  currMV->x = start_x;                  currMV->x = start_x;
645                  currMV->y = start_y;                  currMV->y = start_y;
# Line 873  Line 845 
845          return iMinSAD;          return iMinSAD;
846  }  }
847    
848    #define CHECK_MV16_F_INTERPOL(X,Y) { \
849  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
850    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((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); } } \  
 }  
   
 #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \  
   if ( ((X) <= max_dx) && ((X) >= min_dx) \  
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
851    { \    { \
852      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
853      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),       \
854                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
855                            iEdgedWidth); \
856        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
857        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
858      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
859      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
860  }  }
861    
862  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
863    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
864      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
865    { \    { \
866      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
867      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),       \
868                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
869                            iEdgedWidth); \
870        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
871        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
872      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
873      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
874  }  }
875    
876    #define CHECK_MV16_B_INTERPOL(X,Y) { \
877  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
878    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
879    { \    { \
880      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
881      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),   \
882                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
883                            iEdgedWidth); \
884        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
885        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
886      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
887      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
888  }  }
889    
890    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
891  #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
892    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
893    { \    { \
894      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
895      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),   \
896                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
897                            iEdgedWidth); \
898        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
899        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
900      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
901      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
902  }  }
903    
   
 #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)  
904  int32_t  int32_t
905  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(
906                                          const uint8_t * const f_pRef,                                          const uint8_t * const f_pRef,
907                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
908                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
909                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
910    
911                                           const uint8_t * const cur,                                           const uint8_t * const cur,
912    
913                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 969  Line 932 
932                                     const int b_center_x,                                     const int b_center_x,
933                                     const int b_center_y,                                     const int b_center_y,
934    
935                                           const int32_t min_dx,                                      const int32_t f_min_dx,
936                                           const int32_t max_dx,                                          const int32_t f_max_dx,
937                                           const int32_t min_dy,                                          const int32_t f_min_dy,
938                                           const int32_t max_dy,                                          const int32_t f_max_dy,
939    
940                                        const int32_t b_min_dx,
941                                            const int32_t b_max_dx,
942                                            const int32_t b_min_dy,
943                                            const int32_t b_max_dy,
944    
945                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
946                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
947    
# Line 984  Line 953 
953  {  {
954  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
955    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
956          int32_t iSAD;          int32_t iSAD;
957    
958          VECTOR f_backupMV;          VECTOR f_backupMV;
959          VECTOR b_backupMV;          VECTOR b_backupMV;
960    
961          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
962          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
963          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
964          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
965    
966  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
967            {
968                    iFound = 1;
969    
970          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);  
971    
972          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
973                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
974                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
975                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
976    
977                    b_backupMV = *b_currMV;
978    
979                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
980                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
981                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
982                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
983    
984            } while (!iFound);
985    
986            return iMinSAD;
987    }
988    
989    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
990    
991    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
992            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
993            { int k;\
994            VECTOR mvs,b_mvs;       \
995            iSAD = 0;\
996            for (k = 0; k < 4; k++) {       \
997                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
998                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
999                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
1000                                                : mvs.x - directmv[k].x);                           \
1001                                                                                                                                                                    \
1002                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1003                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1004                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1005                                                : mvs.y - directmv[k].y);                           \
1006                                                                                                                                                                    \
1007      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1008        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1009            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1010        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1011                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1012                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1013                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1014                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1015                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1016                            iEdgedWidth); \
1017                    }       \
1018            else    \
1019                    iSAD = 65535;   \
1020            } \
1021            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1022            if (iSAD < iMinSAD) \
1023                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1024    }
1025    
1026    
1027    
1028    int32_t
1029    Diamond16_DirectMainSearch(
1030                                            const uint8_t * const f_pRef,
1031                                            const uint8_t * const f_pRefH,
1032                                            const uint8_t * const f_pRefV,
1033                                            const uint8_t * const f_pRefHV,
1034    
1035                                            const uint8_t * const cur,
1036    
1037                                            const uint8_t * const b_pRef,
1038                                            const uint8_t * const b_pRefH,
1039                                            const uint8_t * const b_pRefV,
1040                                            const uint8_t * const b_pRefHV,
1041    
1042                                            const int x,
1043                                            const int y,
1044    
1045                                            const int TRB,
1046                                            const int TRD,
1047    
1048                                        const int start_x,
1049                                        const int start_y,
1050    
1051                                        int iMinSAD,
1052                                        VECTOR * const currMV,
1053                                            const VECTOR * const directmv,
1054    
1055                                        const int32_t min_dx,
1056                                            const int32_t max_dx,
1057                                            const int32_t min_dy,
1058                                            const int32_t max_dy,
1059    
1060                                            const int32_t iEdgedWidth,
1061                                            const int32_t iDiamondSize,
1062    
1063                                            const int32_t iQuant,
1064                                            int iFound)
1065    {
1066    /* Do a diamond search around given starting point, return SAD of best */
1067    
1068            int32_t iSAD;
1069    
1070            VECTOR backupMV;
1071    
                         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 {  
1072                  currMV->x = start_x;                  currMV->x = start_x;
1073                  currMV->y = start_y;                  currMV->y = start_y;
1074          }  
1075    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1076    
1077            do
1078            {
1079                    iFound = 1;
1080    
1081                    backupMV = *currMV;
1082    
1083                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1084                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1085                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1086                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1087    
1088            } while (!iFound);
1089    
1090          return iMinSAD;          return iMinSAD;
1091  }  }
 #endif  
1092    
1093    
1094  int32_t  int32_t
# Line 1277  Line 1339 
1339                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1340                                  const int x,                                  const int x,
1341                                  const int y,                                  const int y,
1342                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1343                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1344                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1345                                  const int center_y,                                  const int center_y,
1346                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1347                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1656  Line 1718 
1718          return iMinSAD;          return iMinSAD;
1719  }  }
1720    
1721    
1722    
1723    
1724    int32_t
1725    Square8_MainSearch(const uint8_t * const pRef,
1726                                            const uint8_t * const pRefH,
1727                                            const uint8_t * const pRefV,
1728                                            const uint8_t * const pRefHV,
1729                                            const uint8_t * const cur,
1730                                            const int x,
1731                                            const int y,
1732                                            int32_t start_x,
1733                                            int32_t start_y,
1734                                            int32_t iMinSAD,
1735                                            VECTOR * const currMV,
1736                                       const int center_x,
1737                                       const int center_y,
1738                                            const int32_t min_dx,
1739                                            const int32_t max_dx,
1740                                            const int32_t min_dy,
1741                                            const int32_t max_dy,
1742                                            const int32_t iEdgedWidth,
1743                                            const int32_t iDiamondSize,
1744                                            const int32_t iFcode,
1745                                            const int32_t iQuant,
1746                                            int iFound)
1747    {
1748    /* Do a square search around given starting point, return SAD of best */
1749    
1750            int32_t iDirection = 0;
1751            int32_t iSAD;
1752            VECTOR backupMV;
1753    
1754            backupMV.x = start_x;
1755            backupMV.y = start_y;
1756    
1757    /* It's one search with full square pattern, and new parts for all following diamonds */
1758    
1759    /*   new direction are extra, so 1-4 is normal diamond
1760          537
1761          1*2
1762          648
1763    */
1764    
1765            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1766            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1767            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1768            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1769    
1770            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1771                                                             backupMV.y - iDiamondSize, 5);
1772            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1773                                                             backupMV.y + iDiamondSize, 6);
1774            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1775                                                             backupMV.y - iDiamondSize, 7);
1776            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1777                                                             backupMV.y + iDiamondSize, 8);
1778    
1779    
1780            if (iDirection) {
1781                    while (!iFound) {
1782                            iFound = 1;
1783                            backupMV = *currMV;
1784    
1785                            switch (iDirection) {
1786                            case 1:
1787                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1788                                                                                       backupMV.y, 1);
1789                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1790                                                                                     backupMV.y - iDiamondSize, 5);
1791                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1792                                                                                     backupMV.y - iDiamondSize, 7);
1793                                    break;
1794                            case 2:
1795                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1796                                                                                     2);
1797                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1798                                                                                     backupMV.y + iDiamondSize, 6);
1799                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1800                                                                                     backupMV.y + iDiamondSize, 8);
1801                                    break;
1802    
1803                            case 3:
1804                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1805                                                                                     4);
1806                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1807                                                                                     backupMV.y - iDiamondSize, 7);
1808                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1809                                                                                     backupMV.y + iDiamondSize, 8);
1810                                    break;
1811    
1812                            case 4:
1813                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1814                                                                                     3);
1815                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1816                                                                                     backupMV.y - iDiamondSize, 5);
1817                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1818                                                                                     backupMV.y + iDiamondSize, 6);
1819                                    break;
1820    
1821                            case 5:
1822                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1823                                                                                     1);
1824                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1825                                                                                     3);
1826                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1827                                                                                     backupMV.y - iDiamondSize, 5);
1828                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1829                                                                                     backupMV.y + iDiamondSize, 6);
1830                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1831                                                                                     backupMV.y - iDiamondSize, 7);
1832                                    break;
1833    
1834                            case 6:
1835                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1836                                                                                     2);
1837                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1838                                                                                     3);
1839    
1840                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1841                                                                                     backupMV.y - iDiamondSize, 5);
1842                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1843                                                                                     backupMV.y + iDiamondSize, 6);
1844                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1845                                                                                     backupMV.y + iDiamondSize, 8);
1846    
1847                                    break;
1848    
1849                            case 7:
1850                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1851                                                                                       backupMV.y, 1);
1852                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1853                                                                                     4);
1854                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1855                                                                                     backupMV.y - iDiamondSize, 5);
1856                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1857                                                                                     backupMV.y - iDiamondSize, 7);
1858                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1859                                                                                     backupMV.y + iDiamondSize, 8);
1860                                    break;
1861    
1862                            case 8:
1863                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1864                                                                                     2);
1865                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1866                                                                                     4);
1867                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1868                                                                                     backupMV.y + iDiamondSize, 6);
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1870                                                                                     backupMV.y - iDiamondSize, 7);
1871                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1872                                                                                     backupMV.y + iDiamondSize, 8);
1873                                    break;
1874                            default:
1875                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1876                                                                                     1);
1877                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1878                                                                                     2);
1879                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1880                                                                                     3);
1881                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1882                                                                                     4);
1883    
1884                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1885                                                                                     backupMV.y - iDiamondSize, 5);
1886                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1887                                                                                     backupMV.y + iDiamondSize, 6);
1888                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1889                                                                                     backupMV.y - iDiamondSize, 7);
1890                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1891                                                                                     backupMV.y + iDiamondSize, 8);
1892                                    break;
1893                            }
1894                    }
1895            } else {
1896                    currMV->x = start_x;
1897                    currMV->y = start_y;
1898            }
1899            return iMinSAD;
1900    }
1901    
1902    
1903    
1904    
1905    
1906  int32_t  int32_t
1907  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1908                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1794  Line 2041 
2041    
2042  // Prepare for main loop  // Prepare for main loop
2043    
2044  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2045  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2046  //  else    else
2047    
2048          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2049                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2474  Line 2721 
2721    
2722  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2723    
2724  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2725  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2726  //  else    else
2727    
2728          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2729                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# 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];
# 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 2837  Line 3086 
3086    
3087  /* ***********************************************************  /* ***********************************************************
3088          bvop motion estimation          bvop motion estimation
 // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  
3089  ***************************************************************/  ***************************************************************/
3090    
   
 #define DIRECT_PENALTY 0  
 #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this  
   
3091  void  void
3092  MotionEstimationBVOP(MBParam * const pParam,  MotionEstimationBVOP(MBParam * const pParam,
3093                                           FRAMEINFO * const frame,                                           FRAMEINFO * const frame,
# Line 2866  Line 3110 
3110          const int mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
3111          const int edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
3112    
3113            const int32_t iWidth = pParam->width;
3114            const int32_t iHeight = pParam->height;
3115    
3116          int i, j, k;          int i, j, k;
3117    
3118          static const VECTOR zeroMV={0,0};          static const VECTOR zeroMV={0,0};
# Line 2873  Line 3120 
3120          int f_sad16;    /* forward (as usual) search */          int f_sad16;    /* forward (as usual) search */
3121          int b_sad16;    /* backward (only in b-frames) search */          int b_sad16;    /* backward (only in b-frames) search */
3122          int i_sad16;    /* interpolated (both direction, b-frames only) */          int i_sad16;    /* interpolated (both direction, b-frames only) */
3123          int d_sad16;    /* direct mode (assume linear motion) */          int d_sad16;    /* direct mode (assume almost linear motion) */
3124    
3125          int best_sad;          int best_sad;
3126    
3127          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/          VECTOR f_predMV, b_predMV;      /* there is no prediction for direct mode*/
3128            VECTOR f_interpolMV, b_interpolMV;
3129          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
3130    
3131            int min_dx, max_dx, min_dy, max_dy;
3132            int f_min_dx, f_max_dx, f_min_dy, f_max_dy;
3133            int b_min_dx, b_max_dx, b_min_dy, b_max_dy;
3134    
3135          int f_count=0;          int f_count=0;
3136          int b_count=0;          int b_count=0;
3137          int i_count=0;          int i_count=0;
3138          int d_count=0;          int d_count=0;
         int s_count=0;  
3139    
3140          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;          const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
3141      const int64_t TRD = (int32_t)time_pp;      const int64_t TRD = (int32_t)time_pp;
# Line 2903  Line 3154 
3154    
3155                          mb->deltamv=zeroMV;                          mb->deltamv=zeroMV;
3156    
3157  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */  /* special case, if collocated block is SKIPed: encoding is forward (0,0), cpb=0 without further ado */
3158    
 #ifndef _DISABLE_SKIP  
3159                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
3160                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
3161                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
3162                                  mb->mvs[0].x = 0;                                  mb->b_mvs[0] = mb->mvs[0] = zeroMV;
                                 mb->mvs[0].y = 0;  
                                 mb->b_mvs[0].x = 0;  
                                 mb->b_mvs[0].y = 0;  
3163                                  continue;                                  continue;
3164                          }                          }
 #endif  
   
                         d_sad16 = DIRECT_PENALTY;  
3165    
3166                          if (b_mb->mode == MODE_INTER4V)                          if (b_mb->mode == MODE_INTER4V)
3167                          {                          {
3168                                    d_sad16 = 0;
3169                          /* same method of scaling as in decoder.c, so we copy from there */                          /* same method of scaling as in decoder.c, so we copy from there */
3170                      for (k = 0; k < 4; k++) {                      for (k = 0; k < 4; k++) {
3171    
# Line 2933  Line 3177 
3177                                              : mb->mvs[k].x - mb->directmv[k].x);                                              : mb->mvs[k].x - mb->directmv[k].x);
3178    
3179                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);                      mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3180                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3181                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3182                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3183    
3184                                          d_sad16 +=                                          d_sad16 +=
3185                                                  sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,                                                  sad8bi(frame->image.y + (2*i+(k&1))*8 + (2*j+(k>>1))*8*edged_width,
3186                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3187                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),                                                                  (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->mvs[k], edged_width),
3188                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3189                                                                  2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),                                                                  (2*i+(k&1)), (2*j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
3190                                                    edged_width);                                                    edged_width);
3191                                  }                                  }
3192                          }                          }
# Line 2961  Line 3205 
3205                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                          ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3206                                      : mb->mvs[0].y - mb->directmv[0].y);                                      : mb->mvs[0].y - mb->directmv[0].y);
3207    
3208                                  d_sad16 += sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,                                  d_sad16 = sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3209                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3210                                                                  i, j, 16, &mb->mvs[0], edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
3211                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
# Line 3004  Line 3248 
3248                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,                      i_sad16 += calc_delta_16(mb->b_mvs[0].x-b_predMV.x, mb->b_mvs[0].y-b_predMV.y,
3249                                                                  frame->bcode, frame->quant);                                                                  frame->bcode, frame->quant);
3250    
3251                          // TODO: direct search                          get_range(&f_min_dx, &f_max_dx, &f_min_dy, &f_max_dy, i, j, 16, iWidth, iHeight,
3252                          // predictor + delta vector in range [-32,32] (fcode=1)                            frame->fcode);
3253                            get_range(&b_min_dx, &b_max_dx, &b_min_dy, &b_max_dy, i, j, 16, iWidth, iHeight,
3254                              frame->bcode);
3255    
3256    /* Interpolated MC motion vector search, this is tedious and more complicated because there are
3257       two values for everything, always one for backward and one for forward ME. Still, we don't gain
3258       much from this search, maybe it should simply be skipped and simply current i_sad16 value used
3259       as "optimal". */
3260    
3261                            i_sad16 = Diamond16_InterpolMainSearch(
3262                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3263                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3264                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3265                                                    i, j,
3266                                                    mb->mvs[0].x, mb->mvs[0].y,
3267                                                    mb->b_mvs[0].x, mb->b_mvs[0].y,
3268                                                    i_sad16,
3269                                                    &f_interpolMV, &b_interpolMV,
3270                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3271                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3272                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3273                                                    edged_width,  2,
3274                                                    frame->fcode, frame->bcode,frame->quant,0);
3275    
3276                            i_sad16 = Diamond16_InterpolMainSearch(
3277                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3278                                                    frame->image.y + i * 16 + j * 16 * edged_width,
3279                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3280                                                    i, j,
3281                                                    f_interpolMV.x, f_interpolMV.y,
3282                                                    b_interpolMV.x, b_interpolMV.y,
3283                                                    i_sad16,
3284                                                    &f_interpolMV, &b_interpolMV,
3285                                                    f_predMV.x, f_predMV.y, b_predMV.x, b_predMV.y,
3286                                                    f_min_dx, f_max_dx, f_min_dy, f_max_dy,
3287                                                    b_min_dx, b_max_dx, b_min_dy, b_max_dy,
3288                                                    edged_width,  1,
3289                                                    frame->fcode, frame->bcode,frame->quant,0);             // equiv to halfpel refine
3290    
3291    
3292    /*  DIRECT MODE DELTA VECTOR SEARCH.
3293        This has to be made more effective, but at the moment I'm happy it's running at all */
3294    
3295    /* There are two range restrictions for direct mode: deltaMV is limited to [-32,31] in halfpel units, and
3296       absolute vector must not lie outside of image dimensions. Constraint one is dealt with by CHECK_MV16_DIRECT
3297       and for constraint two we need distance to boundary. This is done by get_range very large fcode (hack!) */
3298    
3299                            get_range(&min_dx, &max_dx, &min_dy, &max_dy, i, j, 16, iWidth, iHeight, 19);
3300    
3301                            d_sad16 = Diamond16_DirectMainSearch(
3302                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3303                                                    frame->image.y + i*16 + j*16*edged_width,
3304                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3305                                                    i, j,
3306                                                    TRB,TRD,
3307                                                    0,0,
3308                                                    d_sad16,
3309                                                    &mb->deltamv,
3310                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3311                                            min_dx, max_dx, min_dy, max_dy,
3312                                                    edged_width, 2, frame->quant, 0);
3313    
3314                            d_sad16 = Diamond16_DirectMainSearch(
3315                                                    f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3316                                                    frame->image.y + i*16 + j*16*edged_width,
3317                                                    b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3318                                                    i, j,
3319                                                    TRB,TRD,
3320                                                    mb->deltamv.x, mb->deltamv.y,
3321                                                    d_sad16,
3322                                                    &mb->deltamv,
3323                                                    mb->directmv, // this has to be pre-initialized with b_mb->mvs[]
3324                                            min_dx, max_dx, min_dy, max_dy,
3325                                                    edged_width, 1, frame->quant, 0);               // equiv to halfpel refine
3326    
3327    
3328                          i_sad16 = 65535;  //                      i_sad16 = 65535;                /* remove the comment to disable any of the MODEs */
3329                          f_sad16 = 65535;  //                      f_sad16 = 65535;
3330                          b_sad16 = 65535;  //                      b_sad16 = 65535;
3331  //                      d_sad16 = 65535;  //                      d_sad16 = 65535;
3332    
3333                          if (f_sad16 < b_sad16) {                          if (f_sad16 < b_sad16) {
# Line 3030  Line 3348 
3348                                  if (b_mb->mode == MODE_INTER4V)                                  if (b_mb->mode == MODE_INTER4V)
3349                                  {                                  {
3350    
3351                                  /* same method of scaling as in decoder.c, so we copy from there */                                  /* how to calc vectors is defined in standard. mvs[] and b_mvs[] are only for motion compensation */
3352                                    /* for the bitstream, the value mb->deltamv is read directly */
3353    
3354                              for (k = 0; k < 4; k++) {                              for (k = 0; k < 4; k++) {
3355    
3356                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);                                                  mb->mvs[k].x = (int32_t) ((TRB * mb->directmv[k].x) / TRD + mb->deltamv.x);
# Line 3039  Line 3359 
3359                                                      : mb->mvs[k].x - mb->directmv[k].x);                                                      : mb->mvs[k].x - mb->directmv[k].x);
3360    
3361                              mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);                              mb->mvs[k].y = (int32_t) ((TRB * mb->directmv[k].y) / TRD + mb->deltamv.y);
3362                          mb->b_mvs[k].y = (int32_t) ((mb->directmv[k].y == 0)                          mb->b_mvs[k].y = (int32_t) ((mb->deltamv.y == 0)
3363                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD                                                                                          ? ((TRB - TRD) * mb->directmv[k].y) / TRD
3364                                              : mb->mvs[k].y - mb->directmv[k].y);                                              : mb->mvs[k].y - mb->directmv[k].y);
3365                                          }                                          }
# Line 3054  Line 3374 
3374    
3375                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);                              mb->mvs[0].y = (int32_t) ((TRB * mb->directmv[0].y) / TRD + mb->deltamv.y);
3376    
3377                          mb->b_mvs[0].y = (int32_t) ((mb->directmv[0].y == 0)                          mb->b_mvs[0].y = (int32_t) ((mb->deltamv.y == 0)
3378                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD                                                                                  ? ((TRB - TRD) * mb->directmv[0].y) / TRD
3379                                              : mb->mvs[0].y - mb->directmv[0].y);                                              : mb->mvs[0].y - mb->directmv[0].y);
3380    
# Line 3064  Line 3384 
3384    
3385                                  best_sad = d_sad16;                                  best_sad = d_sad16;
3386                                  mb->mode = MODE_DIRECT;                                  mb->mode = MODE_DIRECT;
                                 mb->mode = MODE_INTERPOLATE;            // direct mode still broken :-(  
3387                          }                          }
3388    
3389                          switch (mb->mode)                          switch (mb->mode)
# Line 3080  Line 3399 
3399                                          break;                                          break;
3400                                  case MODE_INTERPOLATE:                                  case MODE_INTERPOLATE:
3401                                          i_count++;                                          i_count++;
3402                                            mb->mvs[0] = f_interpolMV;
3403                                            mb->b_mvs[0] = b_interpolMV;
3404                                          f_predMV = mb->mvs[0];                                          f_predMV = mb->mvs[0];
3405                                          b_predMV = mb->b_mvs[0];                                          b_predMV = mb->b_mvs[0];
3406                                          break;                                          break;
# Line 3087  Line 3408 
3408                                          d_count++;                                          d_count++;
3409                                          break;                                          break;
3410                                  default:                                  default:
                                         s_count++;              // ???  
3411                                          break;                                          break;
3412                          }                          }
3413    
# Line 3095  Line 3415 
3415          }          }
3416    
3417  #ifdef _DEBUG_BFRAME_STAT  #ifdef _DEBUG_BFRAME_STAT
3418          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d   S: %04d\n",          fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D: %04d\n",
3419                                  f_count,b_count,i_count,d_count,s_count);                                  f_count,b_count,i_count,d_count);
3420  #endif  #endif
3421    
3422  }  }

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

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