📄 estimation_gmc.c
字号:
} while ( (oldnum != num) && (num>= minblocks) ); if (num < minblocks) { const int iEdgedWidth = pParam->edged_width; num = 0;/* fprintf(stderr,"Warning! Unreliable GME (%d/%d blocks), falling back to translation.\n",num,MBh*MBw);*/ gmc.duv[0].x= gmc.duv[0].y= gmc.duv[1].x= gmc.duv[1].y= gmc.duv[2].x= gmc.duv[2].y=0; if (!(current->motion_flags & XVID_ME_GME_REFINE)) return gmc; for (my = 1; my < (uint32_t)MBh-1; my++) /* ignore boundary blocks */ for (mx = 1; mx < (uint32_t)MBw-1; mx++) /* theirs MVs are often wrong */ { const int mbnum = mx + my * MBw; MACROBLOCK *const pMB = &pMBs[mbnum]; const uint8_t *const pCur = current->image.y + 16*(my*iEdgedWidth + mx); if ( (sad16 ( pCur, pCur+1 , iEdgedWidth, 65536) >= gradx ) && (sad16 ( pCur, pCur+iEdgedWidth, iEdgedWidth, 65536) >= grady ) ) { pMB->mcsel = 1; gmc.duv[0].x += pMB->mvs[0].x; gmc.duv[0].y += pMB->mvs[0].y; num++; } } if (gmc.duv[0].x) gmc.duv[0].x /= num; if (gmc.duv[0].y) gmc.duv[0].y /= num; } else { gmc.duv[0].x=(int)(sol[0]+0.5); gmc.duv[0].y=(int)(sol[3]+0.5); gmc.duv[1].x=(int)(sol[1]*pParam->width+0.5); gmc.duv[1].y=(int)(-sol[2]*pParam->width+0.5); gmc.duv[2].x=-gmc.duv[1].y; /* two warp points only */ gmc.duv[2].y=gmc.duv[1].x; } if (num>maxblocks) { for (my = 1; my < (uint32_t)MBh-1; my++) for (mx = 1; mx < (uint32_t)MBw-1; mx++) { const int mbnum = mx + my * MBw; if (pMBs[mbnum-1].mcsel) pMBs[mbnum].mcsel=0; else if (pMBs[mbnum-MBw].mcsel) pMBs[mbnum].mcsel=0; } } return gmc;}intGlobalMotionEstRefine( WARPPOINTS *const startwp, MACROBLOCK * const pMBs, const MBParam * const pParam, const FRAMEINFO * const current, const FRAMEINFO * const reference, const IMAGE * const pCurr, const IMAGE * const pRef, const IMAGE * const pRefH, const IMAGE * const pRefV, const IMAGE * const pRefHV){ uint8_t* GMCblock = (uint8_t*)malloc(16*pParam->edged_width); WARPPOINTS bestwp=*startwp; WARPPOINTS centerwp,currwp; int gmcminSAD=0; int gmcSAD=0; int direction;#if 0 int mx,my;#endif#if 0 /* use many blocks... */ for (my = 0; my < (uint32_t)pParam->mb_height; my++) { for (mx = 0; mx < (uint32_t)pParam->mb_width; mx++) { const int mbnum = mx + my * pParam->mb_width; pMBs[mbnum].mcsel=1; } }#endif#if 0 /* or rather don't use too many blocks... */ for (my = 1; my < (uint32_t)MBh-1; my++) { for (mx = 1; mx < (uint32_t)MBw-1; mx++) { const int mbnum = mx + my * MBw; if (MBmask[mbnum-1]) MBmask[mbnum-1]=0; else if (MBmask[mbnum-MBw]) MBmask[mbnum-1]=0; } }#endif gmcminSAD = globalSAD(&bestwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if ( (reference->coding_type == S_VOP) && ( (reference->warp.duv[1].x != bestwp.duv[1].x) || (reference->warp.duv[1].y != bestwp.duv[1].y) || (reference->warp.duv[0].x != bestwp.duv[0].x) || (reference->warp.duv[0].y != bestwp.duv[0].y) || (reference->warp.duv[2].x != bestwp.duv[2].x) || (reference->warp.duv[2].y != bestwp.duv[2].y) ) ) { gmcSAD = globalSAD(&reference->warp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = reference->warp; gmcminSAD = gmcSAD; } } do { direction = 0; centerwp = bestwp; currwp = centerwp; currwp.duv[0].x--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 1; } else { currwp = centerwp; currwp.duv[0].x++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 2; } } if (direction) continue; currwp = centerwp; currwp.duv[0].y--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 4; } else { currwp = centerwp; currwp.duv[0].y++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 8; } } if (direction) continue; currwp = centerwp; currwp.duv[1].x++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 32; } currwp.duv[2].y++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 1024; } currwp = centerwp; currwp.duv[1].x--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 16; } else { currwp = centerwp; currwp.duv[1].x++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 32; } } if (direction) continue; currwp = centerwp; currwp.duv[1].y--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 64; } else { currwp = centerwp; currwp.duv[1].y++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 128; } } if (direction) continue; currwp = centerwp; currwp.duv[2].x--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 256; } else { currwp = centerwp; currwp.duv[2].x++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 512; } } if (direction) continue; currwp = centerwp; currwp.duv[2].y--; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 1024; } else { currwp = centerwp; currwp.duv[2].y++; gmcSAD = globalSAD(&currwp, pParam, pMBs, current, pRef, pCurr, GMCblock); if (gmcSAD < gmcminSAD) { bestwp = currwp; gmcminSAD = gmcSAD; direction = 2048; } } } while (direction); free(GMCblock); *startwp = bestwp; return gmcminSAD;}intglobalSAD(const WARPPOINTS *const wp, const MBParam * const pParam, const MACROBLOCK * const pMBs, const FRAMEINFO * const current, const IMAGE * const pRef, const IMAGE * const pCurr, uint8_t *const GMCblock){ NEW_GMC_DATA gmc_data; int iSAD, gmcSAD=0; int num=0; unsigned int mx, my; generate_GMCparameters( 3, 3, wp, pParam->width, pParam->height, &gmc_data); for (my = 0; my < (uint32_t)pParam->mb_height; my++) for (mx = 0; mx < (uint32_t)pParam->mb_width; mx++) { const int mbnum = mx + my * pParam->mb_width; const int iEdgedWidth = pParam->edged_width; if (!pMBs[mbnum].mcsel) continue; gmc_data.predict_16x16(&gmc_data, GMCblock, pRef->y, iEdgedWidth, iEdgedWidth, mx, my, pParam->m_rounding_type); iSAD = sad16 ( pCurr->y + 16*(my*iEdgedWidth + mx), GMCblock , iEdgedWidth, 65536); iSAD -= pMBs[mbnum].sad16; if (iSAD<0) gmcSAD += iSAD; num++; } return gmcSAD;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -