[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 136, Thu Apr 25 06:55:00 2002 UTC revision 175, Sun May 12 17:21: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   *      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()
# Line 53  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 67  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 183  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 218  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 256  Line 276 
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 * pMBs = current->mbs;          MACROBLOCK * const pMBs = current->mbs;
280          IMAGE * pCurrent = &current->image;          MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
   
         MACROBLOCK * prevMBs = reference->mbs;  // previous frame  
         IMAGE * pRef = &reference->image;  
281    
282            const IMAGE * const pCurrent = &current->image;
283            const IMAGE * const pRef = &reference->image;
284    
285          uint32_t i, j, iIntra = 0;          const VECTOR zeroMV = {0,0};
286    
287          VECTOR mv16;          int32_t x, y;
288          VECTOR pmv16;          int32_t iIntra = 0;
289            VECTOR pmv;
         int32_t sad8 = 0;  
         int32_t sad16;  
         int32_t deviation;  
290    
291          if (sadInit)          if (sadInit)
292                  (*sadInit)();                  (*sadInit)();
293    
294            for (y = 0; y < iHcount; y++)
295          /* eventhough we have a seperate prevMBs,                  for (x = 0; x < iWcount; x++)
            pmvfast/epsz does something "funny" with the previous frames data */  
   
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
                 {  
                         pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];  
                         pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];  
                         pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];  
                         pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];  
                 }  
   
         /*dprintf("*** BEFORE ***");  
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
                 {  
                         dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,  
                                 pMBs[j + i * iWcount].mode,  
                                 pMBs[j + i * iWcount].dquant,  
                                 pMBs[j + i * iWcount].mvs[0],  
                                 pMBs[j + i * iWcount].mvs[1],  
                                 pMBs[j + i * iWcount].mvs[2],  
                                 pMBs[j + i * iWcount].mvs[3],  
                                 prevMBs[j + i * iWcount].sad8[0],  
                                 prevMBs[j + i * iWcount].sad8[1],  
                                 prevMBs[j + i * iWcount].sad8[2],  
                                 prevMBs[j + i * iWcount].sad8[3],  
                                 prevMBs[j + i * iWcount].sad16);  
                 }  
         */  
   
         // note: i==horizontal, j==vertical  
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
296                  {                  {
297                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
                         MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];  
298    
299                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                                           j, i, current->motion_flags, current->quant, current->fcode,                                           x, y, current->motion_flags, current->quant, current->fcode,
301                                           pParam, pMBs, prevMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
                         pMB->sad16=sad16;  
302    
303    
304                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
305                             if (dev_intra < sad_inter - 2 * nb) use_intra                          {
306                          */                                  int32_t deviation;
307                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
308                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                                                           pParam->edged_width);
309    
310                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
311                          {                          {
312                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
313                                  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]
314                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
315                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
316                                  pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;                                                               = pMB->sad8[2] = pMB->sad8[3] = 0;
317    
318                                  iIntra++;                                  iIntra++;
319                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 340  Line 321 
321    
322                                  continue;                                  continue;
323                          }                          }
324                            }
325                            pMB->mode = MODE_INTER;
326                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
327               pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
328                    }
329    
330            // we try to do as few INTER4V-searches as possible. So we split ME in two parts, normal
331            // SEARCH16 and only for special blocks SEARCH8. May this should be modified for quality
332            // levels.
333    
334    
335    
336                          if (current->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
337                    for (y = 0; y < iHcount; y++)
338                            for (x = 0; x < iWcount; x++)
339                            {
340                                    MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
341    
342                                    if (pMB->mode == MODE_INTRA)
343                                            continue;
344    
345    
346                                    if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) )
347                                    {
348                                    int32_t neigh=0;
349    
350                                    if (x>0)
351                                    {       neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x));
352                                            neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y));
353                                    }
354                                    if (y>0)
355                                    {       neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x));
356                                            neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y));
357                                    }
358                                    if (x<(iWcount-1))
359                                    {       neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x));
360                                            neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y));
361                                    }
362                                    if (y<(iHcount-1))
363                                    {       neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x));
364                                            neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y));
365                                    }
366    
367                                    if (neigh > NEIGH_MOVE_THRESH)
368                          {                          {
369                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          int32_t sad8 = IMV16X16 * current->quant;
370                                                         2 * j, 2 * i, mv16.x, mv16.y,  
371                                            if (sad8 < pMB->sad16)
372                                            sad8 += pMB->sad8[0]
373                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
374                                                                   2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
375                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
376                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
377    
378                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          if (sad8 < pMB->sad16)
379                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,                                          sad8 += pMB->sad8[1]
380                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
381                                           2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
382                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
383                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
384    
385                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          if (sad8 < pMB->sad16)
386                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,                                          sad8 += pMB->sad8[2]
387                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
388                                                            2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
389                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
390                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
391    
392                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          if (sad8 < pMB->sad16)
393                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,                                          sad8 += pMB->sad8[3]
394                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
395                                                            2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
396                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
397                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
398    
                                 sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];  
                         }  
   
   
