[svn] / trunk / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/motion_est.c

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

revision 184, Mon May 27 18:07:38 2002 UTC revision 326, Sun Jul 21 23:34:08 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /**************************************************************************
2   *   *
3     *      XVID MPEG-4 VIDEO CODEC
4     *      motion estimation
5     *
6     *      This program is an implementation of a part of one or more MPEG-4
7     *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
8     *      to use this software module in hardware or software products are
9     *      advised that its use may infringe existing patents or copyrights, and
10     *      any such use would be at such party's own risk.  The original
11     *      developer of this software module and his/her company, and subsequent
12     *      editors and their companies, will have no liability for use of this
13     *      software or modifications or derivatives thereof.
14     *
15     *      This program is free software; you can redistribute it and/or modify
16     *      it under the terms of the GNU General Public License as published by
17     *      the Free Software Foundation; either version 2 of the License, or
18     *      (at your option) any later version.
19     *
20     *      This program is distributed in the hope that it will be useful,
21     *      but WITHOUT ANY WARRANTY; without even the implied warranty of
22     *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     *      GNU General Public License for more details.
24     *
25     *      You should have received a copy of the GNU General Public License
26     *      along with this program; if not, write to the Free Software
27     *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28     *
29     *************************************************************************/
30    
31    /**************************************************************************
32     *
33   *  Modifications:   *  Modifications:
34   *   *
35   *      01.05.2002      updated MotionEstimationBVOP   *      01.05.2002      updated MotionEstimationBVOP
# Line 47  Line 77 
77  #include "motion.h"  #include "motion.h"
78  #include "sad.h"  #include "sad.h"
79    
 // very large value  
 #define MV_MAX_ERROR    (4096 * 256)  
   
 // stop search if sdelta < THRESHOLD  
 #define MV16_THRESHOLD  192  
 #define MV8_THRESHOLD   56  
   
 #define NEIGH_MOVE_THRESH 0  
 // how much a block's MV must differ from his neighbour  
 // to be search for INTER4V. The more, the faster...  
   
 /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  
 /* nb  = vop pixels * 2^(bpp-8) */  
 #define MV16_00_BIAS    (128+1)  
 #define MV8_00_BIAS     (0)  
   
 /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  
 #define MV16_INTER_BIAS 512  
   
 /* Parameters which control inter/inter4v decision */  
 #define IMV16X16                        5  
   
 /* vector map (vlc delta size) smoother parameters */  
 #define NEIGH_TEND_16X16        2  
 #define NEIGH_TEND_8X8          2  
   
 // fast ((A)/2)*2  
 #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  
   
 #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )  
 #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )  
   
 int32_t PMVfastSearch16(  
                                         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 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);  
   
 int32_t EPZSSearch16(  
                                         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 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);  
   
   
 int32_t PMVfastSearch8(  
                                         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, const int start_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);  
   
 int32_t EPZSSearch8(  
                                         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, const int start_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);  
   
   
 typedef int32_t (MainSearch16Func)(  
         const uint8_t * const pRef,  
         const uint8_t * const pRefH,  
         const uint8_t * const pRefV,  
         const uint8_t * const pRefHV,  
         const uint8_t * const cur,  
         const int x, const int y,  
         int32_t startx, int32_t starty,  
         int32_t iMinSAD,  
         VECTOR * const currMV,  
         const VECTOR * const pmv,  
         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 iFcode,  
         const int32_t iQuant,  
         int iFound);  
   
 typedef MainSearch16Func* MainSearch16FuncPtr;  
   
   
 typedef int32_t (MainSearch8Func)(  
         const uint8_t * const pRef,  
         const uint8_t * const pRefH,  
         const uint8_t * const pRefV,  
         const uint8_t * const pRefHV,  
         const uint8_t * const cur,  
         const int x, const int y,  
         int32_t startx, int32_t starty,  
         int32_t iMinSAD,  
         VECTOR * const currMV,  
         const VECTOR * const pmv,  
         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 iFcode,  
         const int32_t iQuant,  
         int iFound);  
80    
 typedef MainSearch8Func* MainSearch8FuncPtr;  
