[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 504, Sat Sep 21 11:59:22 2002 UTC revision 677, Tue Nov 26 23:44:11 2002 UTC
# Line 4  Line 4 
4   *  - Motion Estimation module -   *  - Motion Estimation module -
5   *   *
6   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>   *  Copyright(C) 2002 Christoph Lampert <gruel@web.de>
7   *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>   *               2002 Michael Militzer <michael@xvid.org>
  *  Copyright(C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>  
8   *   *
9   *  This program is an implementation of a part of one or more MPEG-4   *  This file is part of XviD, a free MPEG-4 video encoder/decoder
  *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
  *  to use this software module in hardware or software products are  
  *  advised that its use may infringe existing patents or copyrights, and  
  *  any such use would be at such party's own risk.  The original  
  *  developer of this software module and his/her company, and subsequent  
  *  editors and their companies, will have no liability for use of this  
  *  software or modifications or derivatives thereof.  
10   *   *
11   *  This program is free software; you can redistribute it and/or modify   *  XviD is free software; you can redistribute it and/or modify it
12   *  it under the terms of the GNU General Public License as published by   *  under the terms of the GNU General Public License as published by
13   *  the Free Software Foundation; either version 2 of the License, or   *  the Free Software Foundation; either version 2 of the License, or
14   *  (at your option) any later version.   *  (at your option) any later version.
15   *   *
# Line 30  Line 22 
22   *  along with this program; if not, write to the Free Software   *  along with this program; if not, write to the Free Software
23   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24   *   *
25     *  Under section 8 of the GNU General Public License, the copyright
26     *  holders of XVID explicitly forbid distribution in the following
27     *  countries:
28     *
29     *    - Japan
30     *    - United States of America
31     *
32     *  Linking XviD statically or dynamically with other modules is making a
33     *  combined work based on XviD.  Thus, the terms and conditions of the
34     *  GNU General Public License cover the whole combination.
35     *
36     *  As a special exception, the copyright holders of XviD give you
37     *  permission to link XviD with independent modules that communicate with
38     *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
39     *  license terms of these independent modules, and to copy and distribute
40     *  the resulting combined work under terms of your choice, provided that
41     *  every copy of the combined work is accompanied by a complete copy of
42     *  the source code of XviD (the version of XviD used to produce the
43     *  combined work), being distributed under the terms of the GNU General
44     *  Public License plus this exception.  An independent module is a module
45     *  which is not derived from or based on XviD.
46     *
47     *  Note that people who make modified versions of XviD are not obligated
48     *  to grant this special exception for their modified versions; it is
49     *  their choice whether to do so.  The GNU General Public License gives
50     *  permission to release a modified version without this exception; this
51     *  exception also makes it possible to release a modified version which
52     *  carries forward this exception.
53     *
54     * $Id: motion_est.c,v 1.54 2002-11-26 23:44:10 edgomez Exp $
55     *
56   *************************************************************************/   *************************************************************************/
57    
58  #include <assert.h>  #include <assert.h>
# Line 66  Line 89 
89    
90    
91    
92  // mv.length table  /* mv.length table */
93  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
94          1, 2, 3, 4, 6, 7, 7, 7,          1, 2, 3, 4, 6, 7, 7, 7,
95          9, 9, 9, 10, 10, 10, 10, 10,          9, 9, 9, 10, 10, 10, 10, 10,
# Line 722  Line 745 
745    
746                  do {                  do {
747                          iDirection = 0;                          iDirection = 0;
748                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)                          if (bDirection & 1)     /*we only want to check left if we came from the right (our last motion was to the left, up-left or down-left) */
749                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
750    
751                          if (bDirection & 2)                          if (bDirection & 2)
# Line 736  Line 759 
759    
760                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
761    
762                          if (iDirection)         //checking if anything found                          if (iDirection)         /*checking if anything found */
763                          {                          {
764                                  bDirection = iDirection;                                  bDirection = iDirection;
765                                  iDirection = 0;                                  iDirection = 0;
766                                  start_x = currMV->x;                                  start_x = currMV->x;
767                                  start_y = currMV->y;                                  start_y = currMV->y;
768                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     /*our candidate is left or right */
769                                  {                                  {
770                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
771                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
772                                  } else                  // what remains here is up or down                                  } else                  /* what remains here is up or down */
773                                  {                                  {
774                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
775                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
# Line 757  Line 780 
780                                          start_x = currMV->x;                                          start_x = currMV->x;
781                                          start_y = currMV->y;                                          start_y = currMV->y;
782                                  }                                  }
783                          } else                          //about to quit, eh? not so fast....                          } else                          /*about to quit, eh? not so fast.... */
784                          {                          {
785                                  switch (bDirection) {                                  switch (bDirection) {
786                                  case 2:                                  case 2:
# Line 817  Line 840 
840                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
841                                                                                           start_y + iDiamondSize, 1 + 8);                                                                                           start_y + iDiamondSize, 1 + 8);
842                                          break;                                          break;
843                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                /*1+2+4+8 == we didn't find anything at all */
844                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
845                                                                                           start_y - iDiamondSize, 1 + 4);                                                                                           start_y - iDiamondSize, 1 + 4);
846                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
# Line 829  Line 852 
852                                          break;                                          break;
853                                  }                                  }
854                                  if (!iDirection)                                  if (!iDirection)
855                                          break;          //ok, the end. really                                          break;          /*ok, the end. really */
856                                  else {                                  else {
857                                          bDirection = iDirection;                                          bDirection = iDirection;
858                                          start_x = currMV->x;                                          start_x = currMV->x;
# Line 837  Line 860 
860                                  }                                  }
861                          }                          }
862                  }                  }
863                  while (1);                              //forever                  while (1);                              /*forever */
         }  
   
         return iMinSAD;  
 }  
   
 /* Disabled bframe specific code */  
 #if 0  
   
 #define CHECK_MV16_F_INTERPOL(X,Y) { \  
   if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \  
     && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \  
   { \  
     iSAD = sad16bi( cur, \  
                         get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \  
                         get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \  
                         iEdgedWidth); \  
     iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\  
     iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); } } \  
 }  
   
 #define CHECK_MV16_F_INTERPOL_FOUND(X,Y) { \  
   if ( ((X) <= f_max_dx) && ((X) >= f_min_dx) \  
     && ((Y) <= f_max_dy) && ((Y) >= f_min_dy) ) \  
   { \  
     iSAD = sad16bi( cur, \  
                         get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \  
                         get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, b_currMV->x, b_currMV->y, iEdgedWidth),   \  
                         iEdgedWidth); \  
     iSAD += calc_delta_16((X) - f_center_x, (Y) - f_center_y, (uint8_t)f_iFcode, iQuant);\  
     iSAD += calc_delta_16(b_currMV->x - b_center_x, b_currMV->y - b_center_y, (uint8_t)b_iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; f_currMV->x=(X); f_currMV->y=(Y); iFound=0;} } \  
 }  
   
 #define CHECK_MV16_B_INTERPOL(X,Y) { \  
   if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \  
     && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \  
   { \  
     iSAD = sad16bi( cur, \  
                         get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \  
                         get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \  
                         iEdgedWidth); \  
     iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\  
     iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); } } \  
 }  
   
 #define CHECK_MV16_B_INTERPOL_FOUND(X,Y) { \  
   if ( ((X) <= b_max_dx) && ((X) >= b_min_dx) \  
     && ((Y) <= b_max_dy) && ((Y) >= b_min_dy) ) \  
   { \  
     iSAD = sad16bi( cur, \  
                         get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, x, y, 16, f_currMV->x, f_currMV->y, iEdgedWidth),   \  
                         get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, x, y, 16, X, Y, iEdgedWidth),       \  
                         iEdgedWidth); \  
     iSAD += calc_delta_16(f_currMV->x - f_center_x, f_currMV->y - f_center_y, (uint8_t)f_iFcode, iQuant);\  
     iSAD += calc_delta_16((X) - b_center_x, (Y) - b_center_y, (uint8_t)b_iFcode, iQuant);\  
     if (iSAD < iMinSAD) \  
     {  iMinSAD=iSAD; b_currMV->x=(X); b_currMV->y=(Y); iFound=0;} } \  
 }  
   
   
 int32_t  
 Diamond16_InterpolMainSearch(const uint8_t * const f_pRef,  
                                                          const uint8_t * const f_pRefH,  
                                                          const uint8_t * const f_pRefV,  
                                                          const uint8_t * const f_pRefHV,  
   
                                                          const uint8_t * const cur,  
   
                                                          const uint8_t * const b_pRef,  
                                                          const uint8_t * const b_pRefH,  
                                                          const uint8_t * const b_pRefV,  
                                                          const uint8_t * const b_pRefHV,  
   
                                                          const int x,  
                                                          const int y,  
   
                                                          const int f_start_x,  
                                                          const int f_start_y,  
                                                          const int b_start_x,  
                                                          const int b_start_y,  
   
                                                          int iMinSAD,  
                                                          VECTOR * const f_currMV,  
                                                          VECTOR * const b_currMV,  
   
                                                          const int f_center_x,  
                                                          const int f_center_y,  
                                                          const int b_center_x,  
                                                          const int b_center_y,  
   
                                                          const int32_t f_min_dx,  
                                                          const int32_t f_max_dx,  
                                                          const int32_t f_min_dy,  
                                                          const int32_t f_max_dy,  
   
                                                          const int32_t b_min_dx,  
                                                          const int32_t b_max_dx,  
                                                          const int32_t b_min_dy,  
                                                          const int32_t b_max_dy,  
   
                                                          const int32_t iEdgedWidth,  
                                                          const int32_t iDiamondSize,  
   
                                                          const int32_t f_iFcode,  
                                                          const int32_t b_iFcode,  
   
                                                          const int32_t iQuant,  
                                                          int iFound)  
 {  
 /* Do a diamond search around given starting point, return SAD of best */  
   
         int32_t iSAD;  
   
         VECTOR f_backupMV;  
         VECTOR b_backupMV;  
   
         f_currMV->x = f_start_x;  
         f_currMV->y = f_start_y;  
         b_currMV->x = b_start_x;  
         b_currMV->y = b_start_y;  
   
         do  
         {  
                 iFound = 1;  
   
                 f_backupMV = *f_currMV;  
   
                 CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x - iDiamondSize, f_backupMV.y);  
                 CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x + iDiamondSize, f_backupMV.y);  
                 CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y - iDiamondSize);  
                 CHECK_MV16_F_INTERPOL_FOUND(f_backupMV.x, f_backupMV.y + iDiamondSize);  
   
                 b_backupMV = *b_currMV;  
   
                 CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x - iDiamondSize, b_backupMV.y);  
                 CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x + iDiamondSize, b_backupMV.y);  
                 CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y - iDiamondSize);  
                 CHECK_MV16_B_INTERPOL_FOUND(b_backupMV.x, b_backupMV.y + iDiamondSize);  
   
         } while (!iFound);  
   
         return iMinSAD;  
 }  
   
 /* Sorry, these MACROS really got too large... I'll turn them into function soon! */  
   
 #define CHECK_MV16_DIRECT_FOUND(X,Y) \  
         if ( (X)>=(-32) && (X)<=(31) && ((Y)>=-32) && ((Y)<=31) ) \  
         { int k;\  
         VECTOR mvs,b_mvs;       \  
         iSAD = 0;\  
         for (k = 0; k < 4; k++) {       \  
                                         mvs.x = (int32_t) ((TRB * directmv[k].x) / TRD + (X));          \  
                     b_mvs.x = (int32_t) (((X) == 0)                                                     \  
                                                                                 ? ((TRB - TRD) * directmv[k].x) / TRD   \  
                                             : mvs.x - directmv[k].x);                           \  
                                                                                                                                                                 \  
                     mvs.y = (int32_t) ((TRB * directmv[k].y) / TRD + (Y));              \  
                         b_mvs.y = (int32_t) (((Y) == 0)                                                         \  
                                                                                 ? ((TRB - TRD) * directmv[k].y) / TRD   \  
                                             : mvs.y - directmv[k].y);                           \  
                                                                                                                                                                 \  
   if ( (mvs.x <= max_dx) && (mvs.x >= min_dx) \  
     && (mvs.y <= max_dy) && (mvs.y >= min_dy)  \  
         && (b_mvs.x <= max_dx) && (b_mvs.x >= min_dx)  \  
     && (b_mvs.y <= max_dy) && (b_mvs.y >= min_dy) ) { \  
             iSAD += sad8bi( cur + 8*(k&1) + 8*(k>>1)*iEdgedWidth,                                                                                                       \  
                         get_ref(f_pRef, f_pRefH, f_pRefV, f_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \  
                                         mvs.x, mvs.y, iEdgedWidth),                                                             \  
                         get_ref(b_pRef, b_pRefH, b_pRefV, b_pRefHV, 2*x+(k&1), 2*y+(k>>1), 8, \  
                                         b_mvs.x, b_mvs.y, iEdgedWidth),                                                         \  
                         iEdgedWidth); \  
                 }       \  
         else    \  
                 iSAD = 65535;   \  
         } \  
         iSAD += calc_delta_16((X),(Y), 1, iQuant);\  
         if (iSAD < iMinSAD) \  
             {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iFound=0; } \  
864  }  }
865    
   
   
 int32_t  
 Diamond16_DirectMainSearch(  
                                         const uint8_t * const f_pRef,  
                                         const uint8_t * const f_pRefH,  
                                         const uint8_t * const f_pRefV,  
                                         const uint8_t * const f_pRefHV,  
   
                                         const uint8_t * const cur,  
   
                                         const uint8_t * const b_pRef,  
                                         const uint8_t * const b_pRefH,  
                                         const uint8_t * const b_pRefV,  
                                         const uint8_t * const b_pRefHV,  
   
                                         const int x,  
                                         const int y,  
   
                                         const int TRB,  
                                         const int TRD,  
   
                                     const int start_x,  
                                     const int start_y,  
   
                                     int iMinSAD,  
                                     VECTOR * const currMV,  
                                         const VECTOR * const directmv,  
   
                                     const int32_t min_dx,  
                                         const int32_t max_dx,  
                                         const int32_t min_dy,  
                                         const int32_t max_dy,  
   
                                         const int32_t iEdgedWidth,  
                                         const int32_t iDiamondSize,  
   
                                         const int32_t iQuant,  
                                         int iFound)  
 {  
 /* Do a diamond search around given starting point, return SAD of best */  
   
         int32_t iSAD;  
   
         VECTOR backupMV;  
   
         currMV->x = start_x;  
         currMV->y = start_y;  
   
 /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  
   
         do  
         {  
                 iFound = 1;  
   
                 backupMV = *currMV;  
   
                 CHECK_MV16_DIRECT_FOUND(backupMV.x - iDiamondSize, backupMV.y);  
                 CHECK_MV16_DIRECT_FOUND(backupMV.x + iDiamondSize, backupMV.y);  
                 CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y - iDiamondSize);  
                 CHECK_MV16_DIRECT_FOUND(backupMV.x, backupMV.y + iDiamondSize);  
   
         } while (!iFound);  
   
