[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 444, Sat Sep 7 13:41:13 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 186  Line 153 
153    
154                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
155    
156                            if (pMB->mode == MODE_NOT_CODED)
157                                    continue;
158    
159                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
160    
161                          pMB->sad16 =                          pMB->sad16 =
# Line 554  Line 524 
524                                                           backupMV.y + iDiamondSize, 8);                                                           backupMV.y + iDiamondSize, 8);
525    
526    
527          if (iDirection)          if (iDirection) {
528                  while (!iFound) {                  while (!iFound) {
529                          iFound = 1;                          iFound = 1;
530                          backupMV = *currMV;                          backupMV = *currMV;
# Line 563  Line 533 
533                          case 1:                          case 1:
534                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
535                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
536                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
537                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
538                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
539                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
540                                  break;                                  break;
541                          case 2:                          case 2:
542                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
543                                                                                   2);                                                                                   2);
544                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
545                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
546                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
547                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
548                                  break;                                  break;
549    
550                          case 3:                          case 3:
551                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
552                                                                                   4);                                                                                   4);
553                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
554                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
555                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
556                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
557                                  break;                                  break;
558    
559                          case 4:                          case 4:
560                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
561                                                                                   3);                                                                                   3);
562                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
563                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
564                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
565                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
566                                  break;                                  break;
567    
568                          case 5:                          case 5:
569                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
570                                                                                   1);                                                                                   1);
571                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
572                                                                                   3);                                                                                   3);
573                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
574                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
575                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
576                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
577                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
578                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
579                                  break;                                  break;
580    
581                          case 6:                          case 6:
582                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
583                                                                                   2);                                                                                   2);
584                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
585                                                                                   3);                                                                                   3);
586    
587                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
588                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
589                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
590                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
591                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
592                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
593    
594                                  break;                                  break;
# Line 626  Line 596 
596                          case 7:                          case 7:
597                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
598                                                                                     backupMV.y, 1);                                                                                     backupMV.y, 1);
599                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
600                                                                                   4);                                                                                   4);
601                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
602                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
603                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
604                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
605                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
606                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
607                                  break;                                  break;
608    
609                          case 8:                          case 8:
610                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
611                                                                                   2);                                                                                   2);
612                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
613                                                                                   4);                                                                                   4);
614                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
615                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
616                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
617                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
618                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
619                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
620                                  break;                                  break;
621                          default:                          default:
622                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
623                                                                                   1);                                                                                   1);
624                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
625                                                                                   2);                                                                                   2);
626                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
627                                                                                   3);                                                                                   3);
628                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
629                                                                                   4);                                                                                   4);
630    
631                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
632                                                                                   backupMV.y - iDiamondSize, 5);                                                                                   backupMV.y - iDiamondSize, 5);
633                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
634                                                                                   backupMV.y + iDiamondSize, 6);                                                                                   backupMV.y + iDiamondSize, 6);
635                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
636                                                                                   backupMV.y - iDiamondSize, 7);                                                                                   backupMV.y - iDiamondSize, 7);
637                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
638                                                                                   backupMV.y + iDiamondSize, 8);                                                                                   backupMV.y + iDiamondSize, 8);
639                                  break;                                  break;
640                          }                          }
641                    }
642          } else {          } else {
643                  currMV->x = start_x;                  currMV->x = start_x;
644                  currMV->y = start_y;                  currMV->y = start_y;
# Line 873  Line 844 
844          return iMinSAD;          return iMinSAD;
845  }  }
846    
847    #define CHECK_MV16_F_INTERPOL(X,Y) { \
848  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
849    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
850    { \    { \
851      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
852      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),       \
853                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
854                            iEdgedWidth); \
855        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
856        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
857      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
858      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \
859  }  }
860    
861  #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \
862    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \
863      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \
864    { \    { \
865      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
866      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),       \
867                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \
868                            iEdgedWidth); \
869        iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\
870        iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\
871      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
872      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \
873  }  }
874    
875  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \  #define CHECK_MV16_B_INTERPOL(X,Y) { \
876    if ( ((X) <= max_dx) && ((X) >= min_dx) \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
877      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
878    { \    { \
879      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
880      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),   \
881                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
882                            iEdgedWidth); \
883        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
884        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
885      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
886      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \
887  }  }
888    
889    #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \
890  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \    if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \
891    if ( ((X) <= max_dx) && ((X) >= min_dx) \      && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \
     && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  
892    { \    { \
893      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16bi( cur, \
894      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),   \
895                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \
896                            iEdgedWidth); \
897        iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\
898        iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\
899      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
900      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \
901  }  }
902    
   
 #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)  