81    
82  static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */  static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
83          {     0    ,(int)(1.00235+0.5), (int)(1.15582+0.5), (int)(1.31976+0.5), (int)(1.49591+0.5), (int)(1.68601+0.5),  { 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),
84          (int)(1.89187+0.5), (int)(2.11542+0.5), (int)(2.35878+0.5), (int)(2.62429+0.5), (int)(2.91455+0.5),                  (int) (1.49591 + 0.5), (int) (1.68601 + 0.5),
85          (int)(3.23253+0.5), (int)(3.58158+0.5), (int)(3.96555+0.5), (int)(4.38887+0.5), (int)(4.85673+0.5),          (int) (1.89187 + 0.5), (int) (2.11542 + 0.5), (int) (2.35878 + 0.5),
86          (int)(5.37519+0.5), (int)(5.95144+0.5), (int)(6.59408+0.5), (int)(7.31349+0.5), (int)(8.12242+0.5),                  (int) (2.62429 + 0.5), (int) (2.91455 + 0.5),
87          (int)(9.03669+0.5), (int)(10.0763+0.5), (int)(11.2669+0.5), (int)(12.6426+0.5), (int)(14.2493+0.5),          (int) (3.23253 + 0.5), (int) (3.58158 + 0.5), (int) (3.96555 + 0.5),
88          (int)(16.1512+0.5), (int)(18.442+0.5),  (int)(21.2656+0.5), (int)(24.8580+0.5), (int)(29.6436+0.5),                  (int) (4.38887 + 0.5), (int) (4.85673 + 0.5),
89          (int)(36.4949+0.5)      };          (int) (5.37519 + 0.5), (int) (5.95144 + 0.5), (int) (6.59408 + 0.5),
90                    (int) (7.31349 + 0.5), (int) (8.12242 + 0.5),
91            (int) (9.03669 + 0.5), (int) (10.0763 + 0.5), (int) (11.2669 + 0.5),
92                    (int) (12.6426 + 0.5), (int) (14.2493 + 0.5),
93            (int) (16.1512 + 0.5), (int) (18.442 + 0.5), (int) (21.2656 + 0.5),
94                    (int) (24.8580 + 0.5), (int) (29.6436 + 0.5),
95            (int) (36.4949 + 0.5)
96    };
97    
98  static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/  static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
99    
# Line 212  Line 108 
108  };  };
109    
110    
111  static __inline uint32_t mv_bits(int32_t component, const uint32_t iFcode)  static __inline uint32_t
112    mv_bits(int32_t component,
113                    const uint32_t iFcode)
114  {  {
115      if (component == 0)      if (component == 0)
116                  return 1;                  return 1;
# Line 220  Line 118 
118      if (component < 0)      if (component < 0)
119                  component = -component;                  component = -component;
120    
121      if (iFcode == 1)          if (iFcode == 1) {
     {  
122                  if (component > 32)                  if (component > 32)
123                      component = 32;                      component = 32;
124    
# Line 238  Line 135 
135  }  }
136    
137    
138  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)  static __inline uint32_t
139    calc_delta_16(const int32_t dx,
140                              const int32_t dy,
141                              const uint32_t iFcode,
142                              const uint32_t iQuant)
143  {  {
144          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) +
145                                                                                                              mv_bits(dy, iFcode));
146  }  }
147    
148  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)  static __inline uint32_t
149    calc_delta_8(const int32_t dx,
150                             const int32_t dy,
151                             const uint32_t iFcode,
152                             const uint32_t iQuant)
153  {  {
154      return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) +
155                                                                                                       mv_bits(dy, iFcode));
156  }  }
157    
158    bool
159    MotionEstimation(MBParam * const pParam,
   
   
 #ifndef SEARCH16  
 #define SEARCH16        PMVfastSearch16  
 //#define SEARCH16      FullSearch16  
 //#define SEARCH16      EPZSSearch16  
 #endif  
   
 #ifndef SEARCH8  
 #define SEARCH8         PMVfastSearch8  
 //#define SEARCH8       EPZSSearch8  
 #endif  
   
 bool MotionEstimation(  
         MBParam * const pParam,  
160          FRAMEINFO * const current,          FRAMEINFO * const current,
161          FRAMEINFO * const reference,          FRAMEINFO * const reference,
162          const IMAGE * const pRefH,          const IMAGE * const pRefH,
# Line 280  Line 171 
171          const IMAGE * const pCurrent = &current->image;          const IMAGE * const pCurrent = &current->image;
172          const IMAGE * const pRef = &reference->image;          const IMAGE * const pRef = &reference->image;
173    
174          const VECTOR zeroMV = {0,0};          static const VECTOR zeroMV = { 0, 0 };
175            VECTOR predMV;
176    
177          int32_t x, y;          int32_t x, y;
178          int32_t iIntra = 0;          int32_t iIntra = 0;
# Line 289  Line 181 
181          if (sadInit)          if (sadInit)
182                  (*sadInit)();                  (*sadInit)();
183    
184          for (y = 0; y < iHcount; y++)          for (y = 0; y < iHcount; y++)   {
185                  for (x = 0; x < iWcount; x++)                  for (x = 0; x < iWcount; x ++)  {
186                  {  
187                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
188    
189                          pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
                                                  x, y, current->motion_flags, current->quant, current->fcode,  
                                                  pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);  
190    
191                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))                          pMB->sad16 =
192                          {                                  SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
193                                                     x, y, predMV.x, predMV.y, predMV.x, predMV.y,
194                                                     current->motion_flags, current->quant,
195                                                     current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,
196                                                     &pMB->pmvs[0]);
197    
198                            if (0 < (pMB->sad16 - MV16_INTER_BIAS)) {
199                                  int32_t deviation;                                  int32_t deviation;
                                 deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, pParam->edged_width);  
200    
201                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))                                  deviation =
202                                  {                                          dev16(pCurrent->y + x * 16 + y * 16 * pParam->edged_width,
203                                                      pParam->edged_width);
204    
205                                    if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) {
206                                          pMB->mode = MODE_INTRA;                                          pMB->mode = MODE_INTRA;
207                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = zeroMV;                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =
208                                          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;                                                  pMB->mvs[3] = zeroMV;
209                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] =
210                                                    pMB->sad8[3] = 0;
211    
212                                          iIntra++;                                          iIntra++;
213                                          if (iIntra >= iLimit)                                          if (iIntra >= iLimit)
# Line 319  Line 219 
219    
220                          pmv = pMB->pmvs[0];                          pmv = pMB->pmvs[0];
221                          if (current->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
222                                  if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) )                                  if ((!(current->global_flags & XVID_LUMIMASKING) ||
223                                  {                                           pMB->dquant == NO_CHANGE)) {
224                                          int32_t sad8 = IMV16X16 * current->quant; if (sad8 < pMB->sad16)                                          int32_t sad8 = IMV16X16 * current->quant;
225    
226                                          sad8 += pMB->sad8[0]            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          if (sad8 < pMB->sad16) {
227                                                                                                                          2*x, 2*y, pMB->mv16.x, pMB->mv16.y,                                                  sad8 += pMB->sad8[0] =
228                                                                                                                          current->motion_flags, current->quant, current->fcode,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
229                                                                                                                          pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                                          pCurrent, 2 * x, 2 * y,
230                                                                            pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
231                                          if (sad8 < pMB->sad16)                                                                          current->motion_flags,
232                                                  sad8 += pMB->sad8[1]    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                                                          current->quant, current->fcode, pParam,
233                                                                                                                          2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,                                                                          pMBs, prevMBs, &pMB->mvs[0],
234                                                                                                                          current->motion_flags, current->quant, current->fcode,                                                                          &pMB->pmvs[0]);
235                                                                                                                          pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                          }
236                                            if (sad8 < pMB->sad16) {
237                                          if (sad8 < pMB->sad16)  
238                                                  sad8 += pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                                  predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 1);
239                                                                                                                          2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,                                                  sad8 += pMB->sad8[1] =
240                                                                                                                          current->motion_flags, current->quant, current->fcode,                                                          SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
241                                                                                                                          pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                                          pCurrent, 2 * x + 1, 2 * y,
242                                                                            pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
243                                          if (sad8 < pMB->sad16)                                                                          current->motion_flags,
244                                                  sad8 += pMB->sad8[3]    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                                                          current->quant, current->fcode, pParam,
245                                                                                                                          2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,                                                                          pMBs, prevMBs, &pMB->mvs[1],
246                                                                                                                          current->motion_flags, current->quant, current->fcode,                                                                          &pMB->pmvs[1]);
247                                                                                                                          pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                          }
248                                            if (sad8 < pMB->sad16) {
249                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 2);
250                                                    sad8 += pMB->sad8[2] =
251                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
252                                                                            pCurrent, 2 * x, 2 * y + 1,
253                                                                            pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
254                                                                            current->motion_flags,
255                                                                            current->quant, current->fcode, pParam,
256                                                                            pMBs, prevMBs, &pMB->mvs[2],
257                                                                            &pMB->pmvs[2]);
258                                            }
259                                            if (sad8 < pMB->sad16) {
260                                                    predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 3);
261                                                    sad8 += pMB->sad8[3] =
262                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
263                                                                            pCurrent, 2 * x + 1, 2 * y + 1,
264                                                                            pMB->mv16.x, pMB->mv16.y, predMV.x, predMV.y,
265                                                                            current->motion_flags,
266                                                                            current->quant, current->fcode, pParam,
267                                                                            pMBs, prevMBs,
268                                                                            &pMB->mvs[3],
269                                                                            &pMB->pmvs[3]);
270                                            }
271    
272                                          /* decide: MODE_INTER or MODE_INTER4V                                          /* decide: MODE_INTER or MODE_INTER4V
273                                                  mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v                                                  mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
274                                          */                                          */
275    
276                                          if (sad8 < pMB->sad16)                                          if (sad8 < pMB->sad16) {
                                         {  
277                                                  pMB->mode = MODE_INTER4V;                                                  pMB->mode = MODE_INTER4V;
278                              pMB->sad8[0] *= 4;                              pMB->sad8[0] *= 4;
279                                                  pMB->sad8[1] *= 4;                                                  pMB->sad8[1] *= 4;
# Line 365  Line 287 
287                                  pMB->mode = MODE_INTER;                                  pMB->mode = MODE_INTER;
288                                  pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3]  are not needed for INTER */                                  pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3]  are not needed for INTER */
289                                  pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;                                  pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
290                                  pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;                          pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =
291                                    pMB->sad16;
292                  }                  }
293                            }
294    
295                  return 0;                  return 0;
296  }  }
297    
298    
299  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
300    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
301      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
302    { \    { \
303      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \
304      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
305      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
306      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
307  }  }
308    
309  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
310      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
311      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
312      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
313      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
314  }  }
# Line 393  Line 318 
318      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
319    { \    { \
320      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
321      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
322      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
323      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
324  }  }
# Line 403  Line 328 
328      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
329    { \    { \
330      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
331      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
332      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
333      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
334  }  }
# Line 413  Line 338 
338      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
339    { \    { \
340      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
341      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
342      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
343      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
344  }  }
# Line 421  Line 346 
346    
347  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
348    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \
349    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\    iSAD += calc_delta_8(-center_x, -center_y, (uint8_t)iFcode, iQuant);\
350    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
351    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
352  }  }
# Line 429  Line 354 
354  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
355    { \    { \
356      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
357      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
358      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
359      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
360  }  }
# Line 439  Line 364 
364      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
365    { \    { \
366      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
367      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
368      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
369      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
370  }  }
# Line 449  Line 374 
374      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
375    { \    { \
376      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
377      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
378      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
379      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
380  }  }
# Line 459  Line 384 
384      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
385    { \    { \
386      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
387      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\      iSAD += calc_delta_8((X)-center_x, (Y)-center_y, (uint8_t)iFcode, iQuant);\
388      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
389      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
390  }  }
# Line 485  Line 410 
410          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
411          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
412          int32_t iSAD;          int32_t iSAD;
413          int32_t pred_x,pred_y;          VECTOR pred;
414    
415    
416          get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y);          pred = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
417    
418          iSAD = sad16( cur,          iSAD = sad16( cur,
419                  get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),                  get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),
# Line 497  Line 423 
423    
424          currMV->x = 0;          currMV->x = 0;
425          currMV->y = 0;          currMV->y = 0;
426          currPMV->x = -pred_x;          currPMV->x = -pred.x;
427          currPMV->y = -pred_y;          currPMV->y = -pred.y;
428    
429          return iSAD;          return iSAD;
430    
431  }  }
432  */  */
433    
434  int32_t Diamond16_MainSearch(  int32_t
435          const uint8_t * const pRef,  Diamond16_MainSearch(const uint8_t * const pRef,
436          const uint8_t * const pRefH,          const uint8_t * const pRefH,
437          const uint8_t * const pRefV,          const uint8_t * const pRefV,
438          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
439          const uint8_t * const cur,          const uint8_t * const cur,
440          const int x, const int y,                                           const int x,
441          int32_t startx, int32_t starty,                                           const int y,
442          int32_t iMinSAD,                                     const int start_x,
443                                       const int start_y,
444                                       int iMinSAD,
445          VECTOR * const currMV,          VECTOR * const currMV,
446          const VECTOR * const pmv,                                     const int center_x,
447          const int32_t min_dx, const int32_t max_dx,                                     const int center_y,
448          const int32_t min_dy, const int32_t max_dy,                                           const int32_t min_dx,
449                                             const int32_t max_dx,
450                                             const int32_t min_dy,
451                                             const int32_t max_dy,
452          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
453          const int32_t iDiamondSize,          const int32_t iDiamondSize,
454          const int32_t iFcode,          const int32_t iFcode,
# Line 529  Line 460 
460          int32_t iDirection=0;          int32_t iDirection=0;
461          int32_t iSAD;          int32_t iSAD;
462          VECTOR backupMV;          VECTOR backupMV;
463          backupMV.x = startx;  
464          backupMV.y = starty;          backupMV.x = start_x;
465            backupMV.y = start_y;
466    
467  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
468    
# Line 540  Line 472 
472          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
473    
474          if (iDirection)          if (iDirection)
475                  while (!iFound)                  while (!iFound) {
                 {  
476                          iFound = 1;                          iFound = 1;
477                          backupMV=*currMV;                          backupMV=*currMV;
478    
479                          if ( iDirection != 2)                          if ( iDirection != 2)
480                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
481                                                                                       backupMV.y, 1);
482                          if ( iDirection != 1)                          if ( iDirection != 1)
483                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
484                                                                                       backupMV.y, 2);
485                          if ( iDirection != 4)                          if ( iDirection != 4)
486                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
487                                                                                       backupMV.y - iDiamondSize, 3);
488                          if ( iDirection != 3)                          if ( iDirection != 3)
489                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
490                  }                                                                                     backupMV.y + iDiamondSize, 4);
491          else          } else {
492          {                  currMV->x = start_x;
493                  currMV->x = startx;                  currMV->y = start_y;
                 currMV->y = starty;  
494          }          }
495          return iMinSAD;          return iMinSAD;
496  }  }
497    
498  int32_t Square16_MainSearch(  int32_t
499                                          const uint8_t * const pRef,  Square16_MainSearch(const uint8_t * const pRef,
500                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
501                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
502                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
503                                          const uint8_t * const cur,                                          const uint8_t * const cur,
504                                          const int x, const int y,                                          const int x,
505                                          int32_t startx, int32_t starty,                                          const int y,
506                                          int32_t iMinSAD,                                     const int start_x,
507                                       const int start_y,
508                                       int iMinSAD,
509                                          VECTOR * const currMV,                                          VECTOR * const currMV,
510                                          const VECTOR * const pmv,                                     const int center_x,
511                                          const int32_t min_dx, const int32_t max_dx,                                     const int center_y,
512                                          const int32_t min_dy, const int32_t max_dy,                                          const int32_t min_dx,
513                                            const int32_t max_dx,
514                                            const int32_t min_dy,
515                                            const int32_t max_dy,
516                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
517                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
518                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 586  Line 524 
524          int32_t iDirection=0;          int32_t iDirection=0;
525          int32_t iSAD;          int32_t iSAD;
526          VECTOR backupMV;          VECTOR backupMV;
527          backupMV.x = startx;  
528          backupMV.y = starty;          backupMV.x = start_x;
529            backupMV.y = start_y;
530    
531  /* It's one search with full square pattern, and new parts for all following diamonds */  /* It's one search with full square pattern, and new parts for all following diamonds */
532    
# Line 602  Line 541 
541          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);
542          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
543    
544          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
545          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                           backupMV.y - iDiamondSize, 5);
546          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
547          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                                           backupMV.y + iDiamondSize, 6);
548            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
549                                                             backupMV.y - iDiamondSize, 7);
550            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
551                                                             backupMV.y + iDiamondSize, 8);
552    
553    
554          if (iDirection)          if (iDirection)
555                  while (!iFound)                  while (!iFound) {
                 {  
556                          iFound = 1;                          iFound = 1;
557                          backupMV=*currMV;                          backupMV=*currMV;
558    
559                          switch (iDirection)                          switch (iDirection) {
                         {  
560                                  case 1:                                  case 1:
561                                          CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
562                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                     backupMV.y, 1);
563                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
564                                                                                     backupMV.y - iDiamondSize, 5);
565                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
566                                                                                     backupMV.y - iDiamondSize, 7);
567                                          break;                                          break;
568                                  case 2:                                  case 2:
569                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
570                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                                                   2);
571                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
572                                                                                     backupMV.y + iDiamondSize, 6);
573                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
574                                                                                     backupMV.y + iDiamondSize, 8);
575                                          break;                                          break;
576    
577                                  case 3:                                  case 3:
578                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
579                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
580                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
581                                                                                     backupMV.y - iDiamondSize, 7);
582                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
583                                                                                     backupMV.y + iDiamondSize, 8);
584                                          break;                                          break;
585    
586                                  case 4:                                  case 4:
587                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
588                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
589                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
590                                                                                     backupMV.y - iDiamondSize, 5);
591                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
592                                                                                     backupMV.y + iDiamondSize, 6);
593                                          break;                                          break;
594    
595                                  case 5:                                  case 5:
596                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,
597                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                                                                   1);
598                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
599                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                                                   3);
600                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
601                                                                                     backupMV.y - iDiamondSize, 5);
602                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
603                                                                                     backupMV.y + iDiamondSize, 6);
604                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
605                                                                                     backupMV.y - iDiamondSize, 7);
606                                          break;                                          break;
607    
608                                  case 6:                                  case 6:
609                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
610                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                                                                   2);
611                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
612                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
613                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);  
614                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
615                                                                                     backupMV.y - iDiamondSize, 5);
616                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
617                                                                                     backupMV.y + iDiamondSize, 6);
618                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
619                                                                                     backupMV.y + iDiamondSize, 8);
620    
621                                          break;                                          break;
622    
623                                  case 7:                                  case 7:
624                                          CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
625                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                     backupMV.y, 1);
626                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
627                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
628                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
629                                                                                     backupMV.y - iDiamondSize, 5);
630                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
631                                                                                     backupMV.y - iDiamondSize, 7);
632                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
633                                                                                     backupMV.y + iDiamondSize, 8);
634                                          break;                                          break;
635    
636                                  case 8:                                  case 8:
637                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
638                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                   2);
639                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
640                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
641                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
642                                                                                     backupMV.y + iDiamondSize, 6);
643                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
644                                                                                     backupMV.y - iDiamondSize, 7);
645                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
646                                                                                     backupMV.y + iDiamondSize, 8);
647                                          break;                                          break;
648                          default:                          default:
649                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,
650                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                                                                   1);
651                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
652                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                   2);
653                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
654                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
655                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
656                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
657                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);  
658                                          break;                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
659                          }                                                                                   backupMV.y - iDiamondSize, 5);
660                  }                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
661          else                                                                                   backupMV.y + iDiamondSize, 6);
662                  {                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
663                          currMV->x = startx;                                                                                   backupMV.y - iDiamondSize, 7);
664                          currMV->y = starty;                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
665                                                                                     backupMV.y + iDiamondSize, 8);
666                                    break;
667                            }
668            } else {
669                    currMV->x = start_x;
670                    currMV->y = start_y;
671                  }                  }
672          return iMinSAD;          return iMinSAD;
673  }  }
674    
675    
676  int32_t Full16_MainSearch(  int32_t
677                                          const uint8_t * const pRef,  Full16_MainSearch(const uint8_t * const pRef,
678                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
679                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
680                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
681                                          const uint8_t * const cur,                                          const uint8_t * const cur,
682                                          const int x, const int y,                                    const int x,
683                                          int32_t startx, int32_t starty,                                    const int y,
684                                          int32_t iMinSAD,                                     const int start_x,
685                                       const int start_y,
686                                       int iMinSAD,
687                                          VECTOR * const currMV,                                          VECTOR * const currMV,
688                                          const VECTOR * const pmv,                                     const int center_x,
689                                          const int32_t min_dx, const int32_t max_dx,                                     const int center_y,
690                                          const int32_t min_dy, const int32_t max_dy,                                    const int32_t min_dx,
691                                      const int32_t max_dx,
692                                      const int32_t min_dy,
693                                      const int32_t max_dy,
694                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
695                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
696                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 716  Line 700 
700          int32_t iSAD;          int32_t iSAD;
701          int32_t dx,dy;          int32_t dx,dy;
702          VECTOR backupMV;          VECTOR backupMV;
703          backupMV.x = startx;  
704          backupMV.y = starty;          backupMV.x = start_x;
705            backupMV.y = start_y;
706    
707          for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)          for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)
708                  for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)                  for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)
# Line 726  Line 711 
711          return iMinSAD;          return iMinSAD;
712  }  }
713    
714  int32_t AdvDiamond16_MainSearch(  int32_t
715          const uint8_t * const pRef,  AdvDiamond16_MainSearch(const uint8_t * const pRef,
716          const uint8_t * const pRefH,          const uint8_t * const pRefH,
717          const uint8_t * const pRefV,          const uint8_t * const pRefV,
718          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
719          const uint8_t * const cur,          const uint8_t * const cur,
720          const int x, const int y,                                                  const int x,
721          int32_t startx, int32_t starty,                                                  const int y,
722          int32_t iMinSAD,                                             int start_x,
723                                               int start_y,
724                                               int iMinSAD,
725          VECTOR * const currMV,          VECTOR * const currMV,
726          const VECTOR * const pmv,                                             const int center_x,
727          const int32_t min_dx, const int32_t max_dx,                                             const int center_y,
728          const int32_t min_dy, const int32_t max_dy,                                                  const int32_t min_dx,
729                                                    const int32_t max_dx,
730                                                    const int32_t min_dy,
731                                                    const int32_t max_dy,
732          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
733          const int32_t iDiamondSize,          const int32_t iDiamondSize,
734          const int32_t iFcode,          const int32_t iFcode,
# Line 750  Line 740 
740    
741  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
742    
743          if (iDirection)          if (iDirection) {
744          {                  CHECK_MV16_CANDIDATE(start_x - iDiamondSize, start_y);
745                  CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x + iDiamondSize, start_y);
746                  CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty);                  CHECK_MV16_CANDIDATE(start_x, start_y - iDiamondSize);
747                  CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize);                  CHECK_MV16_CANDIDATE(start_x, start_y + iDiamondSize);
748                  CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize);          } else {
         }  
         else  
         {  
749                  int bDirection = 1+2+4+8;                  int bDirection = 1+2+4+8;
750                  do  
751                  {                  do {
752                          iDirection = 0;                          iDirection = 0;
753                          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)
754                                  CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1);                                  CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
755    
756                          if (bDirection&2)                          if (bDirection&2)
757                                  CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2);                                  CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
758    
759                          if (bDirection&4)                          if (bDirection&4)
760                                  CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
761    
762                          if (bDirection&8)                          if (bDirection&8)
763                                  CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
764    
765                          /* now we're doing diagonal checks near our candidate */                          /* now we're doing diagonal checks near our candidate */
766    
# Line 781  Line 768 
768                          {                          {
769                                  bDirection = iDirection;                                  bDirection = iDirection;
770                                  iDirection = 0;                                  iDirection = 0;
771                                  startx=currMV->x; starty=currMV->y;                                  start_x = currMV->x;
772                                    start_y = currMV->y;
773                                  if (bDirection & 3) //our candidate is left or right                                  if (bDirection & 3) //our candidate is left or right
774                                  {                                  {
775                                          CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
776                                          CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);                                          CHECK_MV16_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
777                                  }                                  } else                  // what remains here is up or down
                                 else // what remains here is up or down  
778                                  {                                  {
779                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
780                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
781                                  }                                  }
782    
783                                  if (iDirection)                                  if (iDirection) {
784                                  {       bDirection+=iDirection;                                          bDirection += iDirection;
785                                          startx=currMV->x; starty=currMV->y;                                          start_x = currMV->x;
786                                  }                                          start_y = currMV->y;
787                          }                          }
788                          else //about to quit, eh? not so fast....                          } else                          //about to quit, eh? not so fast....
                         {  
                                 switch (bDirection)  
789                                  {                                  {
790                                    switch (bDirection) {
791                                  case 2:                                  case 2:
792                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
793                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                           start_y - iDiamondSize, 2 + 4);
794                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
795                                                                                             start_y + iDiamondSize, 2 + 8);
796                                          break;                                          break;
797                                  case 1:                                  case 1:
798                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);  
799                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
800                                                                                             start_y - iDiamondSize, 1 + 4);
801                                            CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
802                                                                                             start_y + iDiamondSize, 1 + 8);
803                                          break;                                          break;
804                                  case 2+4:                                  case 2+4:
805                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
806                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                                                                           start_y - iDiamondSize, 1 + 4);
807                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
808                                                                                             start_y - iDiamondSize, 2 + 4);
809                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
810                                                                                             start_y + iDiamondSize, 2 + 8);
811                                          break;                                          break;
812                                  case 4:                                  case 4:
813                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
814                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                                                                           start_y - iDiamondSize, 2 + 4);
815                                            CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
816                                                                                             start_y - iDiamondSize, 1 + 4);
817                                          break;                                          break;
818                                  case 8:                                  case 8:
819                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
820                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                           start_y + iDiamondSize, 2 + 8);
821                                            CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
822                                                                                             start_y + iDiamondSize, 1 + 8);
823                                          break;                                          break;
824                                  case 1+4:                                  case 1+4:
825                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
826                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                                                                           start_y + iDiamondSize, 1 + 8);
827                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
828                                                                                             start_y - iDiamondSize, 1 + 4);
829                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
830                                                                                             start_y - iDiamondSize, 2 + 4);
831                                          break;                                          break;
832                                  case 2+8:                                  case 2+8:
833                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
834                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                           start_y - iDiamondSize, 1 + 4);
835                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
836                                                                                             start_y + iDiamondSize, 1 + 8);
837                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
838                                                                                             start_y + iDiamondSize, 2 + 8);
839                                          break;                                          break;
840                                  case 1+8:                                  case 1+8:
841                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
842                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                           start_y - iDiamondSize, 2 + 4);
843                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                          CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
844                                                                                             start_y + iDiamondSize, 2 + 8);
845                                            CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
846                                                                                             start_y + iDiamondSize, 1 + 8);
847                                          break;                                          break;
848                                  default: //1+2+4+8 == we didn't find anything at all                                  default: //1+2+4+8 == we didn't find anything at all
849                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
850                                          CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                           start_y - iDiamondSize, 1 + 4);
851                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV16_CANDIDATE_DIR(start_x - iDiamondSize,
852                                          CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                           start_y + iDiamondSize, 1 + 8);
853                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
854                                                                                             start_y - iDiamondSize, 2 + 4);
855                                            CHECK_MV16_CANDIDATE_DIR(start_x + iDiamondSize,
856                                                                                             start_y + iDiamondSize, 2 + 8);
857                                          break;                                          break;
858                                  }                                  }
859                                  if (!iDirection) break; //ok, the end. really                                  if (!iDirection)
860                                  else                                          break;          //ok, the end. really
861                                  {       bDirection=iDirection;                                  else {
862                                          startx=currMV->x; starty=currMV->y;                                          bDirection = iDirection;
863                                            start_x = currMV->x;
864                                            start_y = currMV->y;
865                                  }                                  }
866                          }                          }
867                  }                  }
# Line 857  Line 870 
870          return iMinSAD;          return iMinSAD;
871  }  }
872    
 int32_t AdvDiamond8_MainSearch(  
         const uint8_t * const pRef,  
         const uint8_t * const pRefH,  
         const uint8_t * const pRefV,  
         const uint8_t * const pRefHV,  
         const uint8_t * const cur,  
         const int x, const int y,  
         int32_t startx, int32_t starty,  
         int32_t iMinSAD,  
         VECTOR * const currMV,  
         const VECTOR * const pmv,  
         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 iFcode,  
         const int32_t iQuant,  
         int iDirection)  
 {  
   
         int32_t iSAD;  
873    
874  /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */  #define CHECK_MV16_F_INTERPOL(X,Y,BX,BY) { \
875      if ( ((X) <= max_dx) && ((X) >= min_dx) \
876        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
877      { \
878        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
879        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
880        if (iSAD < iMinSAD) \
881        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
882    }
883    
884          if (iDirection)  #define CHECK_MV16_F_INTERPOL_DIR(X,Y,BX,BY,D) { \
885          {    if ( ((X) <= max_dx) && ((X) >= min_dx) \
886                  CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty);      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
887                  CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty);    { \
888                  CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize);      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
889                  CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize);      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
890        if (iSAD < iMinSAD) \
891        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
892          }          }
         else  
         {  
                 int bDirection = 1+2+4+8;  
                 do  
                 {  
                         iDirection = 0;  
                         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)  
                                 CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1);  