866          return iMinSAD;          return iMinSAD;
867  }  }
868    
 #endif /* 0 */  
   
869  int32_t  int32_t
870  AdvDiamond8_MainSearch(const uint8_t * const pRef,  AdvDiamond8_MainSearch(const uint8_t * const pRef,
871                                             const uint8_t * const pRefH,                                             const uint8_t * const pRefH,
# Line 1133  Line 906 
906    
907                  do {                  do {
908                          iDirection = 0;                          iDirection = 0;
909                          if (bDirection & 1)     //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)                          if (bDirection & 1)     /*we only want to check left if we came from the right (our last motion was to the left, up-left or down-left) */
910                                  CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);                                  CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
911    
912                          if (bDirection & 2)                          if (bDirection & 2)
# Line 1147  Line 920 
920    
921                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
922    
923                          if (iDirection)         //checking if anything found                          if (iDirection)         /*checking if anything found */
924                          {                          {
925                                  bDirection = iDirection;                                  bDirection = iDirection;
926                                  iDirection = 0;                                  iDirection = 0;
927                                  start_x = currMV->x;                                  start_x = currMV->x;
928                                  start_y = currMV->y;                                  start_y = currMV->y;
929                                  if (bDirection & 3)     //our candidate is left or right                                  if (bDirection & 3)     /*our candidate is left or right */
930                                  {                                  {
931                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
932                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);                                          CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
933                                  } else                  // what remains here is up or down                                  } else                  /* what remains here is up or down */
934                                  {                                  {
935                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
936                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
# Line 1168  Line 941 
941                                          start_x = currMV->x;                                          start_x = currMV->x;
942                                          start_y = currMV->y;                                          start_y = currMV->y;
943                                  }                                  }
944                          } else                          //about to quit, eh? not so fast....                          } else                          /*about to quit, eh? not so fast.... */
945                          {                          {
946                                  switch (bDirection) {                                  switch (bDirection) {
947                                  case 2:                                  case 2:
# Line 1227  Line 1000 
1000                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1001                                                                                          start_y + iDiamondSize, 1 + 8);                                                                                          start_y + iDiamondSize, 1 + 8);
1002                                          break;                                          break;
1003                                  default:                //1+2+4+8 == we didn't find anything at all                                  default:                /*1+2+4+8 == we didn't find anything at all */
1004                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1005                                                                                          start_y - iDiamondSize, 1 + 4);                                                                                          start_y - iDiamondSize, 1 + 4);
1006                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
# Line 1239  Line 1012 
1012                                          break;                                          break;
1013                                  }                                  }
1014                                  if (!(iDirection))                                  if (!(iDirection))
1015                                          break;          //ok, the end. really                                          break;          /*ok, the end. really */
1016                                  else {                                  else {
1017                                          bDirection = iDirection;                                          bDirection = iDirection;
1018                                          start_x = currMV->x;                                          start_x = currMV->x;
# Line 1247  Line 1020 
1020                                  }                                  }
1021                          }                          }
1022                  }                  }
1023                  while (1);                              //forever                  while (1);                              /*forever */
1024          }          }
1025          return iMinSAD;          return iMinSAD;
1026  }  }
# Line 1456  Line 1229 
1229          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
1230                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
1231                   ((int32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
1232                  if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode                  if (iMinSAD < (int)(2 * iQuant))        /* high chances for SKIP-mode */
1233                  {                  {
1234                          if (!MVzero(*currMV)) {                          if (!MVzero(*currMV)) {
1235                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
1236                                  CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures                                  CHECK_MV16_ZERO;        /* (0,0) saves space for letterboxed pictures */
1237                                  iMinSAD -= MV16_00_BIAS;                                  iMinSAD -= MV16_00_BIAS;
1238                          }                          }
1239                  }                  }
# Line 1485  Line 1258 
1258  */  */
1259    
1260          if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))          if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))
1261                  iDiamondSize = 1;               // halfpel!                  iDiamondSize = 1;               /* halfpel! */
1262          else          else
1263                  iDiamondSize = 2;               // halfpel!                  iDiamondSize = 2;               /* halfpel! */
1264    
1265          if (!(MotionFlags & PMV_HALFPELDIAMOND16))          if (!(MotionFlags & PMV_HALFPELDIAMOND16))
1266                  iDiamondSize *= 2;                  iDiamondSize *= 2;
# Line 1499  Line 1272 
1272     If MV is (0,0) subtract offset.     If MV is (0,0) subtract offset.
1273  */  */
1274    
1275  // (0,0) is always possible  /* (0,0) is always possible */
1276    
1277          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
1278                  CHECK_MV16_ZERO;                  CHECK_MV16_ZERO;
1279    
1280  // previous frame MV is always possible  /* previous frame MV is always possible */
1281    
1282          if (!MVzero(prevMB->mvs[0]))          if (!MVzero(prevMB->mvs[0]))
1283                  if (!MVequal(prevMB->mvs[0], pmv[0]))                  if (!MVequal(prevMB->mvs[0], pmv[0]))
1284                          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);                          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);
1285    
1286  // left neighbour, if allowed  /* left neighbour, if allowed */
1287    
1288          if (!MVzero(pmv[1]))          if (!MVzero(pmv[1]))
1289                  if (!MVequal(pmv[1], prevMB->mvs[0]))                  if (!MVequal(pmv[1], prevMB->mvs[0]))
# Line 1522  Line 1295 
1295    
1296                                  CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);                                  CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);
1297                          }                          }
1298  // top neighbour, if allowed  /* top neighbour, if allowed */
1299          if (!MVzero(pmv[2]))          if (!MVzero(pmv[2]))
1300                  if (!MVequal(pmv[2], prevMB->mvs[0]))                  if (!MVequal(pmv[2], prevMB->mvs[0]))
1301                          if (!MVequal(pmv[2], pmv[0]))                          if (!MVequal(pmv[2], pmv[0]))
# Line 1533  Line 1306 
1306                                          }                                          }
1307                                          CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);                                          CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);
1308    
1309  // top right neighbour, if allowed  /* top right neighbour, if allowed */
1310                                          if (!MVzero(pmv[3]))                                          if (!MVzero(pmv[3]))
1311                                                  if (!MVequal(pmv[3], prevMB->mvs[0]))                                                  if (!MVequal(pmv[3], prevMB->mvs[0]))
1312                                                          if (!MVequal(pmv[3], pmv[0]))                                                          if (!MVequal(pmv[3], pmv[0]))
# Line 1636  Line 1409 
1409  */  */
1410    
1411    PMVfast16_Terminate_with_Refine:    PMVfast16_Terminate_with_Refine:
1412          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  /* perform final half-pel step  */
1413                  iMinSAD =                  iMinSAD =
1414                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1415                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
# Line 1697  Line 1470 
1470          if (iDirection) {          if (iDirection) {
1471                  while (!iFound) {                  while (!iFound) {
1472                          iFound = 1;                          iFound = 1;
1473                          backupMV = *currMV;     // since iDirection!=0, this is well defined!                          backupMV = *currMV;     /* since iDirection!=0, this is well defined! */
1474                          iDirectionBackup = iDirection;                          iDirectionBackup = iDirection;
1475    
1476                          if (iDirectionBackup != 2)                          if (iDirectionBackup != 2)
# Line 1986  Line 1759 
1759          VECTOR backupMV;          VECTOR backupMV;
1760          VECTOR startMV;          VECTOR startMV;
1761    
1762  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  /*  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; */
1763          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
1764    
1765           int32_t threshA, threshB;           int32_t threshA, threshB;
# Line 2040  Line 1813 
1813  */  */
1814    
1815    
1816  // Prepare for main loop  /* Prepare for main loop  */
1817    
1818    if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
1819        MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
# Line 2084  Line 1857 
1857  */  */
1858    
1859          if ((!MVzero(pmv[0])) || (threshB < 1536 / 4) || (bPredEq))          if ((!MVzero(pmv[0])) || (threshB < 1536 / 4) || (bPredEq))
1860                  iDiamondSize = 1;               // 1 halfpel!                  iDiamondSize = 1;               /* 1 halfpel! */
1861          else          else
1862                  iDiamondSize = 2;               // 2 halfpel = 1 full pixel!                  iDiamondSize = 2;               /* 2 halfpel = 1 full pixel! */
1863    
1864          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1865                  iDiamondSize *= 2;                  iDiamondSize *= 2;
# Line 2099  Line 1872 
1872     If MV is (0,0) subtract offset.     If MV is (0,0) subtract offset.
1873  */  */
1874    
1875  // the median prediction might be even better than mv16  /* the median prediction might be even better than mv16 */
1876    
1877          if (!MVequal(pmv[0], startMV))          if (!MVequal(pmv[0], startMV))
1878                  CHECK_MV8_CANDIDATE(center_x, center_y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
1879    
1880  // (0,0) if needed  /* (0,0) if needed */
1881          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
1882                  if (!MVzero(startMV))                  if (!MVzero(startMV))
1883                          CHECK_MV8_ZERO;                          CHECK_MV8_ZERO;
1884    
1885  // previous frame MV if needed  /* previous frame MV if needed */
1886          if (!MVzero(prevMB->mvs[iSubBlock]))          if (!MVzero(prevMB->mvs[iSubBlock]))
1887                  if (!MVequal(prevMB->mvs[iSubBlock], startMV))                  if (!MVequal(prevMB->mvs[iSubBlock], startMV))
1888                          if (!MVequal(prevMB->mvs[iSubBlock], pmv[0]))                          if (!MVequal(prevMB->mvs[iSubBlock], pmv[0]))
# Line 2125  Line 1898 
1898                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1899          }          }
1900    
1901  // left neighbour, if allowed and needed  /* left neighbour, if allowed and needed */
1902          if (!MVzero(pmv[1]))          if (!MVzero(pmv[1]))
1903                  if (!MVequal(pmv[1], startMV))                  if (!MVequal(pmv[1], startMV))
1904                          if (!MVequal(pmv[1], prevMB->mvs[iSubBlock]))                          if (!MVequal(pmv[1], prevMB->mvs[iSubBlock]))
# Line 2136  Line 1909 
1909                                          }                                          }
1910                                          CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);                                          CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);
1911                                  }                                  }
1912  // top neighbour, if allowed and needed  /* top neighbour, if allowed and needed */
1913          if (!MVzero(pmv[2]))          if (!MVzero(pmv[2]))
1914                  if (!MVequal(pmv[2], startMV))                  if (!MVequal(pmv[2], startMV))
1915                          if (!MVequal(pmv[2], prevMB->mvs[iSubBlock]))                          if (!MVequal(pmv[2], prevMB->mvs[iSubBlock]))
# Line 2148  Line 1921 
1921                                                  }                                                  }
1922                                                  CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);                                                  CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);
1923    
1924  // top right neighbour, if allowed and needed  /* top right neighbour, if allowed and needed */
1925                                                  if (!MVzero(pmv[3]))                                                  if (!MVzero(pmv[3]))
1926                                                          if (!MVequal(pmv[3], startMV))                                                          if (!MVequal(pmv[3], startMV))
1927                                                                  if (!MVequal(pmv[3], prevMB->mvs[iSubBlock]))                                                                  if (!MVequal(pmv[3], prevMB->mvs[iSubBlock]))
# Line 2243  Line 2016 
2016  */  */
2017    
2018    PMVfast8_Terminate_with_Refine:    PMVfast8_Terminate_with_Refine:
2019          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   /* perform final half-pel step  */
2020                  iMinSAD =                  iMinSAD =
2021                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2022                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
# Line 2300  Line 2073 
2073    
2074          static MACROBLOCK *oldMBs = NULL;          static MACROBLOCK *oldMBs = NULL;
2075    
2076  //  const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  /*  const MACROBLOCK * const pMB = pMBs + x + y * iWcount; */
2077          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
2078          MACROBLOCK *oldMB = NULL;          MACROBLOCK *oldMB = NULL;
2079    
# Line 2312  Line 2085 
2085    
2086          if (oldMBs == NULL) {          if (oldMBs == NULL) {
2087                  oldMBs = (MACROBLOCK *) calloc(iWcount * iHcount, sizeof(MACROBLOCK));                  oldMBs = (MACROBLOCK *) calloc(iWcount * iHcount, sizeof(MACROBLOCK));
2088  //      fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  /*      fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK)); */
2089          }          }
2090          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
2091    
# Line 2336  Line 2109 
2109          If SAD<=256 goto Step 10.          If SAD<=256 goto Step 10.
2110  */  */
2111    
2112  // Prepare for main loop  /* Prepare for main loop  */
2113    
2114          currMV->x = start_x;          currMV->x = start_x;
2115          currMV->y = start_y;          currMV->y = start_y;
# Line 2365  Line 2138 
2138                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2139                                            (uint8_t) iFcode, iQuant);                                            (uint8_t) iFcode, iQuant);
2140    
2141  // thresh1 is fixed to 256  /* thresh1 is fixed to 256  */
2142          if ((iMinSAD < 256) ||          if ((iMinSAD < 256) ||
2143                  ((MVequal(*currMV, prevMB->mvs[0])) &&                  ((MVequal(*currMV, prevMB->mvs[0])) &&
2144                   ((int32_t) iMinSAD < prevMB->sad16))) {                   ((int32_t) iMinSAD < prevMB->sad16))) {
# Line 2377  Line 2150 
2150    
2151  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2152    
2153  // previous frame MV  /* previous frame MV  */
2154          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);
2155    
2156  // set threshhold based on Min of Prediction and SAD of collocated block  /* set threshhold based on Min of Prediction and SAD of collocated block */
2157  // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want  /* CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want */
2158    
2159          if ((x == 0) && (y == 0)) {          if ((x == 0) && (y == 0)) {
2160                  thresh2 = 512;                  thresh2 = 512;
# Line 2391  Line 2164 
2164                  thresh2 = MIN(psad[0], iSAD) * 6 / 5 + 128;                  thresh2 = MIN(psad[0], iSAD) * 6 / 5 + 128;
2165          }          }
2166    
2167  // MV=(0,0) is often a good choice  /* MV=(0,0) is often a good choice */
2168    
2169          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
2170    
2171    
2172  // left neighbour, if allowed  /* left neighbour, if allowed */
2173          if (x != 0) {          if (x != 0) {
2174                  if (!(MotionFlags & PMV_HALFPEL16)) {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2175                          pmv[1].x = EVEN(pmv[1].x);                          pmv[1].x = EVEN(pmv[1].x);
# Line 2404  Line 2177 
2177                  }                  }
2178                  CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);
2179          }          }
2180  // top neighbour, if allowed  /* top neighbour, if allowed */
2181          if (y != 0) {          if (y != 0) {
2182                  if (!(MotionFlags & PMV_HALFPEL16)) {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2183                          pmv[2].x = EVEN(pmv[2].x);                          pmv[2].x = EVEN(pmv[2].x);
# Line 2412  Line 2185 
2185                  }                  }
2186                  CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);
2187    
2188  // top right neighbour, if allowed  /* top right neighbour, if allowed */
2189                  if ((uint32_t) x != (iWcount - 1)) {                  if ((uint32_t) x != (iWcount - 1)) {
2190                          if (!(MotionFlags & PMV_HALFPEL16)) {                          if (!(MotionFlags & PMV_HALFPEL16)) {
2191                                  pmv[3].x = EVEN(pmv[3].x);                                  pmv[3].x = EVEN(pmv[3].x);
# Line 2437  Line 2210 
2210    
2211  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
2212    
2213          backupMV = prevMB->mvs[0];      // collocated MV          backupMV = prevMB->mvs[0];      /* collocated MV */
2214          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x);     // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x);     /* acceleration X */
2215          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y);     // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y);     /* acceleration Y  */
2216    
2217          CHECK_MV16_CANDIDATE(backupMV.x, backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x, backupMV.y);
2218    
2219  // left neighbour  /* left neighbour */
2220          if (x != 0)          if (x != 0)
2221                  CHECK_MV16_CANDIDATE((prevMB - 1)->mvs[0].x, (prevMB - 1)->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB - 1)->mvs[0].x, (prevMB - 1)->mvs[0].y);
2222    
2223  // top neighbour  /* top neighbour  */
2224          if (y != 0)          if (y != 0)
2225                  CHECK_MV16_CANDIDATE((prevMB - iWcount)->mvs[0].x,                  CHECK_MV16_CANDIDATE((prevMB - iWcount)->mvs[0].x,
2226                                                           (prevMB - iWcount)->mvs[0].y);                                                           (prevMB - iWcount)->mvs[0].y);
2227    
2228  // right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs  /* right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs  */
2229    
2230          if ((uint32_t) x != iWcount - 1)          if ((uint32_t) x != iWcount - 1)
2231                  CHECK_MV16_CANDIDATE((prevMB + 1)->mvs[0].x, (prevMB + 1)->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB + 1)->mvs[0].x, (prevMB + 1)->mvs[0].y);
2232    
2233  // bottom neighbour, dito  /* bottom neighbour, dito */
2234          if ((uint32_t) y != iHcount - 1)          if ((uint32_t) y != iHcount - 1)
2235                  CHECK_MV16_CANDIDATE((prevMB + iWcount)->mvs[0].x,                  CHECK_MV16_CANDIDATE((prevMB + iWcount)->mvs[0].x,
2236                                                           (prevMB + iWcount)->mvs[0].y);                                                           (prevMB + iWcount)->mvs[0].y);
# Line 2527  Line 2300 
2300  /***************        Choose best MV found     **************/  /***************        Choose best MV found     **************/
2301    
2302    EPZS16_Terminate_with_Refine:    EPZS16_Terminate_with_Refine:
2303          if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)  /* perform final half-pel step  */
2304                  iMinSAD =                  iMinSAD =
2305                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2306                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
# Line 2588  Line 2361 
2361    
2362          const int32_t iSubBlock = ((y & 1) << 1) + (x & 1);          const int32_t iSubBlock = ((y & 1) << 1) + (x & 1);
2363    
2364  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  /*  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; */
2365          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;          const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
2366    
2367          int32_t bPredEq;          int32_t bPredEq;
# Line 2611  Line 2384 
2384          /* 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; */
2385          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);
2386    
   
