--- trunk/xvidcore/src/motion/motion_est.c 2002/05/11 15:32:59 172 +++ trunk/xvidcore/src/motion/motion_est.c 2002/05/22 12:42:25 181 @@ -54,6 +54,10 @@ #define MV16_THRESHOLD 192 #define MV8_THRESHOLD 56 +#define NEIGH_MOVE_THRESH 0 +// how much a block's MV must differ from his neighbour +// to be search for INTER4V. The more, the faster... + /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */ /* nb = vop pixels * 2^(bpp-8) */ #define MV16_00_BIAS (128+1) @@ -291,16 +295,11 @@ for (x = 0; x < iWcount; x++) { MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; - + pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x, y, current->motion_flags, current->quant, current->fcode, pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]); - } - - for (y = 0; y < iHcount; y++) - for (x = 0; x < iWcount; x++) - { - MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; + if (0 < (pMB->sad16 - MV16_INTER_BIAS)) { @@ -323,68 +322,107 @@ continue; } } + pMB->mode = MODE_INTER; + pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; + pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; + } - if ( (current->global_flags & XVID_INTER4V) - && (!(current->global_flags & XVID_LUMIMASKING) - || pMB->dquant == NO_CHANGE) ) + // we try to do as few INTER4V-searches as possible. So we split ME in two parts, normal + // SEARCH16 and only for special blocks SEARCH8. May this should be modified for quality + // levels. + + + + if (current->global_flags & XVID_INTER4V) + for (y = 0; y < iHcount; y++) + for (x = 0; x < iWcount; x++) { - int32_t sad8 = 129; //IMV16X16 * current->quant; + MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; - if (sad8 < pMB->sad16) - sad8 += pMB->sad8[0] - = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2*x, 2*y, pMB->mv16.x, pMB->mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]); - - if (sad8 < pMB->sad16) - sad8 += pMB->sad8[1] - = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]); - - if (sad8 < pMB->sad16) - sad8 += pMB->sad8[2] - = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]); + if (pMB->mode == MODE_INTRA) + continue; + + + if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) + { + int32_t neigh=0; + + if (x>0) + { neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x)); + neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y)); + } + if (y>0) + { neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x)); + neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y)); + } + if (x<(iWcount-1)) + { neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x)); + neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y)); + } + if (y<(iHcount-1)) + { neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x)); + neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y)); + } + + if (neigh > NEIGH_MOVE_THRESH) + { + int32_t sad8 = IMV16X16 * current->quant; + + if (sad8 < pMB->sad16) + sad8 += pMB->sad8[0] + = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, + 2*x, 2*y, pMB->mv16.x, pMB->mv16.y, + current->motion_flags, current->quant, current->fcode, + pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]); + + if (sad8 < pMB->sad16) + sad8 += pMB->sad8[1] + = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, + 2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y, + current->motion_flags, current->quant, current->fcode, + pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]); + + if (sad8 < pMB->sad16) + sad8 += pMB->sad8[2] + = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, + 2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y, + current->motion_flags, current->quant, current->fcode, + pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]); - if (sad8 < pMB->sad16) - sad8 += pMB->sad8[3] - = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]); + if (sad8 < pMB->sad16) + sad8 += pMB->sad8[3] + = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, + 2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y, + current->motion_flags, current->quant, current->fcode, + pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]); /* decide: MODE_INTER or MODE_INTER4V mpeg4: if (sad8 < pMB->sad16 - nb/2+1) use_inter4v */ - if (sad8 < pMB->sad16) - { - pMB->mode = MODE_INTER4V; - pMB->sad8[0] *= 4; - pMB->sad8[1] *= 4; - pMB->sad8[2] *= 4; - pMB->sad8[3] *= 4; - continue; + if (sad8 < pMB->sad16) + { + pMB->mode = MODE_INTER4V; + pMB->sad8[0] *= 4; + pMB->sad8[1] *= 4; + pMB->sad8[2] *= 4; + pMB->sad8[3] *= 4; + continue; + } + + pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; } - } - pMB->mode = MODE_INTER; - pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16; - pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16; + } + + // get_pmv has to be called again, because inter4v changes predictors + + pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0); + pMB->pmvs[0].x = pMB->mv16.x - pmv.x; /* the other pmvs are only needed in INTER4V-mode */ + pMB->pmvs[0].y = pMB->mv16.y - pmv.y; - if (current->global_flags & XVID_INTER4V) - { pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0); - // get_pmv has to be called again. inter4v changes predictors - - pMB->pmvs[0].x = pMB->mv16.x - pmv.x; - pMB->pmvs[0].y = pMB->mv16.y - pmv.y; } - } + return 0; } @@ -743,6 +781,269 @@ return iMinSAD; } +int32_t AdvDiamond16_MainSearch( + const uint8_t * const pRef, + const uint8_t * const pRefH, + const uint8_t * const pRefV, + const uint8_t * const pRefHV, + const uint8_t * const cur, + const int x, const int y, + int32_t startx, int32_t starty, + int32_t iMinSAD, + VECTOR * const currMV, + const VECTOR * const pmv, + const int32_t min_dx, const int32_t max_dx, + const int32_t min_dy, const int32_t max_dy, + const int32_t iEdgedWidth, + const int32_t iDiamondSize, + const int32_t iFcode, + const int32_t iQuant, + int iDirection) +{ + + int32_t iSAD; + +/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */ + + if (iDirection) + { + CHECK_MV16_CANDIDATE(startx-iDiamondSize, starty); + CHECK_MV16_CANDIDATE(startx+iDiamondSize, starty); + CHECK_MV16_CANDIDATE(startx, starty-iDiamondSize); + CHECK_MV16_CANDIDATE(startx, starty+iDiamondSize); + } + else + { + int bDirection = 1+2+4+8; + do + { + iDirection = 0; + 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) + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize,starty,1); + + if (bDirection&2) + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize,starty,2); + + if (bDirection&4) + CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize,4); + + if (bDirection&8) + CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize,8); + + /* now we're doing diagonal checks near our candidate */ + + if (iDirection) //checking if anything found + { + bDirection = iDirection; + iDirection = 0; + startx=currMV->x; starty=currMV->y; + if (bDirection & 3) //our candidate is left or right + { + CHECK_MV16_CANDIDATE_DIR(startx,starty+iDiamondSize, 8); + CHECK_MV16_CANDIDATE_DIR(startx,starty-iDiamondSize, 4); + } + else // what remains here is up or down + { + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty, 2); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty, 1); + } + + if (iDirection) + { bDirection+=iDirection; + startx=currMV->x; starty=currMV->y; + } + } + else //about to quit, eh? not so fast.... + { + switch (bDirection) + { + case 2: + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 1: + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + case 2+4: + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 4: + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + break; + case 8: + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + case 1+4: + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + break; + case 2+8: + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 1+8: + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + default: //1+2+4+8 == we didn't find anything at all + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV16_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV16_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + } + if (!iDirection) break; //ok, the end. really + else + { bDirection=iDirection; + startx=currMV->x; starty=currMV->y; + } + } + } + while (1); //forever + } + return iMinSAD; +} + +int32_t AdvDiamond8_MainSearch( + const uint8_t * const pRef, + const uint8_t * const pRefH, + const uint8_t * const pRefV, + const uint8_t * const pRefHV, + const uint8_t * const cur, + const int x, const int y, + int32_t startx, int32_t starty, + int32_t iMinSAD, + VECTOR * const currMV, + const VECTOR * const pmv, + const int32_t min_dx, const int32_t max_dx, + const int32_t min_dy, const int32_t max_dy, + const int32_t iEdgedWidth, + const int32_t iDiamondSize, + const int32_t iFcode, + const int32_t iQuant, + int iDirection) +{ + + int32_t iSAD; + +/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */ + + if (iDirection) + { + CHECK_MV8_CANDIDATE(startx-iDiamondSize, starty); + CHECK_MV8_CANDIDATE(startx+iDiamondSize, starty); + CHECK_MV8_CANDIDATE(startx, starty-iDiamondSize); + CHECK_MV8_CANDIDATE(startx, starty+iDiamondSize); + } + else + { + int bDirection = 1+2+4+8; + do + { + iDirection = 0; + 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) + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize,starty,1); + + if (bDirection&2) + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize,starty,2); + + if (bDirection&4) + CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize,4); + + if (bDirection&8) + CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize,8); + + /* now we're doing diagonal checks near our candidate */ + + if (iDirection) //checking if anything found + { + bDirection = iDirection; + iDirection = 0; + startx=currMV->x; starty=currMV->y; + if (bDirection & 3) //our candidate is left or right + { + CHECK_MV8_CANDIDATE_DIR(startx,starty+iDiamondSize, 8); + CHECK_MV8_CANDIDATE_DIR(startx,starty-iDiamondSize, 4); + } + else // what remains here is up or down + { + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty, 2); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty, 1); + } + + if (iDirection) + { bDirection+=iDirection; + startx=currMV->x; starty=currMV->y; + } + } + else //about to quit, eh? not so fast.... + { + switch (bDirection) + { + case 2: + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 1: + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + case 2+4: + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 4: + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + break; + case 8: + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + case 1+4: + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + break; + case 2+8: + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + case 1+8: + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + break; + default: //1+2+4+8 == we didn't find anything at all + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty-iDiamondSize, 1+4); + CHECK_MV8_CANDIDATE_DIR(startx-iDiamondSize, starty+iDiamondSize, 1+8); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty-iDiamondSize, 2+4); + CHECK_MV8_CANDIDATE_DIR(startx+iDiamondSize, starty+iDiamondSize, 2+8); + break; + } + if (!(iDirection)) break; //ok, the end. really + else + { bDirection=iDirection; + startx=currMV->x; starty=currMV->y; + } + } + } + while (1); //forever + } + return iMinSAD; +} + + int32_t Full8_MainSearch( const uint8_t * const pRef, const uint8_t * const pRefH, @@ -850,6 +1151,8 @@ VECTOR pmv[4]; int32_t psad[4]; + + MainSearch16FuncPtr MainSearchPtr; // const MACROBLOCK * const pMB = pMBs + x + y * iWcount; const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; @@ -1052,10 +1355,18 @@ Refine by using small diamond and goto step 10. */ + if (MotionFlags & PMV_USESQUARES16) + MainSearchPtr = Square16_MainSearch; + else + if (MotionFlags & PMV_ADVANCEDDIAMOND16) + MainSearchPtr = AdvDiamond16_MainSearch; + else + MainSearchPtr = Diamond16_MainSearch; + backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ - iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1071,7 +1382,7 @@ /* extended: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) - { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + { iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1084,7 +1395,7 @@ } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) - { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + { iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1258,6 +1569,8 @@ int32_t iSubBlock = (y&1)+(y&1) + (x&1); + MainSearch8FuncPtr MainSearchPtr; + /* Init variables */ startMV.x = start_x; startMV.y = start_y; @@ -1303,6 +1616,16 @@ // Prepare for main loop +// if (MotionFlags & PMV_USESQUARES8) +// MainSearchPtr = Square8_MainSearch; +// else + + if (MotionFlags & PMV_ADVANCEDDIAMOND8) + MainSearchPtr = AdvDiamond8_MainSearch; + else + MainSearchPtr = Diamond8_MainSearch; + + *currMV = startMV; iMinSAD = sad8( cur, @@ -1443,7 +1766,7 @@ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ - iSAD = Diamond8_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1459,7 +1782,7 @@ /* extended: search (up to) two more times: orignal prediction and (0,0) */ if (!(MVequal(pmv[0],backupMV)) ) - { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + { iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1472,7 +1795,7 @@ } if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) - { iSAD = Diamond16_MainSearch(pRef, pRefH, pRefV, pRefHV, cur, + { iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, iFound); @@ -1549,7 +1872,7 @@ int32_t bPredEq; int32_t iMinSAD,iSAD=9999; - MainSearch16FuncPtr EPZSMainSearchPtr; + MainSearch16FuncPtr MainSearchPtr; if (oldMBs == NULL) { oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK)); @@ -1718,12 +2041,7 @@ /* default: use best prediction as starting point for one call of PMVfast_MainSearch */ - if (MotionFlags & PMV_USESQUARES16) - EPZSMainSearchPtr = Square16_MainSearch; - else - EPZSMainSearchPtr = Diamond16_MainSearch; - - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); @@ -1741,7 +2059,7 @@ if (!(MVequal(pmv[0],backupMV)) ) { - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); @@ -1755,7 +2073,7 @@ if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0); @@ -1834,7 +2152,7 @@ int32_t bPredEq; int32_t iMinSAD,iSAD=9999; - MainSearch8FuncPtr EPZSMainSearchPtr; + MainSearch8FuncPtr MainSearchPtr; /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, @@ -1965,13 +2283,20 @@ /* // there is no EPZS^2 for inter4v at the moment if (MotionFlags & PMV_USESQUARES8) - EPZSMainSearchPtr = Square8_MainSearch; + MainSearchPtr = Square8_MainSearch; else */ - EPZSMainSearchPtr = Diamond8_MainSearch; - - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, +// if (MotionFlags & PMV_USESQUARES8) +// MainSearchPtr = Square8_MainSearch; +// else + + if (MotionFlags & PMV_ADVANCEDDIAMOND8) + MainSearchPtr = AdvDiamond8_MainSearch; + else + MainSearchPtr = Diamond8_MainSearch; + + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV->x, currMV->y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, @@ -1990,7 +2315,7 @@ if (!(MVequal(pmv[0],backupMV)) ) { - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, pmv[0].x, pmv[0].y, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0); @@ -2004,7 +2329,7 @@ if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) ) { - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, + iSAD = (*MainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0, iMinSAD, &newMV, pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode, iQuant, 0);