[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 141, Thu Apr 25 23:24:59 2002 UTC revision 181, Wed May 22 12:42:25 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)  #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 68  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 270  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];  
   
                         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;  
298    
299                            pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                                             x, y, current->motion_flags, current->quant, current->fcode,
301                                             pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
302    
                         /* decide: MODE_INTER or MODE_INTRA  
                            if (dev_intra < sad_inter - 2 * nb) use_intra  
                         */  
303    
304                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
305                            {
306                                    int32_t deviation;
307                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
308                                                             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 354  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                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  int32_t neigh=0;
349                                                         2 * j, 2 * i, mv16.x, mv16.y,  
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                                            int32_t sad8 = IMV16X16 * current->quant;
370    
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) \
# Line 794  Line 781 
781          return iMinSAD;          return iMinSAD;
782  }  }
783    
784    int32_t AdvDiamond16_MainSearch(
785            const uint8_t * const pRef,
786            const uint8_t * const pRefH,
787            const uint8_t * const pRefV,
788            const uint8_t * const pRefHV,
789            const uint8_t * const cur,
790            const int x, const int y,
791            int32_t startx, int32_t starty,
792            int32_t iMinSAD,
793            VECTOR * const currMV,
794            const VECTOR * const pmv,
795            const int32_t min_dx, const int32_t max_dx,
796            const int32_t min_dy, const int32_t max_dy,
797            const int32_t iEdgedWidth,
798            const int32_t iDiamondSize,
799            const int32_t iFcode,
800            const int32_t iQuant,
801            int iDirection)
802    {
803    
804            int32_t iSAD;
805    
806    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
807    
808            if (iDirection)
809            {
810                    CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty);
811                    CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty);
812                    CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize);
813                    CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize);
814            }
815            else
816            {
817                    int bDirection = 1+2+4+8;
818                    do
819                    {
820                            iDirection = 0;
821                            if (bDirection&1) //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
822                                    CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
823    
824                            if (bDirection&2)
825                                    CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
826    
827                            if (bDirection&4)
828                                    CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
829    
830                            if (bDirection&8)
831                                    CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
832    
833                            /* now we're doing diagonal checks near our candidate */
834    
835                            if (iDirection) //checking if anything found
836                            {
837                                    bDirection = iDirection;
838                                    iDirection = 0;
839                                    startx=currMV->x; starty=currMV->y;
840                                    if (bDirection & 3) //our candidate is left or right
841                                    {
842                                            CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
843                                            CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
844                                    }
845                                    else // what remains here is up or down
846                                    {
847                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
848                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
849                                    }
850    
851                                    if (iDirection)
852                                    {       bDirection+=iDirection;
853                                            startx=currMV->x; starty=currMV->y;
854                                    }
855                            }
856                            else //about to quit, eh? not so fast....
857                            {
858                                    switch (bDirection)
859                                    {
860                                    case 2:
861                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
862                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
863                                            break;
864                                    case 1:
865                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
866                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
867                                            break;
868                                    case 2+4:
869                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
870                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
871                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
872                                            break;
873                                    case 4:
874                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
875                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
876                                            break;
877                                    case 8:
878                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
879                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
880                                            break;
881                                    case 1+4:
882                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
883                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
884                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
885                                            break;
886                                    case 2+8:
887                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
888                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
889                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
890                                            break;
891                                    case 1+8:
892                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
893                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
894                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
895                                            break;
896                                    default: //1+2+4+8 == we didn't find anything at all
897                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
898                                            CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
899                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
900                                            CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
901                                            break;
902                                    }
903                                    if (!iDirection) break; //ok, the end. really
904                                    else
905                                    {       bDirection=iDirection;
906                                            startx=currMV->x; starty=currMV->y;
907                                    }
908                            }
909                    }
910                    while (1); //forever
911            }
912            return iMinSAD;
913    }
914    
915    int32_t AdvDiamond8_MainSearch(
916            const uint8_t * const pRef,
917            const uint8_t * const pRefH,
918            const uint8_t * const pRefV,
919            const uint8_t * const pRefHV,
920            const uint8_t * const cur,
921            const int x, const int y,
922            int32_t startx, int32_t starty,
923            int32_t iMinSAD,
924            VECTOR * const currMV,
925            const VECTOR * const pmv,
926            const int32_t min_dx, const int32_t max_dx,
927            const int32_t min_dy, const int32_t max_dy,
928            const int32_t iEdgedWidth,
929            const int32_t iDiamondSize,
930            const int32_t iFcode,
931            const int32_t iQuant,
932            int iDirection)
933    {
934    
935            int32_t iSAD;
936    
937    /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
938    
939            if (iDirection)
940            {
941                    CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty);
942                    CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty);
943                    CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize);
944                    CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize);
945            }
946            else
947            {
948                    int bDirection = 1+2+4+8;
949                    do
950                    {
951                            iDirection = 0;
952                            if (bDirection&1) //we only want to check left if we came from the right (our last motion was to the left, up-left or down-left)
953                                    CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1);
954    
955                            if (bDirection&2)
956                                    CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2);
957    
958                            if (bDirection&4)
959                                    CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4);
960    
961                            if (bDirection&8)
962                                    CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8);
963    
964                            /* now we're doing diagonal checks near our candidate */
965    
966                            if (iDirection) //checking if anything found
967                            {
968                                    bDirection = iDirection;
969                                    iDirection = 0;
970                                    startx=currMV->x; starty=currMV->y;
971                                    if (bDirection & 3) //our candidate is left or right
972                                    {
973                                            CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8);
974                                            CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4);
975                                    }
976                                    else // what remains here is up or down
977                                    {
978                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2);
979                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1);
980                                    }
981    
982                                    if (iDirection)
983                                    {       bDirection+=iDirection;
984                                            startx=currMV->x; starty=currMV->y;
985                                    }
986                            }
987                            else //about to quit, eh? not so fast....
988                            {
989                                    switch (bDirection)
990                                    {
991                                    case 2:
992                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
993                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
994                                            break;
995                                    case 1:
996                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
997                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
998                                            break;
999                                    case 2+4:
1000                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1001                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1002                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1003                                            break;
1004                                    case 4:
1005                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1006                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1007                                            break;
1008                                    case 8:
1009                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1010                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1011                                            break;
1012                                    case 1+4:
1013                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1014                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1015                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1016                                            break;
1017                                    case 2+8:
1018                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1019                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1020                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1021                                            break;
1022                                    case 1+8:
1023                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1024                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1025                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1026                                            break;
1027                                    default: //1+2+4+8 == we didn't find anything at all
1028                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4);
1029                                            CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8);
1030                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4);
1031                                            CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8);
1032                                            break;
1033                                    }
1034                                    if (!(iDirection)) break; //ok, the end. really
1035                                    else
1036                                    {       bDirection=iDirection;
1037                                            startx=currMV->x; starty=currMV->y;
1038                                    }
1039                            }
1040                    }
1041                    while (1); //forever
1042            }
1043            return iMinSAD;
1044    }
1045    
1046    
1047  int32_t Full8_MainSearch(  int32_t Full8_MainSearch(
1048                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
1049                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 902  Line 1152 
1152          VECTOR pmv[4];          VECTOR pmv[4];
1153          int32_t psad[4];          int32_t psad[4];
1154    
1155          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;          MainSearch16FuncPtr MainSearchPtr;
1156    
1157    //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1158          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1159    
1160          static int32_t threshA,threshB;          static int32_t threshA,threshB;
# Line 942  Line 1194 
1194    
1195          iFound=0;          iFound=0;
1196    
 /* 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;  
   
1197  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1198     MinSAD=SAD     MinSAD=SAD
1199     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 969  Line 1201 
1201     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
1202  */  */
1203    
   
 // Prepare for main loop  
   
1204          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
1205          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1206          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 1003  Line 1232 
1232    
1233          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) ) )
1234          {          {
1235                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
1236                    {
1237                            if (!MVzero(*currMV))
1238                            {
1239                                    iMinSAD += MV16_00_BIAS;
1240                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
1241                                    iMinSAD -= MV16_00_BIAS;
1242                            }
1243                    }
1244    
1245                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1246                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1010  Line 1248 
1248                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
1249          }          }
1250    
1251    
1252    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1253       vector of the median.
1254       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1255    */
1256    
1257            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
1258                    iFound=2;
1259    
1260    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1261       Otherwise select large Diamond Search.
1262    */
1263    
1264            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1265                    iDiamondSize=1; // halfpel!
1266            else
1267                    iDiamondSize=2; // halfpel!
1268    
1269            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1270                    iDiamondSize*=2;
1271    
1272  /*  /*
1273     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.
1274     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
# Line 1019  Line 1278 
1278    
1279  // (0,0) is always possible  // (0,0) is always possible
1280    
1281            if (!MVzero(pmv[0]))
1282          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1283    
1284  // previous frame MV is always possible  // previous frame MV is always possible
1285    
1286            if (!MVzero(prevMB->mvs[0]))
1287            if (!MVequal(prevMB->mvs[0],pmv[0]))
1288          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1289    
1290  // left neighbour, if allowed  // left neighbour, if allowed
1291          if (x != 0)  
1292            if (!MVzero(pmv[1]))
1293            if (!MVequal(pmv[1],prevMB->mvs[0]))
1294            if (!MVequal(pmv[1],pmv[0]))
1295          {          {
1296                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1297                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1298                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1299                  }                  }
1300    
1301                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1302          }          }
1303    
1304  // top neighbour, if allowed  // top neighbour, if allowed
1305          if (y != 0)          if (!MVzero(pmv[2]))
1306            if (!MVequal(pmv[2],prevMB->mvs[0]))
1307            if (!MVequal(pmv[2],pmv[0]))
1308            if (!MVequal(pmv[2],pmv[1]))
1309          {          {
1310                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1311                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1044  Line 1314 
1314                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1315    
1316  // top right neighbour, if allowed  // top right neighbour, if allowed
1317                  if ((uint32_t)x != (iWcount-1))                  if (!MVzero(pmv[3]))
1318                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1319                    if (!MVequal(pmv[3],pmv[0]))
1320                    if (!MVequal(pmv[3],pmv[1]))
1321                    if (!MVequal(pmv[3],pmv[2]))
1322                  {                  {
1323                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1324                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1081  Line 1355 
1355     Refine by using small diamond and goto step 10.     Refine by using small diamond and goto step 10.
1356  */  */
1357    
1358            if (MotionFlags & PMV_USESQUARES16)
1359                    MainSearchPtr = Square16_MainSearch;
1360            else
1361                    if (MotionFlags & PMV_ADVANCEDDIAMOND16)
1362                            MainSearchPtr = AdvDiamond16_MainSearch;
1363                    else
1364                            MainSearchPtr = Diamond16_MainSearch;
1365    
1366          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1367    
1368  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1369          iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1370                                            x, y,                                            x, y,
1371                                            currMV->x, currMV->y, iMinSAD, &newMV,                                            currMV->x, currMV->y, iMinSAD, &newMV,
1372                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1100  Line 1382 
1382  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1383    
1384                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1385                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1386                                                            x, y,                                                            x, y,
1387                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1388                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1113  Line 1395 
1395                  }                  }
1396    
1397                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1398                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1399                                                            x, y,                                                            x, y,
1400                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1401                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1276  Line 1558 
1558          int32_t psad[4];          int32_t psad[4];
1559          VECTOR newMV;          VECTOR newMV;
1560          VECTOR backupMV;          VECTOR backupMV;
1561            VECTOR startMV;
1562    
1563          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1564          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1565    
1566          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1567          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1568          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1569    
1570          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1571    
1572            MainSearch8FuncPtr MainSearchPtr;
1573    
1574            /* Init variables */
1575            startMV.x = start_x;
1576            startMV.y = start_y;
1577    
1578  /* Get maximum range */  /* Get maximum range */
1579          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
# Line 1317  Line 1606 
1606    
1607          iFound=0;          iFound=0;
1608    
 /* 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[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;  
   
1609  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1610     MinSAD=SAD     MinSAD=SAD
1611     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1347  Line 1616 
1616    
1617  // Prepare for main loop  // Prepare for main loop
1618    
1619          currMV->x=start_x;              /* start with mv16 */  //      if (MotionFlags & PMV_USESQUARES8)
1620          currMV->y=start_y;  //              MainSearchPtr = Square8_MainSearch;
1621    //      else
1622    
1623            if (MotionFlags & PMV_ADVANCEDDIAMOND8)
1624                    MainSearchPtr = AdvDiamond8_MainSearch;
1625            else
1626                    MainSearchPtr = Diamond8_MainSearch;
1627    
1628    
1629            *currMV = startMV;
1630    
1631          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1632                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1633                          iEdgedWidth);                          iEdgedWidth);
1634          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);
1635    
1636          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1637                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1638          {          {
1639                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1640                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1363  Line 1642 
1642                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1643          }          }
1644    
1645    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1646       vector of the median.
1647       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1648    */
1649    
1650            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1651                    iFound=2;
1652    
1653    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1654       Otherwise select large Diamond Search.
1655    */
1656    
1657            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1658                    iDiamondSize=1; // 1 halfpel!
1659            else
1660                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1661    
1662            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1663                    iDiamondSize*=2;
1664    
1665    
1666  /*  /*
1667     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.
# Line 1371  Line 1670 
1670     If MV is (0,0) subtract offset.     If MV is (0,0) subtract offset.
1671  */  */
1672    
1673  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1674    
1675            if (!MVequal(pmv[0],startMV))
1676          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1677    
1678  // (0,0) is always possible  // (0,0) if needed
1679            if (!MVzero(pmv[0]))
1680            if (!MVzero(startMV))
1681          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1682    
1683  // previous frame MV is always possible  // previous frame MV if needed
1684            if (!MVzero(prevMB->mvs[iSubBlock]))
1685            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1686            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1687          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1688    
1689  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1690          if (psad[1] != MV_MAX_ERROR)          {
1691                    if (MotionFlags & PMV_QUICKSTOP16)
1692                            goto PMVfast8_Terminate_without_Refine;
1693                    if (MotionFlags & PMV_EARLYSTOP16)
1694                            goto PMVfast8_Terminate_with_Refine;
1695            }
1696    
1697    
1698    // left neighbour, if allowed and needed
1699            if (!MVzero(pmv[1]))
1700            if (!MVequal(pmv[1],startMV))
1701            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1702            if (!MVequal(pmv[1],pmv[0]))
1703          {          {
1704                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1705                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1390  Line 1708 
1708                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1709          }          }
1710    
1711  // top neighbour, if allowed  // top neighbour, if allowed and needed
1712          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1713            if (!MVequal(pmv[2],startMV))
1714            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1715            if (!MVequal(pmv[2],pmv[0]))
1716            if (!MVequal(pmv[2],pmv[1]))
1717          {          {
1718                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1719                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1399  Line 1721 
1721                  }                  }
1722                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1723    
1724  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1725                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1726            if (!MVequal(pmv[3],startMV))
1727            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1728            if (!MVequal(pmv[3],pmv[0]))
1729            if (!MVequal(pmv[3],pmv[1]))
1730            if (!MVequal(pmv[3],pmv[2]))
1731                  {                  {
1732                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1733                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1439  Line 1766 
1766          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1767    
1768  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
1769          iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1770                                           x, y,                                           x, y,
1771                                           currMV->x, currMV->y, iMinSAD, &newMV,                                           currMV->x, currMV->y, iMinSAD, &newMV,
1772                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                           pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1455  Line 1782 
1782  /* extended: search (up to) two more times: orignal prediction and (0,0) */  /* extended: search (up to) two more times: orignal prediction and (0,0) */
1783    
1784                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
1785                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1786                                                            x, y,                                                            x, y,
1787                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                                            pmv[0].x, pmv[0].y, iMinSAD, &newMV,
1788                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1468  Line 1795 
1795                  }                  }
1796    
1797                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
1798                  {       iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur,                  {       iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1799                                                            x, y,                                                            x, y,
1800                                                            0, 0, iMinSAD, &newMV,                                                            0, 0, iMinSAD, &newMV,
1801                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);                                                            pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound);
# Line 1537  Line 1864 
1864          int32_t psad[8];          int32_t psad[8];
1865    
1866          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1867          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1868          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;          const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1869          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1870    
# Line 1545  Line 1872 
1872          int32_t bPredEq;          int32_t bPredEq;
1873          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
1874    
1875          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr MainSearchPtr;
1876    
1877          if (oldMBs == NULL)          if (oldMBs == NULL)
1878          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
# Line 1714  Line 2041 
2041    
2042  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */
2043    
2044          if (MotionFlags & PMV_USESQUARES16)          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
                 EPZSMainSearchPtr = Square16_MainSearch;  
         else  
                 EPZSMainSearchPtr = Diamond16_MainSearch;  
   
         iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,  