893    
894                          if (bDirection&2)  #define CHECK_MV16_F_INTERPOL_FOUND(X,Y,BX,BY,D) { \
895                                  CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2);    if ( ((X) <= max_dx) && ((X) >= min_dx) \
896        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
897      { \
898        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
899        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
900        if (iSAD < iMinSAD) \
901        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
902    }
903    
                         if (bDirection&4)  
                                 CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4);  
904    
905                          if (bDirection&8)  #define CHECK_MV16_B_INTERPOL(FX,FY,X,Y) { \
906                                  CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8);    if ( ((X) <= max_dx) && ((X) >= min_dx) \
907        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
908      { \
909        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
910        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
911        if (iSAD < iMinSAD) \
912        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
913    }
914    
                         /* now we're doing diagonal checks near our candidate */  
915    
916                          if (iDirection) //checking if anything found  #define CHECK_MV16_B_INTERPOL_DIR(FX,FY,X,Y,D) { \
917                          {    if ( ((X) <= max_dx) && ((X) >= min_dx) \
918                                  bDirection = iDirection;      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
919                                  iDirection = 0;    { \
920                                  startx=currMV->x; starty=currMV->y;      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
921                                  if (bDirection & 3) //our candidate is left or right      iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
922                                  {      if (iSAD < iMinSAD) \
923                                          CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
                                         CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);  
924                                  }                                  }
925                                  else // what remains here is up or down  
926                                  {  
927                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);  #define CHECK_MV16_B_INTERPOL_FOUND(FX,FY,X,Y,D) { \
928                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);    if ( ((X) <= max_dx) && ((X) >= min_dx) \
929        && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
930      { \
931        iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
932        iSAD += calc_delta_16((X) - center_x, (Y) - center_y, (uint8_t)iFcode, iQuant);\
933        if (iSAD < iMinSAD) \
934        {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
935                                  }                                  }
936    
937    
938    #if (0==1)
939    int32_t
940    Diamond16_InterpolMainSearch(
941                                            const uint8_t * const f_pRef,
942                                             const uint8_t * const f_pRefH,
943                                             const uint8_t * const f_pRefV,
944                                             const uint8_t * const f_pRefHV,
945                                             const uint8_t * const cur,
946    
947                                            const uint8_t * const b_pRef,
948                                             const uint8_t * const b_pRefH,
949                                             const uint8_t * const b_pRefV,
950                                             const uint8_t * const b_pRefHV,
951    
952                                             const int x,
953                                             const int y,
954    
955                                       const int f_start_x,
956                                       const int f_start_y,
957                                       const int b_start_x,
958                                       const int b_start_y,
959    
960                                       int iMinSAD,
961                                       VECTOR * const f_currMV,
962                                       VECTOR * const b_currMV,
963    
964                                       const int f_center_x,
965                                       const int f_center_y,
966                                       const int b_center_x,
967                                       const int b_center_y,
968    
969                                             const int32_t min_dx,
970                                             const int32_t max_dx,
971                                             const int32_t min_dy,
972                                             const int32_t max_dy,
973                                             const int32_t iEdgedWidth,
974                                             const int32_t iDiamondSize,
975    
976                                             const int32_t f_iFcode,
977                                             const int32_t b_iFcode,
978    
979                                             const int32_t iQuant,
980                                             int iFound)
981    {
982    /* Do a diamond search around given starting point, return SAD of best */
983    
984            int32_t f_iDirection = 0;
985            int32_t b_iDirection = 0;
986            int32_t iSAD;
987    
988            VECTOR f_backupMV;
989            VECTOR b_backupMV;
990    
991            f_backupMV.x = start_x;
992            f_backupMV.y = start_y;
993            b_backupMV.x = start_x;
994            b_backupMV.y = start_y;
995    
996    /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
997    
998            CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);
999            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);
1000            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);
1001            CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);
1002    
1003                                  if (iDirection)                                  if (iDirection)
1004                                  {       bDirection+=iDirection;                  while (!iFound) {
1005                                          startx=currMV->x; starty=currMV->y;                          iFound = 1;
1006                            backupMV = *currMV;
1007    
1008                            if (iDirection != 2)
1009                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1010                                                                                       backupMV.y, 1);
1011                            if (iDirection != 1)
1012                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1013                                                                                       backupMV.y, 2);
1014                            if (iDirection != 4)
1015                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1016                                                                                       backupMV.y - iDiamondSize, 3);
1017                            if (iDirection != 3)
1018                                    CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
1019                                                                                       backupMV.y + iDiamondSize, 4);
1020            } else {
1021                    currMV->x = start_x;
1022                    currMV->y = start_y;
1023                                  }                                  }
1024            return iMinSAD;
1025                          }                          }
1026                          else //about to quit, eh? not so fast....  #endif
1027    
1028    
1029    int32_t
1030    AdvDiamond8_MainSearch(const uint8_t * const pRef,
1031                                               const uint8_t * const pRefH,
1032                                               const uint8_t * const pRefV,
1033                                               const uint8_t * const pRefHV,
1034                                               const uint8_t * const cur,
1035                                               const int x,
1036                                               const int y,
1037                                               int start_x,
1038                                               int start_y,
1039                                               int iMinSAD,
1040                                               VECTOR * const currMV,
1041                                               const int center_x,
1042                                               const int center_y,
1043                                               const int32_t min_dx,
1044                                               const int32_t max_dx,
1045                                               const int32_t min_dy,
1046                                               const int32_t max_dy,
1047                                               const int32_t iEdgedWidth,
1048                                               const int32_t iDiamondSize,
1049                                               const int32_t iFcode,
1050                                               const int32_t iQuant,
1051                                               int iDirection)
1052                          {                          {
1053                                  switch (bDirection)  
1054            int32_t iSAD;
1055    
1056    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
1057    
1058            if (iDirection) {
1059                    CHECK_MV8_CANDIDATE(start_x - iDiamondSize, start_y);
1060                    CHECK_MV8_CANDIDATE(start_x + iDiamondSize, start_y);
1061                    CHECK_MV8_CANDIDATE(start_x, start_y - iDiamondSize);
1062                    CHECK_MV8_CANDIDATE(start_x, start_y + iDiamondSize);
1063            } else {
1064                    int bDirection = 1 + 2 + 4 + 8;
1065    
1066                    do {
1067                            iDirection = 0;
1068                            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)
1069                                    CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1070    
1071                            if (bDirection & 2)
1072                                    CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1073    
1074                            if (bDirection & 4)
1075                                    CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1076    
1077                            if (bDirection & 8)
1078                                    CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1079    
1080                            /* now we're doing diagonal checks near our candidate */
1081    
1082                            if (iDirection)         //checking if anything found
1083                            {
1084                                    bDirection = iDirection;
1085                                    iDirection = 0;
1086                                    start_x = currMV->x;
1087                                    start_y = currMV->y;
1088                                    if (bDirection & 3)     //our candidate is left or right
1089                                    {
1090                                            CHECK_MV8_CANDIDATE_DIR(start_x, start_y + iDiamondSize, 8);
1091                                            CHECK_MV8_CANDIDATE_DIR(start_x, start_y - iDiamondSize, 4);
1092                                    } else                  // what remains here is up or down
1093                                    {
1094                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize, start_y, 2);
1095                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize, start_y, 1);
1096                                    }
1097    
1098                                    if (iDirection) {
1099                                            bDirection += iDirection;
1100                                            start_x = currMV->x;
1101                                            start_y = currMV->y;
1102                                    }
1103                            } else                          //about to quit, eh? not so fast....
1104                                  {                                  {
1105                                    switch (bDirection) {
1106                                  case 2:                                  case 2:
1107                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1108                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                          start_y - iDiamondSize, 2 + 4);
1109                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1110                                                                                            start_y + iDiamondSize, 2 + 8);
1111                                          break;                                          break;
1112                                  case 1:                                  case 1:
1113                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1114                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                          start_y - iDiamondSize, 1 + 4);
1115                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1116                                                                                            start_y + iDiamondSize, 1 + 8);
1117                                          break;                                          break;
1118                                  case 2+4:                                  case 2+4:
1119                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1120                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                                                                          start_y - iDiamondSize, 1 + 4);
1121                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1122                                                                                            start_y - iDiamondSize, 2 + 4);
1123                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1124                                                                                            start_y + iDiamondSize, 2 + 8);
1125                                          break;                                          break;
1126                                  case 4:                                  case 4:
1127                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1128                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                                                                          start_y - iDiamondSize, 2 + 4);
1129                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1130                                                                                            start_y - iDiamondSize, 1 + 4);
1131                                          break;                                          break;
1132                                  case 8:                                  case 8:
1133                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1134                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                          start_y + iDiamondSize, 2 + 8);
1135                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1136                                                                                            start_y + iDiamondSize, 1 + 8);
1137                                          break;                                          break;
1138                                  case 1+4:                                  case 1+4:
1139                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1140                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                                                                          start_y + iDiamondSize, 1 + 8);
1141                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1142                                                                                            start_y - iDiamondSize, 1 + 4);
1143                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1144                                                                                            start_y - iDiamondSize, 2 + 4);
1145                                          break;                                          break;
1146                                  case 2+8:                                  case 2+8:
1147                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1148                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                          start_y - iDiamondSize, 1 + 4);
1149                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1150                                                                                            start_y + iDiamondSize, 1 + 8);
1151                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1152                                                                                            start_y + iDiamondSize, 2 + 8);
1153                                          break;                                          break;
1154                                  case 1+8:                                  case 1+8:
1155                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1156                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                          start_y - iDiamondSize, 2 + 4);
1157                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                          CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1158                                                                                            start_y + iDiamondSize, 2 + 8);
1159                                            CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1160                                                                                            start_y + iDiamondSize, 1 + 8);
1161                                          break;                                          break;
1162                                  default: //1+2+4+8 == we didn't find anything at all                                  default: //1+2+4+8 == we didn't find anything at all
1163                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1164                                          CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);                                                                                          start_y - iDiamondSize, 1 + 4);
1165                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);                                          CHECK_MV8_CANDIDATE_DIR(start_x - iDiamondSize,
1166                                          CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);                                                                                          start_y + iDiamondSize, 1 + 8);
1167                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1168                                                                                            start_y - iDiamondSize, 2 + 4);
1169                                            CHECK_MV8_CANDIDATE_DIR(start_x + iDiamondSize,
1170                                                                                            start_y + iDiamondSize, 2 + 8);
1171                                          break;                                          break;
1172                                  }                                  }
1173                                  if (!(iDirection)) break; //ok, the end. really                                  if (!(iDirection))
1174                                  else                                          break;          //ok, the end. really
1175                                  {       bDirection=iDirection;                                  else {
1176                                          startx=currMV->x; starty=currMV->y;                                          bDirection = iDirection;
1177                                            start_x = currMV->x;
1178                                            start_y = currMV->y;
1179                                  }                                  }
1180                          }                          }
1181                  }                  }
# Line 989  Line 1185 
1185  }  }
1186    
1187    
1188  int32_t Full8_MainSearch(  int32_t
1189                                          const uint8_t * const pRef,  Full8_MainSearch(const uint8_t * const pRef,
1190                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1191                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1192                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1193                                          const uint8_t * const cur,                                          const uint8_t * const cur,
1194                                          const int x, const int y,                                   const int x,
1195                                          int32_t startx, int32_t starty,                                   const int y,
1196                                          int32_t iMinSAD,                             const int start_x,
1197                               const int start_y,
1198                               int iMinSAD,
1199                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1200                                          const VECTOR * const pmv,                             const int center_x,
1201                                          const int32_t min_dx, const int32_t max_dx,                             const int center_y,
1202                                          const int32_t min_dy, const int32_t max_dy,                                   const int32_t min_dx,
1203                                     const int32_t max_dx,
1204                                     const int32_t min_dy,
1205                                     const int32_t max_dy,
1206                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
1207                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
1208                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 1011  Line 1212 
1212          int32_t iSAD;          int32_t iSAD;
1213          int32_t dx,dy;          int32_t dx,dy;
1214          VECTOR backupMV;          VECTOR backupMV;
1215          backupMV.x = startx;  
1216          backupMV.y = starty;          backupMV.x = start_x;
1217            backupMV.y = start_y;
1218    
1219          for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)          for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)
1220                  for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)                  for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)
# Line 1021  Line 1223 
1223          return iMinSAD;          return iMinSAD;
1224  }  }
1225    
1226    Halfpel8_RefineFuncPtr Halfpel8_Refine;
1227    
1228    int32_t
1229  int32_t Halfpel16_Refine(  Halfpel16_Refine(const uint8_t * const pRef,
         const uint8_t * const pRef,  
1230          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1231          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1232          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1233          const uint8_t * const cur,          const uint8_t * const cur,
1234          const int x, const int y,                                   const int x,
1235                                     const int y,
1236          VECTOR * const currMV,          VECTOR * const currMV,
1237          int32_t iMinSAD,          int32_t iMinSAD,
1238          const VECTOR * const pmv,                             const int center_x,
1239          const int32_t min_dx, const int32_t max_dx,                             const int center_y,
1240          const int32_t min_dy, const int32_t max_dy,                                   const int32_t min_dx,
1241                                     const int32_t max_dx,
1242                                     const int32_t min_dy,
1243                                     const int32_t max_dy,
1244          const int32_t iFcode,          const int32_t iFcode,
1245          const int32_t iQuant,          const int32_t iQuant,
1246          const int32_t iEdgedWidth)          const int32_t iEdgedWidth)
# Line 1059  Line 1265 
1265  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1266    
1267    
1268  int32_t PMVfastSearch16(  
1269                                          const uint8_t * const pRef,  int32_t
1270    PMVfastSearch16(const uint8_t * const pRef,
1271                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1272                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1273                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1274                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1275                                          const int x, const int y,                                  const int x,
1276                                    const int y,
1277                                    const int start_x,
1278                                    const int start_y,
1279                                    const int center_x,
1280                                    const int center_y,
1281                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1282                                          const uint32_t iQuant,                                          const uint32_t iQuant,
1283                                          const uint32_t iFcode,                                          const uint32_t iFcode,
# Line 1099  Line 1311 
1311    
1312          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1313    
 //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  
1314          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1315    
1316          static int32_t threshA,threshB;          int32_t threshA, threshB;
1317          int32_t bPredEq;          int32_t bPredEq;
1318          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1319    
1320  /* Get maximum range */  /* Get maximum range */
1321          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
1322                    x, y, 16, iWidth, iHeight, iFcode);                            iFcode);
1323    
1324  /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */
1325    
1326          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16)) {
1327          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
1328          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
1329          min_dy = EVEN(min_dy);          min_dy = EVEN(min_dy);
1330          max_dy = EVEN(max_dy);          max_dy = EVEN(max_dy);
1331          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
   
1332    
1333          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
1334            //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1335            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1336    
1337          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
1338                  threshA =  512;                  threshA =  512;
1339                  threshB = 1024;                  threshB = 1024;
1340            } else {
         }  
         else  
         {  
1341                  threshA = psad[0];                  threshA = psad[0];
1342                  threshB = threshA+256;                  threshB = threshA+256;
1343                  if (threshA< 512) threshA =  512;                  if (threshA < 512)
1344                  if (threshA>1024) threshA = 1024;                          threshA = 512;
1345                  if (threshB>1792) threshB = 1792;                  if (threshA > 1024)
1346                            threshA = 1024;
1347                    if (threshB > 1792)
1348                            threshB = 1792;
1349          }          }
1350    
1351          iFound=0;          iFound=0;
# Line 1146  Line 1357 
1357     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1358  */  */
1359    
1360          *currMV=pmv[0];         /* current best := prediction */          currMV->x = start_x;
1361          if (!(MotionFlags & PMV_HALFPEL16 ))          currMV->y = start_y;
1362          {       /* This should NOT be necessary! */  
1363            if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
1364                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1365                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
1366          }          }
1367    
1368          if (currMV->x > max_dx)          if (currMV->x > max_dx) {
         {  
1369                  currMV->x=max_dx;                  currMV->x=max_dx;
1370          }          }
1371          if (currMV->x < min_dx)          if (currMV->x < min_dx) {
         {  
1372                  currMV->x=min_dx;                  currMV->x=min_dx;
1373          }          }
1374          if (currMV->y > max_dy)          if (currMV->y > max_dy) {
         {  
1375                  currMV->y=max_dy;                  currMV->y=max_dy;
1376          }          }
1377          if (currMV->y < min_dy)          if (currMV->y < min_dy) {
         {  
1378                  currMV->y=min_dy;                  currMV->y=min_dy;
1379          }          }
1380    
1381          iMinSAD = sad16( cur,          iMinSAD =
1382                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  sad16(cur,
1383                           iEdgedWidth, MV_MAX_ERROR);                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1384          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1385            iMinSAD +=
1386          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )                  calc_delta_16(currMV->x - center_x, currMV->y - center_y,
1387          {                                            (uint8_t) iFcode, iQuant);
1388    
1389            if ((iMinSAD < 256) ||
1390                    ((MVequal(*currMV, prevMB->mvs[0])) &&
1391                     ((int32_t) iMinSAD < prevMB->sad16))) {
1392                  if (iMinSAD < 2*iQuant) // high chances for SKIP-mode                  if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
1393                  {                  {
1394                          if (!MVzero(*currMV))                          if (!MVzero(*currMV)) {
                         {  
1395                                  iMinSAD += MV16_00_BIAS;                                  iMinSAD += MV16_00_BIAS;
1396                                  CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures                                  CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
1397                                  iMinSAD -= MV16_00_BIAS;                                  iMinSAD -= MV16_00_BIAS;
# Line 1236  Line 1447 
1447    
1448          if (!MVzero(pmv[1]))          if (!MVzero(pmv[1]))
1449          if (!MVequal(pmv[1],prevMB->mvs[0]))          if (!MVequal(pmv[1],prevMB->mvs[0]))
1450          if (!MVequal(pmv[1],pmv[0]))                          if (!MVequal(pmv[1], pmv[0])) {
1451          {                                  if (!(MotionFlags & PMV_HALFPEL16)) {
1452                  if (!(MotionFlags & PMV_HALFPEL16 ))                                          pmv[1].x = EVEN(pmv[1].x);
                 {       pmv[1].x = EVEN(pmv[1].x);  
1453                          pmv[1].y = EVEN(pmv[1].y);                          pmv[1].y = EVEN(pmv[1].y);
1454                  }                  }
1455    
1456                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1457          }          }
   
1458  // top neighbour, if allowed  // top neighbour, if allowed
1459          if (!MVzero(pmv[2]))          if (!MVzero(pmv[2]))
1460          if (!MVequal(pmv[2],prevMB->mvs[0]))          if (!MVequal(pmv[2],prevMB->mvs[0]))
1461          if (!MVequal(pmv[2],pmv[0]))          if (!MVequal(pmv[2],pmv[0]))
1462          if (!MVequal(pmv[2],pmv[1]))                                  if (!MVequal(pmv[2], pmv[1])) {
1463          {                                          if (!(MotionFlags & PMV_HALFPEL16)) {
1464                  if (!(MotionFlags & PMV_HALFPEL16 ))                                                  pmv[2].x = EVEN(pmv[2].x);
                 {       pmv[2].x = EVEN(pmv[2].x);  
1465                          pmv[2].y = EVEN(pmv[2].y);                          pmv[2].y = EVEN(pmv[2].y);
1466                  }                  }
1467                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
# Line 1263  Line 1471 
1471                  if (!MVequal(pmv[3],prevMB->mvs[0]))                  if (!MVequal(pmv[3],prevMB->mvs[0]))
1472                  if (!MVequal(pmv[3],pmv[0]))                  if (!MVequal(pmv[3],pmv[0]))
1473                  if (!MVequal(pmv[3],pmv[1]))                  if (!MVequal(pmv[3],pmv[1]))
1474                  if (!MVequal(pmv[3],pmv[2]))                                                                          if (!MVequal(pmv[3], pmv[2])) {
1475                  {                                                                                  if (!(MotionFlags & PMV_HALFPEL16)) {
1476                          if (!(MotionFlags & PMV_HALFPEL16 ))                                                                                          pmv[3].x = EVEN(pmv[3].x);
                         {       pmv[3].x = EVEN(pmv[3].x);  
1477                                  pmv[3].y = EVEN(pmv[3].y);                                  pmv[3].y = EVEN(pmv[3].y);
1478                          }                          }
1479                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);                                                                                  CHECK_MV16_CANDIDATE(pmv[3].x,
1480                                                                                                                             pmv[3].y);
1481                  }                  }
1482          }          }
1483    
1484          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )          if ((MVzero(*currMV)) &&
1485                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1486                  iMinSAD -= MV16_00_BIAS;                  iMinSAD -= MV16_00_BIAS;
1487    
1488    
# Line 1281  Line 1490 
1490     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1491  */  */
1492    
1493          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ((iMinSAD <= threshA) ||
1494          {                  (MVequal(*currMV, prevMB->mvs[0]) &&
1495                     ((int32_t) iMinSAD < prevMB->sad16))) {
1496                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1497                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
1498                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1302  Line 1512 
1512    
1513          if (MotionFlags & PMV_USESQUARES16)          if (MotionFlags & PMV_USESQUARES16)
1514                  MainSearchPtr = Square16_MainSearch;                  MainSearchPtr = Square16_MainSearch;
1515          else          else if (MotionFlags & PMV_ADVANCEDDIAMOND16)
                 if (MotionFlags & PMV_ADVANCEDDIAMOND16)  
1516                          MainSearchPtr = AdvDiamond16_MainSearch;                          MainSearchPtr = AdvDiamond16_MainSearch;
1517                  else                  else
1518                          MainSearchPtr = Diamond16_MainSearch;                          MainSearchPtr = Diamond16_MainSearch;
1519    
1520          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1521    
1522    
1523  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1524          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
1525                                            x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1526                                            currMV->x, currMV->y, iMinSAD, &newMV,                                                    currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y,
1527                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                    min_dx, max_dx,
1528                                                      min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1529                                                      iQuant, iFound);
1530    
1531          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
1532                  *currMV = newMV;                  *currMV = newMV;
1533                  iMinSAD = iSAD;                  iMinSAD = iSAD;
1534          }          }
1535    
1536          if (MotionFlags & PMV_EXTSEARCH16)          if (MotionFlags & PMV_EXTSEARCH16) {
         {  
1537  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1538    
1539                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
1540                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1541                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1542                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    center_x, center_y, iMinSAD, &newMV, center_x, center_y,
1543                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1544                                                                      iDiamondSize, iFcode, iQuant, iFound);
1545    
1546                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1547                          *currMV = newMV;                          *currMV = newMV;
1548                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1549                  }                  }
1550                  }                  }
1551    
1552                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1553                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1554                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1555                                                            0, 0, iMinSAD, &newMV,                                                                    iMinSAD, &newMV, center_x, center_y,
1556                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    min_dx, max_dx, min_dy, max_dy,
1557                                                                      iEdgedWidth, iDiamondSize, iFcode,
1558                                                                      iQuant, iFound);
1559    
1560                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1561                          *currMV = newMV;                          *currMV = newMV;
1562                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1563                  }                  }
# Line 1359  Line 1570 
1570    
1571  PMVfast16_Terminate_with_Refine:  PMVfast16_Terminate_with_Refine:
1572          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step
1573                  iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
1574                                    x, y,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1575                                    currMV, iMinSAD,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1576                                    pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1577    
1578  PMVfast16_Terminate_without_Refine:  PMVfast16_Terminate_without_Refine:
1579          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
1580          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
1581          return iMinSAD;          return iMinSAD;
1582  }  }
1583    
# Line 1375  Line 1586 
1586    
1587    
1588    
1589  int32_t Diamond8_MainSearch(  int32_t
1590          const uint8_t * const pRef,  Diamond8_MainSearch(const uint8_t * const pRef,
1591          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1592          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1593          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1594          const uint8_t * const cur,          const uint8_t * const cur,
1595          const int x, const int y,                                          const int x,
1596          int32_t startx, int32_t starty,                                          const int y,
1597                                            int32_t start_x,
1598                                            int32_t start_y,
1599          int32_t iMinSAD,          int32_t iMinSAD,
1600          VECTOR * const currMV,          VECTOR * const currMV,
1601          const VECTOR * const pmv,                                     const int center_x,
1602          const int32_t min_dx, const int32_t max_dx,                                     const int center_y,
1603          const int32_t min_dy, const int32_t max_dy,                                          const int32_t min_dx,
1604                                            const int32_t max_dx,
1605                                            const int32_t min_dy,
1606                                            const int32_t max_dy,
1607          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
1608          const int32_t iDiamondSize,          const int32_t iDiamondSize,
1609          const int32_t iFcode,          const int32_t iFcode,
# Line 1399  Line 1615 
1615          int32_t iDirection=0;          int32_t iDirection=0;
1616          int32_t iSAD;          int32_t iSAD;
1617          VECTOR backupMV;          VECTOR backupMV;
1618          backupMV.x = startx;  
1619          backupMV.y = starty;          backupMV.x = start_x;
1620            backupMV.y = start_y;
1621    
1622  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */  /* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */
1623    
# Line 1410  Line 1627 
1627          CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
1628    
1629          if (iDirection)          if (iDirection)
1630                  while (!iFound)                  while (!iFound) {
                 {  
1631                          iFound = 1;                          iFound = 1;
1632                          backupMV=*currMV;       // since iDirection!=0, this is well defined!                          backupMV=*currMV;       // since iDirection!=0, this is well defined!
1633    
1634                          if ( iDirection != 2)                          if ( iDirection != 2)
1635                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1636                                                                                      backupMV.y, 1);
1637                          if ( iDirection != 1)                          if ( iDirection != 1)
1638                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1639                                                                                      backupMV.y, 2);
1640                          if ( iDirection != 4)                          if ( iDirection != 4)
1641                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1642                                                                                      backupMV.y - iDiamondSize, 3);
1643                          if ( iDirection != 3)                          if ( iDirection != 3)
1644                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1645                  }                                                                                    backupMV.y + iDiamondSize, 4);
1646          else          } else {
1647          {                  currMV->x = start_x;
1648                  currMV->x = startx;                  currMV->y = start_y;
                 currMV->y = starty;  
1649          }          }
1650          return iMinSAD;          return iMinSAD;
1651  }  }
1652    
1653  int32_t Halfpel8_Refine(  int32_t
1654          const uint8_t * const pRef,  Halfpel8_Refine_c(const uint8_t * const pRef,
1655          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1656          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1657          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1658          const uint8_t * const cur,          const uint8_t * const cur,
1659          const int x, const int y,                                  const int x,
1660                                    const int y,
1661          VECTOR * const currMV,          VECTOR * const currMV,
1662          int32_t iMinSAD,          int32_t iMinSAD,
1663          const VECTOR * const pmv,                             const int center_x,
1664          const int32_t min_dx, const int32_t max_dx,                             const int center_y,
1665          const int32_t min_dy, const int32_t max_dy,                                  const int32_t min_dx,
1666                                    const int32_t max_dx,
1667                                    const int32_t min_dy,
1668                                    const int32_t max_dy,
1669          const int32_t iFcode,          const int32_t iFcode,
1670          const int32_t iQuant,          const int32_t iQuant,
1671          const int32_t iEdgedWidth)          const int32_t iEdgedWidth)
# Line 1468  Line 1690 
1690    
1691  #define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8)  #define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8)
1692    
1693  int32_t PMVfastSearch8(  int32_t
1694                                          const uint8_t * const pRef,  PMVfastSearch8(const uint8_t * const pRef,
1695                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1696                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1697                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1698                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1699                                          const int x, const int y,                             const int x,
1700                                          const int start_x, const int start_y,                             const int y,
1701                               const int start_x,
1702                               const int start_y,
1703                                    const int center_x,
1704                                    const int center_y,
1705                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1706                                          const uint32_t iQuant,                                          const uint32_t iQuant,
1707                                          const uint32_t iFcode,                                          const uint32_t iFcode,
# Line 1508  Line 1734 
1734  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1735          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1736    
1737          static int32_t threshA,threshB;           int32_t threshA, threshB;
1738          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1739          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1740    
# Line 1521  Line 1747 
1747          startMV.y = start_y;          startMV.y = start_y;
1748    
1749          /* Get maximum range */          /* Get maximum range */
1750          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight,
1751                    x, y, 8, iWidth, iHeight, iFcode);                            iFcode);
1752    
1753          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8)) {
1754          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
1755            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
1756            min_dy = EVEN(min_dy);            min_dy = EVEN(min_dy);
1757            max_dy = EVEN(max_dy);            max_dy = EVEN(max_dy);
1758          }               /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          }
   
