[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 118, Sat Apr 13 16:30:02 2002 UTC revision 184, Mon May 27 18:07:38 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>
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
10   *             EPZS and EPZS^2   *             EPZS and EPZS^2
# Line 51  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 65  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(
83                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 78  Line 87 
87                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
88                                          const int x, const int y,                                          const int x, 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    
# Line 91  Line 103 
103                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
104                                          const int x, const int y,                                          const int x, 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    
# Line 104  Line 119 
119                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
120                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
121                                          const int x, const int y,                                          const int x, const int y,
122                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
123                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
124                                            const uint32_t iQuant,
125                                            const uint32_t iFcode,
126                                          const MBParam * const pParam,                                          const MBParam * const pParam,
127                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
128                                            const MACROBLOCK * const prevMBs,
129                                          VECTOR * const currMV,                                          VECTOR * const currMV,
130                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
131    
# Line 118  Line 136 
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, const int y,
139                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
140                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
141                                            const uint32_t iQuant,
142                                            const uint32_t iFcode,
143                                          const MBParam * const pParam,                                          const MBParam * const pParam,
144                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
145                                            const MACROBLOCK * const prevMBs,
146                                          VECTOR * const currMV,                                          VECTOR * const currMV,
147                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
148    
# Line 169  Line 190 
190    
191  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
192    
193    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
194            {     0    ,(int)(1.00235+0.5), (int)(1.15582+0.5), (int)(1.31976+0.5), (int)(1.49591+0.5), (int)(1.68601+0.5),
195            (int)(1.89187+0.5), (int)(2.11542+0.5), (int)(2.35878+0.5), (int)(2.62429+0.5), (int)(2.91455+0.5),
196            (int)(3.23253+0.5), (int)(3.58158+0.5), (int)(3.96555+0.5), (int)(4.38887+0.5), (int)(4.85673+0.5),
197            (int)(5.37519+0.5), (int)(5.95144+0.5), (int)(6.59408+0.5), (int)(7.31349+0.5), (int)(8.12242+0.5),
198            (int)(9.03669+0.5), (int)(10.0763+0.5), (int)(11.2669+0.5), (int)(12.6426+0.5), (int)(14.2493+0.5),
199            (int)(16.1512+0.5), (int)(18.442+0.5),  (int)(21.2656+0.5), (int)(24.8580+0.5), (int)(29.6436+0.5),
200            (int)(36.4949+0.5)      };
201    
202    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
203    
204    
205    
206  // mv.length table  // mv.length table
207  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
208      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 204  Line 238 
238  }  }
239    
240    
241  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
242  {  {
243          return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
244  }  }
245    
246  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
247    
248  {  {
249      return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));      return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
250  }  }
251    
252    
# Line 231  Line 265 
265  #endif  #endif
266    
267  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
268          MBParam * const pParam,          MBParam * const pParam,
269          const IMAGE * const pRef,          FRAMEINFO * const current,
270            FRAMEINFO * const reference,
271          const IMAGE * const pRefH,          const IMAGE * const pRefH,
272          const IMAGE * const pRefV,          const IMAGE * const pRefV,
273          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
274          const uint32_t iLimit)          const uint32_t iLimit)
   
275  {  {
276          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
277          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
278            MACROBLOCK * const pMBs = current->mbs;
279          uint32_t i, j, iIntra = 0;          MACROBLOCK * const prevMBs = reference->mbs;
280            const IMAGE * const pCurrent = &current->image;
281          VECTOR mv16;          const IMAGE * const pRef = &reference->image;
282          VECTOR pmv16;  
283            const VECTOR zeroMV = {0,0};
284          int32_t sad8 = 0;  
285          int32_t sad16;          int32_t x, y;
286          int32_t deviation;          int32_t iIntra = 0;
287            VECTOR pmv;
288    
289          if (sadInit)          if (sadInit)
290                  (*sadInit)();                  (*sadInit)();
291    
292          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
293          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
294                  {                  {
295                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
   
                         sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                          j, i, pParam->motion_flags,  
                                          pParam, pMBs, &mv16, &pmv16);  
                         pMB->sad16=sad16;  
296    
297                            pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
298                                                     x, y, current->motion_flags, current->quant, current->fcode,
299                                                     pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
300    
301                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
302                             if (dev_intra < sad_inter - 2 * nb) use_intra                          {
303                          */                                  int32_t deviation;
304                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, pParam->edged_width);
                         deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);  
305    
306                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
307                          {                          {
308                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
309                                  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] = pMB->mvs[3] = zeroMV;
310                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
311    
312                                  iIntra++;                                  iIntra++;
313                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 286  Line 315 
315    
316                                  continue;                                  continue;
317                          }                          }
   
                         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];  
