📄 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;
}
int
GlobalMotionEstRefine(
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;
}
int
globalSAD(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 + -