399                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
400                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
401                          */                          */
402    
403                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)                                          if (sad8 < pMB->sad16)
                         {  
                                 if (((current->global_flags & XVID_INTER4V)==0) ||  
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))  
404                                  {                                  {
   
                                         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  
405                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
406                          }                        pMB->sad8[0] *= 4;
407                          else                                                  pMB->sad8[1] *= 4;
408                          {                                                  pMB->sad8[2] *= 4;
409                                  sad8 = sad16;                                                  pMB->sad8[3] *= 4;
410                                  pMB->mode = MODE_INTER;                                                  continue;
                                 pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;  
                                 pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;  
                                 pMB->pmvs[0].x = pmv16.x;  
                                 pMB->pmvs[0].y = pmv16.y;  
                         }  
411                  }                  }
412    
413  /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);                                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
         for (i = 0; i < iHcount; i++)  
                 for (j = 0; j < iWcount; j++)  
                 {  
                         dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,  
                                 pMBs[j + i * iWcount].mode,  
                                 pMBs[j + i * iWcount].dquant,  
                                 pMBs[j + i * iWcount].mvs[0],  
                                 pMBs[j + i * iWcount].mvs[1],  
                                 pMBs[j + i * iWcount].mvs[2],  
                                 pMBs[j + i * iWcount].mvs[3],  
                                 pMBs[j + i * iWcount].sad8[0],  
                                 pMBs[j + i * iWcount].sad8[1],  
                                 pMBs[j + i * iWcount].sad8[2],  
                                 pMBs[j + i * iWcount].sad8[3],  
                                 pMBs[j + i * iWcount].sad16);  
414                  }                  }
         */  
415    
         return 0;  
416  }  }
417    
418  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                  // get_pmv has to be called again, because inter4v changes predictors
419    
420  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )                          pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
421                            pMB->pmvs[0].x = pMB->mv16.x - pmv.x;   /* the other pmvs are only needed in INTER4V-mode */
422                            pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
423    
424                            }
425    
426            return 0;
427    }
428    
429  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
430    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
431      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
432    { \    { \
433      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); \
434      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; \  
435      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
436      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
437  }  }
438    
439  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
440      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); \
441      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);\
442      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
443      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
444  }  }
# Line 449  Line 448 
448      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
449    { \    { \
450      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); \
451      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);\
452      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
453      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
454  }  }
# Line 459  Line 458 
458      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
459    { \    { \
460      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); \
461      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);\
462      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
463      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
464  }  }
# Line 469  Line 468 
468      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
469    { \    { \
470      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); \
471      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);\
472      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
473      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
474  }  }
# Line 477  Line 476 
476    
477  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
478    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); \
479    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);\
480    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
481    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
482  }  }
# Line 485  Line 484 
484  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
485    { \    { \
486      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); \
487      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);\
488      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
489      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
490  }  }
# Line 495  Line 494 
494      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
495    { \    { \
496      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); \
497      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);\
498      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
499      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
500  }  }
# Line 505  Line 504 
504      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
505    { \    { \
506      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); \
507      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);\
508      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
509      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
510  }  }
# Line 515  Line 514 
514      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
515    { \    { \
516      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); \
517      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);\
518      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
519      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
520  }  }
# Line 890  Line 889 
889          VECTOR pmv[4];          VECTOR pmv[4];
890          int32_t psad[4];          int32_t psad[4];
891    
892          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
893          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
894    
895          static int32_t threshA,threshB;          static int32_t threshA,threshB;
# Line 930  Line 929 
929    
930          iFound=0;          iFound=0;
931    
 /* 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],prevMB->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;  
   
932  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
933     MinSAD=SAD     MinSAD=SAD
934     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 957  Line 936 
936     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
937  */  */
938    
   
 // Prepare for main loop  
   