2045                          x, y,                          x, y,
2046                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                          currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2047                          2, iFcode, iQuant, 0);                          2, iFcode, iQuant, 0);
# Line 1737  Line 2059 
2059    
2060                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2061                  {                  {
2062                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2063                                  x, y,                                  x, y,
2064                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,                                  pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2065                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
# Line 1751  Line 2073 
2073    
2074                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2075                  {                  {
2076                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2077                                  x, y,                                  x, y,
2078                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2079                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
# Line 1824  Line 2146 
2146    
2147          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
2148    
2149          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
2150          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
2151    
2152          int32_t bPredEq;          int32_t bPredEq;
2153          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
2154    
2155          MainSearch8FuncPtr EPZSMainSearchPtr;          MainSearch8FuncPtr MainSearchPtr;
2156    
2157  /* Get maximum range */  /* Get maximum range */
2158          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
# Line 1961  Line 2283 
2283  /* // there is no EPZS^2 for inter4v at the moment  /* // there is no EPZS^2 for inter4v at the moment
2284    
2285          if (MotionFlags & PMV_USESQUARES8)          if (MotionFlags & PMV_USESQUARES8)
2286                  EPZSMainSearchPtr = Square8_MainSearch;                  MainSearchPtr = Square8_MainSearch;
2287          else          else
2288  */  */
2289    
2290          EPZSMainSearchPtr = Diamond8_MainSearch;  //      if (MotionFlags & PMV_USESQUARES8)
2291    //              MainSearchPtr = Square8_MainSearch;
2292    //      else
2293    
2294            if (MotionFlags & PMV_ADVANCEDDIAMOND8)
2295                    MainSearchPtr = AdvDiamond8_MainSearch;
2296            else
2297                    MainSearchPtr = Diamond8_MainSearch;
2298    
2299          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2300                  x, y,                  x, y,
2301                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2302                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
# Line 1986  Line 2315 
2315    
2316                  if (!(MVequal(pmv[0],backupMV)) )                  if (!(MVequal(pmv[0],backupMV)) )
2317                  {                  {
2318                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2319                                  x, y,                                  x, y,
2320                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,                          pmv[0].x, pmv[0].y, iMinSAD, &newMV,
2321                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 2000  Line 2329 
2329    
2330                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )                  if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )
2331                  {                  {
2332                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2333                                  x, y,                                  x, y,
2334                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
2335                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);
# Line 2038  Line 2367 
2367  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)  // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2368  ***************************************************************/  ***************************************************************/
2369    
2370  /*  
2371  void MotionEstimationBVOP(  void MotionEstimationBVOP(
2372                          MBParam * const pParam,                          MBParam * const pParam,
2373                          FRAMEINFO * const frame,                          FRAMEINFO * const frame,
# Line 2060  Line 2389 
2389      const uint32_t mb_height = pParam->mb_height;      const uint32_t mb_height = pParam->mb_height;
2390          const int32_t edged_width = pParam->edged_width;          const int32_t edged_width = pParam->edged_width;
2391    
2392          int32_t i,j;          uint32_t i,j;
2393    
2394          int32_t f_sad16;          int32_t f_sad16;
2395          int32_t b_sad16;          int32_t b_sad16;
# Line 2084  Line 2413 
2413                                  && b_mb->mvs[0].x == 0                                  && b_mb->mvs[0].x == 0
2414                                  && b_mb->mvs[0].y == 0)                                  && b_mb->mvs[0].y == 0)
2415                          {                          {
2416                                  mb->mode = MB_IGNORE;                                  mb->mode = MODE_NOT_CODED;
2417                                  mb->mvs[0].x = 0;                                  mb->mvs[0].x = 0;
2418                                  mb->mvs[0].y = 0;                                  mb->mvs[0].y = 0;
2419                                  mb->b_mvs[0].x = 0;                                  mb->b_mvs[0].x = 0;
# Line 2099  Line 2428 
2428                                                  i, j,                                                  i, j,
2429                                                  frame->motion_flags,  frame->quant, frame->fcode,                                                  frame->motion_flags,  frame->quant, frame->fcode,
2430                                                  pParam,                                                  pParam,
2431                                                  f_mbs,                                                  f_mbs, f_mbs /* todo */,
2432                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv                                                  &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2433    
2434                          // backward search                          // backward search
# Line 2108  Line 2437 
2437                                                  i, j,                                                  i, j,
2438                                                  frame->motion_flags,  frame->quant, frame->bcode,                                                  frame->motion_flags,  frame->quant, frame->bcode,
2439                                                  pParam,                                                  pParam,
2440                                                  b_mbs,                                                  b_mbs, b_mbs, /* todo */
2441                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv                                                  &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2442    
2443                          // interpolate search (simple, but effective)                          // interpolate search (simple, but effective)
# Line 2128  Line 2457 
2457                          if (f_sad16 < b_sad16)                          if (f_sad16 < b_sad16)
2458                          {                          {
2459                                  best_sad = f_sad16;                                  best_sad = f_sad16;
2460                                  mb->mode = MB_FORWARD;                                  mb->mode = MODE_FORWARD;
2461                          }                          }
2462                          else                          else
2463                          {                          {
2464                                  best_sad = b_sad16;                                  best_sad = b_sad16;
2465                                  mb->mode = MB_BACKWARD;                                  mb->mode = MODE_BACKWARD;
2466                          }                          }
2467    
2468                          if (i_sad16 < best_sad)                          if (i_sad16 < best_sad)
2469                          {                          {
2470                                  best_sad = i_sad16;                                  best_sad = i_sad16;
2471                                  mb->mode = MB_INTERPOLATE;                                  mb->mode = MODE_INTERPOLATE;
2472                          }                          }
2473    
2474                          if (d_sad16 < best_sad)                          if (d_sad16 < best_sad)
2475                          {                          {
2476                                  best_sad = d_sad16;                                  best_sad = d_sad16;
2477                                  mb->mode = MB_DIRECT;                                  mb->mode = MODE_DIRECT;
2478                          }                          }
2479    
2480                  }                  }
2481          }          }
2482  }  }
   
 */  

Legend:
Removed from v.141  
changed lines
  Added in v.181

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