[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 132, Tue Apr 23 00:04:51 2002 UTC revision 254, Wed Jul 3 12:32:50 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      01.05.2002      updated MotionEstimationBVOP
6     *      25.04.2002 partial prevMB conversion
7   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
8   *  14.04.2002 added MotionEstimationBVOP()   *  14.04.2002 added MotionEstimationBVOP()
9   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between
# Line 52  Line 54 
54  #define MV16_THRESHOLD  192  #define MV16_THRESHOLD  192
55  #define MV8_THRESHOLD   56  #define MV8_THRESHOLD   56
56    
57    #define NEIGH_MOVE_THRESH 0
58    // how much a block's MV must differ from his neighbour
59    // to be search for INTER4V. The more, the faster...
60    
61  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
62  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
63  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
64    #define MV8_00_BIAS     (0)
65    
66  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
67  #define INTER_BIAS      512  #define MV16_INTER_BIAS 512
68    
69  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
70  #define IMV16X16                        5  #define IMV16X16                        5
# Line 66  Line 73 
73  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
74  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
75    
   
76  // fast ((A)/2)*2  // fast ((A)/2)*2
77  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
78    
79    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
80    #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
81    
82  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(const uint8_t * const pRef,
                                         const uint8_t * const pRef,  
83                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
84                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
85                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
86                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
87                                          const int x, const int y,                                                  const int x,
88                                                    const int y,
89                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
90                                                    const uint32_t iQuant,
91                                                    const uint32_t iFcode,
92                                          const MBParam * const pParam,                                          const MBParam * const pParam,
93                                          MACROBLOCK * const pMBs,                                                  const MACROBLOCK * const pMBs,
94                                                    const MACROBLOCK * const prevMBs,
95                                          VECTOR * const currMV,                                          VECTOR * const currMV,
96                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
97    
98  int32_t EPZSSearch16(  int32_t EPZSSearch16(const uint8_t * const pRef,
                                         const uint8_t * const pRef,  
99                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
100                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
101                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
102                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
103                                          const int x, const int y,                                           const int x,
104                                             const int y,
105                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
106                                             const uint32_t iQuant,
107                                             const uint32_t iFcode,
108                                          const MBParam * const pParam,                                          const MBParam * const pParam,
109                                          MACROBLOCK * const pMBs,                                           const MACROBLOCK * const pMBs,
110                                             const MACROBLOCK * const prevMBs,
111                                          VECTOR * const currMV,                                          VECTOR * const currMV,
112                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
113    
114    
115  int32_t PMVfastSearch8(  int32_t PMVfastSearch8(const uint8_t * const pRef,
                                         const uint8_t * const pRef,  
116                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
117                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
118                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
119                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
120                                          const int x, const int y,                                             const int x,
121                                          const int start_x, int start_y,                                             const int y,
122                                               const int start_x,
123                                               const int start_y,
124                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
125                                               const uint32_t iQuant,
126                                               const uint32_t iFcode,
127                                          const MBParam * const pParam,                                          const MBParam * const pParam,
128                                          MACROBLOCK * const pMBs,                                             const MACROBLOCK * const pMBs,
129                                               const MACROBLOCK * const prevMBs,
130                                          VECTOR * const currMV,                                          VECTOR * const currMV,
131                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
132    
133  int32_t EPZSSearch8(  int32_t EPZSSearch8(const uint8_t * const pRef,
                                         const uint8_t * const pRef,  
134                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
135                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
136                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
137                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
138                                          const int x, const int y,                                          const int x,
139                                          const int start_x, int start_y,                                          const int y,
140                                            const int start_x,
141                                            const int start_y,
142                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
143                                            const uint32_t iQuant,
144                                            const uint32_t iFcode,
145                                          const MBParam * const pParam,                                          const MBParam * const pParam,
146                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
147                                            const MACROBLOCK * const prevMBs,
148                                          VECTOR * const currMV,                                          VECTOR * const currMV,
149                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
150    
151    
152  typedef int32_t (MainSearch16Func)(  typedef int32_t(MainSearch16Func) (const uint8_t * const pRef,
         const uint8_t * const pRef,  
153          const uint8_t * const pRefH,          const uint8_t * const pRefH,
154          const uint8_t * const pRefV,          const uint8_t * const pRefV,
155          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
156          const uint8_t * const cur,          const uint8_t * const cur,
157          const int x, const int y,                                                                     const int x,
158          int32_t startx, int32_t starty,                                                                     const int y,
159                                                                       int32_t startx,
160                                                                       int32_t starty,
161          int32_t iMinSAD,          int32_t iMinSAD,
162          VECTOR * const currMV,          VECTOR * const currMV,
163          const VECTOR * const pmv,          const VECTOR * const pmv,
164          const int32_t min_dx, const int32_t max_dx,                                                                     const int32_t min_dx,
165          const int32_t min_dy, const int32_t max_dy,                                                                     const int32_t max_dx,
166                                                                       const int32_t min_dy,
167                                                                       const int32_t max_dy,
168          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
169          const int32_t iDiamondSize,          const int32_t iDiamondSize,
170          const int32_t iFcode,          const int32_t iFcode,
# Line 149  Line 174 
174  typedef MainSearch16Func* MainSearch16FuncPtr;  typedef MainSearch16Func* MainSearch16FuncPtr;
175    
176    
177  typedef int32_t (MainSearch8Func)(  typedef int32_t(MainSearch8Func) (const uint8_t * const pRef,
         const uint8_t * const pRef,  
178          const uint8_t * const pRefH,          const uint8_t * const pRefH,
179          const uint8_t * const pRefV,          const uint8_t * const pRefV,
180          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
181          const uint8_t * const cur,          const uint8_t * const cur,
182          const int x, const int y,                                                                    const int x,
183          int32_t startx, int32_t starty,                                                                    const int y,
184                                                                      int32_t startx,
185                                                                      int32_t starty,
186          int32_t iMinSAD,          int32_t iMinSAD,
187          VECTOR * const currMV,          VECTOR * const currMV,
188          const VECTOR * const pmv,          const VECTOR * const pmv,
189          const int32_t min_dx, const int32_t max_dx,                                                                    const int32_t min_dx,
190          const int32_t min_dy, const int32_t max_dy,                                                                    const int32_t max_dx,
191                                                                      const int32_t min_dy,
192                                                                      const int32_t max_dy,
193          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
194          const int32_t iDiamondSize,          const int32_t iDiamondSize,
195          const int32_t iFcode,          const int32_t iFcode,
# Line 170  Line 198 
198    
199  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
200    
201    static int32_t lambda_vec16[32] =       /* rounded values for lambda param for weight of motion bits as in modified H.26L */
202    { 0, (int) (1.00235 + 0.5), (int) (1.15582 + 0.5), (int) (1.31976 + 0.5),
203                    (int) (1.49591 + 0.5), (int) (1.68601 + 0.5),
204            (int) (1.89187 + 0.5), (int) (2.11542 + 0.5), (int) (2.35878 + 0.5),
205                    (int) (2.62429 + 0.5), (int) (2.91455 + 0.5),
206            (int) (3.23253 + 0.5), (int) (3.58158 + 0.5), (int) (3.96555 + 0.5),
207                    (int) (4.38887 + 0.5), (int) (4.85673 + 0.5),
208            (int) (5.37519 + 0.5), (int) (5.95144 + 0.5), (int) (6.59408 + 0.5),
209                    (int) (7.31349 + 0.5), (int) (8.12242 + 0.5),
210            (int) (9.03669 + 0.5), (int) (10.0763 + 0.5), (int) (11.2669 + 0.5),
211                    (int) (12.6426 + 0.5), (int) (14.2493 + 0.5),
212            (int) (16.1512 + 0.5), (int) (18.442 + 0.5), (int) (21.2656 + 0.5),
213                    (int) (24.8580 + 0.5), (int) (29.6436 + 0.5),
214            (int) (36.4949 + 0.5)
215    };
216    
217    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now */
218    
219    
220    
221  // mv.length table  // mv.length table
222  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
223      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 179  Line 227 
227  };  };
228    
229    
230  static __inline uint32_t mv_bits(int32_t component, const uint32_t iFcode)  static __inline uint32_t
231    mv_bits(int32_t component,
232                    const uint32_t iFcode)
233  {  {
234      if (component == 0)      if (component == 0)
235                  return 1;                  return 1;
# Line 187  Line 237 
237      if (component < 0)      if (component < 0)
238                  component = -component;                  component = -component;
239    
240      if (iFcode == 1)          if (iFcode == 1) {
     {  
241                  if (component > 32)                  if (component > 32)
242                      component = 32;                      component = 32;
243    
# Line 205  Line 254 
254  }  }
255    
256    
257  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t
258    calc_delta_16(const int32_t dx,
259                              const int32_t dy,
260                              const uint32_t iFcode,
261                              const uint32_t iQuant)
262    {
263            return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) +
264                                                                                                              mv_bits(dy, iFcode));
265    }
266    
267    static __inline uint32_t
268    calc_delta_8(const int32_t dx,
269                             const int32_t dy,
270                             const uint32_t iFcode,
271                             const uint32_t iQuant)
272  {  {
273          return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) +
274  }                                                                                                     mv_bits(dy, iFcode));
   
 static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode)  
   
 {  
     return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));  
275  }  }
276    
277    
# Line 231  Line 289 
289  //#define SEARCH8       EPZSSearch8  //#define SEARCH8       EPZSSearch8
290  #endif  #endif
291    
292  bool MotionEstimation(  bool
293          MACROBLOCK * const pMBs,  MotionEstimation(MBParam * const pParam,
294          MBParam * const pParam,                                   FRAMEINFO * const current,
295          const IMAGE * const pRef,                                   FRAMEINFO * const reference,
296          const IMAGE * const pRefH,          const IMAGE * const pRefH,
297          const IMAGE * const pRefV,          const IMAGE * const pRefV,
298          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
299          const uint32_t iLimit)          const uint32_t iLimit)
   
300  {  {
301          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
302          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
303            MACROBLOCK *const pMBs = current->mbs;
304          uint32_t i, j, iIntra = 0;          MACROBLOCK *const prevMBs = reference->mbs;
305            const IMAGE *const pCurrent = &current->image;
306          VECTOR mv16;          const IMAGE *const pRef = &reference->image;
307          VECTOR pmv16;  
308            const VECTOR zeroMV = { 0, 0 };
309          int32_t sad8 = 0;  
310          int32_t sad16;          int32_t x, y;
311          int32_t deviation;          int32_t iIntra = 0;
312            VECTOR pmv;
313    
314          if (sadInit)          if (sadInit)
315                  (*sadInit)();                  (*sadInit)();
316    
317          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
318          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++) {
319                  for (j = 0; j < iWcount; j++)                          MACROBLOCK *const pMB = &pMBs[x + y * iWcount];
320                  {  
321                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          pMB->sad16 =
322                                    SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
323                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                                   y, current->motion_flags, current->quant,
324                                           j, i, pParam->motion_flags,                                                   current->fcode, pParam, pMBs, prevMBs, &pMB->mv16,
325                                           pParam, pMBs, &mv16, &pmv16);                                                   &pMB->pmvs[0]);
                         pMB->sad16=sad16;  
   
326    
327                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS)) {
328                             if (dev_intra < sad_inter - 2 * nb) use_intra                                  int32_t deviation;
                         */  
329    
330                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                                  deviation =
331                                            dev16(pCurrent->y + x * 16 + y * 16 * pParam->edged_width,
332                                                      pParam->edged_width);
333    
334                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) {
                         {  
335                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
336                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =
337                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                  pMB->mvs[3] = zeroMV;
338                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] =
339                                                    pMB->sad8[3] = 0;
340    
341                                  iIntra++;                                  iIntra++;
342                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 287  Line 344 
344    
345                                  continue;                                  continue;
346                          }                          }
   
                         if (pParam->global_flags & XVID_INTER4V)  
                         {  
                                 pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);  
   
                                 pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);  
   
                                 pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);  
   
                                 pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);  
   
                                 sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];  
