--- trunk/xvidcore/src/motion/motion_est.c 2002/05/09 00:42:35 169 +++ trunk/xvidcore/src/motion/motion_est.c 2002/05/27 18:07:38 184 @@ -54,13 +54,17 @@ #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) #define MV8_00_BIAS (0) /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */ -#define INTER_BIAS 512 +#define MV16_INTER_BIAS 512 /* Parameters which control inter/inter4v decision */ #define IMV16X16 5 @@ -69,10 +73,11 @@ #define NEIGH_TEND_16X16 2 #define NEIGH_TEND_8X8 2 - // fast ((A)/2)*2 #define EVEN(A) (((A)<0?(A)+1:(A)) & ~1) +#define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) ) +#define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) int32_t PMVfastSearch16( const uint8_t * const pRef, @@ -266,138 +271,106 @@ const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV, - const uint32_t iLimit) - + const uint32_t iLimit) { const uint32_t iWcount = pParam->mb_width; const uint32_t iHcount = pParam->mb_height; - MACROBLOCK * pMBs = current->mbs; - IMAGE * pCurrent = ¤t->image; - - MACROBLOCK * prevMBs = reference->mbs; // previous frame - IMAGE * pRef = &reference->image; - - - uint32_t i, j, iIntra = 0; - - VECTOR mv16; - VECTOR pmv16; - - int32_t sad8 = 0; - int32_t sad16; - int32_t deviation; + MACROBLOCK * const pMBs = current->mbs; + MACROBLOCK * const prevMBs = reference->mbs; + const IMAGE * const pCurrent = ¤t->image; + const IMAGE * const pRef = &reference->image; + + const VECTOR zeroMV = {0,0}; + + int32_t x, y; + int32_t iIntra = 0; + VECTOR pmv; if (sadInit) - (*sadInit)(); - - // note: i==horizontal, j==vertical - for (i = 0; i < iHcount; i++) - for (j = 0; j < iWcount; j++) + (*sadInit)(); + + for (y = 0; y < iHcount; y++) + for (x = 0; x < iWcount; x++) { - MACROBLOCK *pMB = &pMBs[j + i * 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; - - - /* decide: MODE_INTER or MODE_INTRA - if (dev_intra < sad_inter - 2 * nb) use_intra - */ - - deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width); - - if (deviation < (sad16 - INTER_BIAS)) - { - pMB->mode = MODE_INTRA; - pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; - pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; - - pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; - - iIntra++; - if(iIntra >= iLimit) - return 1; + MACROBLOCK* const pMB = &pMBs[x + y * iWcount]; - continue; - } + 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]); - if (current->global_flags & XVID_INTER4V) + if (0 < (pMB->sad16 - MV16_INTER_BIAS)) { - pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2 * j, 2 * i, mv16.x, mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]); - - pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2 * j + 1, 2 * i, mv16.x, mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]); - - pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2 * j, 2 * i + 1, mv16.x, mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]); - - pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent, - 2 * j + 1, 2 * i + 1, mv16.x, mv16.y, - current->motion_flags, current->quant, current->fcode, - pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]); - - sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3]; - } - - - /* decide: MODE_INTER or MODE_INTER4V - mpeg4: if (sad8 < sad16 - nb/2+1) use_inter4v - */ + int32_t deviation; + deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width, pParam->edged_width); - if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) - { - if (((current->global_flags & XVID_INTER4V)==0) || - (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant)))) - { - - sad8 = sad16; - pMB->mode = MODE_INTER; - pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x; - pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y; - pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16; - pMB->pmvs[0].x = pmv16.x; - pMB->pmvs[0].y = pmv16.y; - } - else + if (deviation < (pMB->sad16 - MV16_INTER_BIAS)) { - pMB->mode = MODE_INTER4V; - pMB->sad8[0] *= 4; - pMB->sad8[1] *= 4; - pMB->sad8[2] *= 4; - pMB->sad8[3] *= 4; + pMB->mode = MODE_INTRA; + pMB->mv16 = pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = zeroMV; + pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; + + iIntra++; + if (iIntra >= iLimit) + return 1; + + continue; } - } - else - { - sad8 = sad16; + } + + pmv = pMB->pmvs[0]; + if (current->global_flags & XVID_INTER4V) + if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) ) + { + 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]); + + /* 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; + } + + } + 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->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16; + pMB->pmvs[0] = pmv; /* pMB->pmvs[1] = pMB->pmvs[2] = pMB->pmvs[3] are not needed for 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; - pMB->pmvs[0].x = pmv16.x; - pMB->pmvs[0].y = pmv16.y; - } } - - return 0; + return 0; } -#define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) ) - -#define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) ) - - #define CHECK_MV16_ZERO {\ if ( (0 <= max_dx) && (0 >= min_dx) \ && (0 <= max_dy) && (0 >= min_dy) ) \ @@ -753,6 +726,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, @@ -860,8 +1096,10 @@ VECTOR pmv[4]; int32_t psad[4]; + + MainSearch16FuncPtr MainSearchPtr; - const MACROBLOCK * const pMB = pMBs + x + y * iWcount; +// const MACROBLOCK * const pMB = pMBs + x + y * iWcount; const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; static int32_t threshA,threshB; @@ -1062,10 +1300,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); @@ -1081,7 +1327,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); @@ -1094,7 +1340,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); @@ -1257,9 +1503,9 @@ int32_t psad[4]; VECTOR newMV; VECTOR backupMV; - VECTOR startMV = { start_x, start_y }; + VECTOR startMV; - const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; +// const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; static int32_t threshA,threshB; @@ -1268,7 +1514,13 @@ int32_t iSubBlock = (y&1)+(y&1) + (x&1); -/* Get maximum range */ + MainSearch8FuncPtr MainSearchPtr; + + /* Init variables */ + startMV.x = start_x; + startMV.y = start_y; + + /* Get maximum range */ get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight, iFcode); @@ -1309,6 +1561,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, @@ -1449,7 +1711,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); @@ -1465,7 +1727,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); @@ -1478,7 +1740,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); @@ -1547,7 +1809,7 @@ int32_t psad[8]; static MACROBLOCK * oldMBs = NULL; - const MACROBLOCK * const pMB = pMBs + x + y * iWcount; +// const MACROBLOCK * const pMB = pMBs + x + y * iWcount; const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount; MACROBLOCK * oldMB = NULL; @@ -1555,7 +1817,7 @@ int32_t bPredEq; int32_t iMinSAD,iSAD=9999; - MainSearch16FuncPtr EPZSMainSearchPtr; + MainSearch16FuncPtr MainSearchPtr; if (oldMBs == NULL) { oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK)); @@ -1722,14 +1984,18 @@ backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */ -/* default: use best prediction as starting point for one call of PMVfast_MainSearch */ + if (MotionFlags & PMV_USESQUARES8) + MainSearchPtr = Square16_MainSearch; + else - if (MotionFlags & PMV_USESQUARES16) - EPZSMainSearchPtr = Square16_MainSearch; + if (MotionFlags & PMV_ADVANCEDDIAMOND8) + MainSearchPtr = AdvDiamond16_MainSearch; else - EPZSMainSearchPtr = Diamond16_MainSearch; + MainSearchPtr = Diamond16_MainSearch; - iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur, +/* default: use best prediction as starting point for one call of PMVfast_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, 2, iFcode, iQuant, 0); @@ -1747,7 +2013,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); @@ -1761,7 +2027,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,13 +2100,13 @@ const int32_t iSubBlock = ((y&1)<<1) + (x&1); - const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; +// const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount; 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, @@ -1968,16 +2234,18 @@ /* default: use best prediction as starting point for one call of EPZS_MainSearch */ -/* // there is no EPZS^2 for inter4v at the moment +// there is no EPZS^2 for inter4v at the moment - if (MotionFlags & PMV_USESQUARES8) - EPZSMainSearchPtr = Square8_MainSearch; +// if (MotionFlags & PMV_USESQUARES8) +// MainSearchPtr = Square8_MainSearch; +// else + + if (MotionFlags & PMV_ADVANCEDDIAMOND8) + MainSearchPtr = AdvDiamond8_MainSearch; else -*/ + MainSearchPtr = Diamond8_MainSearch; - EPZSMainSearchPtr = Diamond8_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, @@ -1996,7 +2264,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); @@ -2010,7 +2278,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);