[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 172, Sat May 11 15:32:59 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 56  Line 57 
57  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
58  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
59  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
60    #define MV8_00_BIAS     (0)
61    
62  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
63  #define INTER_BIAS      512  #define MV16_INTER_BIAS 512
64    
65  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
66  #define IMV16X16                        5  #define IMV16X16                        5
# Line 67  Line 69 
69  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
70  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
71    
   
72  // fast ((A)/2)*2  // fast ((A)/2)*2
73  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
74    
75    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
76    #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
77    
78  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
79                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 183  Line 186 
186    
187  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
188    
189    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
190            {     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),
191            (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),
192            (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),
193            (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),
194            (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),
195            (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),
196            (int)(36.4949+0.5)      };
197    
198    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
199    
200    
201    
202  // mv.length table  // mv.length table
203  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
204      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 218  Line 234 
234  }  }
235    
236    
237  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)
238  {  {
239          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));
240  }  }
241    
242  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)
243    
244  {  {
245      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));
246  }  }
247    
248    
# Line 256  Line 272 
272  {  {
273          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
274          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
275          MACROBLOCK * pMBs = current->mbs;          MACROBLOCK * const pMBs = current->mbs;
276          IMAGE * pCurrent = &current->image;          MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
277    
278          MACROBLOCK * prevMBs = reference->mbs;  // previous frame          const IMAGE * const pCurrent = &current->image;
279          IMAGE * pRef = &reference->image;          const IMAGE * const pRef = &reference->image;
280    
281            const VECTOR zeroMV = {0,0};
282    
283          uint32_t i, j, iIntra = 0;          int32_t x, y;
284            int32_t iIntra = 0;
285          VECTOR mv16;          VECTOR pmv;
         VECTOR pmv16;  
   
         int32_t sad8 = 0;  
         int32_t sad16;  
         int32_t deviation;  
286    
287          if (sadInit)          if (sadInit)
288                  (*sadInit)();                  (*sadInit)();
289    
290            for (y = 0; y < iHcount; y++)
291          /* 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++)  
292                  {                  {
293                          pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
294                          pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];  
295                          pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];                          pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
296                          pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];                                           x, y, current->motion_flags, current->quant, current->fcode,
297                  }                                           pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
   
         /*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);  
298                  }                  }
         */  
299    
300          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
301          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
302                  {                  {
303                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
                         MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];  
   
                         sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                          j, i, current->motion_flags, current->quant, current->fcode,  
                                          pParam, pMBs, prevMBs, &mv16, &pmv16);  
                         pMB->sad16=sad16;  
   
304    
305                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
306                             if (dev_intra < sad_inter - 2 * nb) use_intra                          {
307                          */                                  int32_t deviation;
308                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
309                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                                                           pParam->edged_width);
310    
311                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
312                          {                          {
313                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
314                                  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]
315                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
316                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
317                                  pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;                                                               = pMB->sad8[2] = pMB->sad8[3] = 0;
318    
319                                  iIntra++;                                  iIntra++;
320                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 340  Line 322 
322    
323                                  continue;                                  continue;
324                          }                          }
325                            }
326    
327                          if (current->global_flags & XVID_INTER4V)                          if ( (current->global_flags & XVID_INTER4V)
328                          {                                  && (!(current->global_flags & XVID_LUMIMASKING)
329                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                          || pMB->dquant == NO_CHANGE) )
330                                                         2 * j, 2 * i, mv16.x, mv16.y,                          {
331                                    int32_t sad8 = 129; //IMV16X16 * current->quant;
332    
333                                    if (sad8 < pMB->sad16)
334                                    sad8 += pMB->sad8[0]
335                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
336                                                           2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
337                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
338                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
339    
340                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
341                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,                                  sad8 += pMB->sad8[1]
342                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
343                                   2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
344                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
345                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
346    
347                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
348                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,                                  sad8 += pMB->sad8[2]
349                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
350                                                    2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
351                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
352                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
353    
354                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  if (sad8 < pMB->sad16)
355                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,                                  sad8 += pMB->sad8[3]
356                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
357                                                    2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
358                                                             current->motion_flags, current->quant, current->fcode,                                                             current->motion_flags, current->quant, current->fcode,
359                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                         pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
360    
                                 sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];  
                         }  
   
   
361                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
362                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
363                          */                          */
364    
365                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)                                  if (sad8 < pMB->sad16)
366                          {                          {
                                 if (((current->global_flags & XVID_INTER4V)==0) ||  
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * current->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  
367                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
368                          }                 pMB->sad8[0] *= 4;
369                          else                                          pMB->sad8[1] *= 4;
370                          {                                          pMB->sad8[2] *= 4;
371                                  sad8 = sad16;                                          pMB->sad8[3] *= 4;
372                                  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;  
373                          }                          }
374                  }                  }
375    
376  /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);                          pMB->mode = MODE_INTER;
377          for (i = 0; i < iHcount; i++)                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
378                  for (j = 0; j < iWcount; j++)           pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
379                  {  
380                          dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,                          if (current->global_flags & XVID_INTER4V)
381                                  pMBs[j + i * iWcount].mode,                          {       pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
382                                  pMBs[j + i * iWcount].dquant,                                  // get_pmv has to be called again. inter4v changes predictors
                                 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);  
                 }  
         */  