347                          }                          }
348    
349                            pmv = pMB->pmvs[0];
350                            if (current->global_flags & XVID_INTER4V)
351                                    if ((!(current->global_flags & XVID_LUMIMASKING) ||
352                                             pMB->dquant == NO_CHANGE)) {
353                                            int32_t sad8 = IMV16X16 * current->quant;
354    
355                                            if (sad8 < pMB->sad16)
356    
357                                                    sad8 += pMB->sad8[0] =
358                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
359                                                                            pCurrent, 2 * x, 2 * y, pMB->mv16.x,
360                                                                            pMB->mv16.y, current->motion_flags,
361                                                                            current->quant, current->fcode, pParam,
362                                                                            pMBs, prevMBs, &pMB->mvs[0],
363                                                                            &pMB->pmvs[0]);
364    
365                                            if (sad8 < pMB->sad16)
366                                                    sad8 += pMB->sad8[1] =
367                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
368                                                                            pCurrent, 2 * x + 1, 2 * y, pMB->mv16.x,
369                                                                            pMB->mv16.y, current->motion_flags,
370                                                                            current->quant, current->fcode, pParam,
371                                                                            pMBs, prevMBs, &pMB->mvs[1],
372                                                                            &pMB->pmvs[1]);
373    
374                                            if (sad8 < pMB->sad16)
375                                                    sad8 += pMB->sad8[2] =
376                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
377                                                                            pCurrent, 2 * x, 2 * y + 1, pMB->mv16.x,
378                                                                            pMB->mv16.y, current->motion_flags,
379                                                                            current->quant, current->fcode, pParam,
380                                                                            pMBs, prevMBs, &pMB->mvs[2],
381                                                                            &pMB->pmvs[2]);
382    
383                                            if (sad8 < pMB->sad16)
384                                                    sad8 += pMB->sad8[3] =
385                                                            SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y,
386                                                                            pCurrent, 2 * x + 1, 2 * y + 1,
387                                                                            pMB->mv16.x, pMB->mv16.y,
388                                                                            current->motion_flags, current->quant,
389                                                                            current->fcode, pParam, pMBs, prevMBs,
390                                                                            &pMB->mvs[3], &pMB->pmvs[3]);
391    
392                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
393                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
394                          */                          */
395    
396                          if (pMB->dquant == NO_CHANGE) {                                          if (sad8 < pMB->sad16) {
                                 if (((pParam->global_flags & XVID_INTER4V)==0) ||  
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {  
   
                                         sad8 = sad16;  
                                         pMB->mode = MODE_INTER;  
                                         pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;  
                                         pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;  
                                         pMB->pmvs[0].x = pmv16.x;  
                                         pMB->pmvs[0].y = pmv16.y;  
                                 }  
                                 else  
397                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
398                          }                                                  pMB->sad8[0] *= 4;
399                          else                                                  pMB->sad8[1] *= 4;
400                          {                                                  pMB->sad8[2] *= 4;
401                                  sad8 = sad16;                                                  pMB->sad8[3] *= 4;
402                                  pMB->mode = MODE_INTER;                                                  continue;
                                 pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;  
                                 pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;  
                                 pMB->pmvs[0].x = pmv16.x;  
                                 pMB->pmvs[0].y = pmv16.y;  
                         }  
403                  }                  }
404    
         return 0;  