2387  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
2388          MinSAD=SAD          MinSAD=SAD
2389          If Motion Vector equal to Previous frame motion vector          If Motion Vector equal to Previous frame motion vector
# Line 2619  Line 2391 
2391          If SAD<=256 goto Step 10.          If SAD<=256 goto Step 10.
2392  */  */
2393    
2394  // Prepare for main loop  /* Prepare for main loop  */
2395    
2396    
2397          if (!(MotionFlags & PMV_HALFPEL8)) {          if (!(MotionFlags & PMV_HALFPEL8)) {
# Line 2648  Line 2420 
2420                                           (uint8_t) iFcode, iQuant);                                           (uint8_t) iFcode, iQuant);
2421    
2422    
2423  // thresh1 is fixed to 256  /* thresh1 is fixed to 256  */
2424          if (iMinSAD < 256 / 4) {          if (iMinSAD < 256 / 4) {
2425                  if (MotionFlags & PMV_QUICKSTOP8)                  if (MotionFlags & PMV_QUICKSTOP8)
2426                          goto EPZS8_Terminate_without_Refine;                          goto EPZS8_Terminate_without_Refine;
# Line 2659  Line 2431 
2431  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2432    
2433    
2434  // MV=(0,0) is often a good choice  /* MV=(0,0) is often a good choice */
2435          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
2436    
2437  // previous frame MV  /* previous frame MV  */
2438          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x, prevMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x, prevMB->mvs[iSubBlock].y);
2439    
2440  // left neighbour, if allowed  /* left neighbour, if allowed */
2441          if (psad[1] != MV_MAX_ERROR) {          if (psad[1] != MV_MAX_ERROR) {
2442                  if (!(MotionFlags & PMV_HALFPEL8)) {                  if (!(MotionFlags & PMV_HALFPEL8)) {
2443                          pmv[1].x = EVEN(pmv[1].x);                          pmv[1].x = EVEN(pmv[1].x);
# Line 2673  Line 2445 
2445                  }                  }
2446                  CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);
2447          }          }
2448  // top neighbour, if allowed  /* top neighbour, if allowed */
2449          if (psad[2] != MV_MAX_ERROR) {          if (psad[2] != MV_MAX_ERROR) {
2450                  if (!(MotionFlags & PMV_HALFPEL8)) {                  if (!(MotionFlags & PMV_HALFPEL8)) {
2451                          pmv[2].x = EVEN(pmv[2].x);                          pmv[2].x = EVEN(pmv[2].x);
# Line 2681  Line 2453 
2453                  }                  }
2454                  CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);
2455    
2456  // top right neighbour, if allowed  /* top right neighbour, if allowed */
2457                  if (psad[3] != MV_MAX_ERROR) {                  if (psad[3] != MV_MAX_ERROR) {
2458                          if (!(MotionFlags & PMV_HALFPEL8)) {                          if (!(MotionFlags & PMV_HALFPEL8)) {
2459                                  pmv[3].x = EVEN(pmv[3].x);                                  pmv[3].x = EVEN(pmv[3].x);
# Line 2691  Line 2463 
2463                  }                  }
2464          }          }
2465    
2466  /*  // this bias is zero anyway, at the moment!  #if     0
2467      /* this bias is zero anyway, at the moment!  */
2468    
2469          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) /* && (iMinSAD <= iQuant * 96)  */
2470                  iMinSAD -= MV8_00_BIAS;                  iMinSAD -= MV8_00_BIAS;
2471    
2472  */  #endif
2473    
2474  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
2475     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]
# Line 2718  Line 2491 
2491    
2492  /* default: use best prediction as starting point for one call of EPZS_MainSearch */  /* default: use best prediction as starting point for one call of EPZS_MainSearch */
2493    
2494  // there is no EPZS^2 for inter4v at the moment  /* there is no EPZS^2 for inter4v at the moment  */
2495    
2496    if (MotionFlags & PMV_USESQUARES8)    if (MotionFlags & PMV_USESQUARES8)
2497        MainSearchPtr = Square8_MainSearch;        MainSearchPtr = Square8_MainSearch;
# Line 2774  Line 2547 
2547  /***************        Choose best MV found     **************/  /***************        Choose best MV found     **************/
2548    
2549    EPZS8_Terminate_with_Refine:    EPZS8_Terminate_with_Refine:
2550          if (MotionFlags & PMV_HALFPELREFINE8)   // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)   /* perform final half-pel step  */
2551                  iMinSAD =                  iMinSAD =
2552                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2553                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
# Line 2786  Line 2559 
2559          currPMV->y = currMV->y - center_y;          currPMV->y = currMV->y - center_y;
2560          return iMinSAD;          return iMinSAD;
2561  }  }
   
   
 /* Disabled bframe specific code */  
 # if 0  
 int32_t  
 PMVfastIntSearch16(const uint8_t * const pRef,  
                                 const uint8_t * const pRefH,  
                                 const uint8_t * const pRefV,  
                                 const uint8_t * const pRefHV,  
                                 const IMAGE * const pCur,  
                                 const int x,  
                                 const int y,  
                                 const int start_x,              /* start should be most likely vector */  
                                 const int start_y,  
                                 const int center_x,             /* center is from where length of MVs is measured */  
                                 const int center_y,  
                                 const uint32_t MotionFlags,  
                                 const uint32_t iQuant,  
                                 const uint32_t iFcode,  
                                 const MBParam * const pParam,  
                                 const MACROBLOCK * const pMBs,  
                                 const MACROBLOCK * const prevMBs,  
                                 VECTOR * const currMV,  
                                 VECTOR * const currPMV)  
 {  
         const uint32_t iWcount = pParam->mb_width;  
         const int32_t iWidth = pParam->width;  
         const int32_t iHeight = pParam->height;  
         const int32_t iEdgedWidth = pParam->edged_width;  
   
         const uint8_t *cur = pCur->y + x * 16 + y * 16 * iEdgedWidth;  
         const VECTOR zeroMV = { 0, 0 };  
   
         int32_t iDiamondSize;  
   
         int32_t min_dx;  
         int32_t max_dx;  
         int32_t min_dy;  
         int32_t max_dy;  
   
         int32_t iFound;  
   
         VECTOR newMV;  
         VECTOR backupMV;  
   
         VECTOR pmv[4];  
         int32_t psad[4];  
   
         MainSearch16FuncPtr MainSearchPtr;  
   
         MACROBLOCK *const prevMB = (MACROBLOCK *const)prevMBs + x + y * iWcount;  
         MACROBLOCK *const pMB = (MACROBLOCK *const)(pMBs + x + y * iWcount);  
   
         int32_t threshA, threshB;  
         int32_t bPredEq;  
         int32_t iMinSAD, iSAD;  
   
   
 /* Get maximum range */  
         get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,  
                           iFcode);  
   
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
         if ((x == 0) && (y == 0)) {  
                 threshA = 512;  
                 threshB = 1024;  
   
                 bPredEq = 0;  
                 psad[0] = psad[1] = psad[2] = psad[3] = 0;  
                 *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;  
   
         } else {  
   
                 bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);  
   
                 threshA = psad[0];  
                 threshB = threshA + 256;  
                 if (threshA < 512)  
                         threshA = 512;  
                 if (threshA > 1024)  
                         threshA = 1024;  
                 if (threshB > 1792)  
                         threshB = 1792;  
   
                 *currMV = pmv[0];                       /* current best := prediction */  
         }  
   
         iFound = 0;  
   
 /* Step 4: Calculate SAD around the Median prediction.  
    MinSAD=SAD  
    If Motion Vector equal to Previous frame motion vector  
    and MinSAD<PrevFrmSAD goto Step 10.  
    If SAD<=256 goto Step 10.  
 */  
   
         if (currMV->x > max_dx) {  
                 currMV->x = EVEN(max_dx);  
         }  
         if (currMV->x < min_dx) {  
                 currMV->x = EVEN(min_dx);  
         }  
         if (currMV->y > max_dy) {  
                 currMV->y = EVEN(max_dy);  
         }  
         if (currMV->y < min_dy) {  
                 currMV->y = EVEN(min_dy);  
         }  
   
         iMinSAD =  
                 sad16(cur,  
                           get_iref_mv(pRef, x, y, 16, currMV,  
                                                  iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);  
         iMinSAD +=  
                 calc_delta_16(currMV->x - center_x, currMV->y - center_y,  
                                           (uint8_t) iFcode, iQuant);  
   
         if ((iMinSAD < 256) ||  
                 ((MVequal(*currMV, prevMB->i_mvs[0])) &&  
                  ((int32_t) iMinSAD < prevMB->i_sad16))) {  
                 if (iMinSAD < (int)(2 * iQuant))        // high chances for SKIP-mode  
                 {  
                         if (!MVzero(*currMV)) {  
                                 iMinSAD += MV16_00_BIAS;  
                                 CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures  
                                 iMinSAD -= MV16_00_BIAS;  
                         }  
                 }  
   
                 if (MotionFlags & PMV_EARLYSTOP16)  
                         goto PMVfastInt16_Terminate_with_Refine;  
         }  
   
   
 /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0], prevMB->i_mvs[0])))  
                 iFound = 2;  
   
 /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))  
                 iDiamondSize = 2;               // halfpel units!  
         else  
                 iDiamondSize = 4;               // halfpel units!  
   
 /*  
    Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.  
    Also calculate (0,0) but do not subtract offset.  
    Let MinSAD be the smallest SAD up to this point.  
    If MV is (0,0) subtract offset.  
 */  
   
 // (0,0) is often a good choice  
   
         if (!MVzero(pmv[0]))  
                 CHECK_MV16_ZERO;  
   
 // previous frame MV is always possible  
   
         if (!MVzero(prevMB->i_mvs[0]))  
                 if (!MVequal(prevMB->i_mvs[0], pmv[0]))  
                         CHECK_MV16_CANDIDATE(prevMB->i_mvs[0].x, prevMB->i_mvs[0].y);  
   
 // left neighbour, if allowed  
   
         if (!MVzero(pmv[1]))  
                 if (!MVequal(pmv[1], prevMB->i_mvs[0]))  
                         if (!MVequal(pmv[1], pmv[0]))  
                                 CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);  
   
 // top neighbour, if allowed  
         if (!MVzero(pmv[2]))  
                 if (!MVequal(pmv[2], prevMB->i_mvs[0]))  
                         if (!MVequal(pmv[2], pmv[0]))  
                                 if (!MVequal(pmv[2], pmv[1]))  
                                         CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);  
   
 // top right neighbour, if allowed  
                                         if (!MVzero(pmv[3]))  
                                                 if (!MVequal(pmv[3], prevMB->i_mvs[0]))  
                                                         if (!MVequal(pmv[3], pmv[0]))  
                                                                 if (!MVequal(pmv[3], pmv[1]))  
                                                                         if (!MVequal(pmv[3], pmv[2]))  
                                                                                 CHECK_MV16_CANDIDATE(pmv[3].x,  
                                                                                                                          pmv[3].y);  
   
         if ((MVzero(*currMV)) &&  
                 (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )  
                 iMinSAD -= MV16_00_BIAS;  
   
   
 /* Step 6: If MinSAD <= thresa goto Step 10.  
    If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.  
 */  
   
         if ((iMinSAD <= threshA) ||  
                 (MVequal(*currMV, prevMB->i_mvs[0]) &&  
                  ((int32_t) iMinSAD < prevMB->i_sad16))) {  
   
                 if (MotionFlags & PMV_EARLYSTOP16)  
                         goto PMVfastInt16_Terminate_with_Refine;  
         }  
   
   
 /************ (Diamond Search)  **************/  
 /*  
    Step 7: Perform Diamond search, with either the small or large diamond.  
    If Found=2 only examine one Diamond pattern, and afterwards goto step 10  
    Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond.  
    If center then goto step 10.  
    Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center.  
    Refine by using small diamond and goto step 10.  
 */  
   
         if (MotionFlags & PMV_USESQUARES16)  
                 MainSearchPtr = Square16_MainSearch;  
         else if (MotionFlags & PMV_ADVANCEDDIAMOND16)  
                 MainSearchPtr = AdvDiamond16_MainSearch;  
         else  
                 MainSearchPtr = Diamond16_MainSearch;  
   
         backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */  
   
   
 /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  
         iSAD =  
                 (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,  
                                                   currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,  
                                                   min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,  
                                                   iQuant, iFound);  
   
         if (iSAD < iMinSAD) {  
                 *currMV = newMV;  
                 iMinSAD = iSAD;  
         }  
   
         if (MotionFlags & PMV_EXTSEARCH16) {  
 /* extended: search (up to) two more times: orignal prediction and (0,0) */  
   
                 if (!(MVequal(pmv[0], backupMV))) {  
                         iSAD =  
                                 (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,  
                                                                   pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,  
                                                                   min_dx, max_dx, min_dy, max_dy, iEdgedWidth,  
                                                                   iDiamondSize, iFcode, iQuant, iFound);  
   
                         if (iSAD < iMinSAD) {  
                                 *currMV = newMV;  
                                 iMinSAD = iSAD;  
                         }  
                 }  
   
                 if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {  
                         iSAD =  
                                 (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,  
                                                                   iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,  
                                                                   max_dy, iEdgedWidth, iDiamondSize, iFcode,  
                                                                   iQuant, iFound);  
   
                         if (iSAD < iMinSAD) {  
                                 *currMV = newMV;  
                                 iMinSAD = iSAD;  
                         }  
                 }  
         }  
   
 /*  
    Step 10:  The motion vector is chosen according to the block corresponding to MinSAD.  
 */  
   
 PMVfastInt16_Terminate_with_Refine:  
   
         pMB->i_mvs[0] = pMB->i_mvs[1] = pMB->i_mvs[2] = pMB->i_mvs[3] = pMB->i_mv16 = *currMV;  
         pMB->i_sad8[0] = pMB->i_sad8[1] = pMB->i_sad8[2] = pMB->i_sad8[3] = pMB->i_sad16 = iMinSAD;  
   
         if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step  
                 iMinSAD =  
                         Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,  
                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,  
                                                          iFcode, iQuant, iEdgedWidth);  
   
         pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)  
   
         currPMV->x = currMV->x - center_x;  
         currPMV->y = currMV->y - center_y;  
         return iMinSAD;  
 }  
 #endif /* 0 */  

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

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