318                          }                          }
319    
320                            pmv = pMB->pmvs[0];
321                            if (current->global_flags & XVID_INTER4V)
322                                    if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) )
323                                    {
324                                            int32_t sad8 = IMV16X16 * current->quant; if (sad8 < pMB->sad16)
325    
326                                            sad8 += pMB->sad8[0]            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
327                                                                                                                            2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
328                                                                                                                            current->motion_flags, current->quant, current->fcode,
329                                                                                                                            pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
330    
331                                            if (sad8 < pMB->sad16)
332                                                    sad8 += pMB->sad8[1]    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
333                                                                                                                            2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
334                                                                                                                            current->motion_flags, current->quant, current->fcode,
335                                                                                                                            pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
336    
337                                            if (sad8 < pMB->sad16)
338                                                    sad8 += pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
339                                                                                                                            2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
340                                                                                                                            current->motion_flags, current->quant, current->fcode,
341                                                                                                                            pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
342    
343                                            if (sad8 < pMB->sad16)
344                                                    sad8 += pMB->sad8[3]    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
345                                                                                                                            2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
346                                                                                                                            current->motion_flags, current->quant, current->fcode,
347                                                                                                                            pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
348    
349                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
350                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                                                  mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
351                          */                          */
352    
353                          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  
                                         pMB->mode = MODE_INTER4V;  
                         }  
                         else  
354                          {                          {
355                                  sad8 = sad16;                                                  pMB->mode = MODE_INTER4V;
356                                  pMB->mode = MODE_INTER;                              pMB->sad8[0] *= 4;
357                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                                  pMB->sad8[1] *= 4;
358                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                                  pMB->sad8[2] *= 4;
359                                  pMB->pmvs[0].x = pmv16.x;                                                  pMB->sad8[3] *= 4;
360                                  pMB->pmvs[0].y = pmv16.y;                                                  continue;
                         }  
361                  }                  }
362    
         return 0;  