903  int32_t  int32_t
904  Diamond16_InterpolMainSearch(  Diamond16_InterpolMainSearch(
905                                          const uint8_t * const f_pRef,                                          const uint8_t * const f_pRef,
906                                           const uint8_t * const f_pRefH,                                           const uint8_t * const f_pRefH,
907                                           const uint8_t * const f_pRefV,                                           const uint8_t * const f_pRefV,
908                                           const uint8_t * const f_pRefHV,                                           const uint8_t * const f_pRefHV,
909    
910                                           const uint8_t * const cur,                                           const uint8_t * const cur,
911    
912                                          const uint8_t * const b_pRef,                                          const uint8_t * const b_pRef,
# Line 969  Line 931 
931                                     const int b_center_x,                                     const int b_center_x,
932                                     const int b_center_y,                                     const int b_center_y,
933    
934                                           const int32_t min_dx,                                      const int32_t f_min_dx,
935                                           const int32_t max_dx,                                          const int32_t f_max_dx,
936                                           const int32_t min_dy,                                          const int32_t f_min_dy,
937                                           const int32_t max_dy,                                          const int32_t f_max_dy,
938    
939                                        const int32_t b_min_dx,
940                                            const int32_t b_max_dx,
941                                            const int32_t b_min_dy,
942                                            const int32_t b_max_dy,
943    
944                                           const int32_t iEdgedWidth,                                           const int32_t iEdgedWidth,
945                                           const int32_t iDiamondSize,                                           const int32_t iDiamondSize,
946    
# Line 984  Line 952 
952  {  {
953  /* Do a diamond search around given starting point, return SAD of best */  /* Do a diamond search around given starting point, return SAD of best */
954    
         int32_t f_iDirection = 0;  
         int32_t b_iDirection = 0;  
955          int32_t iSAD;          int32_t iSAD;
956    
957          VECTOR f_backupMV;          VECTOR f_backupMV;
958          VECTOR b_backupMV;          VECTOR b_backupMV;
959    
960          f_backupMV.x = start_x;          f_currMV->x = f_start_x;
961          f_backupMV.y = start_y;          f_currMV->y = f_start_y;
962          b_backupMV.x = start_x;          b_currMV->x = b_start_x;
963          b_backupMV.y = start_y;          b_currMV->y = b_start_y;
964    
965  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */          do
966            {
967                    iFound = 1;
968    
969          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);  
970    
971          if (iDirection)                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);
972                  while (!iFound) {                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);
973                          iFound = 1;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);
974                          backupMV = *currMV;                  CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);
975    
976                    b_backupMV = *b_currMV;
977    
978                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);
979                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);
980                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);
981                    CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);
982    
983            } while (!iFound);
984    
985            return iMinSAD;
986    }
987    
988    /* Sorry, these MACROS really got too large... I'll turn them into function soon! */
989    
990    #define CHECK_MV16_DIRECT_FOUND(X,Y) \
991            if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \
992            { int k;\
993            VECTOR mvs,b_mvs;       \
994            iSAD = 0;\
995            for (k = 0; k < 4; k++) {       \
996                                            mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \
997                        b_mvs.x = (int32_t) (((X) == 0)                                                     \
998                                                                                    ? ((TRB - TRD) * directmv[k].x) / TRD   \
999                                                : mvs.x - directmv[k].x);                           \
1000                                                                                                                                                                    \
1001                        mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \
1002                            b_mvs.y = (int32_t) (((Y) == 0)                                                         \
1003                                                                                    ? ((TRB - TRD) * directmv[k].y) / TRD   \
1004                                                : mvs.y - directmv[k].y);                           \
1005                                                                                                                                                                    \
1006      if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \
1007        && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \
1008            && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \
1009        && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \
1010                iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \
1011                            get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1012                                            mvs.x, mvs.y, iEdgedWidth),                                                             \
1013                            get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \
1014                                            b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \
1015                            iEdgedWidth); \
1016                    }       \
1017            else    \
1018                    iSAD = 65535;   \
1019            } \
1020            iSAD += calc_delta_16((X),(Y), 1, iQuant);\
1021            if (iSAD < iMinSAD) \
1022                {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \
1023    }
1024    
1025    
1026    
1027    int32_t
1028    Diamond16_DirectMainSearch(
1029                                            const uint8_t * const f_pRef,
1030                                            const uint8_t * const f_pRefH,
1031                                            const uint8_t * const f_pRefV,
1032                                            const uint8_t * const f_pRefHV,
1033    
1034                                            const uint8_t * const cur,
1035    
1036                                            const uint8_t * const b_pRef,
1037                                            const uint8_t * const b_pRefH,
1038                                            const uint8_t * const b_pRefV,
1039                                            const uint8_t * const b_pRefHV,
1040    
1041                                            const int x,
1042                                            const int y,
1043    
1044                                            const int TRB,
1045                                            const int TRD,
1046    
1047                                        const int start_x,
1048                                        const int start_y,
1049    
1050                                        int iMinSAD,
1051                                        VECTOR * const currMV,
1052                                            const VECTOR * const directmv,
1053    
1054                                        const int32_t min_dx,
1055                                            const int32_t max_dx,
1056                                            const int32_t min_dy,
1057                                            const int32_t max_dy,
1058    
1059                                            const int32_t iEdgedWidth,
1060                                            const int32_t iDiamondSize,
1061    
1062                                            const int32_t iQuant,
1063                                            int iFound)
1064    {
1065    /* Do a diamond search around given starting point, return SAD of best */
1066    
1067            int32_t iSAD;
1068    
1069            VECTOR backupMV;
1070    
                         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 {  
1071                  currMV->x = start_x;                  currMV->x = start_x;
1072                  currMV->y = start_y;                  currMV->y = start_y;
1073          }  
1074    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1075    
1076            do
1077            {
1078                    iFound = 1;
1079    
1080                    backupMV = *currMV;
1081    
1082                    CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);
1083                    CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);
1084                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);
1085                    CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);
1086    
1087            } while (!iFound);
1088    
1089          return iMinSAD;          return iMinSAD;
1090  }  }
 #endif  