405  }  }
406    
407  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                          pMB->mode = MODE_INTER;
408                            pMB->pmvs[0] = pmv;     /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3]  are not needed for INTER */
409  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
410                            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] =
411                                    pMB->sad16;
412    
413                    }
414            return 0;
415    }
416    
417  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
418    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
419      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
420    { \    { \
421      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); \
422      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
     if (iSAD <= iQuant * 96)    \  
         iSAD -= MV16_00_BIAS; \  
423      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
424      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
425  }  }
426    
427  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
428      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); \
429      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
430      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
431      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
432  }  }
# Line 371  Line 436 
436      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
437    { \    { \
438      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); \
439      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
440      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
441      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
442  }  }
# Line 381  Line 446 
446      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
447    { \    { \
448      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); \
449      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
450      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
451      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
452  }  }
# Line 391  Line 456 
456      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
457    { \    { \
458      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); \
459      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
462  }  }
# Line 399  Line 464 
464    
465  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
466    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); \
467    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
468    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
469    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
470  }  }
# Line 407  Line 472 
472  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
473    { \    { \
474      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); \
475      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
476      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
477      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
478  }  }
# Line 417  Line 482 
482      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
483    { \    { \
484      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); \
485      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
486      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
487      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
488  }  }
# Line 427  Line 492 
492      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
493    { \    { \
494      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); \
495      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
496      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
497      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
498  }  }
# Line 437  Line 502 
502      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
503    { \    { \
504      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); \
505      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
506      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
507      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
508  }  }
# Line 452  Line 517 
517                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
518                                          const int x, const int y,                                          const int x, const int y,
519                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
520                                            const uint32_t iQuant,
521                                            const uint32_t iFcode,
522                                          MBParam * const pParam,                                          MBParam * const pParam,
523                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
524                                            const MACROBLOCK * const prevMBs,
525                                          VECTOR * const currMV,                                          VECTOR * const currMV,
526                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
527  {  {
528          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
529          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
530          int32_t iSAD;          int32_t iSAD;
531          int32_t pred_x,pred_y;          VECTOR pred;
532    
533          get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y);  
534            pred = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0);
535    
536          iSAD = sad16( cur,          iSAD = sad16( cur,
537                  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 473  Line 541 
541    
542          currMV->x = 0;          currMV->x = 0;
543          currMV->y = 0;          currMV->y = 0;
544          currPMV->x = -pred_x;          currPMV->x = -pred.x;
545          currPMV->y = -pred_y;          currPMV->y = -pred.y;
546    
547          return iSAD;          return iSAD;
548    
549  }  }
550  */  */
551    
552  int32_t Diamond16_MainSearch(  int32_t
553          const uint8_t * const pRef,  Diamond16_MainSearch(const uint8_t * const pRef,
554          const uint8_t * const pRefH,          const uint8_t * const pRefH,
555          const uint8_t * const pRefV,          const uint8_t * const pRefV,
556          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
557          const uint8_t * const cur,          const uint8_t * const cur,
558          const int x, const int y,                                           const int x,
559          int32_t startx, int32_t starty,                                           const int y,
560                                             int32_t startx,
561                                             int32_t starty,
562          int32_t iMinSAD,          int32_t iMinSAD,
563          VECTOR * const currMV,          VECTOR * const currMV,
564          const VECTOR * const pmv,          const VECTOR * const pmv,
565          const int32_t min_dx, const int32_t max_dx,                                           const int32_t min_dx,
566          const int32_t min_dy, const int32_t max_dy,                                           const int32_t max_dx,
567                                             const int32_t min_dy,
568                                             const int32_t max_dy,
569          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
570          const int32_t iDiamondSize,          const int32_t iDiamondSize,
571          const int32_t iFcode,          const int32_t iFcode,
# Line 505  Line 577 
577          int32_t iDirection=0;          int32_t iDirection=0;
578          int32_t iSAD;          int32_t iSAD;
579          VECTOR backupMV;          VECTOR backupMV;
580    
581          backupMV.x = startx;          backupMV.x = startx;
582          backupMV.y = starty;          backupMV.y = starty;
583    
# Line 516  Line 589 
589          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
590    
591          if (iDirection)          if (iDirection)
592                  while (!iFound)                  while (!iFound) {
                 {  
593                          iFound = 1;                          iFound = 1;
594                          backupMV=*currMV;                          backupMV=*currMV;
595    
596                          if ( iDirection != 2)                          if ( iDirection != 2)
597                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
598                                                                                       backupMV.y, 1);
599                          if ( iDirection != 1)                          if ( iDirection != 1)
600                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
601                                                                                       backupMV.y, 2);
602                          if ( iDirection != 4)                          if ( iDirection != 4)
603                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
604                                                                                       backupMV.y - iDiamondSize, 3);
605                          if ( iDirection != 3)                          if ( iDirection != 3)
606                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x,
607                  }                                                                                     backupMV.y + iDiamondSize, 4);
608          else          } else {
         {  
609                  currMV->x = startx;                  currMV->x = startx;
610                  currMV->y = starty;                  currMV->y = starty;
611          }          }
612          return iMinSAD;          return iMinSAD;
613  }  }
614    
615  int32_t Square16_MainSearch(  int32_t
616                                          const uint8_t * const pRef,  Square16_MainSearch(const uint8_t * const pRef,
617                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
618                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
619                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
620                                          const uint8_t * const cur,                                          const uint8_t * const cur,
621                                          const int x, const int y,                                          const int x,
622                                          int32_t startx, int32_t starty,                                          const int y,
623                                            int32_t startx,
624                                            int32_t starty,
625                                          int32_t iMinSAD,                                          int32_t iMinSAD,
626                                          VECTOR * const currMV,                                          VECTOR * const currMV,
627                                          const VECTOR * const pmv,                                          const VECTOR * const pmv,
628                                          const int32_t min_dx, const int32_t max_dx,                                          const int32_t min_dx,
629                                          const int32_t min_dy, const int32_t max_dy,                                          const int32_t max_dx,
630                                            const int32_t min_dy,
631                                            const int32_t max_dy,
632                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
633                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
634                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 562  Line 640 
640          int32_t iDirection=0;          int32_t iDirection=0;
641          int32_t iSAD;          int32_t iSAD;
642          VECTOR backupMV;          VECTOR backupMV;
643    
644          backupMV.x = startx;          backupMV.x = startx;
645          backupMV.y = starty;          backupMV.y = starty;
646    
# Line 578  Line 657 
657          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);
658          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
659    
660          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
661          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                           backupMV.y - iDiamondSize, 5);
662          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);          CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
663          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                                           backupMV.y + iDiamondSize, 6);
664            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
665                                                             backupMV.y - iDiamondSize, 7);
666            CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
667                                                             backupMV.y + iDiamondSize, 8);
668    
669    
670          if (iDirection)          if (iDirection)
671                  while (!iFound)                  while (!iFound) {
                 {  
672                          iFound = 1;                          iFound = 1;
673                          backupMV=*currMV;                          backupMV=*currMV;
674    
675                          switch (iDirection)                          switch (iDirection) {
                         {  
676                                  case 1:                                  case 1:
677                                          CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
678                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                     backupMV.y, 1);
679                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
680                                                                                     backupMV.y - iDiamondSize, 5);
681                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
682                                                                                     backupMV.y - iDiamondSize, 7);
683                                          break;                                          break;
684                                  case 2:                                  case 2:
685                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
686                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                                                   2);
687                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
688                                                                                     backupMV.y + iDiamondSize, 6);
689                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
690                                                                                     backupMV.y + iDiamondSize, 8);
691                                          break;                                          break;
692    
693                                  case 3:                                  case 3:
694                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
695                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
696                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
697                                                                                     backupMV.y - iDiamondSize, 7);
698                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
699                                                                                     backupMV.y + iDiamondSize, 8);
700                                          break;                                          break;
701    
702                                  case 4:                                  case 4:
703                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
704                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
705                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
706                                                                                     backupMV.y - iDiamondSize, 5);
707                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
708                                                                                     backupMV.y + iDiamondSize, 6);
709                                          break;                                          break;
710    
711                                  case 5:                                  case 5:
712                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,
713                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                                                                   1);
714                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
715                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                                                                   3);
716                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
717                                                                                     backupMV.y - iDiamondSize, 5);
718                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
719                                                                                     backupMV.y + iDiamondSize, 6);
720                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
721                                                                                     backupMV.y - iDiamondSize, 7);
722                                          break;                                          break;
723    
724                                  case 6:                                  case 6:
725                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
726                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                                                                   2);
727                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
728                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
729                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);  
730                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
731                                                                                     backupMV.y - iDiamondSize, 5);
732                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
733                                                                                     backupMV.y + iDiamondSize, 6);
734                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
735                                                                                     backupMV.y + iDiamondSize, 8);
736    
737                                          break;                                          break;
738    
739                                  case 7:                                  case 7:
740                                          CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
741                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                     backupMV.y, 1);
742                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
743                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
744                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
745                                                                                     backupMV.y - iDiamondSize, 5);
746                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
747                                                                                     backupMV.y - iDiamondSize, 7);
748                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
749                                                                                     backupMV.y + iDiamondSize, 8);
750                                          break;                                          break;
751    
752                                  case 8:                                  case 8:
753                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
754                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                   2);
755                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
756                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
757                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
758                                                                                     backupMV.y + iDiamondSize, 6);
759                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
760                                                                                     backupMV.y - iDiamondSize, 7);
761                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
762                                                                                     backupMV.y + iDiamondSize, 8);
763                                          break;                                          break;
764                          default:                          default:
765                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y,
766                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);                                                                                   1);
767                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y,
768                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);                                                                                   2);
769                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize,
770                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);                                                                                   3);
771                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);                                  CHECK_MV16_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize,
772                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);                                                                                   4);
773                                          CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);  
774                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
775                                                                                     backupMV.y - iDiamondSize, 5);
776                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x - iDiamondSize,
777                                                                                     backupMV.y + iDiamondSize, 6);
778                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
779                                                                                     backupMV.y - iDiamondSize, 7);
780                                    CHECK_MV16_CANDIDATE_DIR(backupMV.x + iDiamondSize,
781                                                                                     backupMV.y + iDiamondSize, 8);
782                                          break;                                          break;
783                          }                          }
784                  }          } else {
         else  
                 {  
785                          currMV->x = startx;                          currMV->x = startx;
786                          currMV->y = starty;                          currMV->y = starty;
787                  }                  }
# Line 670  Line 789 
789  }  }
790    
791    
792  int32_t Full16_MainSearch(  int32_t
793                                          const uint8_t * const pRef,  Full16_MainSearch(const uint8_t * const pRef,
794                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
795                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
796                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
797                                          const uint8_t * const cur,                                          const uint8_t * const cur,
798                                          const int x, const int y,                                    const int x,
799                                          int32_t startx, int32_t starty,                                    const int y,
800                                      int32_t startx,
801                                      int32_t starty,
802                                          int32_t iMinSAD,                                          int32_t iMinSAD,
803                                          VECTOR * const currMV,                                          VECTOR * const currMV,
804                                          const VECTOR * const pmv,                                          const VECTOR * const pmv,
805                                          const int32_t min_dx, const int32_t max_dx,                                    const int32_t min_dx,
806                                          const int32_t min_dy, const int32_t max_dy,                                    const int32_t max_dx,
807                                      const int32_t min_dy,
808                                      const int32_t max_dy,
809                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
810                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
811                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 692  Line 815 
815          int32_t iSAD;          int32_t iSAD;
816          int32_t dx,dy;          int32_t dx,dy;
817          VECTOR backupMV;          VECTOR backupMV;
818    
819          backupMV.x = startx;          backupMV.x = startx;
820          backupMV.y = starty;          backupMV.y = starty;
821    
# Line 702  Line 826 
826          return iMinSAD;          return iMinSAD;
827  }  }
828    
829  int32_t Full8_MainSearch(  int32_t
830                                          const uint8_t * const pRef,  AdvDiamond16_MainSearch(const uint8_t * const pRef,
831                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
832                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
833                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
834                                          const uint8_t * const cur,                                          const uint8_t * const cur,
835                                          const int x, const int y,                                                  const int x,
836                                          int32_t startx, int32_t starty,                                                  const int y,
837                                                    int32_t startx,
838                                                    int32_t starty,
839                                                    int32_t iMinSAD,
840                                                    VECTOR * const currMV,
841                                                    const VECTOR * const pmv,
842                                                    const int32_t min_dx,
843                                                    const int32_t max_dx,
844                                                    const int32_t min_dy,
845                                                    const int32_t max_dy,
846                                                    const int32_t iEdgedWidth,
847                                                    const int32_t iDiamondSize,
848                                                    const int32_t iFcode,
849                                                    const int32_t iQuant,
850                                                    int iDirection)
851    {
852    
853            int32_t iSAD;
854    
855    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
856    
857            if (iDirection) {
858                    CHECK_MV16_CANDIDATE(startx - iDiamondSize, starty);
859                    CHECK_MV16_CANDIDATE(startx + iDiamondSize, starty);
860                    CHECK_MV16_CANDIDATE(startx, starty - iDiamondSize);
861                    CHECK_MV16_CANDIDATE(startx, starty + iDiamondSize);
862            } else {
863                    int bDirection = 1 + 2 + 4 + 8;
864    
865                    do {
866                            iDirection = 0;
867                            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)
868                                    CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);
869    
870                            if (bDirection & 2)
871                                    CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);
872    
873                            if (bDirection & 4)
874                                    CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);
875    
876                            if (bDirection & 8)
877                                    CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);
878    
879                            /* now we're doing diagonal checks near our candidate */
880    
881                            if (iDirection)         //checking if anything found
882                            {
883                                    bDirection = iDirection;
884                                    iDirection = 0;
885                                    startx = currMV->x;
886                                    starty = currMV->y;
887                                    if (bDirection & 3)     //our candidate is left or right
888                                    {
889                                            CHECK_MV16_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);
890                                            CHECK_MV16_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);
891                                    } else                  // what remains here is up or down
892                                    {
893                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);
894                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);
895                                    }
896    
897                                    if (iDirection) {
898                                            bDirection += iDirection;
899                                            startx = currMV->x;
900                                            starty = currMV->y;
901                                    }
902                            } else                          //about to quit, eh? not so fast....
903                            {
904                                    switch (bDirection) {
905                                    case 2:
906                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
907                                                                                             starty - iDiamondSize, 2 + 4);
908                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
909                                                                                             starty + iDiamondSize, 2 + 8);
910                                            break;
911                                    case 1:
912                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
913                                                                                             starty - iDiamondSize, 1 + 4);
914                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
915                                                                                             starty + iDiamondSize, 1 + 8);
916                                            break;
917                                    case 2 + 4:
918                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
919                                                                                             starty - iDiamondSize, 1 + 4);
920                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
921                                                                                             starty - iDiamondSize, 2 + 4);
922                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
923                                                                                             starty + iDiamondSize, 2 + 8);
924                                            break;
925                                    case 4:
926                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
927                                                                                             starty - iDiamondSize, 2 + 4);
928                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
929                                                                                             starty - iDiamondSize, 1 + 4);
930                                            break;
931                                    case 8:
932                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
933                                                                                             starty + iDiamondSize, 2 + 8);
934                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
935                                                                                             starty + iDiamondSize, 1 + 8);
936                                            break;
937                                    case 1 + 4:
938                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
939                                                                                             starty + iDiamondSize, 1 + 8);
940                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
941                                                                                             starty - iDiamondSize, 1 + 4);
942                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
943                                                                                             starty - iDiamondSize, 2 + 4);
944                                            break;
945                                    case 2 + 8:
946                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
947                                                                                             starty - iDiamondSize, 1 + 4);
948                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
949                                                                                             starty + iDiamondSize, 1 + 8);
950                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
951                                                                                             starty + iDiamondSize, 2 + 8);
952                                            break;
953                                    case 1 + 8:
954                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
955                                                                                             starty - iDiamondSize, 2 + 4);
956                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
957                                                                                             starty + iDiamondSize, 2 + 8);
958                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
959                                                                                             starty + iDiamondSize, 1 + 8);
960                                            break;
961                                    default:                //1+2+4+8 == we didn't find anything at all
962                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
963                                                                                             starty - iDiamondSize, 1 + 4);
964                                            CHECK_MV16_CANDIDATE_DIR(startx - iDiamondSize,
965                                                                                             starty + iDiamondSize, 1 + 8);
966                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
967                                                                                             starty - iDiamondSize, 2 + 4);
968                                            CHECK_MV16_CANDIDATE_DIR(startx + iDiamondSize,
969                                                                                             starty + iDiamondSize, 2 + 8);
970                                            break;
971                                    }
972                                    if (!iDirection)
973                                            break;          //ok, the end. really
974                                    else {
975                                            bDirection = iDirection;
976                                            startx = currMV->x;
977                                            starty = currMV->y;
978                                    }
979                            }
980                    }
981                    while (1);                              //forever
982            }
983            return iMinSAD;
984    }
985    
986    int32_t
987    AdvDiamond8_MainSearch(const uint8_t * const pRef,
988                                               const uint8_t * const pRefH,
989                                               const uint8_t * const pRefV,
990                                               const uint8_t * const pRefHV,
991                                               const uint8_t * const cur,
992                                               const int x,
993                                               const int y,
994                                               int32_t startx,
995                                               int32_t starty,
996                                          int32_t iMinSAD,                                          int32_t iMinSAD,
997                                          VECTOR * const currMV,                                          VECTOR * const currMV,
998                                          const VECTOR * const pmv,                                          const VECTOR * const pmv,
999                                          const int32_t min_dx, const int32_t max_dx,                                             const int32_t min_dx,
1000                                          const int32_t min_dy, const int32_t max_dy,                                             const int32_t max_dx,
1001                                               const int32_t min_dy,
1002                                               const int32_t max_dy,
1003                                               const int32_t iEdgedWidth,
1004                                               const int32_t iDiamondSize,
1005                                               const int32_t iFcode,
1006                                               const int32_t iQuant,
1007                                               int iDirection)
1008    {
1009    
1010            int32_t iSAD;
1011    
1012    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
1013    
1014            if (iDirection) {
1015                    CHECK_MV8_CANDIDATE(startx - iDiamondSize, starty);
1016                    CHECK_MV8_CANDIDATE(startx + iDiamondSize, starty);
1017                    CHECK_MV8_CANDIDATE(startx, starty - iDiamondSize);
1018                    CHECK_MV8_CANDIDATE(startx, starty + iDiamondSize);
1019            } else {
1020                    int bDirection = 1 + 2 + 4 + 8;
1021    
1022                    do {
1023                            iDirection = 0;
1024                            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)
1025                                    CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);
1026    
1027                            if (bDirection & 2)
1028                                    CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);
1029    
1030                            if (bDirection & 4)
1031                                    CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);
1032    
1033                            if (bDirection & 8)
1034                                    CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);
1035    
1036                            /* now we're doing diagonal checks near our candidate */
1037    
1038                            if (iDirection)         //checking if anything found
1039                            {
1040                                    bDirection = iDirection;
1041                                    iDirection = 0;
1042                                    startx = currMV->x;
1043                                    starty = currMV->y;
1044                                    if (bDirection & 3)     //our candidate is left or right
1045                                    {
1046                                            CHECK_MV8_CANDIDATE_DIR(startx, starty + iDiamondSize, 8);
1047                                            CHECK_MV8_CANDIDATE_DIR(startx, starty - iDiamondSize, 4);
1048                                    } else                  // what remains here is up or down
1049                                    {
1050                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize, starty, 2);
1051                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize, starty, 1);
1052                                    }
1053    
1054                                    if (iDirection) {
1055                                            bDirection += iDirection;
1056                                            startx = currMV->x;
1057                                            starty = currMV->y;
1058                                    }
1059                            } else                          //about to quit, eh? not so fast....
1060                            {
1061                                    switch (bDirection) {
1062                                    case 2:
1063                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1064                                                                                            starty - iDiamondSize, 2 + 4);
1065                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1066                                                                                            starty + iDiamondSize, 2 + 8);
1067                                            break;
1068                                    case 1:
1069                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1070                                                                                            starty - iDiamondSize, 1 + 4);
1071                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1072                                                                                            starty + iDiamondSize, 1 + 8);
1073                                            break;
1074                                    case 2 + 4:
1075                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1076                                                                                            starty - iDiamondSize, 1 + 4);
1077                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1078                                                                                            starty - iDiamondSize, 2 + 4);
1079                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1080                                                                                            starty + iDiamondSize, 2 + 8);
1081                                            break;
1082                                    case 4:
1083                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1084                                                                                            starty - iDiamondSize, 2 + 4);
1085                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1086                                                                                            starty - iDiamondSize, 1 + 4);
1087                                            break;
1088                                    case 8:
1089                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1090                                                                                            starty + iDiamondSize, 2 + 8);
1091                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1092                                                                                            starty + iDiamondSize, 1 + 8);
1093                                            break;
1094                                    case 1 + 4:
1095                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1096                                                                                            starty + iDiamondSize, 1 + 8);
1097                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1098                                                                                            starty - iDiamondSize, 1 + 4);
1099                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1100                                                                                            starty - iDiamondSize, 2 + 4);
1101                                            break;
1102                                    case 2 + 8:
1103                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1104                                                                                            starty - iDiamondSize, 1 + 4);
1105                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1106                                                                                            starty + iDiamondSize, 1 + 8);
1107                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1108                                                                                            starty + iDiamondSize, 2 + 8);
1109                                            break;
1110                                    case 1 + 8:
1111                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1112                                                                                            starty - iDiamondSize, 2 + 4);
1113                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1114                                                                                            starty + iDiamondSize, 2 + 8);
1115                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1116                                                                                            starty + iDiamondSize, 1 + 8);
1117                                            break;
1118                                    default:                //1+2+4+8 == we didn't find anything at all
1119                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1120                                                                                            starty - iDiamondSize, 1 + 4);
1121                                            CHECK_MV8_CANDIDATE_DIR(startx - iDiamondSize,
1122                                                                                            starty + iDiamondSize, 1 + 8);
1123                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1124                                                                                            starty - iDiamondSize, 2 + 4);
1125                                            CHECK_MV8_CANDIDATE_DIR(startx + iDiamondSize,
1126                                                                                            starty + iDiamondSize, 2 + 8);
1127                                            break;
1128                                    }
1129                                    if (!(iDirection))
1130                                            break;          //ok, the end. really
1131                                    else {
1132                                            bDirection = iDirection;
1133                                            startx = currMV->x;
1134                                            starty = currMV->y;
1135                                    }
1136                            }
1137                    }
1138                    while (1);                              //forever
1139            }
1140            return iMinSAD;
1141    }
1142    
1143    
1144    int32_t
1145    Full8_MainSearch(const uint8_t * const pRef,
1146                                     const uint8_t * const pRefH,
1147                                     const uint8_t * const pRefV,
1148                                     const uint8_t * const pRefHV,
1149                                     const uint8_t * const cur,
1150                                     const int x,
1151                                     const int y,
1152                                     int32_t startx,
1153                                     int32_t starty,
1154                                     int32_t iMinSAD,
1155                                     VECTOR * const currMV,
1156                                     const VECTOR * const pmv,
1157                                     const int32_t min_dx,
1158                                     const int32_t max_dx,
1159                                     const int32_t min_dy,
1160                                     const int32_t max_dy,
1161                                          const int32_t iEdgedWidth,                                          const int32_t iEdgedWidth,
1162                                          const int32_t iDiamondSize,                                          const int32_t iDiamondSize,
1163                                          const int32_t iFcode,                                          const int32_t iFcode,
# Line 724  Line 1167 
1167          int32_t iSAD;          int32_t iSAD;
1168          int32_t dx,dy;          int32_t dx,dy;
1169          VECTOR backupMV;          VECTOR backupMV;
1170    
1171          backupMV.x = startx;          backupMV.x = startx;
1172          backupMV.y = starty;          backupMV.y = starty;
1173    
# Line 736  Line 1180 
1180    
1181    
1182    
1183  int32_t Halfpel16_Refine(  int32_t
1184          const uint8_t * const pRef,  Halfpel16_Refine(const uint8_t * const pRef,
1185          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1186          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1187          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1188          const uint8_t * const cur,          const uint8_t * const cur,
1189          const int x, const int y,                                   const int x,
1190                                     const int y,
1191          VECTOR * const currMV,          VECTOR * const currMV,
1192          int32_t iMinSAD,          int32_t iMinSAD,
1193          const VECTOR * const pmv,          const VECTOR * const pmv,
1194          const int32_t min_dx, const int32_t max_dx,                                   const int32_t min_dx,
1195          const int32_t min_dy, const int32_t max_dy,                                   const int32_t max_dx,
1196                                     const int32_t min_dy,
1197                                     const int32_t max_dy,
1198          const int32_t iFcode,          const int32_t iFcode,
1199          const int32_t iQuant,          const int32_t iQuant,
1200          const int32_t iEdgedWidth)          const int32_t iEdgedWidth)
# Line 772  Line 1219 
1219  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)  #define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)
1220    
1221    
1222  int32_t PMVfastSearch16(  int32_t
1223                                          const uint8_t * const pRef,  PMVfastSearch16(const uint8_t * const pRef,
1224                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1225                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1226                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1227                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1228                                          const int x, const int y,                                  const int x,
1229                                    const int y,
1230                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1231                                    const uint32_t iQuant,
1232                                    const uint32_t iFcode,
1233                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1234                                          MACROBLOCK * const pMBs,                                  const MACROBLOCK * const pMBs,
1235                                    const MACROBLOCK * const prevMBs,
1236                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1237                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1238  {  {
1239      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1240          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1241          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1242          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 809  Line 1258 
1258          VECTOR pmv[4];          VECTOR pmv[4];
1259          int32_t psad[4];          int32_t psad[4];
1260    
1261          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          MainSearch16FuncPtr MainSearchPtr;
1262    
1263    //  const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1264            const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
1265    
1266          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1267          int32_t bPredEq;          int32_t bPredEq;
1268          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1269    
1270  /* Get maximum range */  /* Get maximum range */
1271          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,
1272                    x, y, 16, iWidth, iHeight, iFcode);                            iFcode);
1273    
1274  /* 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 */
1275    
1276          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16)) {
1277          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
1278          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
1279          min_dy = EVEN(min_dy);          min_dy = EVEN(min_dy);
1280          max_dy = EVEN(max_dy);          max_dy = EVEN(max_dy);
1281          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
   
1282    
1283            /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
1284          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
1285            // bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
1286    
1287          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
1288                  threshA =  512;                  threshA =  512;
1289                  threshB = 1024;                  threshB = 1024;
1290    
1291          }          } else {
         else  
         {  
1292                  threshA = psad[0];                  threshA = psad[0];
1293                  threshB = threshA+256;                  threshB = threshA+256;
1294                  if (threshA< 512) threshA =  512;                  if (threshA < 512)
1295                  if (threshA>1024) threshA = 1024;                          threshA = 512;
1296                  if (threshB>1792) threshB = 1792;                  if (threshA > 1024)
1297                            threshA = 1024;
1298                    if (threshB > 1792)
1299                            threshB = 1792;
1300          }          }
1301    
1302          iFound=0;          iFound=0;
1303    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536) || (bPredEq) )  
                 iDiamondSize=1; // halfpel!  
         else  
                 iDiamondSize=2; // halfpel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND16) )  
                 iDiamondSize*=2;  
   