383    
384                                    pMB->pmvs[0].x = pMB->mv16.x - pmv.x;
385                                    pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
386                            }
387                    }
388          return 0;          return 0;
389  }  }
390    
 #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )  
   
 #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )  
   
   
391  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
392    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
393      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
394    { \    { \
395      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); \
396      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; \  
397      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
398      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
399  }  }
400    
401  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
402      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); \
403      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);\
404      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
405      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
406  }  }
# Line 449  Line 410 
410      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
411    { \    { \
412      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); \
413      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);\
414      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
415      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
416  }  }
# Line 459  Line 420 
420      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
421    { \    { \
422      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); \
423      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);\
424      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
425      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
426  }  }
# Line 469  Line 430 
430      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
431    { \    { \
432      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); \
433      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);\
434      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
435      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
436  }  }
# Line 477  Line 438 
438    
439  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
440    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); \
441    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);\
442    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
443    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
444  }  }
# Line 485  Line 446 
446  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
447    { \    { \
448      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); \
449      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);\
450      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
451      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
452  }  }
# Line 495  Line 456 
456      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
457    { \    { \
458      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); \
459      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);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
462  }  }
# Line 505  Line 466 
466      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
467    { \    { \
468      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); \
469      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);\
470      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
471      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
472  }  }
# Line 515  Line 476 
476      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
477    { \    { \
478      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); \
479      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);\
480      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
481      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
482  }  }
# Line 890  Line 851 
851          VECTOR pmv[4];          VECTOR pmv[4];
852          int32_t psad[4];          int32_t psad[4];
853    
854          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
855          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
856    
857          static int32_t threshA,threshB;          static int32_t threshA,threshB;
# Line 930  Line 891 
891    
892          iFound=0;          iFound=0;
893    
 /* 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;  
   
894  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
895     MinSAD=SAD     MinSAD=SAD
896     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 957  Line 898 
898     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
899  */  */
900    
   
 // Prepare for main loop  
   
