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

📄 motion_est.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	currPMV->x = currMV->x - pmv[0].x;	currPMV->y = currMV->y - pmv[0].y;		return iMinSAD;}int32_t EPZSSearch16(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const IMAGE * const pCur,					const int x, const int y,					const uint32_t MotionFlags,					const MBParam * const pParam,					MACROBLOCK * const pMBs,					VECTOR * const currMV,					VECTOR * const currPMV){        const uint32_t iWcount = pParam->mb_width;        const uint32_t iHcount = pParam->mb_height;	const int32_t iFcode = pParam->fixed_code;	const int32_t iQuant = pParam->quant;	const int32_t iWidth = pParam->width;	const int32_t iHeight = pParam->height;	const int32_t iEdgedWidth = pParam->edged_width; 	const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;	int32_t min_dx;	int32_t max_dx;	int32_t min_dy;	int32_t max_dy;			VECTOR newMV;	VECTOR backupMV;		VECTOR pmv[4];	int32_t psad[8];		static MACROBLOCK * oldMBs = NULL; 	MACROBLOCK * const pMB = pMBs + x + y * iWcount;	MACROBLOCK * oldMB = NULL;	static int32_t thresh2;    	int32_t bPredEq;    	int32_t iMinSAD,iSAD=9999;	MainSearch16FuncPtr EPZSMainSearchPtr;	if (oldMBs == NULL)	{	oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));		fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));	}	oldMB = oldMBs + x + y * iWcount;/* Get maximum range */	get_range(&min_dx, &max_dx, &min_dy, &max_dy,			x, y, 16, iWidth, iHeight, iFcode);/* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */	if (!(MotionFlags & PMV_HALFPEL16 ))	{ min_dx = EVEN(min_dx);	  max_dx = EVEN(max_dx);	  min_dy = EVEN(min_dy);	  max_dy = EVEN(max_dy); 	}		/* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */			bPredEq  = get_pmvdata(pMBs, x, y, iWcount, 0, pmv, psad);/* Step 4: Calculate SAD around the Median prediction.         MinSAD=SAD         If Motion Vector equal to Previous frame motion vector 		and MinSAD<PrevFrmSAD goto Step 10.         If SAD<=256 goto Step 10. */	// Prepare for main loop 	*currMV=pmv[0];		/* current best := median prediction */	if (!(MotionFlags & PMV_HALFPEL16))	{ 			currMV->x = EVEN(currMV->x);		currMV->y = EVEN(currMV->y);	}		if (currMV->x > max_dx) 			currMV->x=max_dx;	if (currMV->x < min_dx) 		currMV->x=min_dx;	if (currMV->y > max_dy) 		currMV->y=max_dy;	if (currMV->y < min_dy) 		currMV->y=min_dy;/***************** This is predictor SET A: only median prediction ******************/ 		iMinSAD = sad16( cur, 		get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),		iEdgedWidth, MV_MAX_ERROR);  	iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;	// thresh1 is fixed to 256 	if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )		{			if (MotionFlags & PMV_QUICKSTOP16) 				goto EPZS16_Terminate_without_Refine;			if (MotionFlags & PMV_EARLYSTOP16) 				goto EPZS16_Terminate_with_Refine;		}/************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/ // previous frame MV 	CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);// set threshhold based on Min of Prediction and SAD of collocated block// CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want	if ((x==0) && (y==0) )	{		thresh2 =  512;	}	else	{/* T_k = 1.2 * MIN(SAD_top,SAD_left,SAD_topleft,SAD_coll) +128;   [Tourapis, 2002] */		thresh2 = MIN(psad[0],iSAD)*6/5 + 128;		}// MV=(0,0) is often a good choice	CHECK_MV16_ZERO;	// left neighbour, if allowed	if (x != 0) 	{		if (!(MotionFlags & PMV_HALFPEL16 ))		{	pmv[1].x = EVEN(pmv[1].x);			pmv[1].y = EVEN(pmv[1].y);		}		CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);			}// top neighbour, if allowed	if (y != 0)	{			if (!(MotionFlags & PMV_HALFPEL16 ))		{	pmv[2].x = EVEN(pmv[2].x);			pmv[2].y = EVEN(pmv[2].y);		}		CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);	// top right neighbour, if allowed		if (x != (iWcount-1))		{			if (!(MotionFlags & PMV_HALFPEL16 ))			{	pmv[3].x = EVEN(pmv[3].x);				pmv[3].y = EVEN(pmv[3].y);			}			CHECK_MV16_CANDIDATE(pmv[3].x,pmv[3].y);		}	}/* Terminate if MinSAD <= T_2    Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1] */	if ( (iMinSAD <= thresh2) 		|| ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )		{				if (MotionFlags & PMV_QUICKSTOP16) 				goto EPZS16_Terminate_without_Refine;			if (MotionFlags & PMV_EARLYSTOP16) 				goto EPZS16_Terminate_with_Refine;		}/***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/	backupMV = pMB->mvs[0]; 		// last MV	backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );	// acceleration X	backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );	// acceleration Y 	CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);	// left neighbour	if (x != 0)  		CHECK_MV16_CANDIDATE((oldMB-1)->mvs[0].x,oldMB->mvs[0].y);		// top neighbour 	if (y != 0)		CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y);		// right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs 	if (x != iWcount-1)		CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);		// bottom neighbour, dito	if (y != iHcount-1)		CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);		/* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */	if (iMinSAD <= thresh2)		{				if (MotionFlags & PMV_QUICKSTOP16) 				goto EPZS16_Terminate_without_Refine;			if (MotionFlags & PMV_EARLYSTOP16) 				goto EPZS16_Terminate_with_Refine;		}/************ (if Diamond Search)  **************/	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_USESQUARES16)		EPZSMainSearchPtr = Square16_MainSearch;	else		EPZSMainSearchPtr = Diamond16_MainSearch;	iSAD = (*EPZSMainSearchPtr)(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);		if (iSAD < iMinSAD) 	{		*currMV = newMV;		iMinSAD = iSAD;	}	if (MotionFlags & PMV_EXTSEARCH16)	{/* extended mode: search (up to) two more times: orignal prediction and (0,0) */		if (!(MVequal(pmv[0],backupMV)) )		{ 				iSAD = (*EPZSMainSearchPtr)(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);		}					if (iSAD < iMinSAD) 		{			*currMV = newMV;			iMinSAD = iSAD;		}			if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )		{ 				iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,				x, y, 			0, 0, iMinSAD, &newMV, 			pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0);					if (iSAD < iMinSAD) 			{				*currMV = newMV;				iMinSAD = iSAD;			}		}	}/*************** 	Choose best MV found     **************/EPZS16_Terminate_with_Refine:	if (MotionFlags & PMV_HALFPELREFINE16) 		// perform final half-pel step 		iMinSAD = Halfpel16_Refine( pRef, pRefH, pRefV, pRefHV, cur,				x, y,				currMV, iMinSAD, 				pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);EPZS16_Terminate_without_Refine:	*oldMB = *pMB;		currPMV->x = currMV->x - pmv[0].x;	currPMV->y = currMV->y - pmv[0].y;	return iMinSAD;}int32_t EPZSSearch8(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const IMAGE * const pCur,					const int x, const int y,					const int start_x, int start_y,					const uint32_t MotionFlags,					const MBParam * const pParam,					MACROBLOCK * const pMBs,					VECTOR * const currMV,					VECTOR * const currPMV){        const uint32_t iWcount = pParam->mb_width;	const int32_t iFcode = pParam->fixed_code;	const int32_t iQuant = pParam->quant;	const int32_t iWidth = pParam->width;	const int32_t iHeight = pParam->height;	const int32_t iEdgedWidth = pParam->edged_width; 	const uint8_t * cur = pCur->y + x*8 + y*8*iEdgedWidth;	int32_t iDiamondSize=1;		int32_t min_dx;	int32_t max_dx;	int32_t min_dy;	int32_t max_dy;			VECTOR newMV;	VECTOR backupMV;		VECTOR pmv[4];	int32_t psad[8];	const	int32_t iSubBlock = ((y&1)<<1) + (x&1);		MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;    	int32_t bPredEq;    	int32_t iMinSAD,iSAD=9999;	MainSearch8FuncPtr EPZSMainSearchPtr;/* Get maximum range */	get_range(&min_dx, &max_dx, &min_dy, &max_dy,			x, y, 8, iWidth, iHeight, iFcode);/* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */	if (!(MotionFlags & PMV_HALFPEL8 ))	{ min_dx = EVEN(min_dx);	  max_dx = EVEN(max_dx);	  min_dy = EVEN(min_dy);	  max_dy = EVEN(max_dy); 	}		/* because we might use something like IF (dx>max_dx) THEN dx=max_dx; */			bPredEq  = get_pmvdata(pMBs, x>>1, y>>1, iWcount, iSubBlock, pmv, psad);/* Step 4: Calculate SAD around the Median prediction.         MinSAD=SAD         If Motion Vector equal to Previous frame motion vector 		and MinSAD<PrevFrmSAD goto Step 10.         If SAD<=256 goto Step 10. */// Prepare for main loop 		if (!(MotionFlags & PMV_HALFPEL8))	{ 			currMV->x = EVEN(currMV->x);		currMV->y = EVEN(currMV->y);	}		if (currMV->x > max_dx) 			currMV->x=max_dx;	if (currMV->x < min_dx) 		currMV->x=min_dx;	if (currMV->y > max_dy) 		currMV->y=max_dy;	if (currMV->y < min_dy) 		currMV->y=min_dy;/***************** This is predictor SET A: only median prediction ******************/ 		iMinSAD = sad8( cur, 		get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),		iEdgedWidth);  	iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;	// thresh1 is fixed to 256 	if (iMinSAD < 256/4 )		{			if (MotionFlags & PMV_QUICKSTOP8) 				goto EPZS8_Terminate_without_Refine;			if (MotionFlags & PMV_EARLYSTOP8) 				goto EPZS8_Terminate_with_Refine;		}/************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/ // previous frame MV 	CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);// MV=(0,0) is often a good choice	CHECK_MV8_ZERO;/* Terminate if MinSAD <= T_2    Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1] */	if (iMinSAD < 512/4) 	/* T_2 == 512/4 hardcoded */		{			if (MotionFlags & PMV_QUICKSTOP8) 				goto EPZS8_Terminate_without_Refine;			if (MotionFlags & PMV_EARLYSTOP8) 				goto EPZS8_Terminate_with_Refine;		}/************ (if Diamond Search)  **************/	backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */	if (!(MotionFlags & PMV_HALFPELDIAMOND8))		iDiamondSize *= 2;		/* default: use best prediction as starting point for one call of PMVfast_MainSearch *///	if (MotionFlags & PMV_USESQUARES8)//		EPZSMainSearchPtr = Square8_MainSearch;//	else		EPZSMainSearchPtr = Diamond8_MainSearch;			iSAD = (*EPZSMainSearchPtr)(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, 00);		if (iSAD < iMinSAD) 	{		*currMV = newMV;		iMinSAD = iSAD;	}	if (MotionFlags & PMV_EXTSEARCH8)	{/* extended mode: search (up to) two more times: orignal prediction and (0,0) */		if (!(MVequal(pmv[0],backupMV)) )		{ 				iSAD = (*EPZSMainSearchPtr)(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);					if (iSAD < iMinSAD) 			{				*currMV = newMV;				iMinSAD = iSAD;			}		}		if ( (!(MVzero(pmv[0]))) && (!(MVzero(backupMV))) )		{ 				iSAD = (*EPZSMainSearchPtr)(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);					if (iSAD < iMinSAD) 			{				*currMV = newMV;				iMinSAD = iSAD;			}		}	}/*************** 	Choose best MV found     **************/EPZS8_Terminate_with_Refine:	if (MotionFlags & PMV_HALFPELREFINE8) 		// perform final half-pel step 		iMinSAD = Halfpel8_Refine( pRef, pRefH, pRefV, pRefHV, cur,				x, y,				currMV, iMinSAD, 				pmv, min_dx, max_dx, min_dy, max_dy, iFcode, iQuant, iEdgedWidth);EPZS8_Terminate_without_Refine:	currPMV->x = currMV->x - pmv[0].x;	currPMV->y = currMV->y - pmv[0].y;	return iMinSAD;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -