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

📄 motion_est.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		#define NOCHECK_MV8_CANDIDATE(X,Y) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \}#define CHECK_MV8_CANDIDATE(X,Y) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \}#define CHECK_MV8_CANDIDATE_DIR(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \}#define CHECK_MV8_CANDIDATE_FOUND(X,Y,D) { \  if ( ((X) <= max_dx) && ((X) >= min_dx) \    && ((Y) <= max_dy) && ((Y) >= min_dy) ) \  { \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \    iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\    if (iSAD < iMinSAD) \    {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \}/* too slow and not fully functional at the moment *//*int32_t ZeroSearch16(					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, 									MBParam * const pParam,					MACROBLOCK * const pMBs,									VECTOR * const currMV,					VECTOR * const currPMV){	const int32_t iEdgedWidth = pParam->edged_width; 	const int32_t iQuant = pParam->quant;	const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;	int32_t iSAD;	int32_t pred_x,pred_y;	get_pmv(pMBs, x, y, pParam->mb_width, 0, &pred_x, &pred_y);    	iSAD = sad16( cur, 		get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0,0, iEdgedWidth),		iEdgedWidth, MV_MAX_ERROR);	if (iSAD <= iQuant * 96)		   	iSAD -= MV16_00_BIAS; 	currMV->x = 0;	currMV->y = 0;	currPMV->x = -pred_x;	currPMV->y = -pred_y;	return iSAD;}*/int32_t Diamond16_MainSearch(	const uint8_t * const pRef,	const uint8_t * const pRefH,	const uint8_t * const pRefV,	const uint8_t * const pRefHV,	const uint8_t * const cur,	const int x, const int y,	int32_t startx, int32_t starty,		int32_t iMinSAD,	VECTOR * const currMV,	const VECTOR * const pmv,	const int32_t min_dx, const int32_t max_dx, 	const int32_t min_dy, const int32_t max_dy,	const int32_t iEdgedWidth, 	const int32_t iDiamondSize, 	const int32_t iFcode,	const int32_t iQuant,	int iFound){/* Do a diamond search around given starting point, return SAD of best */	int32_t iDirection=0;	int32_t iSAD;	VECTOR backupMV;	backupMV.x = startx;	backupMV.y = starty;	/* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */	CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);	CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);	CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);	CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);	if (iDirection)		while (!iFound)		{				iFound = 1; 			backupMV=*currMV;				if ( iDirection != 2) 				CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);			if ( iDirection != 1) 				CHECK_MV16_CANDIDATE_FOUND(backupMV.x+iDiamondSize,backupMV.y,2);			if ( iDirection != 4) 				CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y-iDiamondSize,3);			if ( iDirection != 3) 				CHECK_MV16_CANDIDATE_FOUND(backupMV.x,backupMV.y+iDiamondSize,4);		}	else	{			currMV->x = startx;		currMV->y = starty;	}	return iMinSAD;}int32_t Square16_MainSearch(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const uint8_t * const cur,					const int x, const int y,					int32_t startx, int32_t starty,						int32_t iMinSAD,					VECTOR * const currMV,					const VECTOR * const pmv,					const int32_t min_dx, const int32_t max_dx, 					const int32_t min_dy, const int32_t max_dy,					const int32_t iEdgedWidth, 					const int32_t iDiamondSize, 					const int32_t iFcode,					const int32_t iQuant,					int iFound){/* Do a square search around given starting point, return SAD of best */	int32_t iDirection=0;	int32_t iSAD;	VECTOR backupMV;	backupMV.x = startx;	backupMV.y = starty;	/* It's one search with full square pattern, and new parts for all following diamonds *//*   new direction are extra, so 1-4 is normal diamond      537      1*2      648  */	CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);	CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);	CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);	CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);	CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);	CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);	CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);	CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);		if (iDirection)		while (!iFound)		{				iFound = 1; 			backupMV=*currMV;				switch (iDirection)			{				case 1:					CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					break;				case 2:					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);						CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);					break;									case 3:					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);					break;									case 4:					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					break;				case 5:						CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					break; 									case 6:					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);								CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);						break;									case 7:					CHECK_MV16_CANDIDATE_FOUND(backupMV.x-iDiamondSize,backupMV.y,1);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);					break;									case 8:					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);					break; 			default:					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y,1);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y,2);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y-iDiamondSize,3);					CHECK_MV16_CANDIDATE_DIR(backupMV.x,backupMV.y+iDiamondSize,4);									CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y-iDiamondSize,5);					CHECK_MV16_CANDIDATE_DIR(backupMV.x-iDiamondSize,backupMV.y+iDiamondSize,6);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y-iDiamondSize,7);					CHECK_MV16_CANDIDATE_DIR(backupMV.x+iDiamondSize,backupMV.y+iDiamondSize,8);					break;			}		}	else		{				currMV->x = startx;			currMV->y = starty;		}	return iMinSAD;}int32_t Full16_MainSearch(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const uint8_t * const cur,					const int x, const int y,					int32_t startx, int32_t starty,						int32_t iMinSAD,					VECTOR * const currMV,					const VECTOR * const pmv,					const int32_t min_dx, const int32_t max_dx, 					const int32_t min_dy, const int32_t max_dy,					const int32_t iEdgedWidth, 					const int32_t iDiamondSize, 					const int32_t iFcode,					const int32_t iQuant,					int iFound){	int32_t iSAD;	int32_t dx,dy;	VECTOR backupMV;	backupMV.x = startx;	backupMV.y = starty;		for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)		for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)			NOCHECK_MV16_CANDIDATE(dx,dy);	return iMinSAD;}int32_t Full8_MainSearch(					const uint8_t * const pRef,					const uint8_t * const pRefH,					const uint8_t * const pRefV,					const uint8_t * const pRefHV,					const uint8_t * const cur,					const int x, const int y,					int32_t startx, int32_t starty,						int32_t iMinSAD,					VECTOR * const currMV,					const VECTOR * const pmv,					const int32_t min_dx, const int32_t max_dx, 					const int32_t min_dy, const int32_t max_dy,					const int32_t iEdgedWidth, 					const int32_t iDiamondSize, 					const int32_t iFcode,					const int32_t iQuant,					int iFound){	int32_t iSAD;	int32_t dx,dy;	VECTOR backupMV;	backupMV.x = startx;	backupMV.y = starty;		for (dx = min_dx; dx<=max_dx; dx+=iDiamondSize)		for (dy = min_dy; dy<= max_dy; dy+=iDiamondSize)			NOCHECK_MV8_CANDIDATE(dx,dy);	return iMinSAD;}int32_t Halfpel16_Refine(	const uint8_t * const pRef,	const uint8_t * const pRefH,	const uint8_t * const pRefV,	const uint8_t * const pRefHV,	const uint8_t * const cur,	const int x, const int y,	VECTOR * const currMV,	int32_t iMinSAD,	const VECTOR * const pmv,	const int32_t min_dx, const int32_t max_dx, 	const int32_t min_dy, const int32_t max_dy,	const int32_t iFcode,	const int32_t iQuant,	const int32_t iEdgedWidth){/* Do a half-pel refinement (or rather a "smallest possible amount" refinement) */	int32_t iSAD;	VECTOR backupMV = *currMV;		CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y-1);	CHECK_MV16_CANDIDATE(backupMV.x  ,backupMV.y-1);	CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y-1);	CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y);	CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y);	CHECK_MV16_CANDIDATE(backupMV.x-1,backupMV.y+1);	CHECK_MV16_CANDIDATE(backupMV.x  ,backupMV.y+1);	CHECK_MV16_CANDIDATE(backupMV.x+1,backupMV.y+1);		return iMinSAD;}#define PMV_HALFPEL16 (PMV_HALFPELDIAMOND16|PMV_HALFPELREFINE16)int32_t PMVfastSearch16(					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 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 iDiamondSize;		int32_t min_dx;	int32_t max_dx;	int32_t min_dy;	int32_t max_dy;			int32_t iFound;	VECTOR newMV;	VECTOR backupMV;	/* just for PMVFAST */		VECTOR pmv[4];	int32_t psad[4];		MACROBLOCK * const pMB = pMBs + x + y * iWcount;	static int32_t threshA,threshB;    	int32_t bPredEq;    	int32_t iMinSAD,iSAD;/* 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);	if ((x==0) && (y==0) )	{		threshA =  512;		threshB = 1024;		}	else	{		threshA = psad[0];		threshB = threshA+256;		if (threshA< 512) threshA =  512;                if (threshA>1024) threshA = 1024;         	if (threshB>1792) threshB = 1792; 	}	iFound=0;	/* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion    vector of the median.    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  */        if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )		iFound=2;/* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.    Otherwise select large Diamond Search. */	if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536) || (bPredEq) ) 		iDiamondSize=1;	// halfpel!	else		iDiamondSize=2;	// halfpel!	if (!(MotionFlags & PMV_HALFPELDIAMOND16) )		iDiamondSize*=2;/* 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 := prediction */	if (!(MotionFlags & PMV_HALFPEL16 ))	{ 	/* This should NOT be necessary! */		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) 

⌨️ 快捷键说明

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