⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 estimation_gmc.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 2 页
字号:
	} 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 + -