1304  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1305     MinSAD=SAD     MinSAD=SAD
1306     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 875  Line 1308 
1308     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1309  */  */
1310    
   
 // Prepare for main loop  
   
1311          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
1312          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16)) {   /* This should NOT be necessary! */
         {       /* This should NOT be necessary! */  
1313                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
1314                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
1315          }          }
1316    
1317          if (currMV->x > max_dx)          if (currMV->x > max_dx) {
         {  
1318                  currMV->x=max_dx;                  currMV->x=max_dx;
1319          }          }
1320          if (currMV->x < min_dx)          if (currMV->x < min_dx) {
         {  
1321                  currMV->x=min_dx;                  currMV->x=min_dx;
1322          }          }
1323          if (currMV->y > max_dy)          if (currMV->y > max_dy) {
         {  
1324                  currMV->y=max_dy;                  currMV->y=max_dy;
1325          }          }
1326          if (currMV->y < min_dy)          if (currMV->y < min_dy) {
         {  
1327                  currMV->y=min_dy;                  currMV->y=min_dy;
1328          }          }
1329    
1330          iMinSAD = sad16( cur,          iMinSAD =
1331                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  sad16(cur,
1332                           iEdgedWidth, MV_MAX_ERROR);                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
1333          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
1334            iMinSAD +=
1335          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )                  calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
1336          {                                            (uint8_t) iFcode, iQuant);
1337    
1338            if ((iMinSAD < 256) ||
1339                    ((MVequal(*currMV, prevMB->mvs[0])) &&
1340                     ((uint32_t) iMinSAD < prevMB->sad16))) {
1341                    if (iMinSAD < 2 * iQuant)       // high chances for SKIP-mode
1342                    {
1343                            if (!MVzero(*currMV)) {
1344                                    iMinSAD += MV16_00_BIAS;
1345                                    CHECK_MV16_ZERO;        // (0,0) saves space for letterboxed pictures
1346                                    iMinSAD -= MV16_00_BIAS;
1347                            }
1348                    }
1349    
1350                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1351                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 916  Line 1353 
1353                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
1354          }          }
1355    
1356    
1357    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1358       vector of the median.
1359       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1360    */
1361    
1362            if ((bPredEq) && (MVequal(pmv[0], prevMB->mvs[0])))
1363                    iFound = 2;
1364    
1365    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1366       Otherwise select large Diamond Search.
1367    */
1368    
1369            if ((!MVzero(pmv[0])) || (threshB < 1536) || (bPredEq))
1370                    iDiamondSize = 1;               // halfpel!
1371            else
1372                    iDiamondSize = 2;               // halfpel!
1373    
1374            if (!(MotionFlags & PMV_HALFPELDIAMOND16))
1375                    iDiamondSize *= 2;
1376    
1377  /*  /*
1378     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
1379     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1380     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1381     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1382  */  */
1383    
1384  // (0,0) is always possible  // (0,0) is always possible
1385    
1386            if (!MVzero(pmv[0]))
1387          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1388    
1389  // previous frame MV is always possible  // previous frame MV is always possible
1390          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1391            if (!MVzero(prevMB->mvs[0]))
1392                    if (!MVequal(prevMB->mvs[0], pmv[0]))
1393                            CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);
1394    
1395  // left neighbour, if allowed  // left neighbour, if allowed
1396          if (x != 0)  
1397          {          if (!MVzero(pmv[1]))
1398                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!MVequal(pmv[1], prevMB->mvs[0]))
1399                  {       pmv[1].x = EVEN(pmv[1].x);                          if (!MVequal(pmv[1], pmv[0])) {
1400                                    if (!(MotionFlags & PMV_HALFPEL16)) {
1401                                            pmv[1].x = EVEN(pmv[1].x);
1402                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1403                  }                  }
1404    
1405                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1406          }          }
   