1091    
1092    
1093  int32_t  int32_t
# Line 1277  Line 1338 
1338                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
1339                                  const int x,                                  const int x,
1340                                  const int y,                                  const int y,
1341                                  const int start_x,                                  const int start_x,      /* start is searched first, so it should contain the most */
1342                                  const int start_y,                                  const int start_y,  /* likely motion vector for this block */
1343                                  const int center_x,                                  const int center_x,     /* center is from where length of MVs is measured */
1344                                  const int center_y,                                  const int center_y,
1345                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1346                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 1334  Line 1395 
1395          }          }
1396    
1397          /* 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);  
1398          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1399    
1400          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 1656  Line 1716 
1716          return iMinSAD;          return iMinSAD;
1717  }  }
1718    
1719    
1720    
1721    
1722    int32_t
1723    Square8_MainSearch(const uint8_t * const pRef,
1724                                            const uint8_t * const pRefH,
1725                                            const uint8_t * const pRefV,
1726                                            const uint8_t * const pRefHV,
1727                                            const uint8_t * const cur,
1728                                            const int x,
1729                                            const int y,
1730                                            int32_t start_x,
1731                                            int32_t start_y,
1732                                            int32_t iMinSAD,
1733                                            VECTOR * const currMV,
1734                                       const int center_x,
1735                                       const int center_y,
1736                                            const int32_t min_dx,
1737                                            const int32_t max_dx,
1738                                            const int32_t min_dy,
1739                                            const int32_t max_dy,
1740                                            const int32_t iEdgedWidth,
1741                                            const int32_t iDiamondSize,
1742                                            const int32_t iFcode,
1743                                            const int32_t iQuant,
1744                                            int iFound)
1745    {
1746    /* Do a square search around given starting point, return SAD of best */
1747    
1748            int32_t iDirection = 0;
1749            int32_t iSAD;
1750            VECTOR backupMV;
1751    
1752            backupMV.x = start_x;
1753            backupMV.y = start_y;
1754    
1755    /* It's one search with full square pattern, and new parts for all following diamonds */
1756    
1757    /*   new direction are extra, so 1-4 is normal diamond
1758          537
1759          1*2
1760          648
1761    */
1762    
1763            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
1764            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1765            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1766            CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1767    
1768            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1769                                                             backupMV.y - iDiamondSize, 5);
1770            CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,
1771                                                             backupMV.y + iDiamondSize, 6);
1772            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1773                                                             backupMV.y - iDiamondSize, 7);
1774            CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,
1775                                                             backupMV.y + iDiamondSize, 8);
1776    
1777    
1778            if (iDirection) {
1779                    while (!iFound) {
1780                            iFound = 1;
1781                            backupMV = *currMV;
1782    
1783                            switch (iDirection) {
1784                            case 1:
1785                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1786                                                                                       backupMV.y, 1);
1787                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1788                                                                                     backupMV.y - iDiamondSize, 5);
1789                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1790                                                                                     backupMV.y - iDiamondSize, 7);
1791                                    break;
1792                            case 2:
1793                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1794                                                                                     2);
1795                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1796                                                                                     backupMV.y + iDiamondSize, 6);
1797                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1798                                                                                     backupMV.y + iDiamondSize, 8);
1799                                    break;
1800    
1801                            case 3:
1802                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1803                                                                                     4);
1804                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1805                                                                                     backupMV.y - iDiamondSize, 7);
1806                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1807                                                                                     backupMV.y + iDiamondSize, 8);
1808                                    break;
1809    
1810                            case 4:
1811                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1812                                                                                     3);
1813                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1814                                                                                     backupMV.y - iDiamondSize, 5);
1815                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1816                                                                                     backupMV.y + iDiamondSize, 6);
1817                                    break;
1818    
1819                            case 5:
1820                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1821                                                                                     1);
1822                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1823                                                                                     3);
1824                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1825                                                                                     backupMV.y - iDiamondSize, 5);
1826                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1827                                                                                     backupMV.y + iDiamondSize, 6);
1828                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1829                                                                                     backupMV.y - iDiamondSize, 7);
1830                                    break;
1831    
1832                            case 6:
1833                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1834                                                                                     2);
1835                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1836                                                                                     3);
1837    
1838                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1839                                                                                     backupMV.y - iDiamondSize, 5);
1840                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1841                                                                                     backupMV.y + iDiamondSize, 6);
1842                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1843                                                                                     backupMV.y + iDiamondSize, 8);
1844    
1845                                    break;
1846    
1847                            case 7:
1848                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1849                                                                                       backupMV.y, 1);
1850                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1851                                                                                     4);
1852                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1853                                                                                     backupMV.y - iDiamondSize, 5);
1854                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1855                                                                                     backupMV.y - iDiamondSize, 7);
1856                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1857                                                                                     backupMV.y + iDiamondSize, 8);
1858                                    break;
1859    
1860                            case 8:
1861                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1862                                                                                     2);
1863                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1864                                                                                     4);
1865                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1866                                                                                     backupMV.y + iDiamondSize, 6);
1867                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1868                                                                                     backupMV.y - iDiamondSize, 7);
1869                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1870                                                                                     backupMV.y + iDiamondSize, 8);
1871                                    break;
1872                            default:
1873                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,
1874                                                                                     1);
1875                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,
1876                                                                                     2);
1877                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,
1878                                                                                     3);
1879                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,
1880                                                                                     4);
1881    
1882                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1883                                                                                     backupMV.y - iDiamondSize, 5);
1884                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1885                                                                                     backupMV.y + iDiamondSize, 6);
1886                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1887                                                                                     backupMV.y - iDiamondSize, 7);
1888                                    CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1889                                                                                     backupMV.y + iDiamondSize, 8);
1890                                    break;
1891                            }
1892                    }
1893            } else {
1894                    currMV->x = start_x;
1895                    currMV->y = start_y;
1896            }
1897            return iMinSAD;
1898    }
1899    
1900    
1901    
1902    
1903    
1904  int32_t  int32_t
1905  Halfpel8_Refine_c(const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1906                                  const uint8_t * const pRefH,                                  const uint8_t * const pRefH,
# Line 1764  Line 2009 
2009          }          }
2010    
2011          /* 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);  
2012          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);
2013    
2014          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
# Line 1794  Line 2038 
2038    
2039  // Prepare for main loop  // Prepare for main loop
2040    
2041  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2042  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2043  //  else    else
2044    
2045          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2046                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2079  Line 2323 
2323                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2324          }          }
2325          /* 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);  
2326          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);          bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2327    
2328  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2362  Line 2605 
2605                  max_dy = EVEN(max_dy);                  max_dy = EVEN(max_dy);
2606          }          }
2607          /* 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);  
2608          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);
2609    
2610    
# Line 2474  Line 2716 
2716    
2717  // there is no EPZS^2 for inter4v at the moment  // there is no EPZS^2 for inter4v at the moment
2718    
2719  //  if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2720  //      MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
2721  //  else    else
2722    
2723          if (MotionFlags & PMV_ADVANCEDDIAMOND8)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2724                  MainSearchPtr = AdvDiamond8_MainSearch;                  MainSearchPtr = AdvDiamond8_MainSearch;
# Line 2551  Line 2793 
2793                                  const IMAGE * const pCur,                                  const IMAGE * const pCur,
2794                                  const int x,                                  const int x,
2795                                  const int y,                                  const int y,
2796                          const int start_x,                                  const int start_x,              /* start should be most likely vector */
2797                          const int start_y,                          const int start_y,
2798                          const int center_x,                                  const int center_x,             /* center is from where length of MVs is measured */
2799                          const int center_y,                          const int center_y,
2800                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
2801                                  const uint32_t iQuant,                                  const uint32_t iQuant,
# Line 2582  Line 2824 
2824          int32_t iFound;          int32_t iFound;
2825    
2826          VECTOR newMV;          VECTOR newMV;
2827          VECTOR backupMV;                        /* just for PMVFAST */          VECTOR backupMV;
2828    
2829          VECTOR pmv[4];          VECTOR pmv[4];
2830          int32_t psad[4];          int32_t psad[4];
# Line 2612  Line 2854 
2854                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;                  *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2855    
2856          } else {          } else {
2857    
2858                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2859    
2860                  threshA = psad[0];                  threshA = psad[0];
2861                  threshB = threshA + 256;                  threshB = threshA + 256;
2862                  if (threshA < 512)                  if (threshA < 512)
# Line 2621  Line 2866 
2866                  if (threshB > 1792)                  if (threshB > 1792)
2867                          threshB = 1792;                          threshB = 1792;
2868    
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
2869                  *currMV = pmv[0];                       /* current best := prediction */                  *currMV = pmv[0];                       /* current best := prediction */
2870          }          }
2871    
# Line 2833  Line 3077 
3077          return iMinSAD;          return iMinSAD;
3078  }  }
3079    
   
   
 /* ***********************************************************  
         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.444

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