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

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

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

revision 132, Tue Apr 23 00:04:51 2002 UTC revision 174, Sat May 11 23:54:30 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      01.05.2002      updated MotionEstimationBVOP
6     *      25.04.2002 partial prevMB conversion
7   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>   *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
8   *  14.04.2002 added MotionEstimationBVOP()   *  14.04.2002 added MotionEstimationBVOP()
9   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between
# Line 52  Line 54 
54  #define MV16_THRESHOLD  192  #define MV16_THRESHOLD  192
55  #define MV8_THRESHOLD   56  #define MV8_THRESHOLD   56
56    
57    #define NEIGH_MOVE_THRESH 8
58    // how much a block's MV must differ from his neighbour
59    // to be search for INTER4V. The more, the faster...
60    
61  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
62  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
63  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
64    #define MV8_00_BIAS     (0)
65    
66  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
67  #define INTER_BIAS      512  #define MV16_INTER_BIAS 512
68    
69  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
70  #define IMV16X16                        5  #define IMV16X16                        5
# Line 66  Line 73 
73  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
74  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
75    
   
76  // fast ((A)/2)*2  // fast ((A)/2)*2
77  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
78    
79    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
80    #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
81    
82  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
83                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 79  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 92  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 105  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 119  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 170  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 205  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 232  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  {  {
277          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
278          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
279            MACROBLOCK * const pMBs = current->mbs;
280            MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
281    
282          uint32_t i, j, iIntra = 0;          const IMAGE * const pCurrent = &current->image;
283            const IMAGE * const pRef = &reference->image;
284    
285          VECTOR mv16;          const VECTOR zeroMV = {0,0};
         VECTOR pmv16;  
286    
287          int32_t sad8 = 0;          int32_t x, y;
288          int32_t sad16;          int32_t iIntra = 0;
289          int32_t deviation;          VECTOR pmv;
290    
291          if (sadInit)          if (sadInit)
292                  (*sadInit)();                  (*sadInit)();
293    
294          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
295          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
296                  {                  {
297                          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;  
298    
299                            pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                                             x, y, current->motion_flags, current->quant, current->fcode,
301                                             pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
302                    }
303    
304                          /* decide: MODE_INTER or MODE_INTRA          for (y = 0; y < iHcount; y++)
305                             if (dev_intra < sad_inter - 2 * nb) use_intra                  for (x = 0; x < iWcount; x++)
306                          */                  {
307                            MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
308    
309                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
310                            {
311                                    int32_t deviation;
312                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
313                                                             pParam->edged_width);
314    
315                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
316                          {                          {
317                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
318                                  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]
319                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
320                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
321                                                                 = pMB->sad8[2] = pMB->sad8[3] = 0;
322    
323                                  iIntra++;                                  iIntra++;
324                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 287  Line 326 
326    
327                                  continue;                                  continue;
328                          }                          }
   
                         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];  
329                          }                          }
330    
331                            if ( (current->global_flags & XVID_INTER4V)
332                                    && (!(current->global_flags & XVID_LUMIMASKING)
333                                            || pMB->dquant == NO_CHANGE) )
334                            {
335                                    int32_t neigh=0;
336    
337                                    if (x>0)
338                                    {       neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x));
339                                            neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y));
340                                    }
341                                    if (y>0)
342                                    {       neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x));
343                                            neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y));
344                                    }
345                                    if (x<(iWcount-1))
346                                    {       neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x));
347                                            neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y));
348                                    }
349                                    if (y<(iHcount-1))
350                                    {       neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x));
351                                            neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y));
352                                    }
353    
354                                    if (neigh > NEIGH_MOVE_THRESH)
355                                    {
356                                            int32_t sad8 = 129; //IMV16X16 * current->quant;
357    
358                                    if (sad8 < pMB->sad16)
359                                    sad8 += pMB->sad8[0]
360                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
361                                                           2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
362                                                               current->motion_flags, current->quant, current->fcode,
363                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
364    
365                                    if (sad8 < pMB->sad16)
366                                    sad8 += pMB->sad8[1]
367                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
368                                   2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
369                                                    current->motion_flags, current->quant, current->fcode,
370                                                    pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
371    
372                                    if (sad8 < pMB->sad16)
373                                    sad8 += pMB->sad8[2]
374                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
375                                                    2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
376                                                    current->motion_flags, current->quant, current->fcode,
377                                                    pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
378    
379                                    if (sad8 < pMB->sad16)
380                                    sad8 += pMB->sad8[3]
381                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
382                                                    2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
383                                                    current->motion_flags, current->quant, current->fcode,
384                                                    pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
385    
386                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
387                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
388                          */                          */
389    
390                          if (pMB->dquant == NO_CHANGE) {                                  if (sad8 < pMB->sad16)
391                                  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  
392                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
393                   pMB->sad8[0] *= 4;
394                                            pMB->sad8[1] *= 4;
395                                            pMB->sad8[2] *= 4;
396                                            pMB->sad8[3] *= 4;
397                                            continue;
398                          }                          }
                         else  
                         {  
                                 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;  
399                          }                          }
400                  }                  }
401    
402          return 0;                          pMB->mode = MODE_INTER;
403  }                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
404             pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
405    
406  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                          pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
407                            // get_pmv has to be called again.
408                            // intra-decision and inter4v change predictors
409    
410  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )                                  pMB->pmvs[0].x = pMB->mv16.x - pmv.x;
411                                    pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
412                    }
413    
414            return 0;
415    }
416    
417  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
418    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
419      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
420    { \    { \
421      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \
422      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
     if (iSAD <= iQuant * 96)    \  
         iSAD -= MV16_00_BIAS; \  
423      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
424      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
425  }  }
426    
427  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
428      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
429      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
430      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
431      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
432  }  }
# Line 371  Line 436 
436      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
437    { \    { \
438      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
439      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
440      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
441      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
442  }  }
# Line 381  Line 446 
446      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
447    { \    { \
448      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
449      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
450      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
451      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
452  }  }
# Line 391  Line 456 
456      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
457    { \    { \
458      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
459      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
462  }  }
# Line 399  Line 464 
464    
465  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
466    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \
467    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
468    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
469    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
470  }  }
# Line 407  Line 472 
472  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
473    { \    { \
474      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
475      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
476      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
477      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
478  }  }
# Line 417  Line 482 
482      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
483    { \    { \
484      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
485      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
486      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
487      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
488  }  }
# Line 427  Line 492 
492      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
493    { \    { \
494      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
495      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
496      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
497      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
498  }  }
# Line 437  Line 502 
502      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
503    { \    { \
504      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
505      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
506      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
507      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
508  }  }
# Line 452  Line 517 
517                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
518                                          const int x, const int y,                                          const int x, const int y,
519                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
520                                            const uint32_t iQuant,
521                                            const uint32_t iFcode,
522                                          MBParam * const pParam,                                          MBParam * const pParam,
523                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
524                                            const MACROBLOCK * const prevMBs,
525                                          VECTOR * const currMV,                                          VECTOR * const currMV,
526                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
527  {  {
528          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
529          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
530          int32_t iSAD;          int32_t iSAD;
531          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 780  Line 847 
847                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
848                                          const int x, const int y,                                          const int x, const int y,
849                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
850                                            const uint32_t iQuant,
851                                            const uint32_t iFcode,
852                                          const MBParam * const pParam,                                          const MBParam * const pParam,
853                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
854                                            const MACROBLOCK * const prevMBs,
855                                          VECTOR * const currMV,                                          VECTOR * const currMV,
856                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
857  {  {
858      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;  
859          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
860          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
861          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 809  Line 877 
877          VECTOR pmv[4];          VECTOR pmv[4];
878          int32_t psad[4];          int32_t psad[4];
879    
880          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
881            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
882    
883          static int32_t threshA,threshB;          static int32_t threshA,threshB;
884          int32_t bPredEq;          int32_t bPredEq;
# Line 848  Line 917 
917    
918          iFound=0;          iFound=0;
919    
 /* 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;  
   
920  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
921     MinSAD=SAD     MinSAD=SAD
922     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 875  Line 924 
924     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
925  */  */
926    
   
 // Prepare for main loop  
   
927          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
928          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
929          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 905  Line 951 
951          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
952                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
953                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
954          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);
955    
956          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
957          {          {
958                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
959                    {
960                            if (!MVzero(*currMV))
961                            {
962                                    iMinSAD += MV16_00_BIAS;
963                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
964                                    iMinSAD -= MV16_00_BIAS;
965                            }
966                    }
967    
968                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
969                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 916  Line 971 
971                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
972          }          }
973    
974    
975    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
976       vector of the median.
977       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
978    */
979    
980            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
981                    iFound=2;
982    
983    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
984       Otherwise select large Diamond Search.
985    */
986    
987            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
988                    iDiamondSize=1; // halfpel!
989            else
990                    iDiamondSize=2; // halfpel!
991    
992            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
993                    iDiamondSize*=2;
994    
995  /*  /*
996     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.
997     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
998     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
999     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1000  */  */
1001    
1002  // (0,0) is always possible  // (0,0) is always possible
1003    
1004            if (!MVzero(pmv[0]))
1005          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1006    
1007  // previous frame MV is always possible  // previous frame MV is always possible
1008          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1009            if (!MVzero(prevMB->mvs[0]))
1010            if (!MVequal(prevMB->mvs[0],pmv[0]))
1011                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1012    
1013  // left neighbour, if allowed  // left neighbour, if allowed
1014          if (x != 0)  
1015            if (!MVzero(pmv[1]))
1016            if (!MVequal(pmv[1],prevMB->mvs[0]))
1017            if (!MVequal(pmv[1],pmv[0]))
1018          {          {
1019                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1020                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1021                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1022                  }                  }
1023    
1024                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1025          }          }
1026    
1027  // top neighbour, if allowed  // top neighbour, if allowed
1028          if (y != 0)          if (!MVzero(pmv[2]))
1029            if (!MVequal(pmv[2],prevMB->mvs[0]))
1030            if (!MVequal(pmv[2],pmv[0]))
1031            if (!MVequal(pmv[2],pmv[1]))
1032          {          {
1033                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1034                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 950  Line 1037 
1037                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1038    
1039  // top right neighbour, if allowed  // top right neighbour, if allowed
1040                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1041                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1042                    if (!MVequal(pmv[3],pmv[0]))
1043                    if (!MVequal(pmv[3],pmv[1]))
1044                    if (!MVequal(pmv[3],pmv[2]))
1045                  {                  {
1046                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1047                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 960  Line 1051 
1051                  }                  }
1052          }          }
1053    
1054            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1055                    iMinSAD -= MV16_00_BIAS;
1056    
1057    
1058  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1059     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.
1060  */  */
1061    
1062          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1063          {          {
1064                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1065                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1150  Line 1245 
1245                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1246                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1247                                          const int x, const int y,                                          const int x, const int y,
1248                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1249                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1250                                            const uint32_t iQuant,
1251                                            const uint32_t iFcode,
1252                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1253                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1254                                            const MACROBLOCK * const prevMBs,
1255                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1256                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1257  {  {
1258          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;  
1259          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1260          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1261          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1178  Line 1273 
1273          int32_t psad[4];          int32_t psad[4];
1274          VECTOR newMV;          VECTOR newMV;
1275          VECTOR backupMV;          VECTOR backupMV;
1276            VECTOR startMV;
1277    
1278          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1279            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1280    
1281          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1282          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1283          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1284    
1285          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1286    
1287            /* Init variables */
1288            startMV.x = start_x;
1289            startMV.y = start_y;
1290    
1291  /* Get maximum range */  /* Get maximum range */
1292          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1293                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1294    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1295          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1296          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1297          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1220  Line 1319 
1319    
1320          iFound=0;          iFound=0;
1321    
 /* 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;  
   
1322  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1323     MinSAD=SAD     MinSAD=SAD
1324     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1250  Line 1329 
1329    
1330  // Prepare for main loop  // Prepare for main loop
1331    
1332          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1333    
1334          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1335                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1336                          iEdgedWidth);                          iEdgedWidth);
1337          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);
1338    
1339          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1340                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1341          {          {
1342                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1343                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1266  Line 1345 
1345                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1346          }          }
1347    
1348    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1349       vector of the median.
1350       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1351    */
1352    
1353            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1354                    iFound=2;
1355    
1356    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1357       Otherwise select large Diamond Search.
1358    */
1359    
1360            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1361                    iDiamondSize=1; // 1 halfpel!
1362            else
1363                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1364    
1365            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1366                    iDiamondSize*=2;
1367    
1368    
1369  /*  /*
1370     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.
1371     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1372     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1373     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1374  */  */
1375    
1376  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1377    
1378            if (!MVequal(pmv[0],startMV))
1379          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1380    
1381  // (0,0) is always possible  // (0,0) if needed
1382            if (!MVzero(pmv[0]))
1383            if (!MVzero(startMV))
1384          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1385    
1386  // previous frame MV is always possible  // previous frame MV if needed
1387          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1388            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1389            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1390            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1391    
1392  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1393          if (psad[1] != MV_MAX_ERROR)          {
1394                    if (MotionFlags & PMV_QUICKSTOP16)
1395                            goto PMVfast8_Terminate_without_Refine;
1396                    if (MotionFlags & PMV_EARLYSTOP16)
1397                            goto PMVfast8_Terminate_with_Refine;
1398            }
1399    
1400    
1401    // left neighbour, if allowed and needed
1402            if (!MVzero(pmv[1]))
1403            if (!MVequal(pmv[1],startMV))
1404            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1405            if (!MVequal(pmv[1],pmv[0]))
1406          {          {
1407                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1408                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1293  Line 1411 
1411                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1412          }          }
1413    
1414  // top neighbour, if allowed  // top neighbour, if allowed and needed
1415          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1416            if (!MVequal(pmv[2],startMV))
1417            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1418            if (!MVequal(pmv[2],pmv[0]))
1419            if (!MVequal(pmv[2],pmv[1]))
1420          {          {
1421                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1422                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1302  Line 1424 
1424                  }                  }
1425                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1426    
1427  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1428                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1429            if (!MVequal(pmv[3],startMV))
1430            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1431            if (!MVequal(pmv[3],pmv[0]))
1432            if (!MVequal(pmv[3],pmv[1]))
1433            if (!MVequal(pmv[3],pmv[2]))
1434                  {                  {
1435                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1436                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1313  Line 1440 
1440                  }                  }
1441          }          }
1442    
1443            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1444                    iMinSAD -= MV8_00_BIAS;
1445    
1446    
1447  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1448     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.
1449  */  */
1450    
1451          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1452          {          {
1453                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1454                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1407  Line 1538 
1538                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1539                                          const int x, const int y,                                          const int x, const int y,
1540                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1541                                            const uint32_t iQuant,
1542                                            const uint32_t iFcode,
1543                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1544                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1545                                            const MACROBLOCK * const prevMBs,
1546                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1547                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1548  {  {
1549      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1550      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;  
1551    
1552          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1553          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1435  Line 1567 
1567          int32_t psad[8];          int32_t psad[8];
1568    
1569          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1570          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1571            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1572          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1573    
1574          static int32_t thresh2;          static int32_t thresh2;
# Line 1445  Line 1578 
1578          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1579    
1580          if (oldMBs == NULL)          if (oldMBs == NULL)
1581          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1582                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1583          }          }
1584          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1585    
# Line 1454  Line 1587 
1587          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1588                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1589    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1590          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1591          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1592            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1495  Line 1626 
1626          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1627                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1628                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1629          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);
1630    
1631  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1632          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1633                  {                  {
1634                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1635                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1509  Line 1640 
1640  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1641    
1642  // previous frame MV  // previous frame MV
1643          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1644    
1645  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1646  // 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 1565  Line 1696 
1696  */  */
1697    
1698          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1699                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1700                  {                  {
1701                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1702                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1575  Line 1706 
1706    
1707  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1708    
1709          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1710          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1711          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1712    
1713          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1714    
1715  // left neighbour  // left neighbour
1716          if (x != 0)          if (x != 0)
1717                  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);
1718    
1719  // top neighbour  // top neighbour
1720          if (y != 0)          if (y != 0)
1721                  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);
1722    
1723  // 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
1724    
1725          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1726                  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);
1727    
1728  // bottom neighbour, dito  // bottom neighbour, dito
1729          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1730                  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);
1731    
1732  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1733          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1653  Line 1784 
1784                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1785                                  x, y,                                  x, y,
1786                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1787                          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);
1788    
1789                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1790                          {                          {
# Line 1674  Line 1805 
1805    
1806  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1807    
1808          *oldMB = *pMB;          *oldMB = *prevMB;
1809    
1810          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1811          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1691  Line 1822 
1822                                          const int x, const int y,                                          const int x, const int y,
1823                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1824                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1825                                            const uint32_t iQuant,
1826                                            const uint32_t iFcode,
1827                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1828                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1829                                            const MACROBLOCK * const prevMBs,
1830                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1831                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1832  {  {
1833      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;  
1834    
1835            const uint32_t iWcount = pParam->mb_width;
1836          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1837          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1838          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1721  Line 1854 
1854    
1855          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1856    
1857          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1858            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1859    
1860          int32_t bPredEq;          int32_t bPredEq;
1861          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1775  Line 1909 
1909          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1910                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1911                  iEdgedWidth);                  iEdgedWidth);
1912          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);
1913    
1914    
1915  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1789  Line 1923 
1923    
1924  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1925    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1926    
1927  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1928          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1929    
1930    // previous frame MV
1931            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1932    
1933    // left neighbour, if allowed
1934            if (psad[1] != MV_MAX_ERROR)
1935            {
1936                    if (!(MotionFlags & PMV_HALFPEL8 ))
1937                    {       pmv[1].x = EVEN(pmv[1].x);
1938                            pmv[1].y = EVEN(pmv[1].y);
1939                    }
1940                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1941            }
1942    
1943    // top neighbour, if allowed
1944            if (psad[2] != MV_MAX_ERROR)
1945            {
1946                    if (!(MotionFlags & PMV_HALFPEL8 ))
1947                    {       pmv[2].x = EVEN(pmv[2].x);
1948                            pmv[2].y = EVEN(pmv[2].y);
1949                    }
1950                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1951    
1952    // top right neighbour, if allowed
1953                    if (psad[3] != MV_MAX_ERROR)
1954                    {
1955                            if (!(MotionFlags & PMV_HALFPEL8 ))
1956                            {       pmv[3].x = EVEN(pmv[3].x);
1957                                    pmv[3].y = EVEN(pmv[3].y);
1958                            }
1959                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1960                    }
1961            }
1962    
1963    /*  // this bias is zero anyway, at the moment!
1964    
1965            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1966                    iMinSAD -= MV8_00_BIAS;
1967    
1968    */
1969    
1970  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1971     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]
1972  */  */
# Line 1808  Line 1979 
1979                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1980                  }                  }
1981    
1982  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1983    
1984          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1985    
1986          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1987                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1988    
1989  /* 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 */
1990    
1991    /* // there is no EPZS^2 for inter4v at the moment
1992    
1993            if (MotionFlags & PMV_USESQUARES8)
1994                    EPZSMainSearchPtr = Square8_MainSearch;
1995            else
1996    */
1997    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1998                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1999    
2000          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2001                  x, y,                  x, y,
2002                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2003                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2004                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2005    
2006    
2007          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1893  Line 2068 
2068  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2069  ***************************************************************/  ***************************************************************/
2070    
2071  /*  
2072  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2073                          MBParam * const pParam,                          MBParam * const pParam,
2074                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 1915  Line 2090 
2090      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2091          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2092    
2093          int32_t i,j;          uint32_t i,j;
2094    
2095          int32_t f_sad16;          int32_t f_sad16;
2096          int32_t b_sad16;          int32_t b_sad16;
# Line 1939  Line 2114 
2114                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2115                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2116                          {                          {
2117                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2118                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2119                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2120                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 1954  Line 2129 
2129                                                  i, j,                                                  i, j,
2130                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2131                                                  pParam,                                                  pParam,
2132                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2133                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2134    
2135                          // backward search                          // backward search
# Line 1963  Line 2138 
2138                                                  i, j,                                                  i, j,
2139                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2140                                                  pParam,                                                  pParam,
2141                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2142                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2143    
2144                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 1983  Line 2158 
2158                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2159                          {                          {
2160                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2161                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2162                          }                          }
2163                          else                          else
2164                          {                          {
2165                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2166                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2167                          }                          }
2168    
2169                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2170                          {                          {
2171                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2172                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2173                          }                          }
2174    
2175                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2176                          {                          {
2177                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2178                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2179                          }                          }
2180    
2181                  }                  }
2182          }          }
2183  }  }
   
 */  

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

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