1407  // top neighbour, if allowed  // top neighbour, if allowed
1408          if (y != 0)          if (!MVzero(pmv[2]))
1409          {                  if (!MVequal(pmv[2], prevMB->mvs[0]))
1410                  if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!MVequal(pmv[2], pmv[0]))
1411                  {       pmv[2].x = EVEN(pmv[2].x);                                  if (!MVequal(pmv[2], pmv[1])) {
1412                                            if (!(MotionFlags & PMV_HALFPEL16)) {
1413                                                    pmv[2].x = EVEN(pmv[2].x);
1414                  pmv[2].y = EVEN(pmv[2].y);                  pmv[2].y = EVEN(pmv[2].y);
1415                  }                  }
1416                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1417    
1418  // top right neighbour, if allowed  // top right neighbour, if allowed
1419                  if ((uint32_t)x != (iWcount-1))                                          if (!MVzero(pmv[3]))
1420                  {                                                  if (!MVequal(pmv[3], prevMB->mvs[0]))
1421                          if (!(MotionFlags & PMV_HALFPEL16 ))                                                          if (!MVequal(pmv[3], pmv[0]))
1422                          {       pmv[3].x = EVEN(pmv[3].x);                                                                  if (!MVequal(pmv[3], pmv[1]))
1423                                                                            if (!MVequal(pmv[3], pmv[2])) {
1424                                                                                    if (!(MotionFlags & PMV_HALFPEL16)) {
1425                                                                                            pmv[3].x = EVEN(pmv[3].x);
1426                          pmv[3].y = EVEN(pmv[3].y);                          pmv[3].y = EVEN(pmv[3].y);
1427                          }                          }
1428                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);                                                                                  CHECK_MV16_CANDIDATE(pmv[3].x,
1429                                                                                                                             pmv[3].y);
1430                  }                  }
1431          }          }
1432    
1433            if ((MVzero(*currMV)) &&
1434                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1435                    iMinSAD -= MV16_00_BIAS;
1436    
1437    
1438  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1439     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.
1440  */  */
1441    
1442          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ((iMinSAD <= threshA) ||
1443          {                  (MVequal(*currMV, prevMB->mvs[0]) &&
1444                     ((uint32_t) iMinSAD < prevMB->sad16))) {
1445                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1446                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
1447                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 983  Line 1459 
1459     Refine by using small diamond and goto step 10.     Refine by using small diamond and goto step 10.
1460  */  */
1461    
1462            if (MotionFlags & PMV_USESQUARES16)
1463                    MainSearchPtr = Square16_MainSearch;
1464            else if (MotionFlags & PMV_ADVANCEDDIAMOND16)
1465                    MainSearchPtr = AdvDiamond16_MainSearch;
1466            else
1467                    MainSearchPtr = Diamond16_MainSearch;
1468    
1469          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1470    
1471  /* 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 */
1472          iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
1473                                            x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
1474                                            currMV->x, currMV->y, iMinSAD, &newMV,                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,
1475                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1476                                                      iQuant, iFound);
1477    
1478          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
1479                  *currMV = newMV;                  *currMV = newMV;
1480                  iMinSAD = iSAD;                  iMinSAD = iSAD;
1481          }          }
1482    
1483          if (MotionFlags & PMV_EXTSEARCH16)          if (MotionFlags & PMV_EXTSEARCH16) {
         {  
1484  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1485    
1486                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
1487                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1488                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1489                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,
1490                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1491                                                                      iDiamondSize, iFcode, iQuant, iFound);
1492    
1493                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1494                          *currMV = newMV;                          *currMV = newMV;
1495                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1496                  }                  }
1497                  }                  }
1498    
1499                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1500                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1501                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1502                                                            0, 0, iMinSAD, &newMV,                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,
1503                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
1504                                                                      iQuant, iFound);
1505    
1506                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1507                          *currMV = newMV;                          *currMV = newMV;
1508                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1509                  }                  }
# Line 1034  Line 1516 
1516    
1517  PMVfast16_Terminate_with_Refine:  PMVfast16_Terminate_with_Refine:
1518          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step
1519                  iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
1520                                    x, y,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1521                                    currMV, iMinSAD,                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
1522                                    pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
1523    
1524  PMVfast16_Terminate_without_Refine:  PMVfast16_Terminate_without_Refine:
1525          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
# Line 1050  Line 1532 
1532    
1533    
1534    
1535  int32_t Diamond8_MainSearch(  int32_t
1536          const uint8_t * const pRef,  Diamond8_MainSearch(const uint8_t * const pRef,
1537          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1538          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1539          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1540          const uint8_t * const cur,          const uint8_t * const cur,
1541          const int x, const int y,                                          const int x,
1542          int32_t startx, int32_t starty,                                          const int y,
1543                                            int32_t startx,
1544                                            int32_t starty,
1545          int32_t iMinSAD,          int32_t iMinSAD,
1546          VECTOR * const currMV,          VECTOR * const currMV,
1547          const VECTOR * const pmv,          const VECTOR * const pmv,
1548          const int32_t min_dx, const int32_t max_dx,                                          const int32_t min_dx,
1549          const int32_t min_dy, const int32_t max_dy,                                          const int32_t max_dx,
1550                                            const int32_t min_dy,
1551                                            const int32_t max_dy,
1552          const int32_t iEdgedWidth,          const int32_t iEdgedWidth,
1553          const int32_t iDiamondSize,          const int32_t iDiamondSize,
1554          const int32_t iFcode,          const int32_t iFcode,
# Line 1074  Line 1560 
1560          int32_t iDirection=0;          int32_t iDirection=0;
1561          int32_t iSAD;          int32_t iSAD;
1562          VECTOR backupMV;          VECTOR backupMV;
1563    
1564          backupMV.x = startx;          backupMV.x = startx;
1565          backupMV.y = starty;          backupMV.y = starty;
1566    
# Line 1085  Line 1572 
1572          CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);          CHECK_MV8_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);
1573    
1574          if (iDirection)          if (iDirection)
1575                  while (!iFound)                  while (!iFound) {
                 {  
1576                          iFound = 1;                          iFound = 1;
1577                          backupMV=*currMV;       // since iDirection!=0, this is well defined!                          backupMV=*currMV;       // since iDirection!=0, this is well defined!
1578    
1579                          if ( iDirection != 2)                          if ( iDirection != 2)
1580                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,
1581                                                                                      backupMV.y, 1);
1582                          if ( iDirection != 1)                          if ( iDirection != 1)
1583                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,
1584                                                                                      backupMV.y, 2);
1585                          if ( iDirection != 4)                          if ( iDirection != 4)
1586                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1587                                                                                      backupMV.y - iDiamondSize, 3);
1588                          if ( iDirection != 3)                          if ( iDirection != 3)
1589                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4);                                  CHECK_MV8_CANDIDATE_FOUND(backupMV.x,
1590                  }                                                                                    backupMV.y + iDiamondSize, 4);
1591          else          } else {
         {  
1592                  currMV->x = startx;                  currMV->x = startx;
1593                  currMV->y = starty;                  currMV->y = starty;
1594          }          }
1595          return iMinSAD;          return iMinSAD;
1596  }  }
1597    
1598  int32_t Halfpel8_Refine(  int32_t
1599          const uint8_t * const pRef,  Halfpel8_Refine(const uint8_t * const pRef,
1600          const uint8_t * const pRefH,          const uint8_t * const pRefH,
1601          const uint8_t * const pRefV,          const uint8_t * const pRefV,
1602          const uint8_t * const pRefHV,          const uint8_t * const pRefHV,
1603          const uint8_t * const cur,          const uint8_t * const cur,
1604          const int x, const int y,                                  const int x,
1605                                    const int y,
1606          VECTOR * const currMV,          VECTOR * const currMV,
1607          int32_t iMinSAD,          int32_t iMinSAD,
1608          const VECTOR * const pmv,          const VECTOR * const pmv,
1609          const int32_t min_dx, const int32_t max_dx,                                  const int32_t min_dx,
1610          const int32_t min_dy, const int32_t max_dy,                                  const int32_t max_dx,
1611                                    const int32_t min_dy,
1612                                    const int32_t max_dy,
1613          const int32_t iFcode,          const int32_t iFcode,
1614          const int32_t iQuant,          const int32_t iQuant,
1615          const int32_t iEdgedWidth)          const int32_t iEdgedWidth)
# Line 1143  Line 1634 
1634    
1635  #define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8)  #define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8)
1636    
1637  int32_t PMVfastSearch8(  int32_t
1638                                          const uint8_t * const pRef,  PMVfastSearch8(const uint8_t * const pRef,
1639                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1640                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1641                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1642                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1643                                          const int x, const int y,                             const int x,
1644                                          const int start_x, int start_y,                             const int y,
1645                               const int start_x,
1646                               const int start_y,
1647                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1648                               const uint32_t iQuant,
1649                               const uint32_t iFcode,
1650                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1651                                          MACROBLOCK * const pMBs,                             const MACROBLOCK * const pMBs,
1652                               const MACROBLOCK * const prevMBs,
1653                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1654                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1655  {  {
1656          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
   
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1657          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1658          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1659          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1178  Line 1671 
1671          int32_t psad[4];          int32_t psad[4];
1672          VECTOR newMV;          VECTOR newMV;
1673          VECTOR backupMV;          VECTOR backupMV;
1674            VECTOR startMV;
1675    
1676          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1677            const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
1678    
1679          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1680          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1681          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1682    
1683          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y & 1) + (y & 1) + (x & 1);
1684    
1685  /* Get maximum range */          MainSearch8FuncPtr MainSearchPtr;
         get_range(&min_dx, &max_dx, &min_dy, &max_dy,  
                   x, y, 8, iWidth, iHeight, iFcode);  
1686    
1687  /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */          /* Init variables */
1688            startMV.x = start_x;
1689            startMV.y = start_y;
1690    
1691          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          /* Get maximum range */
1692          { min_dx = EVEN(min_dx);          get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight,
1693                              iFcode);
1694    
1695            if (!(MotionFlags & PMV_HALFPELDIAMOND8)) {
1696                    min_dx = EVEN(min_dx);
1697          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
1698          min_dy = EVEN(min_dy);          min_dy = EVEN(min_dy);
1699          max_dy = EVEN(max_dy);          max_dy = EVEN(max_dy);
1700          }               /* because we might use IF (dx>max_dx) THEN dx=max_dx; */          }
   
1701    
1702            /* because we might use IF (dx>max_dx) THEN dx=max_dx; */
1703          bPredEq  = get_pmvdata(pMBs, (x>>1), (y>>1), iWcount, iSubBlock, pmv, psad);          bPredEq  = get_pmvdata(pMBs, (x>>1), (y>>1), iWcount, iSubBlock, pmv, psad);
1704            // bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);
1705    
1706          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
1707                  threshA =  512/4;                  threshA =  512/4;
1708                  threshB = 1024/4;                  threshB = 1024/4;
1709    
1710          }          } else {
         else  
         {  
1711                  threshA = psad[0]/4;                    /* good estimate */                  threshA = psad[0]/4;                    /* good estimate */
1712                  threshB = threshA+256/4;                  threshB = threshA+256/4;
1713                  if (threshA< 512/4) threshA =  512/4;                  if (threshA < 512 / 4)
1714                  if (threshA>1024/4) threshA = 1024/4;                          threshA = 512 / 4;
1715                  if (threshB>1792/4) threshB = 1792/4;                  if (threshA > 1024 / 4)
1716                            threshA = 1024 / 4;
1717                    if (threshB > 1792 / 4)
1718                            threshB = 1792 / 4;
1719          }          }
1720    
1721          iFound=0;          iFound=0;
1722    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536/4) || (bPredEq) )  
                 iDiamondSize=1; // 1 halfpel!  
         else  
                 iDiamondSize=2; // 2 halfpel = 1 full pixel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND8) )  
                 iDiamondSize*=2;  
   