939          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
940          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
941          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 987  Line 963 
963          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
964                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
965                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
966          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);
967    
968          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
969          {          {
970                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
971                    {
972                            if (!MVzero(*currMV))
973                            {
974                                    iMinSAD += MV16_00_BIAS;
975                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
976                                    iMinSAD -= MV16_00_BIAS;
977                            }
978                    }
979    
980                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
981                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 998  Line 983 
983                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
984          }          }
985    
986    
987    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
988       vector of the median.
989       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
990    */
991    
992            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
993                    iFound=2;
994    
995    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
996       Otherwise select large Diamond Search.
997    */
998    
999            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1000                    iDiamondSize=1; // halfpel!
1001            else
1002                    iDiamondSize=2; // halfpel!
1003    
1004            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1005                    iDiamondSize*=2;
1006    
1007  /*  /*
1008     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.
1009     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1010     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1011     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1012  */  */
1013    
1014  // (0,0) is always possible  // (0,0) is always possible
1015    
1016            if (!MVzero(pmv[0]))
1017          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1018    
1019  // previous frame MV is always possible  // previous frame MV is always possible
1020    
1021            if (!MVzero(prevMB->mvs[0]))
1022            if (!MVequal(prevMB->mvs[0],pmv[0]))
1023          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1024    
1025  // left neighbour, if allowed  // left neighbour, if allowed
1026          if (x != 0)  
1027            if (!MVzero(pmv[1]))
1028            if (!MVequal(pmv[1],prevMB->mvs[0]))
1029            if (!MVequal(pmv[1],pmv[0]))
1030          {          {
1031                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1032                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1033                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1034                  }                  }
1035    
1036                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1037          }          }
1038    
1039  // top neighbour, if allowed  // top neighbour, if allowed
1040          if (y != 0)          if (!MVzero(pmv[2]))
1041            if (!MVequal(pmv[2],prevMB->mvs[0]))
1042            if (!MVequal(pmv[2],pmv[0]))
1043            if (!MVequal(pmv[2],pmv[1]))
1044          {          {
1045                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1046                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1032  Line 1049 
1049                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1050    
1051  // top right neighbour, if allowed  // top right neighbour, if allowed
1052                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1053                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1054                    if (!MVequal(pmv[3],pmv[0]))
1055                    if (!MVequal(pmv[3],pmv[1]))
1056                    if (!MVequal(pmv[3],pmv[2]))
1057                  {                  {
1058                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1059                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1042  Line 1063 
1063                  }                  }
1064          }          }
1065    
1066            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1067                    iMinSAD -= MV16_00_BIAS;
1068    
1069    
1070  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1071     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.
1072  */  */
# Line 1260  Line 1285 
1285          int32_t psad[4];          int32_t psad[4];
1286          VECTOR newMV;          VECTOR newMV;
1287          VECTOR backupMV;          VECTOR backupMV;
1288            VECTOR startMV;
1289    
1290          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1291          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1292    
1293          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1294          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1295          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1296    
1297          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1298    
1299            /* Init variables */
1300            startMV.x = start_x;
1301            startMV.y = start_y;
1302    
1303  /* Get maximum range */  /* Get maximum range */
1304          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1305                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1306    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1307          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1308          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1309          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1303  Line 1331 
1331    
1332          iFound=0;          iFound=0;
1333    
 /* 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;  
   
1334  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1335     MinSAD=SAD     MinSAD=SAD
1336     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1333  Line 1341 
1341    
1342  // Prepare for main loop  // Prepare for main loop
1343    
1344          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1345    
1346          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1347                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1348                          iEdgedWidth);                          iEdgedWidth);
1349          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);
1350    
1351          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1352                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1353          {          {
1354                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1355                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1349  Line 1357 
1357                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1358          }          }
1359    
1360    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1361       vector of the median.
1362       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1363    */
1364    
1365            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1366                    iFound=2;
1367    
1368    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1369       Otherwise select large Diamond Search.
1370    */
1371    
1372            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1373                    iDiamondSize=1; // 1 halfpel!
1374            else
1375                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1376    
1377            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1378                    iDiamondSize*=2;
1379    
1380    
1381  /*  /*
1382     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.
1383     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1384     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1385     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1386  */  */
1387    
1388  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1389    
1390            if (!MVequal(pmv[0],startMV))
1391          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1392    
1393  // (0,0) is always possible  // (0,0) if needed
1394            if (!MVzero(pmv[0]))
1395            if (!MVzero(startMV))
1396          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1397    
1398  // previous frame MV is always possible  // previous frame MV if needed
1399          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1400            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1401            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1402            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1403    
1404  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1405          if (psad[1] != MV_MAX_ERROR)          {
1406                    if (MotionFlags & PMV_QUICKSTOP16)
1407                            goto PMVfast8_Terminate_without_Refine;
1408                    if (MotionFlags & PMV_EARLYSTOP16)
1409                            goto PMVfast8_Terminate_with_Refine;
1410            }
1411    
1412    
1413    // left neighbour, if allowed and needed
1414            if (!MVzero(pmv[1]))
1415            if (!MVequal(pmv[1],startMV))
1416            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1417            if (!MVequal(pmv[1],pmv[0]))
1418          {          {
1419                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1420                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1376  Line 1423 
1423                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1424          }          }
1425    
1426  // top neighbour, if allowed  // top neighbour, if allowed and needed
1427          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1428            if (!MVequal(pmv[2],startMV))
1429            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1430            if (!MVequal(pmv[2],pmv[0]))
1431            if (!MVequal(pmv[2],pmv[1]))
1432          {          {
1433                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1434                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1385  Line 1436 
1436                  }                  }
1437                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1438    
1439  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1440                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1441            if (!MVequal(pmv[3],startMV))
1442            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1443            if (!MVequal(pmv[3],pmv[0]))
1444            if (!MVequal(pmv[3],pmv[1]))
1445            if (!MVequal(pmv[3],pmv[2]))
1446                  {                  {
1447                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1448                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1396  Line 1452 
1452                  }                  }
1453          }          }
1454    
1455            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1456                    iMinSAD -= MV8_00_BIAS;
1457    
1458    
1459  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1460     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.
1461  */  */
1462    
1463          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1464          {          {
1465                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1466                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1519  Line 1579 
1579          int32_t psad[8];          int32_t psad[8];
1580    
1581          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1582          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1583          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1584          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1585    
# Line 1530  Line 1590 
1590          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1591    
1592          if (oldMBs == NULL)          if (oldMBs == NULL)
1593          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1594                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1595          }          }
1596          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1597    
# Line 1539  Line 1599 
1599          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1600                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1601    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1602          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1603          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1604            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1580  Line 1638 
1638          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1639                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1640                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1641          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);
1642    
1643  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1644          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1645                  {                  {
1646                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1647                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1594  Line 1652 
1652  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1653    
1654  // previous frame MV  // previous frame MV
1655          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1656    
1657  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1658  // 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 1650  Line 1708 
1708  */  */
1709    
1710          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1711                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1712                  {                  {
1713                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1714                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1660  Line 1718 
1718    
1719  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1720    
1721          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1722          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1723          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1724    
1725          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1726    
1727  // left neighbour  // left neighbour
1728          if (x != 0)          if (x != 0)
1729                  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);
1730    
1731  // top neighbour  // top neighbour
1732          if (y != 0)          if (y != 0)
1733                  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);
1734    
1735  // 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
1736    
1737          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1738                  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);
1739    
1740  // bottom neighbour, dito  // bottom neighbour, dito
1741          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1742                  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);
1743    
1744  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1745          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1738  Line 1796 
1796                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1797                                  x, y,                                  x, y,
1798                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1799                          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);
1800    
1801                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1802                          {                          {
# Line 1759  Line 1817 
1817    
1818  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1819    
1820          *oldMB = *pMB;          *oldMB = *prevMB;
1821    
1822          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1823          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1784  Line 1842 
1842                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1843                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1844  {  {
1845    /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
1846    
1847      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1848          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1849          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1806  Line 1866 
1866    
1867          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1868    
1869          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1870          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1871    
1872          int32_t bPredEq;          int32_t bPredEq;
# Line 1861  Line 1921 
1921          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1922                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1923                  iEdgedWidth);                  iEdgedWidth);
1924          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);
1925    
1926    
1927  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1935 
1935    
1936  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1937    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1938    
1939  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1940          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1941    
1942    // previous frame MV
1943            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1944    
1945    // left neighbour, if allowed
1946            if (psad[1] != MV_MAX_ERROR)
1947            {
1948                    if (!(MotionFlags & PMV_HALFPEL8 ))
1949                    {       pmv[1].x = EVEN(pmv[1].x);
1950                            pmv[1].y = EVEN(pmv[1].y);
1951                    }
1952                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1953            }
1954    
1955    // top neighbour, if allowed
1956            if (psad[2] != MV_MAX_ERROR)
1957            {
1958                    if (!(MotionFlags & PMV_HALFPEL8 ))
1959                    {       pmv[2].x = EVEN(pmv[2].x);
1960                            pmv[2].y = EVEN(pmv[2].y);
1961                    }
1962                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1963    
1964    // top right neighbour, if allowed
1965                    if (psad[3] != MV_MAX_ERROR)
1966                    {
1967                            if (!(MotionFlags & PMV_HALFPEL8 ))
1968                            {       pmv[3].x = EVEN(pmv[3].x);
1969                                    pmv[3].y = EVEN(pmv[3].y);
1970                            }
1971                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1972                    }
1973            }
1974    
1975    /*  // this bias is zero anyway, at the moment!
1976    
1977            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1978                    iMinSAD -= MV8_00_BIAS;
1979    
1980    */
1981    
1982  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1983     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]
1984  */  */
# Line 1894  Line 1991 
1991                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1992                  }                  }
1993    
1994  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1995    
1996          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1997    
1998          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1999                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2000    
2001  /* 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 */
2002    
2003    /* // there is no EPZS^2 for inter4v at the moment
2004    
2005            if (MotionFlags & PMV_USESQUARES8)
2006                    EPZSMainSearchPtr = Square8_MainSearch;
2007            else
2008    */
2009    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
2010                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
2011    
2012          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2013                  x, y,                  x, y,
2014                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2015                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2016                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2017    
2018    
2019          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1979  Line 2080 
2080  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2081  ***************************************************************/  ***************************************************************/
2082    
2083  /*  
2084  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2085                          MBParam * const pParam,                          MBParam * const pParam,
2086                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2001  Line 2102 
2102      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2103          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2104    
2105          int32_t i,j;          uint32_t i,j;
2106    
2107          int32_t f_sad16;          int32_t f_sad16;
2108          int32_t b_sad16;          int32_t b_sad16;
# Line 2025  Line 2126 
2126                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2127                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2128                          {                          {
2129                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2130                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2131                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2132                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2040  Line 2141 
2141                                                  i, j,                                                  i, j,
2142                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2143                                                  pParam,                                                  pParam,
2144                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2145                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2146    
2147                          // backward search                          // backward search
# Line 2049  Line 2150 
2150                                                  i, j,                                                  i, j,
2151                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2152                                                  pParam,                                                  pParam,
2153                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2154                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2155    
2156                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2069  Line 2170 
2170                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2171                          {                          {
2172                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2173                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2174                          }                          }
2175                          else                          else
2176                          {                          {
2177                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2178                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2179                          }                          }
2180    
2181                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2182                          {                          {
2183                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2184                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2185                          }                          }
2186    
2187                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2188                          {                          {
2189                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2190                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2191                          }                          }
2192    
2193                  }                  }
2194          }          }
2195  }  }
   
 */  

Legend:
Removed from v.136  
changed lines
  Added in v.175

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