--- trunk/xvidcore/src/motion/estimation_pvop.c 2005/12/18 02:55:54 1667 +++ trunk/xvidcore/src/motion/estimation_pvop.c 2005/12/18 06:52:12 1668 @@ -21,7 +21,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: estimation_pvop.c,v 1.17 2005-03-31 22:14:20 Isibaar Exp $ + * $Id: estimation_pvop.c,v 1.18 2005-12-18 06:52:12 syskin Exp $ * ****************************************************************************/ @@ -705,6 +705,106 @@ } else Data->iMinSAD[1] = 4096*256; } +static int +InitialSkipDecisionP(int sad00, + const MBParam * pParam, + const FRAMEINFO * current, + MACROBLOCK * pMB, + const MACROBLOCK * prevMB, + int x, int y, + const SearchData * Data, + const IMAGE * const pGMC, + const IMAGE * const pCurrent, + const IMAGE * const pRef, + const uint32_t MotionFlags) +{ + const unsigned int iEdgedWidth = pParam->edged_width; + + int skip_thresh = INITIAL_SKIP_THRESH * \ + (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1); + int stat_thresh = 0; + + /* initial skip decision */ + if (current->coding_type != S_VOP) { /* no fast SKIP for S(GMC)-VOPs */ + if (pMB->dquant == 0 && sad00 < pMB->quant * skip_thresh) + if (Data->chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant)) { + ZeroMacroblockP(pMB, sad00); + pMB->mode = MODE_NOT_CODED; + return 1; + } + } + + if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) { + VECTOR *cmpMV; + VECTOR staticMV = { 0, 0 }; + const MACROBLOCK * pMBs = current->mbs; + + if (current->coding_type == S_VOP) + cmpMV = &pMB->amv; + else + cmpMV = &staticMV; + + if(x > 0 && y > 0 && x < pParam->mb_width) { + if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], *cmpMV) && + MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) && + MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) && + MVequal(prevMB->mvs[0], *cmpMV)) { + stat_thresh = MAX((&pMBs[(x-1) + y * pParam->mb_width])->sad16, + MAX((&pMBs[x + (y-1) * pParam->mb_width])->sad16, + MAX((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16, + prevMB->sad16))); + } else { + stat_thresh = MIN((&pMBs[(x-1) + y * pParam->mb_width])->sad16, + MIN((&pMBs[x + (y-1) * pParam->mb_width])->sad16, + MIN((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16, + prevMB->sad16))); + } + } + } + + /* favorize (0,0) or global vector for cartoons */ + if (current->vop_flags & XVID_VOP_CARTOON) { + if (current->coding_type == S_VOP) { + int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16, + pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536); + + if (Data->chroma) { + iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2); + iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2); + } + + if (iSAD <= stat_thresh) { /* mode decision GMC */ + pMB->mode = MODE_INTER; + pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD; + pMB->mcsel = 1; + if (Data->qpel) { + pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv; + pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2; + pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2; + } else + pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; + + return 1; + } + } + else if (sad00 < stat_thresh) { + VECTOR predMV; + if (Data->qpel) + predMV = get_qpmv2(current->mbs, pParam->mb_width, 0, x, y, 0); + else + predMV = get_pmv2(current->mbs, pParam->mb_width, 0, x, y, 0); + + ZeroMacroblockP(pMB, sad00); + pMB->cbp = 0x3f; + pMB->pmvs[0].x = - predMV.x; + pMB->pmvs[0].y = - predMV.y; + return 1; + } + } + + return 0; +} + static __inline uint32_t MakeGoodMotionFlags(const uint32_t MotionFlags, const uint32_t VopFlags, const uint32_t VolFlags) { @@ -784,14 +884,14 @@ } } -bool +void MotionEstimation(MBParam * const pParam, FRAMEINFO * const current, FRAMEINFO * const reference, const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV, - const IMAGE * const pGMC, + const IMAGE * const pGMC, const uint32_t iLimit) { MACROBLOCK *const pMBs = current->mbs; @@ -806,9 +906,10 @@ int MVmax = 0, mvSum = 0, mvCount = 0; uint32_t x, y; - int32_t sad00; + int sad00; int skip_thresh = INITIAL_SKIP_THRESH * \ (current->vop_flags & XVID_VOP_MODEDECISION_RD ? 2:1); + int block = 0; /* some pre-initialized thingies for SearchP */ DECLARE_ALIGNED_MATRIX(dct_space, 3, 64, int16_t, CACHE_LINE); @@ -828,14 +929,16 @@ for (y = 0; y < mb_height; y++) { for (x = 0; x < mb_width; x++) { - MACROBLOCK *pMB = &pMBs[x + y * pParam->mb_width]; - MACROBLOCK *prevMB = &reference->mbs[x + y * pParam->mb_width]; + MACROBLOCK *pMB = &pMBs[block]; + MACROBLOCK *prevMB = &reference->mbs[block]; + int skip; + block++; pMB->sad16 = sad16v(pCurrent->y + (x + y * iEdgedWidth) * 16, pRef->y + (x + y * iEdgedWidth) * 16, pParam->edged_width, pMB->sad8); - + sad00 = 4*MAX(MAX(pMB->sad8[0], pMB->sad8[1]), MAX(pMB->sad8[2], pMB->sad8[3])); if (Data.chroma) { @@ -847,82 +950,9 @@ sad00 += Data.chromaSAD; } - /* initial skip decision */ - if (current->coding_type != S_VOP) { /* no fast SKIP for S(GMC)-VOPs */ - if (pMB->dquant == 0 && sad00 < pMB->quant * skip_thresh) - if (Data.chroma || xvid_me_SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant)) { - ZeroMacroblockP(pMB, sad00); - pMB->mode = MODE_NOT_CODED; - continue; - } - } - - if(MotionFlags & XVID_ME_DETECT_STATIC_MOTION) { - VECTOR *cmpMV; - VECTOR staticMV = { 0, 0 }; - - if (current->coding_type == S_VOP) - cmpMV = &pMB->amv; - else - cmpMV = &staticMV; - - if(x > 0 && y > 0 && x < pParam->mb_width) { - if(MVequal((&pMBs[(x-1) + y * pParam->mb_width])->mvs[0], *cmpMV) && - MVequal((&pMBs[x + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) && - MVequal((&pMBs[(x+1) + (y-1) * pParam->mb_width])->mvs[0], *cmpMV) && - MVequal(prevMB->mvs[0], *cmpMV)) { - stat_thresh = MAX((&pMBs[(x-1) + y * pParam->mb_width])->sad16, - MAX((&pMBs[x + (y-1) * pParam->mb_width])->sad16, - MAX((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16, - prevMB->sad16))); - } else { - stat_thresh = MIN((&pMBs[(x-1) + y * pParam->mb_width])->sad16, - MIN((&pMBs[x + (y-1) * pParam->mb_width])->sad16, - MIN((&pMBs[(x+1) + (y-1) * pParam->mb_width])->sad16, - prevMB->sad16))); - } - } - } - - /* favorize (0,0) or global vector for cartoons */ - if (current->vop_flags & XVID_VOP_CARTOON) { - if (current->coding_type == S_VOP) { - int32_t iSAD = sad16(pCurrent->y + (x + y * iEdgedWidth) * 16, - pGMC->y + 16*y*iEdgedWidth + 16*x, iEdgedWidth, 65536); - - if (Data.chroma) { - iSAD += sad8(pCurrent->u + x*8 + y*(iEdgedWidth/2)*8, pGMC->u + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2); - iSAD += sad8(pCurrent->v + (x + y*(iEdgedWidth/2))*8, pGMC->v + 8*y*(iEdgedWidth/2) + 8*x, iEdgedWidth/2); - } - - if (iSAD <= stat_thresh) { /* mode decision GMC */ - pMB->mode = MODE_INTER; - pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = iSAD; - pMB->mcsel = 1; - if (Data.qpel) { - pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv; - pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = pMB->amv.x/2; - pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = pMB->amv.y/2; - } else - pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv; - - continue; - } - } - else if (sad00 < stat_thresh) { - VECTOR predMV; - if (current->vol_flags & XVID_VOL_QUARTERPEL) - predMV = get_qpmv2(current->mbs, mb_width, 0, x, y, 0); - else - predMV = get_pmv2(current->mbs, mb_width, 0, x, y, 0); - - ZeroMacroblockP(pMB, sad00); - pMB->cbp = 0x3f; - pMB->pmvs[0].x = - predMV.x; - pMB->pmvs[0].y = - predMV.y; - continue; - } - } + skip = InitialSkipDecisionP(sad00, pParam, current, pMB, prevMB, x, y, &Data, pGMC, + pCurrent, pRef, MotionFlags); + if (skip) continue; SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x, y, MotionFlags, current->vop_flags, @@ -950,6 +980,4 @@ current->fcode = getMinFcode(MVmax); current->sStat.iMvSum = mvSum; current->sStat.iMvCount = mvCount; - - return 0; }