1723  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1724     MinSAD=SAD     MinSAD=SAD
1725     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1250  Line 1730 
1730    
1731  // Prepare for main loop  // Prepare for main loop
1732    
1733          currMV->x=start_x;              /* start with mv16 */  //  if (MotionFlags & PMV_USESQUARES8)
1734          currMV->y=start_y;  //      MainSearchPtr = Square8_MainSearch;
1735    //  else
1736    
1737          iMinSAD = sad8( cur,          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1738                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  MainSearchPtr = AdvDiamond8_MainSearch;
1739                          iEdgedWidth);          else
1740          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode) * iQuant;                  MainSearchPtr = Diamond8_MainSearch;
1741    
1742          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )  
1743          {          *currMV = startMV;
1744    
1745            iMinSAD =
1746                    sad8(cur,
1747                             get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
1748                                                    iEdgedWidth), iEdgedWidth);
1749            iMinSAD +=
1750                    calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
1751                                             (uint8_t) iFcode, iQuant);
1752    
1753            if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))
1754                                                                    && ((uint32_t) iMinSAD <
1755                                                                            prevMB->sad8[iSubBlock]))) {
1756                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1757                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1758                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
1759                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1760          }          }
1761    
1762    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1763       vector of the median.
1764       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1765    */
1766    
1767            if ((bPredEq) && (MVequal(pmv[0], prevMB->mvs[iSubBlock])))
1768                    iFound = 2;
1769    
1770    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1771       Otherwise select large Diamond Search.
1772    */
1773    
1774            if ((!MVzero(pmv[0])) || (threshB < 1536 / 4) || (bPredEq))
1775                    iDiamondSize = 1;               // 1 halfpel!
1776            else
1777                    iDiamondSize = 2;               // 2 halfpel = 1 full pixel!
1778    
1779            if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1780                    iDiamondSize *= 2;
1781    
1782    
1783  /*  /*
1784     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
1785     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1786     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1787     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1788  */  */
1789    
1790  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1791    
1792            if (!MVequal(pmv[0], startMV))
1793          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1794    
1795  // (0,0) is always possible  // (0,0) if needed
1796            if (!MVzero(pmv[0]))
1797                    if (!MVzero(startMV))
1798          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1799    
1800  // previous frame MV is always possible  // previous frame MV if needed
1801          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1802                    if (!MVequal(prevMB->mvs[iSubBlock], startMV))
1803                            if (!MVequal(prevMB->mvs[iSubBlock], pmv[0]))
1804                                    CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,
1805                                                                            prevMB->mvs[iSubBlock].y);
1806    
1807            if ((iMinSAD <= threshA) ||
1808                    (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1809                     ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1810                    if (MotionFlags & PMV_QUICKSTOP16)
1811                            goto PMVfast8_Terminate_without_Refine;
1812                    if (MotionFlags & PMV_EARLYSTOP16)
1813                            goto PMVfast8_Terminate_with_Refine;
1814            }
1815    
1816  // left neighbour, if allowed  // left neighbour, if allowed and needed
1817          if (psad[1] != MV_MAX_ERROR)          if (!MVzero(pmv[1]))
1818          {                  if (!MVequal(pmv[1], startMV))
1819                  if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!MVequal(pmv[1], prevMB->mvs[iSubBlock]))
1820                  {       pmv[1].x = EVEN(pmv[1].x);                                  if (!MVequal(pmv[1], pmv[0])) {
1821                                            if (!(MotionFlags & PMV_HALFPEL8)) {
1822                                                    pmv[1].x = EVEN(pmv[1].x);
1823                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1824                  }                  }
1825                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1826          }          }
1827    // top neighbour, if allowed and needed
1828  // top neighbour, if allowed          if (!MVzero(pmv[2]))
1829          if (psad[2] != MV_MAX_ERROR)                  if (!MVequal(pmv[2], startMV))
1830          {                          if (!MVequal(pmv[2], prevMB->mvs[iSubBlock]))
1831                  if (!(MotionFlags & PMV_HALFPEL8 ))                                  if (!MVequal(pmv[2], pmv[0]))
1832                  {       pmv[2].x = EVEN(pmv[2].x);                                          if (!MVequal(pmv[2], pmv[1])) {
1833                                                    if (!(MotionFlags & PMV_HALFPEL8)) {
1834                                                            pmv[2].x = EVEN(pmv[2].x);
1835                  pmv[2].y = EVEN(pmv[2].y);                  pmv[2].y = EVEN(pmv[2].y);
1836                  }                  }
1837                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1838    
1839  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1840                  if (psad[3] != MV_MAX_ERROR)                                                  if (!MVzero(pmv[3]))
1841                  {                                                          if (!MVequal(pmv[3], startMV))
1842                          if (!(MotionFlags & PMV_HALFPEL8 ))                                                                  if (!MVequal(pmv[3], prevMB->mvs[iSubBlock]))
1843                          {       pmv[3].x = EVEN(pmv[3].x);                                                                          if (!MVequal(pmv[3], pmv[0]))
1844                                                                                    if (!MVequal(pmv[3], pmv[1]))
1845                                                                                            if (!MVequal(pmv[3], pmv[2])) {
1846                                                                                                    if (!
1847                                                                                                            (MotionFlags &
1848                                                                                                             PMV_HALFPEL8)) {
1849                                                                                                            pmv[3].x = EVEN(pmv[3].x);
1850                          pmv[3].y = EVEN(pmv[3].y);                          pmv[3].y = EVEN(pmv[3].y);
1851                          }                          }
1852                          CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);                                                                                                  CHECK_MV8_CANDIDATE(pmv[3].x,
1853                                                                                                                                            pmv[3].y);
1854                  }                  }
1855          }          }
1856    
1857            if ((MVzero(*currMV)) &&
1858                    (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1859                    iMinSAD -= MV8_00_BIAS;
1860    
1861    
1862  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1863     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.
1864  */  */
1865    
1866          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ((iMinSAD <= threshA) ||
1867          {                  (MVequal(*currMV, prevMB->mvs[iSubBlock]) &&
1868                     ((uint32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {
1869                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1870                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
1871                  if (MotionFlags & PMV_EARLYSTOP16)                  if (MotionFlags & PMV_EARLYSTOP16)
# Line 1338  Line 1885 
1885          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1886    
1887  /* 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 */
1888          iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD =
1889                                           x, y,                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
1890                                           currMV->x, currMV->y, iMinSAD, &newMV,                                                    currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,
1891                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                    min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
1892                                                      iQuant, iFound);
1893    
1894          if (iSAD < iMinSAD)          if (iSAD < iMinSAD) {
         {  
1895                  *currMV = newMV;                  *currMV = newMV;
1896                  iMinSAD = iSAD;                  iMinSAD = iSAD;
1897          }          }
1898    
1899          if (MotionFlags & PMV_EXTSEARCH8)          if (MotionFlags & PMV_EXTSEARCH8) {
         {  
1900  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1901    
1902                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
1903                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1904                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
1905                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,
1906                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1907                                                                      iDiamondSize, iFcode, iQuant, iFound);
1908    
1909                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1910                          *currMV = newMV;                          *currMV = newMV;
1911                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1912                  }                  }
1913                  }                  }
1914    
1915                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
1916                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD =
1917                                                            x, y,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
1918                                                            0, 0, iMinSAD, &newMV,                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,
1919                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
1920                                                                      iQuant, iFound);
1921    
1922                  if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                 {  
1923                          *currMV = newMV;                          *currMV = newMV;
1924                          iMinSAD = iSAD;                          iMinSAD = iSAD;
1925                  }                  }
# Line 1386  Line 1932 
1932    
1933  PMVfast8_Terminate_with_Refine:  PMVfast8_Terminate_with_Refine:
1934          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step
1935                  iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
1936                                                   x, y,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
1937                                                   currMV, iMinSAD,                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
1938                                                   pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
1939    
1940    
1941  PMVfast8_Terminate_without_Refine:  PMVfast8_Terminate_without_Refine:
# Line 1399  Line 1945 
1945          return iMinSAD;          return iMinSAD;
1946  }  }
1947    
1948  int32_t EPZSSearch16(  int32_t
1949                                          const uint8_t * const pRef,  EPZSSearch16(const uint8_t * const pRef,
1950                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
1951                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
1952                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1953                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1954                                          const int x, const int y,                           const int x,
1955                             const int y,
1956                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1957                             const uint32_t iQuant,
1958                             const uint32_t iFcode,
1959                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1960                                          MACROBLOCK * const pMBs,                           const MACROBLOCK * const pMBs,
1961                             const MACROBLOCK * const prevMBs,
1962                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1963                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1964  {  {
1965      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1966      const uint32_t iHcount = pParam->mb_height;      const uint32_t iHcount = pParam->mb_height;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1967    
1968          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1969          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1435  Line 1983 
1983          int32_t psad[8];          int32_t psad[8];
1984    
1985          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1986          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  
1987    //  const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1988            const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;
1989          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1990    
1991          static int32_t thresh2;          static int32_t thresh2;
1992          int32_t bPredEq;          int32_t bPredEq;
1993          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
1994    
1995          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1996    
1997          if (oldMBs == NULL)          if (oldMBs == NULL) {
1998          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));                  oldMBs = (MACROBLOCK *) calloc(iWcount * iHcount, sizeof(MACROBLOCK));
1999                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //      fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
2000          }          }
2001          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
2002    
2003  /* Get maximum range */  /* Get maximum range */
2004          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,
2005                          x, y, 16, iWidth, iHeight, iFcode);                            iFcode);
2006    
2007  /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */          if (!(MotionFlags & PMV_HALFPEL16)) {
2008                    min_dx = EVEN(min_dx);
         if (!(MotionFlags & PMV_HALFPEL16 ))  
         { min_dx = EVEN(min_dx);  
2009            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
2010            min_dy = EVEN(min_dy);            min_dy = EVEN(min_dy);
2011            max_dy = EVEN(max_dy);            max_dy = EVEN(max_dy);
2012          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
2013            /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
2014          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);          bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);
2015            // bPredEq = get_pmvdata2(pMBs, iWcount, 0, x, y, 0, pmv, psad);
2016    
2017  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
2018          MinSAD=SAD          MinSAD=SAD
# Line 1475  Line 2024 
2024  // Prepare for main loop  // Prepare for main loop
2025    
2026          *currMV=pmv[0];         /* current best := median prediction */          *currMV=pmv[0];         /* current best := median prediction */
2027          if (!(MotionFlags & PMV_HALFPEL16))          if (!(MotionFlags & PMV_HALFPEL16)) {
         {  
2028                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2029                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
2030          }          }
# Line 1492  Line 2040 
2040    
2041  /***************** This is predictor SET A: only median prediction ******************/  /***************** This is predictor SET A: only median prediction ******************/
2042    
2043          iMinSAD = sad16( cur,          iMinSAD =
2044                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  sad16(cur,
2045                  iEdgedWidth, MV_MAX_ERROR);                            get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
2046          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;                                                   iEdgedWidth), iEdgedWidth, MV_MAX_ERROR);
2047            iMinSAD +=
2048                    calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
2049                                              (uint8_t) iFcode, iQuant);
2050    
2051  // thresh1 is fixed to 256  // thresh1 is fixed to 256
2052          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ((iMinSAD < 256) ||
2053                  {                  ((MVequal(*currMV, prevMB->mvs[0])) &&
2054                     ((uint32_t) iMinSAD < prevMB->sad16))) {
2055                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2056                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2057                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1509  Line 2061 
2061  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2062    
2063  // previous frame MV  // previous frame MV
2064          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x, prevMB->mvs[0].y);
2065    
2066  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
2067  // 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
2068    
2069          if ((x==0) && (y==0) )          if ((x == 0) && (y == 0)) {
         {  
2070                  thresh2 =  512;                  thresh2 =  512;
2071          }          } else {
         else  
         {  
2072  /* 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] */
2073    
2074                  thresh2 = MIN(psad[0],iSAD)*6/5 + 128;                  thresh2 = MIN(psad[0],iSAD)*6/5 + 128;
# Line 1531  Line 2080 
2080    
2081    
2082  // left neighbour, if allowed  // left neighbour, if allowed
2083          if (x != 0)          if (x != 0) {
2084          {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2085                  if (!(MotionFlags & PMV_HALFPEL16 ))                          pmv[1].x = EVEN(pmv[1].x);
                 {       pmv[1].x = EVEN(pmv[1].x);  
2086                          pmv[1].y = EVEN(pmv[1].y);                          pmv[1].y = EVEN(pmv[1].y);
2087                  }                  }
2088                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
2089          }          }
   
2090  // top neighbour, if allowed  // top neighbour, if allowed
2091          if (y != 0)          if (y != 0) {
2092          {                  if (!(MotionFlags & PMV_HALFPEL16)) {
2093                  if (!(MotionFlags & PMV_HALFPEL16 ))                          pmv[2].x = EVEN(pmv[2].x);
                 {       pmv[2].x = EVEN(pmv[2].x);  
2094                          pmv[2].y = EVEN(pmv[2].y);                          pmv[2].y = EVEN(pmv[2].y);
2095                  }                  }
2096                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
2097    
2098  // top right neighbour, if allowed  // top right neighbour, if allowed
2099                  if ((uint32_t)x != (iWcount-1))                  if ((uint32_t) x != (iWcount - 1)) {
2100                  {                          if (!(MotionFlags & PMV_HALFPEL16)) {
2101                          if (!(MotionFlags & PMV_HALFPEL16 ))                                  pmv[3].x = EVEN(pmv[3].x);
                         {       pmv[3].x = EVEN(pmv[3].x);  
2102                                  pmv[3].y = EVEN(pmv[3].y);                                  pmv[3].y = EVEN(pmv[3].y);
2103                          }                          }
2104                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);                          CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);
# Line 1565  Line 2110 
2110  */  */
2111    
2112          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
2113                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= pMB->sad16) ) )                  || (MVequal(*currMV, prevMB->mvs[0]) &&
2114                  {                          ((uint32_t) iMinSAD <= prevMB->sad16))) {
2115                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2116                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2117                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1575  Line 2120 
2120    
2121  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
2122    
2123          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];      // collocated MV
2124          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x);     // acceleration X
2125          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y);     // acceleration Y
2126    
2127          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
2128    
2129  // left neighbour  // left neighbour
2130          if (x != 0)          if (x != 0)
2131                  CHECK_MV16_CANDIDATE((oldMB-1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB - 1)->mvs[0].x, (prevMB - 1)->mvs[0].y);
2132    
2133  // top neighbour  // top neighbour
2134          if (y != 0)          if (y != 0)
2135                  CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB - iWcount)->mvs[0].x,
2136                                                             (prevMB - iWcount)->mvs[0].y);
2137    
2138  // 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
2139    
2140          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
2141                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB + 1)->mvs[0].x, (prevMB + 1)->mvs[0].y);
2142    
2143  // bottom neighbour, dito  // bottom neighbour, dito
2144          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
2145                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB + iWcount)->mvs[0].x,
2146                                                             (prevMB + iWcount)->mvs[0].y);
2147    
2148  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
2149          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2) {
                 {  
2150                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
2151                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
2152                          if (MotionFlags & PMV_EARLYSTOP16)                          if (MotionFlags & PMV_EARLYSTOP16)
# Line 1611  Line 2157 
2157    
2158          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
2159    
2160  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */          if (MotionFlags & PMV_USESQUARES8)
2161                    MainSearchPtr = Square16_MainSearch;
2162          if (MotionFlags & PMV_USESQUARES16)          else
2163                  EPZSMainSearchPtr = Square16_MainSearch;           if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2164                    MainSearchPtr = AdvDiamond16_MainSearch;
2165          else          else
2166                  EPZSMainSearchPtr = Diamond16_MainSearch;                  MainSearchPtr = Diamond16_MainSearch;
2167    
2168          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
                         x, y,  
                         currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,  
                         2, iFcode, iQuant, 0);  
2169    
2170          if (iSAD < iMinSAD)          iSAD =
2171          {                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2172                                                      currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,
2173                                                      min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2174    
2175            if (iSAD < iMinSAD) {
2176                  *currMV = newMV;                  *currMV = newMV;
2177                  iMinSAD = iSAD;                  iMinSAD = iSAD;
2178          }          }
2179    
2180    
2181          if (MotionFlags & PMV_EXTSEARCH16)          if (MotionFlags & PMV_EXTSEARCH16) {
         {  
2182  /* 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) */
2183    
2184                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
2185                  {                          iSAD =
2186                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2187                                  x, y,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,
2188                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2189                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                                                    2, iFcode, iQuant, 0);
2190                  }                  }
2191    
2192                  if (iSAD < iMinSAD)                  if (iSAD < iMinSAD) {
                 {  
2193                          *currMV = newMV;                          *currMV = newMV;
2194                          iMinSAD = iSAD;                          iMinSAD = iSAD;
2195                  }                  }
2196    
2197                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2198                  {                          iSAD =
2199                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2200                                  x, y,                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,
2201                          0, 0, iMinSAD, &newMV,                                                                    max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
                         pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0);  
2202    
2203                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2204                                  *currMV = newMV;                                  *currMV = newMV;
2205                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2206                          }                          }
# Line 1667  Line 2211 
2211    
2212  EPZS16_Terminate_with_Refine:  EPZS16_Terminate_with_Refine:
2213          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE16)          // perform final half-pel step
2214                  iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
2215                                  x, y,                          Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2216                                  currMV, iMinSAD,                                                           iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
2217                                  pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                           iFcode, iQuant, iEdgedWidth);
2218    
2219  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
2220    
2221          *oldMB = *pMB;          *oldMB = *prevMB;
2222    
2223          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
2224          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1682  Line 2226 
2226  }  }
2227    
2228    
2229  int32_t EPZSSearch8(  int32_t
2230                                          const uint8_t * const pRef,  EPZSSearch8(const uint8_t * const pRef,
2231                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
2232                                          const uint8_t * const pRefV,                                          const uint8_t * const pRefV,
2233                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
2234                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
2235                                          const int x, const int y,                          const int x,
2236                                          const int start_x, const int start_y,                          const int y,
2237                            const int start_x,
2238                            const int start_y,
2239                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
2240                            const uint32_t iQuant,
2241                            const uint32_t iFcode,
2242                                          const MBParam * const pParam,                                          const MBParam * const pParam,
2243                                          MACROBLOCK * const pMBs,                          const MACROBLOCK * const pMBs,
2244                            const MACROBLOCK * const prevMBs,
2245                                          VECTOR * const currMV,                                          VECTOR * const currMV,
2246                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
2247  {  {
2248      const uint32_t iWcount = pParam->mb_width;  /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
2249    
2250            const uint32_t iWcount = pParam->mb_width;
2251          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
2252          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
2253          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1721  Line 2269 
2269    
2270          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
2271    
2272          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
2273            const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;
2274    
2275          int32_t bPredEq;          int32_t bPredEq;
2276          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
2277    
2278          MainSearch8FuncPtr EPZSMainSearchPtr;          MainSearch8FuncPtr MainSearchPtr;
2279    
2280  /* Get maximum range */  /* Get maximum range */
2281          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,
2282                          x, y, 8, iWidth, iHeight, iFcode);                            iFcode);
2283    
2284  /* 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 */
2285    
2286          if (!(MotionFlags & PMV_HALFPEL8 ))          if (!(MotionFlags & PMV_HALFPEL8)) {
2287          { min_dx = EVEN(min_dx);                  min_dx = EVEN(min_dx);
2288            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
2289            min_dy = EVEN(min_dy);            min_dy = EVEN(min_dy);
2290            max_dy = EVEN(max_dy);            max_dy = EVEN(max_dy);
2291          }               /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */          }
2292            /* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */
2293          bPredEq  = get_pmvdata(pMBs, x>>1, y>>1, iWcount, iSubBlock, pmv, psad);          bPredEq  = get_pmvdata(pMBs, x>>1, y>>1, iWcount, iSubBlock, pmv, psad);
2294            // bPredEq = get_pmvdata2(pMBs, iWcount, 0, x >> 1, y >> 1, iSubBlock, pmv, psad);
2295    
2296    
2297  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
# Line 1754  Line 2304 
2304  // Prepare for main loop  // Prepare for main loop
2305    
2306    
2307          if (!(MotionFlags & PMV_HALFPEL8))          if (!(MotionFlags & PMV_HALFPEL8)) {
         {  
2308                  currMV->x = EVEN(currMV->x);                  currMV->x = EVEN(currMV->x);
2309                  currMV->y = EVEN(currMV->y);                  currMV->y = EVEN(currMV->y);
2310          }          }
# Line 1772  Line 2321 
2321  /***************** This is predictor SET A: only median prediction ******************/  /***************** This is predictor SET A: only median prediction ******************/
2322    
2323    
2324          iMinSAD = sad8( cur,          iMinSAD =
2325                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  sad8(cur,
2326                  iEdgedWidth);                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,
2327          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;                                                  iEdgedWidth), iEdgedWidth);
2328            iMinSAD +=
2329                    calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
2330                                             (uint8_t) iFcode, iQuant);
2331    
2332    
2333  // thresh1 is fixed to 256  // thresh1 is fixed to 256
2334          if (iMinSAD < 256/4 )          if (iMinSAD < 256 / 4) {
                 {  
2335                          if (MotionFlags & PMV_QUICKSTOP8)                          if (MotionFlags & PMV_QUICKSTOP8)
2336                                  goto EPZS8_Terminate_without_Refine;                                  goto EPZS8_Terminate_without_Refine;
2337                          if (MotionFlags & PMV_EARLYSTOP8)                          if (MotionFlags & PMV_EARLYSTOP8)
# Line 1789  Line 2340 
2340    
2341  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2342    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
2343    
2344  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
2345          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
2346    
2347    // previous frame MV
2348            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x, prevMB->mvs[iSubBlock].y);
2349    
2350    // left neighbour, if allowed
2351            if (psad[1] != MV_MAX_ERROR) {
2352                    if (!(MotionFlags & PMV_HALFPEL8)) {
2353                            pmv[1].x = EVEN(pmv[1].x);
2354                            pmv[1].y = EVEN(pmv[1].y);
2355                    }
2356                    CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);
2357            }
2358    // top neighbour, if allowed
2359            if (psad[2] != MV_MAX_ERROR) {
2360                    if (!(MotionFlags & PMV_HALFPEL8)) {
2361                            pmv[2].x = EVEN(pmv[2].x);
2362                            pmv[2].y = EVEN(pmv[2].y);
2363                    }
2364                    CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);
2365    
2366    // top right neighbour, if allowed
2367                    if (psad[3] != MV_MAX_ERROR) {
2368                            if (!(MotionFlags & PMV_HALFPEL8)) {
2369                                    pmv[3].x = EVEN(pmv[3].x);
2370                                    pmv[3].y = EVEN(pmv[3].y);
2371                            }
2372                            CHECK_MV8_CANDIDATE(pmv[3].x, pmv[3].y);
2373                    }
2374            }
2375    
2376    /*  // this bias is zero anyway, at the moment!
2377    
2378            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
2379                    iMinSAD -= MV8_00_BIAS;
2380    
2381    */
2382    
2383  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
2384     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]
2385  */  */
2386    
2387          if (iMinSAD < 512/4)    /* T_2 == 512/4 hardcoded */          if (iMinSAD < 512 / 4) {        /* T_2 == 512/4 hardcoded */
                 {  
2388                          if (MotionFlags & PMV_QUICKSTOP8)                          if (MotionFlags & PMV_QUICKSTOP8)
2389                                  goto EPZS8_Terminate_without_Refine;                                  goto EPZS8_Terminate_without_Refine;
2390                          if (MotionFlags & PMV_EARLYSTOP8)                          if (MotionFlags & PMV_EARLYSTOP8)
2391                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
2392                  }                  }
2393    
2394  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
2395    
2396          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
2397    
2398          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
2399                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2400    
2401  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of EPZS_MainSearch */
2402    
2403    // there is no EPZS^2 for inter4v at the moment
2404    
2405  //      if (MotionFlags & PMV_USESQUARES8)  //      if (MotionFlags & PMV_USESQUARES8)
2406  //              EPZSMainSearchPtr = Square8_MainSearch;  //      MainSearchPtr = Square8_MainSearch;
2407  //      else  //      else
                 EPZSMainSearchPtr = Diamond8_MainSearch;  