901          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
902          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
903          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 987  Line 925 
925          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
926                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
927                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
928          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);
929    
930          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) ) )
931          {          {
932                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
933                    {
934                            if (!MVzero(*currMV))
935                            {
936                                    iMinSAD += MV16_00_BIAS;
937                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
938                                    iMinSAD -= MV16_00_BIAS;
939                            }
940                    }
941    
942                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
943                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 998  Line 945 
945                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
946          }          }
947    
948    
949    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
950       vector of the median.
951       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
952    */
953    
954            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
955                    iFound=2;
956    
957    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
958       Otherwise select large Diamond Search.
959    */
960    
961            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
962                    iDiamondSize=1; // halfpel!
963            else
964                    iDiamondSize=2; // halfpel!
965    
966            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
967                    iDiamondSize*=2;
968    
969  /*  /*
970     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.
971     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
972     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
973     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
974  */  */
975    
976  // (0,0) is always possible  // (0,0) is always possible
977    
978            if (!MVzero(pmv[0]))
979          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
980    
981  // previous frame MV is always possible  // previous frame MV is always possible
982    
983            if (!MVzero(prevMB->mvs[0]))
984            if (!MVequal(prevMB->mvs[0],pmv[0]))
985          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
986    
987  // left neighbour, if allowed  // left neighbour, if allowed
988          if (x != 0)  
989            if (!MVzero(pmv[1]))
990            if (!MVequal(pmv[1],prevMB->mvs[0]))
991            if (!MVequal(pmv[1],pmv[0]))
992          {          {
993                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
994                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
995                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
996                  }                  }
997    
998                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
999          }          }
1000    
1001  // top neighbour, if allowed  // top neighbour, if allowed
1002          if (y != 0)          if (!MVzero(pmv[2]))
1003            if (!MVequal(pmv[2],prevMB->mvs[0]))
1004            if (!MVequal(pmv[2],pmv[0]))
1005            if (!MVequal(pmv[2],pmv[1]))
1006          {          {
1007                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1008                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1032  Line 1011 
1011                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1012    
1013  // top right neighbour, if allowed  // top right neighbour, if allowed
1014                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1015                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1016                    if (!MVequal(pmv[3],pmv[0]))
1017                    if (!MVequal(pmv[3],pmv[1]))
1018                    if (!MVequal(pmv[3],pmv[2]))
1019                  {                  {
1020                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1021                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1042  Line 1025 
1025                  }                  }
1026          }          }
1027    
1028            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1029                    iMinSAD -= MV16_00_BIAS;
1030    
1031    
1032  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1033     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.
1034  */  */
# Line 1260  Line 1247 
1247          int32_t psad[4];          int32_t psad[4];
1248          VECTOR newMV;          VECTOR newMV;
1249          VECTOR backupMV;          VECTOR backupMV;
1250            VECTOR startMV;
1251    
1252          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1253          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1254    
1255          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1256          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1257          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1258    
1259          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1260    
1261            /* Init variables */
1262            startMV.x = start_x;
1263            startMV.y = start_y;
1264    
1265  /* Get maximum range */  /* Get maximum range */
1266          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1267                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1268    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1269          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1270          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1271          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1303  Line 1293 
1293    
1294          iFound=0;          iFound=0;
1295    
 /* 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;  
   
1296  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1297     MinSAD=SAD     MinSAD=SAD
1298     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1333  Line 1303 
1303    
1304  // Prepare for main loop  // Prepare for main loop
1305    
1306          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1307    
1308          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1309                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1310                          iEdgedWidth);                          iEdgedWidth);
1311          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);
1312    
1313          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1314                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1315          {          {
1316                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1317                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1349  Line 1319 
1319                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1320          }          }
1321    
1322    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1323       vector of the median.
1324       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1325    */
1326    
1327            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1328                    iFound=2;
1329    
1330    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1331       Otherwise select large Diamond Search.
1332    */
1333    
1334            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1335                    iDiamondSize=1; // 1 halfpel!
1336            else
1337                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1338    
1339            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1340                    iDiamondSize*=2;
1341    
1342    
1343  /*  /*
1344     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.
1345     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1346     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1347     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1348  */  */
1349    
1350  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1351    
1352            if (!MVequal(pmv[0],startMV))
1353          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1354    
1355  // (0,0) is always possible  // (0,0) if needed
1356            if (!MVzero(pmv[0]))
1357            if (!MVzero(startMV))
1358          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1359    
1360  // previous frame MV is always possible  // previous frame MV if needed
1361          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1362            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1363            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1364            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1365    
1366  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1367          if (psad[1] != MV_MAX_ERROR)          {
1368                    if (MotionFlags & PMV_QUICKSTOP16)
1369                            goto PMVfast8_Terminate_without_Refine;
1370                    if (MotionFlags & PMV_EARLYSTOP16)
1371                            goto PMVfast8_Terminate_with_Refine;
1372            }
1373    
1374    
1375    // left neighbour, if allowed and needed
1376            if (!MVzero(pmv[1]))
1377            if (!MVequal(pmv[1],startMV))
1378            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1379            if (!MVequal(pmv[1],pmv[0]))
1380          {          {
1381                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1382                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1376  Line 1385 
1385                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1386          }          }
1387    
1388  // top neighbour, if allowed  // top neighbour, if allowed and needed
1389          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1390            if (!MVequal(pmv[2],startMV))
1391            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1392            if (!MVequal(pmv[2],pmv[0]))
1393            if (!MVequal(pmv[2],pmv[1]))
1394          {          {
1395                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1396                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1385  Line 1398 
1398                  }                  }
1399                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1400    
1401  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1402                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1403            if (!MVequal(pmv[3],startMV))
1404            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1405            if (!MVequal(pmv[3],pmv[0]))
1406            if (!MVequal(pmv[3],pmv[1]))
1407            if (!MVequal(pmv[3],pmv[2]))
1408                  {                  {
1409                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1410                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1396  Line 1414 
1414                  }                  }
1415          }          }
1416    
1417            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1418                    iMinSAD -= MV8_00_BIAS;
1419    
1420    
1421  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1422     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.
1423  */  */
1424    
1425          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]) ) )
1426          {          {
1427                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1428                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1519  Line 1541 
1541          int32_t psad[8];          int32_t psad[8];
1542    
1543          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1544          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1545          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1546          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1547    
# Line 1530  Line 1552 
1552          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1553    
1554          if (oldMBs == NULL)          if (oldMBs == NULL)
1555          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1556                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1557          }          }
1558          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1559    
# Line 1539  Line 1561 
1561          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1562                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1563    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1564          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1565          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1566            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1580  Line 1600 
1600          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1601                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1602                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1603          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);
1604    
1605  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1606          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) ) )
1607                  {                  {
1608                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1609                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1594  Line 1614 
1614  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1615    
1616  // previous frame MV  // previous frame MV
1617          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1618    
1619  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1620  // 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 1670 
1670  */  */
1671    
1672          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1673                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1674                  {                  {
1675                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1676                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1660  Line 1680 
1680    
1681  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1682    
1683          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1684          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1685          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1686    
1687          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1688    
1689  // left neighbour  // left neighbour
1690          if (x != 0)          if (x != 0)
1691                  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);
1692    
1693  // top neighbour  // top neighbour
1694          if (y != 0)          if (y != 0)
1695                  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);
1696    
1697  // 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
1698    
1699          if ((uint32_t)x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1700                  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);
1701    
1702  // bottom neighbour, dito  // bottom neighbour, dito
1703          if ((uint32_t)y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1704                  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);
1705    
1706  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1707          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1738  Line 1758 
1758                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1759                                  x, y,                                  x, y,
1760                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1761                          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);
1762    
1763                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1764                          {                          {
# Line 1759  Line 1779 
1779    
1780  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1781    
1782          *oldMB = *pMB;          *oldMB = *prevMB;
1783    
1784          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1785          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1784  Line 1804 
1804                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1805                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1806  {  {
1807    /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
1808    
1809      const uint32_t iWcount = pParam->mb_width;      const uint32_t iWcount = pParam->mb_width;
1810          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1811          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1806  Line 1828 
1828    
1829          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1830    
1831          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1832          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1833    
1834          int32_t bPredEq;          int32_t bPredEq;
# Line 1861  Line 1883 
1883          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1884                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1885                  iEdgedWidth);                  iEdgedWidth);
1886          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);
1887    
1888    
1889  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1897 
1897    
1898  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1899    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1900    
1901  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1902          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1903    
1904    // previous frame MV
1905            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1906    
1907    // left neighbour, if allowed
1908            if (psad[1] != MV_MAX_ERROR)
1909            {
1910                    if (!(MotionFlags & PMV_HALFPEL8 ))
1911                    {       pmv[1].x = EVEN(pmv[1].x);
1912                            pmv[1].y = EVEN(pmv[1].y);
1913                    }
1914                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1915            }
1916    
1917    // top neighbour, if allowed
1918            if (psad[2] != MV_MAX_ERROR)
1919            {
1920                    if (!(MotionFlags & PMV_HALFPEL8 ))
1921                    {       pmv[2].x = EVEN(pmv[2].x);
1922                            pmv[2].y = EVEN(pmv[2].y);
1923                    }
1924                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1925    
1926    // top right neighbour, if allowed
1927                    if (psad[3] != MV_MAX_ERROR)
1928                    {
1929                            if (!(MotionFlags & PMV_HALFPEL8 ))
1930                            {       pmv[3].x = EVEN(pmv[3].x);
1931                                    pmv[3].y = EVEN(pmv[3].y);
1932                            }
1933                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1934                    }
1935            }
1936    
1937    /*  // this bias is zero anyway, at the moment!
1938    
1939            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1940                    iMinSAD -= MV8_00_BIAS;
1941    
1942    */
1943    
1944  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1945     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]
1946  */  */
# Line 1894  Line 1953 
1953                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1954                  }                  }
1955    
1956  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1957    
1958          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1959    
1960          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1961                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1962    
1963  /* 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 */
1964    
1965    /* // there is no EPZS^2 for inter4v at the moment
1966    
1967            if (MotionFlags & PMV_USESQUARES8)
1968                    EPZSMainSearchPtr = Square8_MainSearch;
1969            else
1970    */
1971    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1972                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1973    
1974          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1975                  x, y,                  x, y,
1976                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1977                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1978                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1979    
1980    
1981          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1979  Line 2042 
2042  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2043  ***************************************************************/  ***************************************************************/
2044    
2045  /*  
2046  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2047                          MBParam * const pParam,                          MBParam * const pParam,
2048                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2001  Line 2064 
2064      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2065          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2066    
2067          int32_t i,j;          uint32_t i,j;
2068    
2069          int32_t f_sad16;          int32_t f_sad16;
2070          int32_t b_sad16;          int32_t b_sad16;
# Line 2025  Line 2088 
2088                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2089                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2090                          {                          {
2091                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2092                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2093                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2094                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2040  Line 2103 
2103                                                  i, j,                                                  i, j,
2104                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2105                                                  pParam,                                                  pParam,
2106                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2107                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2108    
2109                          // backward search                          // backward search
# Line 2049  Line 2112 
2112                                                  i, j,                                                  i, j,
2113                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2114                                                  pParam,                                                  pParam,
2115                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2116                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2117    
2118                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2069  Line 2132 
2132                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2133                          {                          {
2134                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2135                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2136                          }                          }
2137                          else                          else
2138                          {                          {
2139                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2140                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2141                          }                          }
2142    
2143                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2144                          {                          {
2145                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2146                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2147                          }                          }
2148    
2149                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2150                          {                          {
2151                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2152                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2153                          }                          }
2154    
2155                  }                  }
2156          }          }
2157  }  }
   
 */  

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

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