1759    
1760          bPredEq  = get_pmvdata(pMBs, (x>>1), (y>>1), iWcount, iSubBlock, pmv, psad);          /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
1761            //bPredEq = get_pmvdata(pMBs, (x >> 1), (y >> 1), iWcount, iSubBlock, pmv, psad);
1762            bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);
1763    
1764          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
1765                  threshA =  512/4;                  threshA =  512/4;
1766                  threshB = 1024/4;                  threshB = 1024/4;
1767    
1768          }          } else {
1769          else                  threshA = psad[0] / 4;  /* good estimate? */
         {  
                 threshA = psad[0]/4;                    /* good estimate */  
1770                  threshB = threshA+256/4;                  threshB = threshA+256/4;
1771                  if (threshA< 512/4) threshA =  512/4;                  if (threshA < 512 / 4)
1772                  if (threshA>1024/4) threshA = 1024/4;                          threshA = 512 / 4;
1773                  if (threshB>1792/4) threshB = 1792/4;                  if (threshA > 1024 / 4)
1774                            threshA = 1024 / 4;
1775                    if (threshB > 1792 / 4)
1776                            threshB = 1792 / 4;
1777          }          }
1778    
1779          iFound=0;          iFound=0;
# Line 1573  Line 1800 
1800    
1801          *currMV = startMV;          *currMV = startMV;
1802    
1803          iMinSAD = sad8( cur,          iMinSAD =
1804                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  sad8(cur,
1805                          iEdgedWidth);                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
1806          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode, iQuant);                                                  iEdgedWidth), iEdgedWidth);
1807            iMinSAD +=
1808                    calc_delta_8(currMV->x - center_x, currMV->y - center_y,
1809                                             (uint8_t) iFcode, iQuant);
1810    
1811          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1812                                  && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )                                                                  && ((int32_t) iMinSAD <
1813          {                                                                          prevMB->sad8[iSubBlock]))) {
1814                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1815                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1816                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1618  Line 1848 
1848  // the median prediction might be even better than mv16  // the median prediction might be even better than mv16
1849    
1850          if (!MVequal(pmv[0],startMV))          if (!MVequal(pmv[0],startMV))
1851                  CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);                  CHECK_MV8_CANDIDATE(center_x, center_y);
1852    
1853  // (0,0) if needed  // (0,0) if needed
1854          if (!MVzero(pmv[0]))          if (!MVzero(pmv[0]))
# Line 1629  Line 1859 
1859          if (!MVzero(prevMB->mvs[iSubBlock]))          if (!MVzero(prevMB->mvs[iSubBlock]))
1860          if (!MVequal(prevMB->mvs[iSubBlock],startMV))          if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1861          if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))          if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1862          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);                                  CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,
1863                                                                            prevMB->mvs[iSubBlock].y);
1864    
1865          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ((iMinSAD <= threshA) ||
1866          {                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1867                     ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1868                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1869                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1870                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
1871                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1872          }          }
1873    
   