2408    
2409          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2410                  x, y,                  MainSearchPtr = AdvDiamond8_MainSearch;
2411                  currMV->x, currMV->y, iMinSAD, &newMV,          else
2412                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  MainSearchPtr = Diamond8_MainSearch;
                 iDiamondSize, iFcode, iQuant, 00);  
2413    
2414            iSAD =
2415                    (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x,
2416                                                      currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx,
2417                                                      min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,
2418                                                      iQuant, 0);
2419    
2420          if (iSAD < iMinSAD)  
2421          {          if (iSAD < iMinSAD) {
2422                  *currMV = newMV;                  *currMV = newMV;
2423                  iMinSAD = iSAD;                  iMinSAD = iSAD;
2424          }          }
2425    
2426          if (MotionFlags & PMV_EXTSEARCH8)          if (MotionFlags & PMV_EXTSEARCH8) {
         {  
2427  /* 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) */
2428    
2429                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0], backupMV))) {
2430                  {                          iSAD =
2431                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,
2432                                  x, y,                                                                    pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv,
2433                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                                    min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2434                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                                                                    iDiamondSize, iFcode, iQuant, 0);
2435    
2436                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2437                                  *currMV = newMV;                                  *currMV = newMV;
2438                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2439                          }                          }
2440                  }                  }
2441    
2442                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {
2443                  {                          iSAD =
2444                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                                  (*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,
2445                                  x, y,                                                                    iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy,
2446                          0, 0, iMinSAD, &newMV,                                                                    max_dy, iEdgedWidth, iDiamondSize, iFcode,
2447                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                                                                    iQuant, 0);
2448    
2449                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD) {
                         {  
2450                                  *currMV = newMV;                                  *currMV = newMV;
2451                                  iMinSAD = iSAD;                                  iMinSAD = iSAD;
2452                          }                          }
# Line 1872  Line 2457 
2457    
2458  EPZS8_Terminate_with_Refine:  EPZS8_Terminate_with_Refine:
2459          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step          if (MotionFlags & PMV_HALFPELREFINE8)           // perform final half-pel step
2460                  iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur,                  iMinSAD =
2461                                  x, y,                          Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
2462                                  currMV, iMinSAD,                                                          iMinSAD, pmv, min_dx, max_dx, min_dy, max_dy,
2463                                  pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);                                                          iFcode, iQuant, iEdgedWidth);
2464    
2465  EPZS8_Terminate_without_Refine:  EPZS8_Terminate_without_Refine:
2466    
# Line 1893  Line 2478 
2478  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2479  ***************************************************************/  ***************************************************************/
2480    
 /*  
 void MotionEstimationBVOP(  
                         MBParam * const pParam,  
                         FRAMEINFO * const frame,  
2481    
2482    void
2483    MotionEstimationBVOP(MBParam * const pParam,
2484                                             FRAMEINFO * const frame,
2485                          // forward (past) reference                          // forward (past) reference
2486                          const MACROBLOCK * const f_mbs,                          const MACROBLOCK * const f_mbs,
2487                      const IMAGE * const f_ref,                      const IMAGE * const f_ref,
# Line 1915  Line 2499 
2499      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2500          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2501    
2502          int32_t i,j;          uint32_t i, j;
2503    
2504          int32_t f_sad16;          int32_t f_sad16;
2505          int32_t b_sad16;          int32_t b_sad16;
# Line 1926  Line 2510 
2510          VECTOR pmv_dontcare;          VECTOR pmv_dontcare;
2511    
2512          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
2513      for (j = 0; j < mb_height; j++)          for (j = 0; j < mb_height; j++) {
2514          {                  for (i = 0; i < mb_width; i++) {
                 for (i = 0; i < mb_width; i++)  
                 {  
2515                          MACROBLOCK *mb = &frame->mbs[i + j*mb_width];                          MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2516                          const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];                          const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2517                          const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];                          const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2518    
2519                          if (b_mb->mode == MODE_INTER                          if (b_mb->mode == MODE_INTER && b_mb->cbp == 0 &&
2520                                  && b_mb->cbp == 0                                  b_mb->mvs[0].x == 0 && b_mb->mvs[0].y == 0) {
2521                                  && b_mb->mvs[0].x == 0                                  mb->mode = MODE_NOT_CODED;
                                 && b_mb->mvs[0].y == 0)  
                         {  
                                 mb->mode = MB_IGNORE;  
2522                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2523                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2524                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
2525                                  mb->b_mvs[0].y = 0;                                  mb->b_mvs[0].y = 0;
2526                                  continue;                                  continue;
2527                          }                          }
2528                    /* force F_SAD16
2529                            f_sad16 = 100;
2530                            b_sad16 = 65535;
2531    
2532                            mb->mode = MODE_FORWARD;
2533                            mb->mvs[0].x = 1;
2534                            mb->mvs[0].y = 1;
2535                            mb->b_mvs[0].x = 1;
2536                            mb->b_mvs[0].y = 1;
2537                            continue;
2538                     ^^ force F_SAD16 */
2539    
2540    
2541                          // forward search                          // forward search
2542                          f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                          f_sad16 =
2543                                                  &frame->image,                                  SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2544                                                  i, j,                                                   &frame->image, i, j, frame->motion_flags,
2545                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                   frame->quant, frame->fcode, pParam,
2546                                                  pParam,                                                   f_mbs,  f_mbs, /* todo */
                                                 f_mbs,  