363  }  }
364    
365  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                                  pMB->mode = MODE_INTER;
366                                    pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3]  are not needed for INTER */
367  #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;
368                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
369    
370                    }
371                    return 0;
372    }
373    
374  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
375    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
376      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
377    { \    { \
378      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); \
379      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; \  
380      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
381      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
382  }  }
383    
384  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
385      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); \
386      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);\
387      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
388      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
389  }  }
# Line 370  Line 393 
393      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
394    { \    { \
395      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); \
396      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);\
397      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
398      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
399  }  }
# Line 380  Line 403 
403      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
404    { \    { \
405      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); \
406      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);\
407      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
408      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
409  }  }
# Line 390  Line 413 
413      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
414    { \    { \
415      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); \
416      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);\
417      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
418      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
419  }  }
# Line 398  Line 421 
421    
422  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
423    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); \
424    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);\
425    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
426    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
427  }  }
# Line 406  Line 429 
429  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
430    { \    { \
431      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); \
432      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);\
433      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
434      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
435  }  }
# Line 416  Line 439 
439      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
440    { \    { \
441      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); \
442      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);\
443      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
444      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
445  }  }
# Line 426  Line 449 
449      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
450    { \    { \
451      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); \
452      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);\
453      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
454      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
455  }  }
# Line 436  Line 459 
459      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
460    { \    { \
461      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); \
462      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);\
463      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
464      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
465  }  }
# Line 451  Line 474 
474                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
475                                          const int x, const int y,                                          const int x, const int y,
476                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
477                                            const uint32_t iQuant,
478                                            const uint32_t iFcode,
479                                          MBParam * const pParam,                                          MBParam * const pParam,
480                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
481                                            const MACROBLOCK * const prevMBs,
482                                          VECTOR * const currMV,                                          VECTOR * const currMV,
483                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
484  {  {
485          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
486          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
487          int32_t iSAD;          int32_t iSAD;
488          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 701  Line 726 
726          return iMinSAD;          return iMinSAD;
727  }  }
728    
729    int32_t AdvDiamond16_MainSearch(
730            const uint8_t * const pRef,
731            const uint8_t * const pRefH,
732            const uint8_t * const pRefV,
733            const uint8_t * const pRefHV,
734            const uint8_t * const cur,
735            const int x, const int y,
736            int32_t startx, int32_t starty,
737            int32_t iMinSAD,
738            VECTOR * const currMV,
739            const VECTOR * const pmv,
740            const int32_t min_dx, const int32_t max_dx,
741            const int32_t min_dy, const int32_t max_dy,
742            const int32_t iEdgedWidth,
743            const int32_t iDiamondSize,
744            const int32_t iFcode,
745            const int32_t iQuant,
746            int iDirection)
747    {
748    
749            int32_t iSAD;
750    
751    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
752    
753            if (iDirection)
754            {
755                    CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty);
756                    CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty);
757                    CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize);
758                    CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize);
759            }
760            else
761            {
762                    int bDirection = 1+2+4+8;
763                    do
764                    {
765                            iDirection = 0;
766                            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)
767                                    CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
768    
769                            if (bDirection&2)
770                                    CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
771    
772                            if (bDirection&4)
773                                    CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
774    
775                            if (bDirection&8)
776                                    CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
777    
778                            /* now we're doing diagonal checks near our candidate */
779    
780                            if (iDirection) //checking if anything found
781                            {
782                                    bDirection = iDirection;
783                                    iDirection = 0;
784                                    startx=currMV->x; starty=currMV->y;
785                                    if (bDirection & 3) //our candidate is left or right
786                                    {
787                                            CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
788                                            CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
789                                    }
790                                    else // what remains here is up or down
791                                    {
792                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
793                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
794                                    }
795    
796                                    if (iDirection)
797                                    {       bDirection+=iDirection;
798                                            startx=currMV->x; starty=currMV->y;
799                                    }
800                            }
801                            else //about to quit, eh? not so fast....
802                            {
803                                    switch (bDirection)
804                                    {
805                                    case 2:
806                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
807                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
808                                            break;
809                                    case 1:
810                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
811                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
812                                            break;
813                                    case 2+4:
814                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
815                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
816                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
817                                            break;
818                                    case 4:
819                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
820                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
821                                            break;
822                                    case 8:
823                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
824                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
825                                            break;
826                                    case 1+4:
827                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
828                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
829                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
830                                            break;
831                                    case 2+8:
832                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
833                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
834                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
835                                            break;
836                                    case 1+8:
837                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
838                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
839                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
840                                            break;
841                                    default: //1+2+4+8 == we didn't find anything at all
842                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
843                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
844                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
845                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
846                                            break;
847                                    }
848                                    if (!iDirection) break; //ok, the end. really
849                                    else
850                                    {       bDirection=iDirection;
851                                            startx=currMV->x; starty=currMV->y;
852                                    }
853                            }
854                    }
855                    while (1); //forever
856            }
857            return iMinSAD;
858    }
859    
860    int32_t AdvDiamond8_MainSearch(
861            const uint8_t * const pRef,
862            const uint8_t * const pRefH,
863            const uint8_t * const pRefV,
864            const uint8_t * const pRefHV,
865            const uint8_t * const cur,
866            const int x, const int y,
867            int32_t startx, int32_t starty,
868            int32_t iMinSAD,
869            VECTOR * const currMV,
870            const VECTOR * const pmv,
871            const int32_t min_dx, const int32_t max_dx,
872            const int32_t min_dy, const int32_t max_dy,
873            const int32_t iEdgedWidth,
874            const int32_t iDiamondSize,
875            const int32_t iFcode,
876            const int32_t iQuant,
877            int iDirection)
878    {
879    
880            int32_t iSAD;
881    
882    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
883    
884            if (iDirection)
885            {
886                    CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty);
887                    CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty);
888                    CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize);
889                    CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize);
890            }
891            else
892            {
893                    int bDirection = 1+2+4+8;
894                    do
895                    {
896                            iDirection = 0;
897                            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)
898                                    CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
899    
900                            if (bDirection&2)
901                                    CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
902    
903                            if (bDirection&4)
904                                    CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
905    
906                            if (bDirection&8)
907                                    CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
908    
909                            /* now we're doing diagonal checks near our candidate */
910    
911                            if (iDirection) //checking if anything found
912                            {
913                                    bDirection = iDirection;
914                                    iDirection = 0;
915                                    startx=currMV->x; starty=currMV->y;
916                                    if (bDirection & 3) //our candidate is left or right
917                                    {
918                                            CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
919                                            CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
920                                    }
921                                    else // what remains here is up or down
922                                    {
923                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
924                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
925                                    }
926    
927                                    if (iDirection)
928                                    {       bDirection+=iDirection;
929                                            startx=currMV->x; starty=currMV->y;
930                                    }
931                            }
932                            else //about to quit, eh? not so fast....
933                            {
934                                    switch (bDirection)
935                                    {
936                                    case 2:
937                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
938                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
939                                            break;
940                                    case 1:
941                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
942                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
943                                            break;
944                                    case 2+4:
945                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
946                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
947                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
948                                            break;
949                                    case 4:
950                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
951                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
952                                            break;
953                                    case 8:
954                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
955                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
956                                            break;
957                                    case 1+4:
958                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
959                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
960                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
961                                            break;
962                                    case 2+8:
963                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
964                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
965                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
966                                            break;
967                                    case 1+8:
968                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
969                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
970                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
971                                            break;
972                                    default: //1+2+4+8 == we didn't find anything at all
973                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
974                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
975                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
976                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
977                                            break;
978                                    }
979                                    if (!(iDirection)) break; //ok, the end. really
980                                    else
981                                    {       bDirection=iDirection;
982                                            startx=currMV->x; starty=currMV->y;
983                                    }
984                            }
985                    }
986                    while (1); //forever
987            }
988            return iMinSAD;
989    }
990    
991    
992  int32_t Full8_MainSearch(  int32_t Full8_MainSearch(
993                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
994                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 779  Line 1067 
1067                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1068                                          const int x, const int y,                                          const int x, const int y,
1069                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1070                                            const uint32_t iQuant,
1071                                            const uint32_t iFcode,
1072                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1073                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1074                                            const MACROBLOCK * const prevMBs,
1075                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1076                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1077  {  {
1078          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;  
1079          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1080          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1081          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 808  Line 1097 
1097          VECTOR pmv[4];          VECTOR pmv[4];
1098          int32_t psad[4];          int32_t psad[4];
1099    
1100          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          MainSearch16FuncPtr MainSearchPtr;
1101    
1102    //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1103            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1104    
1105          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1106          int32_t bPredEq;          int32_t bPredEq;
# Line 847  Line 1139 
1139    
1140          iFound=0;          iFound=0;
1141    
 /* 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;  
   
1142  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1143     MinSAD=SAD     MinSAD=SAD
1144     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 874  Line 1146 
1146     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1147  */  */
1148    
   
 // Prepare for main loop  
   
1149          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
1150          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1151          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 904  Line 1173 
1173          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1174                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1175                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
1176          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1177    
1178          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1179          {          {
1180                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
1181                    {
1182                            if (!MVzero(*currMV))
1183                            {
1184                                    iMinSAD += MV16_00_BIAS;
1185                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
1186                                    iMinSAD -= MV16_00_BIAS;
1187                            }
1188                    }
1189    
1190                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1191                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 915  Line 1193 
1193                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
1194          }          }
1195    
1196    
1197    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1198       vector of the median.
1199       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1200    */
1201    
1202            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
1203                    iFound=2;
1204    
1205    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1206       Otherwise select large Diamond Search.
1207    */
1208    
1209            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1210                    iDiamondSize=1; // halfpel!
1211            else
1212                    iDiamondSize=2; // halfpel!
1213    
1214            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1215                    iDiamondSize*=2;
1216    
1217  /*  /*
1218     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.
1219     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1220     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1221     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1222  */  */
1223    
1224  // (0,0) is always possible  // (0,0) is always possible
1225    
1226            if (!MVzero(pmv[0]))
1227          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1228    
1229  // previous frame MV is always possible  // previous frame MV is always possible
1230          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1231            if (!MVzero(prevMB->mvs[0]))
1232            if (!MVequal(prevMB->mvs[0],pmv[0]))
1233                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1234    
1235  // left neighbour, if allowed  // left neighbour, if allowed
1236          if (x != 0)  
1237            if (!MVzero(pmv[1]))
1238            if (!MVequal(pmv[1],prevMB->mvs[0]))
1239            if (!MVequal(pmv[1],pmv[0]))
1240          {          {
1241                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1242                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1243                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1244                  }                  }
1245    
1246                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1247          }          }
1248    
1249  // top neighbour, if allowed  // top neighbour, if allowed
1250          if (y != 0)          if (!MVzero(pmv[2]))
1251            if (!MVequal(pmv[2],prevMB->mvs[0]))
1252            if (!MVequal(pmv[2],pmv[0]))
1253            if (!MVequal(pmv[2],pmv[1]))
1254          {          {
1255                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1256                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 949  Line 1259 
1259                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1260    
1261  // top right neighbour, if allowed  // top right neighbour, if allowed
1262                  if (x != (iWcount-1))                  if (!MVzero(pmv[3]))
1263                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1264                    if (!MVequal(pmv[3],pmv[0]))
1265                    if (!MVequal(pmv[3],pmv[1]))
1266                    if (!MVequal(pmv[3],pmv[2]))
1267                  {                  {
1268                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1269                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 959  Line 1273 
1273                  }                  }
1274          }          }
1275    
1276            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1277                    iMinSAD -= MV16_00_BIAS;
1278    
1279    
1280  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1281     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.
1282  */  */
1283    
1284          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1285          {          {
1286                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1287                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 982  Line 1300 
1300     Refine by using small diamond and goto step 10.     Refine by using small diamond and goto step 10.
1301  */  */
1302    
1303            if (MotionFlags & PMV_USESQUARES16)
1304                    MainSearchPtr = Square16_MainSearch;
1305            else
1306                    if (MotionFlags & PMV_ADVANCEDDIAMOND16)
1307                            MainSearchPtr = AdvDiamond16_MainSearch;
1308                    else
1309                            MainSearchPtr = Diamond16_MainSearch;
1310    
1311          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1312    
1313  /* 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 */
1314          iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1315                                            x, y,                                            x, y,
1316                                            currMV->x, currMV->y, iMinSAD, &newMV,                                            currMV->x, currMV->y, iMinSAD, &newMV,
1317                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1001  Line 1327 
1327  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1328    
1329                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1330                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1331                                                            x, y,                                                            x, y,
1332                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1333                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1014  Line 1340 
1340                  }                  }
1341    
1342                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1343                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1344                                                            x, y,                                                            x, y,
1345                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1346                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1149  Line 1475 
1475                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1476                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1477                                          const int x, const int y,                                          const int x, const int y,
1478                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1479                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1480                                            const uint32_t iQuant,
1481                                            const uint32_t iFcode,
1482                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1483                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1484                                            const MACROBLOCK * const prevMBs,
1485                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1486                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1487  {  {
1488          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;  
1489          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1490          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1491          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1177  Line 1503 
1503          int32_t psad[4];          int32_t psad[4];
1504          VECTOR newMV;          VECTOR newMV;
1505          VECTOR backupMV;          VECTOR backupMV;
1506            VECTOR startMV;
1507    
1508          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1509            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1510    
1511          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1512          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1513          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1514    
1515          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1516    
1517            MainSearch8FuncPtr MainSearchPtr;
1518    
1519            /* Init variables */
1520            startMV.x = start_x;
1521            startMV.y = start_y;
1522    
1523  /* Get maximum range */  /* Get maximum range */
1524          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1525                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1526    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1527          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1528          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1529          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1219  Line 1551 
1551    
1552          iFound=0;          iFound=0;
1553    
 /* 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;  
   
1554  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1555     MinSAD=SAD     MinSAD=SAD
1556     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1249  Line 1561 
1561    
1562  // Prepare for main loop  // Prepare for main loop
1563    
1564          currMV->x=start_x;              /* start with mv16 */  //      if (MotionFlags & PMV_USESQUARES8)
1565          currMV->y=start_y;  //              MainSearchPtr = Square8_MainSearch;
1566    //      else
1567    
1568            if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1569                    MainSearchPtr = AdvDiamond8_MainSearch;
1570            else
1571                    MainSearchPtr = Diamond8_MainSearch;
1572    
1573    
1574            *currMV = startMV;
1575    
1576          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1577                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1578                          iEdgedWidth);                          iEdgedWidth);
1579          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode, iQuant);
1580    
1581          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1582                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1583          {          {
1584                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1585                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1265  Line 1587 
1587                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1588          }          }
1589    
1590    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1591       vector of the median.
1592       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1593    */
1594    
1595            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1596                    iFound=2;
1597    
1598    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1599       Otherwise select large Diamond Search.
1600    */
1601    
1602            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1603                    iDiamondSize=1; // 1 halfpel!
1604            else
1605                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1606    
1607            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1608                    iDiamondSize*=2;
1609    
1610    
1611  /*  /*
1612     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.
1613     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1614     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1615     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1616  */  */
1617    
1618  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1619    
1620            if (!MVequal(pmv[0],startMV))
1621          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1622    
1623  // (0,0) is always possible  // (0,0) if needed
1624            if (!MVzero(pmv[0]))
1625            if (!MVzero(startMV))
1626          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1627    
1628  // previous frame MV is always possible  // previous frame MV if needed
1629          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1630            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1631            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1632            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1633    
1634  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1635          if (psad[1] != MV_MAX_ERROR)          {
1636                    if (MotionFlags & PMV_QUICKSTOP16)
1637                            goto PMVfast8_Terminate_without_Refine;
1638                    if (MotionFlags & PMV_EARLYSTOP16)
1639                            goto PMVfast8_Terminate_with_Refine;
1640            }
1641    
1642    
1643    // left neighbour, if allowed and needed
1644            if (!MVzero(pmv[1]))
1645            if (!MVequal(pmv[1],startMV))
1646            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1647            if (!MVequal(pmv[1],pmv[0]))
1648          {          {
1649                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1650                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1292  Line 1653 
1653                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1654          }          }
1655    
1656  // top neighbour, if allowed  // top neighbour, if allowed and needed
1657          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1658            if (!MVequal(pmv[2],startMV))
1659            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1660            if (!MVequal(pmv[2],pmv[0]))
1661            if (!MVequal(pmv[2],pmv[1]))
1662          {          {
1663                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1664                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1301  Line 1666 
1666                  }                  }
1667                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1668    
1669  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1670                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1671            if (!MVequal(pmv[3],startMV))
1672            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1673            if (!MVequal(pmv[3],pmv[0]))
1674            if (!MVequal(pmv[3],pmv[1]))
1675            if (!MVequal(pmv[3],pmv[2]))
1676                  {                  {
1677                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1678                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1312  Line 1682 
1682                  }                  }
1683          }          }
1684    
1685            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1686                    iMinSAD -= MV8_00_BIAS;
1687    
1688    
1689  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1690     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.
1691  */  */
1692    
1693          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1694          {          {
1695                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1696                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1337  Line 1711 
1711          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1712    
1713  /* 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 */
1714          iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1715                                           x, y,                                           x, y,
1716                                           currMV->x, currMV->y, iMinSAD, &newMV,                                           currMV->x, currMV->y, iMinSAD, &newMV,
1717                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1353  Line 1727 
1727  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1728    
1729                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1730                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1731                                                            x, y,                                                            x, y,
1732                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1733                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1366  Line 1740 
1740                  }                  }
1741    
1742                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1743                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1744                                                            x, y,                                                            x, y,
1745                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1746                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1406  Line 1780 
1780                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1781                                          const int x, const int y,                                          const int x, const int y,
1782                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1783                                            const uint32_t iQuant,
1784                                            const uint32_t iFcode,
1785                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1786                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1787                                            const MACROBLOCK * const prevMBs,
1788                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1789                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1790  {  {
1791          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1792          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;  
1793    
1794          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1795          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1434  Line 1809 
1809          int32_t psad[8];          int32_t psad[8];
1810    
1811          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1812          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1813            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1814          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1815    
1816          static int32_t thresh2;          static int32_t thresh2;
1817          int32_t bPredEq;          int32_t bPredEq;
1818          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
1819    
1820          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1821    
1822          if (oldMBs == NULL)          if (oldMBs == NULL)
1823          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1824                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1825          }          }
1826          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1827    
# Line 1453  Line 1829 
1829          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1830                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1831    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1832          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1833          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1834            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1494  Line 1868 
1868          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1869                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1870                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1871          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1872    
1873  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1874          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1875                  {                  {
1876                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1877                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1508  Line 1882 
1882  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1883    
1884  // previous frame MV  // previous frame MV
1885          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1886    
1887  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1888  // 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
# Line 1549  Line 1923 
1923                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1924    
1925  // top right neighbour, if allowed  // top right neighbour, if allowed
1926                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1927                  {                  {
1928                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1929                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1564  Line 1938 
1938  */  */
1939    
1940          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1941                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1942                  {                  {
1943                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1944                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1574  Line 1948 
1948    
1949  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1950    
1951          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1952          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1953          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1954    
1955          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1956    
1957  // left neighbour  // left neighbour
1958          if (x != 0)          if (x != 0)
1959                  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);
1960    
1961  // top neighbour  // top neighbour
1962          if (y != 0)          if (y != 0)
1963                  CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB-iWcount)->mvs[0].x,(prevMB-iWcount)->mvs[0].y);
1964    
1965  // 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
1966    
1967          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1968                  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);
1969    
1970  // bottom neighbour, dito  // bottom neighbour, dito
1971          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1972                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB+iWcount)->mvs[0].x,(prevMB+iWcount)->mvs[0].y);
1973    
1974  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1975          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1610  Line 1984 
1984    
1985          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1986    
1987  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */          if (MotionFlags & PMV_USESQUARES8)
1988                    MainSearchPtr = Square16_MainSearch;
1989            else
1990    
1991          if (MotionFlags & PMV_USESQUARES16)          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1992                  EPZSMainSearchPtr = Square16_MainSearch;                  MainSearchPtr = AdvDiamond16_MainSearch;
1993          else          else
1994                  EPZSMainSearchPtr = Diamond16_MainSearch;                  MainSearchPtr = Diamond16_MainSearch;
1995    
1996    /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1997    
1998          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1999                          x, y,                          x, y,
2000                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2001                          2, iFcode, iQuant, 0);                          2, iFcode, iQuant, 0);
# Line 1635  Line 2013 
2013    
2014                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2015                  {                  {
2016                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2017                                  x, y,                                  x, y,
2018                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2019                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
# Line 1649  Line 2027 
2027    
2028                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2029                  {                  {
2030                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2031                                  x, y,                                  x, y,
2032                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2033                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
2034    
2035                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
2036                          {                          {
# Line 1673  Line 2051 
2051    
2052  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
2053    
2054          *oldMB = *pMB;          *oldMB = *prevMB;
2055    
2056          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
2057          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1690  Line 2068 
2068                                          const int x, const int y,                                          const int x, const int y,
2069                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
2070                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
2071                                            const uint32_t iQuant,
2072                                            const uint32_t iFcode,
2073                                          const MBParam * const pParam,                                          const MBParam * const pParam,
2074                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
2075                                            const MACROBLOCK * const prevMBs,
2076                                          VECTOR * const currMV,                                          VECTOR * const currMV,
2077                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
2078  {  {
2079          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;  
2080    
2081            const uint32_t iWcount = pParam->mb_width;
2082          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
2083          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
2084          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1720  Line 2100 
2100    
2101          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
2102    
2103          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
2104            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
2105    
2106          int32_t bPredEq;          int32_t bPredEq;
2107          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
2108    
2109          MainSearch8FuncPtr EPZSMainSearchPtr;          MainSearch8FuncPtr MainSearchPtr;
2110    
2111  /* Get maximum range */  /* Get maximum range */
2112          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
# Line 1774  Line 2155 
2155          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
2156                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
2157                  iEdgedWidth);                  iEdgedWidth);
2158          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
2159    
2160    
2161  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1788  Line 2169 
2169    
2170  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
2171    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
2172    
2173  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
2174          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
2175    
2176    // previous frame MV
2177            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
2178    
2179    // left neighbour, if allowed
2180            if (psad[1] != MV_MAX_ERROR)
2181            {
2182                    if (!(MotionFlags & PMV_HALFPEL8 ))
2183                    {       pmv[1].x = EVEN(pmv[1].x);
2184                            pmv[1].y = EVEN(pmv[1].y);
2185                    }
2186                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
2187            }
2188    
2189    // top neighbour, if allowed
2190            if (psad[2] != MV_MAX_ERROR)
2191            {
2192                    if (!(MotionFlags & PMV_HALFPEL8 ))
2193                    {       pmv[2].x = EVEN(pmv[2].x);
2194                            pmv[2].y = EVEN(pmv[2].y);
2195                    }
2196                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
2197    
2198    // top right neighbour, if allowed
2199                    if (psad[3] != MV_MAX_ERROR)
2200                    {
2201                            if (!(MotionFlags & PMV_HALFPEL8 ))
2202                            {       pmv[3].x = EVEN(pmv[3].x);
2203                                    pmv[3].y = EVEN(pmv[3].y);
2204                            }
2205                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
2206                    }
2207            }
2208    
2209    /*  // this bias is zero anyway, at the moment!
2210    
2211            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
2212                    iMinSAD -= MV8_00_BIAS;
2213    
2214    */
2215    
2216  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
2217     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]
2218  */  */
# Line 1807  Line 2225 
2225                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
2226                  }                  }
2227    
2228  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
2229    
2230          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
2231    
2232          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
2233                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2234    
2235  /* 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 */
2236    
2237    // there is no EPZS^2 for inter4v at the moment
2238    
2239  //      if (MotionFlags & PMV_USESQUARES8)  //      if (MotionFlags & PMV_USESQUARES8)
2240  //              EPZSMainSearchPtr = Square8_MainSearch;  //              MainSearchPtr = Square8_MainSearch;
2241  //      else  //      else
                 EPZSMainSearchPtr = Diamond8_MainSearch;  
2242    
2243          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2244                    MainSearchPtr = AdvDiamond8_MainSearch;
2245            else
2246                    MainSearchPtr = Diamond8_MainSearch;
2247    
2248            iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2249                  x, y,                  x, y,
2250                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2251                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2252                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2253    
2254    
2255          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1840  Line 2264 
2264    
2265                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2266                  {                  {
2267                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2268                                  x, y,                                  x, y,
2269                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2270                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 1854  Line 2278 
2278    
2279                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2280                  {                  {
2281                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2282                                  x, y,                                  x, y,
2283                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2284                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 1892  Line 2316 
2316  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2317  ***************************************************************/  ***************************************************************/
2318    
2319  /*  
2320  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2321                          MBParam * const pParam,                          MBParam * const pParam,
2322                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 1914  Line 2338 
2338      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2339          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2340    
2341          int32_t i,j;          uint32_t i,j;
2342    
2343          int32_t f_sad16;          int32_t f_sad16;
2344          int32_t b_sad16;          int32_t b_sad16;
# Line 1938  Line 2362 
2362                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2363                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2364                          {                          {
2365                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2366                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2367                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2368                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 1953  Line 2377 
2377                                                  i, j,                                                  i, j,
2378                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2379                                                  pParam,                                                  pParam,
2380                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2381                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2382    
2383                          // backward search                          // backward search
# Line 1962  Line 2386 
2386                                                  i, j,                                                  i, j,
2387                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2388                                                  pParam,                                                  pParam,
2389                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2390                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2391    
2392                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 1982  Line 2406 
2406                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2407                          {                          {
2408                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2409                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2410                          }                          }
2411                          else                          else
2412                          {                          {
2413                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2414                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2415                          }                          }
2416    
2417                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2418                          {                          {
2419                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2420                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2421                          }                          }
2422    
2423                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2424                          {                          {
2425                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2426                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2427                          }                          }
2428    
2429                  }                  }
2430          }          }
2431  }  }
   
 */  

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

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