1874  // left neighbour, if allowed and needed  // left neighbour, if allowed and needed
1875          if (!MVzero(pmv[1]))          if (!MVzero(pmv[1]))
1876          if (!MVequal(pmv[1],startMV))          if (!MVequal(pmv[1],startMV))
1877          if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))          if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1878          if (!MVequal(pmv[1],pmv[0]))                                  if (!MVequal(pmv[1], pmv[0])) {
1879          {                                          if (!(MotionFlags & PMV_HALFPEL8)) {
1880                  if (!(MotionFlags & PMV_HALFPEL8 ))                                                  pmv[1].x = EVEN(pmv[1].x);
                 {       pmv[1].x = EVEN(pmv[1].x);  
1881                          pmv[1].y = EVEN(pmv[1].y);                          pmv[1].y = EVEN(pmv[1].y);
1882                  }                  }
1883                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1884          }          }
   
1885  // top neighbour, if allowed and needed  // top neighbour, if allowed and needed
1886          if (!MVzero(pmv[2]))          if (!MVzero(pmv[2]))
1887          if (!MVequal(pmv[2],startMV))          if (!MVequal(pmv[2],startMV))
1888          if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))          if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1889          if (!MVequal(pmv[2],pmv[0]))          if (!MVequal(pmv[2],pmv[0]))
1890          if (!MVequal(pmv[2],pmv[1]))                                          if (!MVequal(pmv[2], pmv[1])) {
1891          {                                                  if (!(MotionFlags & PMV_HALFPEL8)) {
1892                  if (!(MotionFlags & PMV_HALFPEL8 ))                                                          pmv[2].x = EVEN(pmv[2].x);
                 {       pmv[2].x = EVEN(pmv[2].x);  
1893                          pmv[2].y = EVEN(pmv[2].y);                          pmv[2].y = EVEN(pmv[2].y);
1894                  }                  }
1895                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
# Line 1672  Line 1900 
1900          if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))          if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1901          if (!MVequal(pmv[3],pmv[0]))          if (!MVequal(pmv[3],pmv[0]))
1902          if (!MVequal(pmv[3],pmv[1]))          if (!MVequal(pmv[3],pmv[1]))
1903          if (!MVequal(pmv[3],pmv[2]))                                                                                          if (!MVequal(pmv[3], pmv[2])) {
1904                  {                                                                                                  if (!
1905                          if (!(MotionFlags & PMV_HALFPEL8 ))                                                                                                          (MotionFlags &
1906                          {       pmv[3].x = EVEN(pmv[3].x);                                                                                                           PMV_HALFPEL8)) {
1907                                                                                                            pmv[3].x = EVEN(pmv[3].x);
1908                                  pmv[3].y = EVEN(pmv[3].y);                                  pmv[3].y = EVEN(pmv[3].y);
1909                          }                          }
1910                          CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);                                                                                                  CHECK_MV8_CANDIDATE(pmv[3].x,
1911                                                                                                                                            pmv[3].y);
1912                  }                  }
1913          }          }
1914    
1915          if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )          if ((MVzero(*currMV)) &&
1916                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1917                  iMinSAD -= MV8_00_BIAS;                  iMinSAD -= MV8_00_BIAS;
1918    
1919    
# Line 1690  Line 1921 
1921     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1922  */  */
1923    
1924          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ((iMinSAD <= threshA) ||
1925          {                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1926                     ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1927                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1928                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1929                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1711  Line 1943 
1943          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1944    
1945  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1946          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
1947                                           x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
1948                                           currMV->x, currMV->y, iMinSAD, &newMV,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
1949                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1950                                                      iQuant, iFound);
1951    
1952          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
1953                  *currMV = newMV;                  *currMV = newMV;
1954                  iMinSAD = iSAD;                  iMinSAD = iSAD;
1955          }          }
1956    
1957          if (MotionFlags & PMV_EXTSEARCH8)          if (MotionFlags & PMV_EXTSEARCH8) {
         {  
1958  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1959    
1960                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
1961                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1962                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1963                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
1964                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1965                                                                      iDiamondSize, iFcode, iQuant, iFound);
1966    
1967                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1968                          *currMV = newMV;                          *currMV = newMV;
1969                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1970                  }                  }
1971                  }                  }
1972    
1973                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1974                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1975                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1976                                                            0, 0, iMinSAD, &newMV,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
1977                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
1978                                                                      iQuant, iFound);
1979    
1980                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1981                          *currMV = newMV;                          *currMV = newMV;
1982                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1983                  }                  }
# Line 1759  Line 1990 
1990    
1991  PMVfast8_Terminate_with_Refine:  PMVfast8_Terminate_with_Refine:
1992          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step
1993                  iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
1994                                                   x, y,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1995                                                   currMV, iMinSAD,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
1996                                                   pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
1997    
1998    
1999  PMVfast8_Terminate_without_Refine:  PMVfast8_Terminate_without_Refine:
2000          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2001          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2002    
2003          return iMinSAD;          return iMinSAD;
2004  }  }
2005    
2006  int32_t EPZSSearch16(  int32_t
2007                                          const uint8_t * const pRef,  EPZSSearch16(const uint8_t * const pRef,
2008                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
2009                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
2010                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
2011                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
2012                                          const int x, const int y,                           const int x,
2013                             const int y,
2014                            const int start_x,
2015                            const int start_y,
2016                            const int center_x,
2017                            const int center_y,
2018                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
2019                                          const uint32_t iQuant,                                          const uint32_t iQuant,
2020                                          const uint32_t iFcode,                                          const uint32_t iFcode,
# Line 1809  Line 2045 
2045          int32_t psad[8];          int32_t psad[8];
2046    
2047          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
2048    
2049  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
2050          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
2051          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
2052    
2053          static int32_t thresh2;           int32_t thresh2;
2054          int32_t bPredEq;          int32_t bPredEq;
2055          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
2056    
2057          MainSearch16FuncPtr MainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
2058    
2059          if (oldMBs == NULL)          if (oldMBs == NULL) {
2060          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));                  oldMBs = (MACROBLOCK *) calloc(iWcount * iHcount, sizeof(MACROBLOCK));
2061  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
2062          }          }
2063          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
2064    
2065  /* Get maximum range */  /* Get maximum range */
2066          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
2067                          x, y, 16, iWidth, iHeight, iFcode);                            iFcode);
2068    
2069          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16)) {
2070          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
2071            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
2072            min_dy = EVEN(min_dy);            min_dy = EVEN(min_dy);
2073            max_dy = EVEN(max_dy);            max_dy = EVEN(max_dy);
2074          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
2075            /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
2076          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
2077            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2078    
2079  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
2080          MinSAD=SAD          MinSAD=SAD
# Line 1847  Line 2085 
2085    
2086  // Prepare for main loop  // Prepare for main loop
2087    
2088          *currMV=pmv[0];         /* current best := median prediction */          currMV->x = start_x;
2089          if (!(MotionFlags & PMV_HALFPEL16))          currMV->y = start_y;
2090          {  
2091            if (!(MotionFlags & PMV_HALFPEL16)) {
2092                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2093                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
2094          }          }
# Line 1865  Line 2104 
2104    
2105  /***************** This is predictor SET A: only median prediction ******************/  /***************** This is predictor SET A: only median prediction ******************/
2106    
2107          iMinSAD = sad16( cur,          iMinSAD =
2108                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  sad16(cur,
2109                  iEdgedWidth, MV_MAX_ERROR);                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2110          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2111            iMinSAD +=
2112                    calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2113                                              (uint8_t) iFcode, iQuant);
2114    
2115  // thresh1 is fixed to 256  // thresh1 is fixed to 256
2116          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ((iMinSAD < 256) ||
2117                  {                  ((MVequal(*currMV, prevMB->mvs[0])) &&
2118                     ((int32_t) iMinSAD < prevMB->sad16))) {
2119                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2120                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2121                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1887  Line 2130 
2130  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
2131  // 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
2132    
2133          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
2134                  thresh2 =  512;                  thresh2 =  512;
2135          }          } else {
         else  
         {  
2136  /* T_k = 1.2 * MIN(SAD_top,SAD_left,SAD_topleft,SAD_coll) +128;   [Tourapis, 2002] */  /* T_k = 1.2 * MIN(SAD_top,SAD_left,SAD_topleft,SAD_coll) +128;   [Tourapis, 2002] */
2137    
2138                  thresh2 = MIN(psad[0],iSAD)*6/5 + 128;                  thresh2 = MIN(psad[0],iSAD)*6/5 + 128;
# Line 1904  Line 2144 
2144    
2145    
2146  // left neighbour, if allowed  // left neighbour, if allowed
2147          if (x != 0)          if (x != 0) {
2148          {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2149                  if (!(MotionFlags & PMV_HALFPEL16 ))                          pmv[1].x = EVEN(pmv[1].x);
                 {       pmv[1].x = EVEN(pmv[1].x);  
2150                          pmv[1].y = EVEN(pmv[1].y);                          pmv[1].y = EVEN(pmv[1].y);
2151                  }                  }
2152                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
2153          }          }
   
2154  // top neighbour, if allowed  // top neighbour, if allowed
2155          if (y != 0)          if (y != 0) {
2156          {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2157                  if (!(MotionFlags & PMV_HALFPEL16 ))                          pmv[2].x = EVEN(pmv[2].x);
                 {       pmv[2].x = EVEN(pmv[2].x);  
2158                          pmv[2].y = EVEN(pmv[2].y);                          pmv[2].y = EVEN(pmv[2].y);
2159                  }                  }
2160                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
2161    
2162  // top right neighbour, if allowed  // top right neighbour, if allowed
2163                  if ((uint32_t)x != (iWcount-1))                  if ((uint32_t) x != (iWcount - 1)) {
2164                  {                          if (!(MotionFlags & PMV_HALFPEL16)) {
2165                          if (!(MotionFlags & PMV_HALFPEL16 ))                                  pmv[3].x = EVEN(pmv[3].x);
                         {       pmv[3].x = EVEN(pmv[3].x);  
2166                                  pmv[3].y = EVEN(pmv[3].y);                                  pmv[3].y = EVEN(pmv[3].y);
2167                          }                          }
2168                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);
# Line 1938  Line 2174 
2174  */  */
2175    
2176          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
2177                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || (MVequal(*currMV, prevMB->mvs[0]) &&
2178                  {                          ((int32_t) iMinSAD <= prevMB->sad16))) {
2179                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2180                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2181                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1960  Line 2196 
2196    
2197  // top neighbour  // top neighbour
2198          if (y != 0)          if (y != 0)
2199                  CHECK_MV16_CANDIDATE((prevMB-iWcount)->mvs[0].x,(prevMB-iWcount)->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB - iWcount)->mvs[0].x,
2200                                                             (prevMB - iWcount)->mvs[0].y);
2201    
2202  // 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
2203    
# Line 1969  Line 2206 
2206    
2207  // bottom neighbour, dito  // bottom neighbour, dito
2208          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
2209                  CHECK_MV16_CANDIDATE((prevMB+iWcount)->mvs[0].x,(prevMB+iWcount)->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB + iWcount)->mvs[0].x,
2210                                                             (prevMB + iWcount)->mvs[0].y);
2211    
2212  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
2213          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2) {
                 {  
2214                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2215                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2216                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1984  Line 2221 
2221    
2222          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
2223    
2224          if (MotionFlags & PMV_USESQUARES8)          if (MotionFlags & PMV_USESQUARES16)
2225                  MainSearchPtr = Square16_MainSearch;                  MainSearchPtr = Square16_MainSearch;
2226          else          else
2227             if (MotionFlags & PMV_ADVANCEDDIAMOND16)
         if (MotionFlags & PMV_ADVANCEDDIAMOND8)  
2228                  MainSearchPtr = AdvDiamond16_MainSearch;                  MainSearchPtr = AdvDiamond16_MainSearch;
2229          else          else
2230                  MainSearchPtr = Diamond16_MainSearch;                  MainSearchPtr = Diamond16_MainSearch;
2231    
2232  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2233    
2234          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
2235                          x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2236                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2237                          2, iFcode, iQuant, 0);                                                    min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2238    
2239          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
2240                  *currMV = newMV;                  *currMV = newMV;
2241                  iMinSAD = iSAD;                  iMinSAD = iSAD;
2242          }          }
2243    
2244    
2245          if (MotionFlags & PMV_EXTSEARCH16)          if (MotionFlags & PMV_EXTSEARCH16) {
         {  
2246  /* extended mode: search (up to) two more times: orignal prediction and (0,0) */  /* extended mode: search (up to) two more times: orignal prediction and (0,0) */
2247    
2248                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
2249                  {                          iSAD =
2250                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2251                                  x, y,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2252                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2253                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2254                  }                  }
2255    
2256                  if (iSAD < iMinSAD)                  if (iSAD < iMinSAD) {
                 {  
2257                          *currMV = newMV;                          *currMV = newMV;
2258                          iMinSAD = iSAD;                          iMinSAD = iSAD;
2259                  }                  }
2260    
2261                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2262                  {                          iSAD =
2263                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2264                                  x, y,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2265                          0, 0, iMinSAD, &newMV,                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
                         pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);  
2266    
2267                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2268                                  *currMV = newMV;                                  *currMV = newMV;
2269                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2270                          }                          }
# Line 2044  Line 2275 
2275    
2276  EPZS16_Terminate_with_Refine:  EPZS16_Terminate_with_Refine:
2277          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step
2278                  iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
2279                                  x, y,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2280                                  currMV, iMinSAD,                                                           iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2281                                  pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2282    
2283  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
2284    
2285          *oldMB = *prevMB;          *oldMB = *prevMB;
2286    
2287          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2288          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2289          return iMinSAD;          return iMinSAD;
2290  }  }
2291    
2292    
2293  int32_t EPZSSearch8(  int32_t
2294                                          const uint8_t * const pRef,  EPZSSearch8(const uint8_t * const pRef,
2295                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
2296                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
2297                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
2298                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
2299                                          const int x, const int y,                          const int x,
2300                                          const int start_x, const int start_y,                          const int y,
2301                            const int start_x,
2302                            const int start_y,
2303                            const int center_x,
2304                            const int center_y,
2305                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
2306                                          const uint32_t iQuant,                                          const uint32_t iQuant,
2307                                          const uint32_t iFcode,                                          const uint32_t iFcode,
# Line 2109  Line 2344 
2344          MainSearch8FuncPtr MainSearchPtr;          MainSearch8FuncPtr MainSearchPtr;
2345    
2346  /* Get maximum range */  /* Get maximum range */
2347          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight,
2348                          x, y, 8, iWidth, iHeight, iFcode);                            iFcode);
2349    
2350  /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */
2351    
2352          if (!(MotionFlags & PMV_HALFPEL8 ))          if (!(MotionFlags & PMV_HALFPEL8)) {
2353          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
2354            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
2355            min_dy = EVEN(min_dy);            min_dy = EVEN(min_dy);
2356            max_dy = EVEN(max_dy);            max_dy = EVEN(max_dy);
2357          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
2358            /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
2359          bPredEq  = get_pmvdata(pMBs, x>>1, y>>1, iWcount, iSubBlock, pmv, psad);          //bPredEq = get_pmvdata(pMBs, x >> 1, y >> 1, iWcount, iSubBlock, pmv[0].x, pmv[0].y, psad);
2360            bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2361    
2362    
2363  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 2134  Line 2370 
2370  // Prepare for main loop  // Prepare for main loop
2371    
2372    
2373          if (!(MotionFlags & PMV_HALFPEL8))          if (!(MotionFlags & PMV_HALFPEL8)) {
         {  
2374                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2375                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
2376          }          }
# Line 2152  Line 2387 
2387  /***************** This is predictor SET A: only median prediction ******************/  /***************** This is predictor SET A: only median prediction ******************/
2388    
2389    
2390          iMinSAD = sad8( cur,          iMinSAD =
2391                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  sad8(cur,
2392                  iEdgedWidth);                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2393          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);                                                  iEdgedWidth), iEdgedWidth);
2394            iMinSAD +=
2395                    calc_delta_8(currMV->x - center_x, currMV->y - center_y,
2396                                             (uint8_t) iFcode, iQuant);
2397    
2398    
2399  // thresh1 is fixed to 256  // thresh1 is fixed to 256
2400          if (iMinSAD < 256/4 )          if (iMinSAD < 256 / 4) {
                 {  
2401                          if (MotionFlags & PMV_QUICKSTOP8)                          if (MotionFlags & PMV_QUICKSTOP8)
2402                                  goto EPZS8_Terminate_without_Refine;                                  goto EPZS8_Terminate_without_Refine;
2403                          if (MotionFlags & PMV_EARLYSTOP8)                          if (MotionFlags & PMV_EARLYSTOP8)
# Line 2177  Line 2414 
2414          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
2415    
2416  // left neighbour, if allowed  // left neighbour, if allowed
2417          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR) {
2418          {                  if (!(MotionFlags & PMV_HALFPEL8)) {
2419                  if (!(MotionFlags & PMV_HALFPEL8 ))                          pmv[1].x = EVEN(pmv[1].x);
                 {       pmv[1].x = EVEN(pmv[1].x);  
2420                          pmv[1].y = EVEN(pmv[1].y);                          pmv[1].y = EVEN(pmv[1].y);
2421                  }                  }
2422                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
2423          }          }
   
2424  // top neighbour, if allowed  // top neighbour, if allowed
2425          if (psad[2] != MV_MAX_ERROR)          if (psad[2] != MV_MAX_ERROR) {
2426          {                  if (!(MotionFlags & PMV_HALFPEL8)) {
2427                  if (!(MotionFlags & PMV_HALFPEL8 ))                          pmv[2].x = EVEN(pmv[2].x);
                 {       pmv[2].x = EVEN(pmv[2].x);  
2428                          pmv[2].y = EVEN(pmv[2].y);                          pmv[2].y = EVEN(pmv[2].y);
2429                  }                  }
2430                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
2431    
2432  // top right neighbour, if allowed  // top right neighbour, if allowed
2433                  if (psad[3] != MV_MAX_ERROR)                  if (psad[3] != MV_MAX_ERROR) {
2434                  {                          if (!(MotionFlags & PMV_HALFPEL8)) {
2435                          if (!(MotionFlags & PMV_HALFPEL8 ))                                  pmv[3].x = EVEN(pmv[3].x);
                         {       pmv[3].x = EVEN(pmv[3].x);  
2436                                  pmv[3].y = EVEN(pmv[3].y);                                  pmv[3].y = EVEN(pmv[3].y);
2437                          }                          }
2438                          CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);                          CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
# Line 2217  Line 2450 
2450     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]
2451  */  */
2452    
2453          if (iMinSAD < 512/4)    /* T_2 == 512/4 hardcoded */          if (iMinSAD < 512 / 4) {        /* T_2 == 512/4 hardcoded */
                 {  
2454                          if (MotionFlags & PMV_QUICKSTOP8)                          if (MotionFlags & PMV_QUICKSTOP8)
2455                                  goto EPZS8_Terminate_without_Refine;                                  goto EPZS8_Terminate_without_Refine;
2456                          if (MotionFlags & PMV_EARLYSTOP8)                          if (MotionFlags & PMV_EARLYSTOP8)
# Line 2245  Line 2477 
2477          else          else
2478                  MainSearchPtr = Diamond8_MainSearch;                  MainSearchPtr = Diamond8_MainSearch;
2479    
2480          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
2481                  x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2482                  currMV->x, currMV->y, iMinSAD, &newMV,                                                    currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2483                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2484                  iDiamondSize, iFcode, iQuant, 0);                                                    iQuant, 0);
2485    
2486    
2487          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
2488                  *currMV = newMV;                  *currMV = newMV;
2489                  iMinSAD = iSAD;                  iMinSAD = iSAD;
2490          }          }
2491    
2492          if (MotionFlags & PMV_EXTSEARCH8)          if (MotionFlags & PMV_EXTSEARCH8) {
         {  
2493  /* extended mode: search (up to) two more times: orignal prediction and (0,0) */  /* extended mode: search (up to) two more times: orignal prediction and (0,0) */
2494    
2495                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
2496                  {                          iSAD =
2497                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2498                                  x, y,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2499                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2500                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2501    
2502                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2503                                  *currMV = newMV;                                  *currMV = newMV;
2504                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2505                          }                          }
2506                  }                  }
2507    
2508                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2509                  {                          iSAD =
2510                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2511                                  x, y,                                                                    iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2512                          0, 0, iMinSAD, &newMV,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2513                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                                                                    iQuant, 0);
2514    
2515                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2516                                  *currMV = newMV;                                  *currMV = newMV;
2517                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2518                          }                          }
# Line 2295  Line 2523 
2523    
2524  EPZS8_Terminate_with_Refine:  EPZS8_Terminate_with_Refine:
2525          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step
2526                  iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
2527                                  x, y,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2528                                  currMV, iMinSAD,                                                          iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2529                                  pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2530    
2531  EPZS8_Terminate_without_Refine:  EPZS8_Terminate_without_Refine:
2532    
2533          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - center_x;
2534          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - center_y;
2535          return iMinSAD;          return iMinSAD;
2536  }  }
2537    
2538    
2539    
2540    int32_t
2541    PMVfastIntSearch16(const uint8_t * const pRef,
2542                                    const uint8_t * const pRefH,
2543                                    const uint8_t * const pRefV,
2544                                    const uint8_t * const pRefHV,
2545                                    const IMAGE * const pCur,
2546                                    const int x,
2547                                    const int y,
2548                            const int start_x,
2549                            const int start_y,
2550                            const int center_x,
2551                            const int center_y,
2552                                    const uint32_t MotionFlags,
2553                                    const uint32_t iQuant,
2554                                    const uint32_t iFcode,
2555                                    const MBParam * const pParam,
2556                                    const MACROBLOCK * const pMBs,
2557                                    const MACROBLOCK * const prevMBs,
2558                                    VECTOR * const currMV,
2559                                    VECTOR * const currPMV)
2560    {
2561            const uint32_t iWcount = pParam->mb_width;
2562            const int32_t iWidth = pParam->width;
2563            const int32_t iHeight = pParam->height;
2564            const int32_t iEdgedWidth = pParam->edged_width;
2565    
2566            const uint8_t *cur = pCur->y + x * 16 + y * 16 * iEdgedWidth;
2567            const VECTOR zeroMV = { 0, 0 };
2568    
2569            int32_t iDiamondSize;
2570    
2571            int32_t min_dx;
2572            int32_t max_dx;
2573            int32_t min_dy;
2574            int32_t max_dy;
2575    
2576            int32_t iFound;
2577    
2578            VECTOR newMV;
2579            VECTOR backupMV;                        /* just for PMVFAST */
2580    
2581            VECTOR pmv[4];
2582            int32_t psad[4];
2583    
2584            MainSearch16FuncPtr MainSearchPtr;
2585    
2586            const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
2587            MACROBLOCK *const pMB = pMBs + x + y * iWcount;
2588    
2589            int32_t threshA, threshB;
2590            int32_t bPredEq;
2591            int32_t iMinSAD, iSAD;
2592    
2593    
2594    /* Get maximum range */
2595            get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 16, iWidth, iHeight,
2596                              iFcode);
2597    
2598    /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */
2599    
2600            if ((x == 0) && (y == 0)) {
2601                    threshA = 512;
2602                    threshB = 1024;
2603    
2604                    bPredEq = 0;
2605                    psad[0] = psad[1] = psad[2] = psad[3] = 0;
2606                    *currMV = pmv[0] = pmv[1] = pmv[2] = pmv[3] = zeroMV;
2607    
2608            } else {
2609                    threshA = psad[0];
2610                    threshB = threshA + 256;
2611                    if (threshA < 512)
2612                            threshA = 512;
2613                    if (threshA > 1024)
2614                            threshA = 1024;
2615                    if (threshB > 1792)
2616                            threshB = 1792;
2617    
2618                    bPredEq = get_ipmvdata(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2619                    *currMV = pmv[0];                       /* current best := prediction */
2620            }
2621    
2622            iFound = 0;
2623    
2624    /* Step 4: Calculate SAD around the Median prediction.
2625       MinSAD=SAD
2626       If Motion Vector equal to Previous frame motion vector
2627       and MinSAD<PrevFrmSAD goto Step 10.
2628       If SAD<=256 goto Step 10.
2629    */
2630    
2631            if (currMV->x > max_dx) {
2632                    currMV->x = EVEN(max_dx);
2633            }
2634            if (currMV->x < min_dx) {
2635                    currMV->x = EVEN(min_dx);
2636            }
2637            if (currMV->y > max_dy) {
2638                    currMV->y = EVEN(max_dy);
2639            }
2640            if (currMV->y < min_dy) {
2641                    currMV->y = EVEN(min_dy);
2642            }
2643    
2644            iMinSAD =
2645                    sad16(cur,
2646                              get_iref_mv(pRef, x, y, 16, currMV,
2647                                                     iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2648            iMinSAD +=
2649                    calc_delta_16(currMV->x - center_x, currMV->y - center_y,
2650                                              (uint8_t) iFcode, iQuant);
2651    
2652            if ((iMinSAD < 256) ||
2653                    ((MVequal(*currMV, prevMB->i_mvs[0])) &&
2654                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2655                    if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
2656                    {
2657                            if (!MVzero(*currMV)) {
2658                                    iMinSAD += MV16_00_BIAS;
2659                                    CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures
2660                                    iMinSAD -= MV16_00_BIAS;
2661                            }
2662                    }
2663    
2664                    if (MotionFlags & PMV_EARLYSTOP16)
2665                            goto PMVfastInt16_Terminate_with_Refine;
2666            }
2667    
2668    
2669    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
2670       vector of the median.
2671       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
2672    */
2673    
2674            if ((bPredEq) && (MVequal(pmv[0], prevMB->i_mvs[0])))
2675                    iFound = 2;
2676    
2677    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
2678       Otherwise select large Diamond Search.
2679    */
2680    
2681            if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))
2682                    iDiamondSize = 2;               // halfpel units!
2683            else
2684                    iDiamondSize = 4;               // halfpel units!
2685    
2686    /*
2687       Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
2688       Also calculate (0,0) but do not subtract offset.
2689       Let MinSAD be the smallest SAD up to this point.
2690       If MV is (0,0) subtract offset.
2691    */
2692    
2693    // (0,0) is often a good choice
2694    
2695            if (!MVzero(pmv[0]))
2696                    CHECK_MV16_ZERO;
2697    
2698    // previous frame MV is always possible
2699    
2700            if (!MVzero(prevMB->i_mvs[0]))
2701                    if (!MVequal(prevMB->i_mvs[0], pmv[0]))
2702                            CHECK_MV16_CANDIDATE(prevMB->i_mvs[0].x, prevMB->i_mvs[0].y);
2703    
2704    // left neighbour, if allowed
2705    
2706            if (!MVzero(pmv[1]))
2707                    if (!MVequal(pmv[1], prevMB->i_mvs[0]))
2708                            if (!MVequal(pmv[1], pmv[0]))
2709                                    CHECK_MV16_CANDIDATE(pmv[1].x, pmv[1].y);
2710    
2711    // top neighbour, if allowed
2712            if (!MVzero(pmv[2]))
2713                    if (!MVequal(pmv[2], prevMB->i_mvs[0]))
2714                            if (!MVequal(pmv[2], pmv[0]))
2715                                    if (!MVequal(pmv[2], pmv[1]))
2716                                            CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);
2717    
2718    // top right neighbour, if allowed
2719                                            if (!MVzero(pmv[3]))
2720                                                    if (!MVequal(pmv[3], prevMB->i_mvs[0]))
2721                                                            if (!MVequal(pmv[3], pmv[0]))
2722                                                                    if (!MVequal(pmv[3], pmv[1]))
2723                                                                            if (!MVequal(pmv[3], pmv[2]))
2724                                                                                    CHECK_MV16_CANDIDATE(pmv[3].x,
2725                                                                                                                             pmv[3].y);
2726    
2727            if ((MVzero(*currMV)) &&
2728                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
2729                    iMinSAD -= MV16_00_BIAS;
2730    
2731    
2732    /* Step 6: If MinSAD <= thresa goto Step 10.
2733       If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
2734    */
2735    
2736            if ((iMinSAD <= threshA) ||
2737                    (MVequal(*currMV, prevMB->i_mvs[0]) &&
2738                     ((int32_t) iMinSAD < prevMB->i_sad16))) {
2739    
2740                    if (MotionFlags & PMV_EARLYSTOP16)
2741                            goto PMVfastInt16_Terminate_with_Refine;
2742            }
2743    
2744    
2745    /************ (Diamond Search)  **************/
2746    /*
2747       Step 7: Perform Diamond search, with either the small or large diamond.
2748       If Found=2 only examine one Diamond pattern, and afterwards goto step 10
2749       Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond.
2750       If center then goto step 10.
2751       Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center.
2752       Refine by using small diamond and goto step 10.
2753    */
2754    
2755            if (MotionFlags & PMV_USESQUARES16)
2756                    MainSearchPtr = Square16_MainSearch;
2757            else if (MotionFlags & PMV_ADVANCEDDIAMOND16)
2758                    MainSearchPtr = AdvDiamond16_MainSearch;
2759            else
2760                    MainSearchPtr = Diamond16_MainSearch;
2761    
2762            backupMV = *currMV;                     /* save best prediction, actually only for EXTSEARCH */
2763    
2764    
2765    /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2766            iSAD =
2767                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2768                                                      currMV->y, iMinSAD, &newMV, center_x, center_y, min_dx, max_dx,
2769                                                      min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2770                                                      iQuant, iFound);
2771    
2772            if (iSAD < iMinSAD) {
2773                    *currMV = newMV;
2774                    iMinSAD = iSAD;
2775            }
2776    
2777            if (MotionFlags & PMV_EXTSEARCH16) {
2778    /* extended: search (up to) two more times: orignal prediction and (0,0) */
2779    
2780                    if (!(MVequal(pmv[0], backupMV))) {
2781                            iSAD =
2782                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2783                                                                      pmv[0].x, pmv[0].y, iMinSAD, &newMV, center_x, center_y,
2784                                                                      min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2785                                                                      iDiamondSize, iFcode, iQuant, iFound);
2786    
2787                            if (iSAD < iMinSAD) {
2788                                    *currMV = newMV;
2789                                    iMinSAD = iSAD;
2790                            }
2791                    }
2792    
2793                    if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2794                            iSAD =
2795                                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2796                                                                      iMinSAD, &newMV, center_x, center_y, min_dx, max_dx, min_dy,
2797                                                                      max_dy, iEdgedWidth, iDiamondSize, iFcode,
2798                                                                      iQuant, iFound);
2799    
2800                            if (iSAD < iMinSAD) {
2801                                    *currMV = newMV;
2802                                    iMinSAD = iSAD;
2803                            }
2804                    }
2805            }
2806    
2807    /*
2808       Step 10:  The motion vector is chosen according to the block corresponding to MinSAD.
2809    */
2810    
2811    PMVfastInt16_Terminate_with_Refine:
2812    
2813            pMB->i_mvs[0] = pMB->i_mvs[1] = pMB->i_mvs[2] = pMB->i_mvs[3] = pMB->i_mv16 = *currMV;
2814            pMB->i_sad8[0] = pMB->i_sad8[1] = pMB->i_sad8[2] = pMB->i_sad8[3] = pMB->i_sad16 = iMinSAD;
2815    
2816            if (MotionFlags & PMV_HALFPELREFINE16)  // perform final half-pel step
2817                    iMinSAD =
2818                            Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2819                                                             iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,
2820                                                             iFcode, iQuant, iEdgedWidth);
2821    
2822            pmv[0] = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);          // get _REAL_ prediction (halfpel possible)
2823    
2824    PMVfastInt16_Terminate_without_Refine:
2825            currPMV->x = currMV->x - center_x;
2826            currPMV->y = currMV->y - center_y;
2827            return iMinSAD;
2828    }
2829    
2830    
2831    
2832  /* ***********************************************************  /* ***********************************************************
# Line 2317  Line 2835 
2835  ***************************************************************/  ***************************************************************/
2836    
2837    
2838  void MotionEstimationBVOP(  #define DIRECT_PENALTY 0
2839                          MBParam * const pParam,  #define DIRECT_UPPERLIMIT 256   // never use direct mode if SAD is larger than this
                         FRAMEINFO * const frame,  
2840    
2841    void
2842    MotionEstimationBVOP(MBParam * const pParam,
2843                                             FRAMEINFO * const frame,
2844                                             const int32_t time_bp,
2845                                             const int32_t time_pp,
2846                          // forward (past) reference                          // forward (past) reference
2847                          const MACROBLOCK * const f_mbs,                          const MACROBLOCK * const f_mbs,
2848                      const IMAGE * const f_ref,                      const IMAGE * const f_ref,
# Line 2334  Line 2856 
2856                      const IMAGE * const b_refV,                      const IMAGE * const b_refV,
2857                          const IMAGE * const b_refHV)                          const IMAGE * const b_refHV)
2858  {  {
2859      const uint32_t mb_width = pParam->mb_width;          const int mb_width = pParam->mb_width;
2860      const uint32_t mb_height = pParam->mb_height;          const int mb_height = pParam->mb_height;
2861          const int32_t edged_width = pParam->edged_width;          const int edged_width = pParam->edged_width;
   
         uint32_t i,j;  
   
         int32_t f_sad16;  
         int32_t b_sad16;  
         int32_t i_sad16;  
         int32_t d_sad16;  
         int32_t best_sad;  
2862    
2863            int i, j, k;
2864    
2865            static const VECTOR zeroMV={0,0};
2866    
2867            int f_sad16;    /* forward (as usual) search */
2868            int b_sad16;    /* backward (only in b-frames) search */
2869            int i_sad16;    /* interpolated (both direction, b-frames only) */
2870            int d_sad16;    /* direct mode (assume linear motion) */
2871            int dnv_sad16;  /* direct mode (assume linear motion) without correction vector */
2872    
2873            int best_sad;
2874    
2875            VECTOR f_predMV, b_predMV;      /* there is no direct prediction */
2876          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
2877    
2878            int f_count=0;
2879            int b_count=0;
2880            int i_count=0;
2881            int d_count=0;
2882            int dnv_count=0;
2883            int s_count=0;
2884            const int64_t TRB = (int32_t)time_pp - (int32_t)time_bp;
2885        const int64_t TRD = (int32_t)time_pp;
2886    
2887            // fprintf(stderr,"TRB = %lld  TRD = %lld  time_bp =%d time_pp =%d\n\n",TRB,TRD,time_bp,time_pp);
2888          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
2889      for (j = 0; j < mb_height; j++)          for (j = 0; j < mb_height; j++) {
2890          {  
2891                  for (i = 0; i < mb_width; i++)                  f_predMV = zeroMV;      /* prediction is reset at left boundary */
2892                  {                  b_predMV = zeroMV;
2893    
2894                    for (i = 0; i < mb_width; i++) {
2895                          MACROBLOCK *mb = &frame->mbs[i + j*mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2896                          const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2897                          const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2898    
2899                          if (b_mb->mode == MODE_INTER                          VECTOR directMV;
2900                                  && b_mb->cbp == 0                          VECTOR deltaMV=zeroMV;
2901                                  && b_mb->mvs[0].x == 0  
2902                                  && b_mb->mvs[0].y == 0)  /* special case, if collocated block is SKIPed: encoding is forward(0,0)  */
2903                          {  
2904                            if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
2905                                    b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
2906                                  mb->mode = MODE_NOT_CODED;                                  mb->mode = MODE_NOT_CODED;
2907                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2908                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
# Line 2370  Line 2911 
2911                                  continue;                                  continue;
2912                          }                          }
2913    
2914                            dnv_sad16 = DIRECT_PENALTY;
2915    
2916                            if (b_mb->mode == MODE_INTER4V)
2917                            {
2918    
2919                            /* same method of scaling as in decoder.c, so we copy from there */
2920                        for (k = 0; k < 4; k++) {
2921    
2922                                            directMV = b_mb->mvs[k];
2923    
2924                                            mb->mvs[k].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);
2925                        mb->b_mvs[k].x = (int32_t) ((deltaMV.x == 0)
2926                                                                                    ? ((TRB - TRD) * directMV.x) / TRD
2927                                                : mb->mvs[k].x - directMV.x);
2928                        mb->mvs[k].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);
2929                            mb->b_mvs[k].y = (int32_t) ((deltaMV.y == 0)
2930                                                                                    ? ((TRB - TRD) * directMV.y) / TRD
2931                                                : mb->mvs[k].y - directMV.y);
2932    
2933                                            dnv_sad16 +=
2934                                                    sad8bi(frame->image.y + 2*(i+(k&1))*8 + 2*(j+(k>>1))*8*edged_width,
2935                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2936                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->mvs[k], edged_width),
2937                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2938                                                                    2*(i+(k&1)), 2*(j+(k>>1)), 8, &mb->b_mvs[k], edged_width),
2939                                                      edged_width);
2940                                    }
2941                            }
2942                            else
2943                            {
2944                                    directMV = b_mb->mvs[0];
2945    
2946                                    mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);
2947                    mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)
2948                                                                    ? ((TRB - TRD) * directMV.x) / TRD
2949                                        : mb->mvs[0].x - directMV.x);
2950                    mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);
2951                        mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)
2952                                                                    ? ((TRB - TRD) * directMV.y) / TRD
2953                                    : mb->mvs[0].y - directMV.y);
2954    
2955                                    dnv_sad16 = DIRECT_PENALTY +
2956                                            sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2957                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2958                                                                    i, j, 16, &mb->mvs[0], edged_width),
2959                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2960                                                                    i, j, 16, &mb->b_mvs[0], edged_width),
2961                                                      edged_width);
2962    
2963    
2964                }
2965    
2966                          // forward search                          // forward search
2967                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2968                                                  &frame->image,                                                  &frame->image, i, j,
2969                                                  i, j,                                                  mb->mvs[0].x, mb->mvs[0].y,                     /* start point f_directMV */
2970                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  f_predMV.x, f_predMV.y,                         /* center is f-prediction */
2971                                                  pParam,                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),
2972                                                  f_mbs, f_mbs /* todo */,                                                  frame->quant, frame->fcode, pParam,
2973                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  f_mbs, f_mbs,
2974                                                    &mb->mvs[0], &pmv_dontcare);
2975    
2976    
2977                          // backward search                          // backward search
2978                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                          b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2979                                                  &frame->image,                                                  &frame->image, i, j,
2980                                                  i, j,                                                  mb->b_mvs[0].x, mb->b_mvs[0].y,         /* start point b_directMV */
2981                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  b_predMV.x, b_predMV.y,                         /* center is b-prediction */
2982                                                  pParam,                                                  frame->motion_flags & (~(PMV_EARLYSTOP16|PMV_QUICKSTOP16)),
2983                                                  b_mbs, b_mbs, /* todo */                                                  frame->quant, frame->bcode, pParam,
2984                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  b_mbs, b_mbs,
2985                                                    &mb->b_mvs[0], &pmv_dontcare);
2986                          // interpolate search (simple, but effective)  
2987                          i_sad16 = sad16bi_c(                          i_sad16 =
2988                                          frame->image.y + i*16 + j*16*edged_width,                                  sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
2989                                          get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                                    get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2990                                                  i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),                                                                  i, j, 16, &mb->mvs[0], edged_width),
2991                                          get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                    get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2992                                                  i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),                                                                  i, j, 16, &mb->b_mvs[0], edged_width),
2993                                          edged_width);                                          edged_width);
2994                        i_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
2995                                                                    frame->fcode, frame->quant);
2996                        i_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,
2997                                                                    frame->bcode, frame->quant);
2998    
2999                          // TODO: direct search                          // TODO: direct search
3000                          // predictor + range of [-32,32]                          // predictor + delta vector in range [-32,32] (fcode=1)
                         d_sad16 = 65535;  