2547                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2548    
2549                          // backward search                          // backward search
2550                          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,
2551                                                  &frame->image,                                                  &frame->image, i, j, frame->motion_flags,
2552                                                  i, j,                                                  frame->quant, frame->bcode, pParam,
2553                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  b_mbs, b_mbs,   /* todo */
                                                 pParam,  
                                                 b_mbs,  
2554                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2555    
2556                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
2557                          i_sad16 = sad16bi_c(                          i_sad16 = 65535;
2558                                          frame->image.y + i*16 + j*16*edged_width,  
2559                            /*
2560                            x/y range somewhat buggy
2561                            i_sad16 =
2562                                    sad16bi_c(frame->image.y + i * 16 + j * 16 * edged_width,
2563                                          get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,                                          get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2564                                                  i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),                                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y,
2565                                          get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,                                                                    edged_width), get_ref(b_ref->y, b_refH->y,
2566                                                  i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),                                                                                                                  b_refV->y, b_refHV->y,
2567                                                                                                                    i, j, 16,
2568                                                                                                                    mb->b_mvs[0].x,
2569                                                                                                                    mb->b_mvs[0].x,
2570                                                                                                                    edged_width),
2571                                          edged_width);                                          edged_width);
2572                            */
2573    
2574                          // TODO: direct search                          // TODO: direct search
2575                          // predictor + range of [-32,32]                          // predictor + range of [-32,32]
2576                          d_sad16 = 65535;                          d_sad16 = 65535;
2577    
2578    
2579                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16) {
                         {  
2580                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2581                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2582                          }                          } else {
                         else  
                         {  
2583                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2584                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2585                          }                          }
2586    
2587                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad) {
                         {  
2588                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2589                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2590                          }                          }
2591    
2592                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad) {
                         {  
2593                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2594                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2595                          }                          }
2596    
2597                  }                  }
2598          }          }
2599  }  }
   
 */  

Legend:
Removed from v.132  
changed lines
  Added in v.254

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