3001    
3002    //                      i_sad16 = 65535;
3003    //                      f_sad16 = 65535;
3004    //                      b_sad16 = 65535;
3005    
3006                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16) {
                         {  
3007                                  best_sad = f_sad16;                                  best_sad = f_sad16;
3008                                  mb->mode = MODE_FORWARD;                                  mb->mode = MODE_FORWARD;
3009                          }                          } else {
                         else  
                         {  
3010                                  best_sad = b_sad16;                                  best_sad = b_sad16;
3011                                  mb->mode = MODE_BACKWARD;                                  mb->mode = MODE_BACKWARD;
3012                          }                          }
3013    
3014                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad) {
                         {  
3015                                  best_sad = i_sad16;                                  best_sad = i_sad16;
3016                                  mb->mode = MODE_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
3017                          }                          }
3018    
3019                          if (d_sad16 < best_sad)                          if (dnv_sad16 < best_sad) {
3020    
3021                                    if (dnv_sad16 > DIRECT_UPPERLIMIT)
3022                          {                          {
3023                                  best_sad = d_sad16;                                          /* if SAD value is too large, try same vector with MODE_INTERPOLATE
3024                                  mb->mode = MODE_DIRECT;                                             instead (interpolate has residue encoding, direct mode without MV
3025                                               doesn't)
3026    
3027                                                    This has to be replaced later by "real" direct mode, including delta
3028                                                    vector and (if needed) residue encoding
3029    
3030                                            */
3031    
3032                                            directMV = b_mb->mvs[0];
3033    
3034                                            mb->mvs[0].x = (int32_t) ((TRB * directMV.x) / TRD + deltaMV.x);
3035                        mb->b_mvs[0].x = (int32_t) ((deltaMV.x == 0)
3036                                                                                    ? ((TRB - TRD) * directMV.x) / TRD
3037                                            : mb->mvs[0].x - directMV.x);
3038                            mb->mvs[0].y = (int32_t) ((TRB * directMV.y) / TRD + deltaMV.y);
3039                            mb->b_mvs[0].y = (int32_t) ((deltaMV.y == 0)
3040                                                                                    ? ((TRB - TRD) * directMV.y) / TRD
3041                                                : mb->mvs[0].y - directMV.y);
3042    
3043                                            dnv_sad16 =
3044                                                    sad16bi(frame->image.y + i * 16 + j * 16 * edged_width,
3045                                                      get_ref_mv(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
3046                                                                    i, j, 16, &mb->mvs[0], edged_width),
3047                                                      get_ref_mv(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
3048                                                                    i, j, 16, &mb->b_mvs[0], edged_width),
3049                                                      edged_width);
3050                                    dnv_sad16 += calc_delta_16(mb->mvs[0].x-f_predMV.x, mb->mvs[0].y-f_predMV.y,
3051                                                                    frame->fcode, frame->quant);
3052                                        dnv_sad16 += calc_delta_16(mb->b_mvs[0].y-b_predMV.y, mb->b_mvs[0].y-b_predMV.y,
3053                                                                    frame->bcode, frame->quant);
3054    
3055                                            if (dnv_sad16 < best_sad)
3056                                            {
3057                                                    best_sad = dnv_sad16;
3058                                                    mb->mode = MODE_INTERPOLATE;
3059    
3060    /*                                              fprintf(stderr,"f_sad16 = %d, b_sad16 = %d, i_sad16 = %d, dnv_sad16 = %d\n",
3061                                                            f_sad16,b_sad16,i_sad16,dnv_sad16);
3062    */                                      }
3063                                    }
3064                                    else
3065                                    {
3066                                            best_sad = dnv_sad16;
3067                                            mb->mode = MODE_DIRECT_NONE_MV;
3068                                    }
3069                            }
3070    
3071                            switch (mb->mode)
3072                            {
3073                                    case MODE_FORWARD:
3074                                            f_count++;
3075                                            f_predMV = mb->mvs[0];
3076                                            break;
3077                                    case MODE_BACKWARD:
3078                                            b_count++;
3079                                            b_predMV = mb->b_mvs[0];
3080    
3081                                            break;
3082                                    case MODE_INTERPOLATE:
3083                                            i_count++;
3084                                            f_predMV = mb->mvs[0];
3085                                            b_predMV = mb->b_mvs[0];
3086                                            break;
3087                                    case MODE_DIRECT:
3088                                            d_count++; break;
3089                                    case MODE_DIRECT_NONE_MV:
3090                                            dnv_count++; break;
3091                                    default:
3092                                            s_count++; break;
3093                          }                          }
3094    
3095                  }                  }
3096          }          }
3097    
3098    #ifdef _DEBUG_BFRAME_STAT
3099            fprintf(stderr,"B-Stat: F: %04d   B: %04d   I: %04d  D0: %04d   D: %04d   S: %04d\n",
3100                                    f_count,b_count,i_count,dnv_count,d_count,s_count);
3101    #endif
3102    
3103  }  }

Legend:
Removed from v.184  
changed lines
  Added in v.326

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