motion_est.c

来自「mpeg4代码,比较具体」· C语言 代码 · 共 2,172 行 · 第 1/5 页

C
2,172
字号
					}					CHECK_MV16_CANDIDATE(pmv[2].x, pmv[2].y);/* top right neighbour, if allowed */					if (!MVzero(pmv[3]))						if (!MVequal(pmv[3], prevMB->mvs[0]))							if (!MVequal(pmv[3], pmv[0]))								if (!MVequal(pmv[3], pmv[1]))									if (!MVequal(pmv[3], pmv[2])) {										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);									}				}	if ((MVzero(*currMV)) &&		(!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )		iMinSAD -= MV16_00_BIAS;/* Step 6: If MinSAD <= thresa goto Step 10.    If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10. */	if ((iMinSAD <= threshA) ||		(MVequal(*currMV, prevMB->mvs[0]) &&		 ((int32_t) iMinSAD < prevMB->sad16))) {		if (MotionFlags & PMV_QUICKSTOP16)			goto PMVfast16_Terminate_without_Refine;		if (MotionFlags & PMV_EARLYSTOP16)			goto PMVfast16_Terminate_with_Refine;	}/************ (Diamond Search)  **************//*    Step 7: Perform Diamond search, with either the small or large diamond.    If Found=2 only examine one Diamond pattern, and afterwards goto step 10    Step 8: If small diamond, iterate small diamond search pattern until motion vector lies in the center of the diamond.    If center then goto step 10.    Step 9: If large diamond, iterate large diamond search pattern until motion vector lies in the center.    Refine by using small diamond and goto step 10. */	if (MotionFlags & PMV_USESQUARES16)		MainSearchPtr = Square16_MainSearch;	else if (MotionFlags & PMV_ADVANCEDDIAMOND16)		MainSearchPtr = AdvDiamond16_MainSearch;	else		MainSearchPtr = Diamond16_MainSearch;	backupMV = *currMV;			/* save best prediction, actually only for EXTSEARCH *//* default: use best prediction as starting point for one call of PMVfast_MainSearch */	iSAD =		(*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 						  currMV->x, currMV->y, iMinSAD, &newMV, center_x, center_y, 						  min_dx, max_dx,						  min_dy, max_dy, iEdgedWidth, iDiamondSize, iFcode,						  iQuant, iFound);	if (iSAD < iMinSAD) {		*currMV = newMV;		iMinSAD = iSAD;	}	if (MotionFlags & PMV_EXTSEARCH16) {/* extended: search (up to) two more times: orignal prediction and (0,0) */		if (!(MVequal(pmv[0], backupMV))) {			iSAD =				(*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y,								  center_x, center_y, iMinSAD, &newMV, center_x, center_y,								  min_dx, max_dx, min_dy, max_dy, iEdgedWidth,								  iDiamondSize, iFcode, iQuant, iFound);			if (iSAD < iMinSAD) {				*currMV = newMV;				iMinSAD = iSAD;			}		}		if ((!(MVzero(pmv[0]))) && (!(MVzero(backupMV)))) {			iSAD =				(*MainSearchPtr) (pRef, pRefH, pRefV, pRefHV, cur, x, y, 0, 0,								  iMinSAD, &newMV, center_x, center_y, 								  min_dx, max_dx, min_dy, max_dy, 								  iEdgedWidth, iDiamondSize, iFcode,								  iQuant, iFound);			if (iSAD < iMinSAD) {				*currMV = newMV;				iMinSAD = iSAD;			}		}	}/*    Step 10:  The motion vector is chosen according to the block corresponding to MinSAD.*/  PMVfast16_Terminate_with_Refine:	if (MotionFlags & PMV_HALFPELREFINE16)	/* perform final half-pel step  */		iMinSAD =			Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,							 iMinSAD, center_x, center_y, min_dx, max_dx, min_dy, max_dy,							 iFcode, iQuant, iEdgedWidth);  PMVfast16_Terminate_without_Refine:	currPMV->x = currMV->x - center_x;	currPMV->y = currMV->y - center_y;	return iMinSAD;}int32_tDiamond8_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,					const int32_t start_x,					const int32_t start_y,					int32_t iMinSAD,					VECTOR * const currMV,					const int center_x,					const int center_y,					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 iDirectionBackup;	int32_t iSAD;	VECTOR backupMV;	backupMV.x = start_x;	backupMV.y = start_y;/* It's one search with full Diamond pattern, and only 3 of 4 for all following diamonds */	CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);	CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);	CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);	CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);	if (iDirection)	{		while (!iFound) {			iFound = 1;			backupMV = *currMV;	/* since iDirection!=0, this is well defined! */			iDirectionBackup = iDirection;			if (iDirectionBackup != 2)				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										  backupMV.y, 1);			if (iDirectionBackup != 1)				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										  backupMV.y, 2);			if (iDirectionBackup != 4)				CHECK_MV8_CANDIDATE_FOUND(backupMV.x,										  backupMV.y - iDiamondSize, 3);			if (iDirectionBackup != 3)				CHECK_MV8_CANDIDATE_FOUND(backupMV.x,										  backupMV.y + iDiamondSize, 4);		}	} else {		currMV->x = start_x;		currMV->y = start_y;	}	return iMinSAD;}int32_tSquare8_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,				   const int32_t start_x,				   const int32_t start_y,				   int32_t iMinSAD,				   VECTOR * const currMV,				   const int center_x,				   const int center_y,				   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 = start_x;	backupMV.y = start_y;/* 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_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize, backupMV.y, 1);	CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize, backupMV.y, 2);	CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y - iDiamondSize, 3);	CHECK_MV8_CANDIDATE_DIR(backupMV.x, backupMV.y + iDiamondSize, 4);	CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,							 backupMV.y - iDiamondSize, 5);	CHECK_MV8_CANDIDATE_DIR(backupMV.x - iDiamondSize,							 backupMV.y + iDiamondSize, 6);	CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,							 backupMV.y - iDiamondSize, 7);	CHECK_MV8_CANDIDATE_DIR(backupMV.x + iDiamondSize,							 backupMV.y + iDiamondSize, 8);	if (iDirection)	{		while (!iFound) {			iFound = 1;			backupMV = *currMV;			switch (iDirection) {			case 1:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										   backupMV.y, 1);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				break;			case 2:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,										 2);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			case 3:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,										 4);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			case 4:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,										 3);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				break;			case 5:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,										 1);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,										 3);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				break;			case 6:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,										 2);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,										 3);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			case 7:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										   backupMV.y, 1);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,										 4);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			case 8:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,										 2);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,										 4);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			default:				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize, backupMV.y,										 1);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize, backupMV.y,										 2);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y - iDiamondSize,										 3);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x, backupMV.y + iDiamondSize,										 4);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y - iDiamondSize, 5);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x - iDiamondSize,										 backupMV.y + iDiamondSize, 6);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y - iDiamondSize, 7);				CHECK_MV8_CANDIDATE_FOUND(backupMV.x + iDiamondSize,										 backupMV.y + iDiamondSize, 8);				break;			}		}	} else {		currMV->x = start_x;		currMV->y = start_y;	}	return iMinSAD;}int32_tHalfpel8_Refine_c(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 int center_x,				  const int center_y,				  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_MV8_CANDIDATE(backupMV.x - 1, backupMV.y - 1);	CHECK_MV8_CANDIDATE(backupMV.x, backupMV.y - 1);	CHECK_MV8_CANDIDATE(backupMV.x + 1, backupMV.y - 1);	CHECK_MV8_CANDIDATE(backupMV.x - 1, backupMV.y);	CHECK_MV8_CANDIDATE(backupMV.x + 1, backupMV.y);	CHECK_MV8_CANDIDATE(backupMV.x - 1, backupMV.y + 1);	CHECK_MV8_CANDIDATE(backupMV.x, backupMV.y + 1);	CHECK_MV8_CANDIDATE(backupMV.x + 1, backupMV.y + 1);	return iMinSAD;}#define PMV_HALFPEL8 (PMV_HALFPELDIAMOND8|PMV_HALFPELREFINE8)int32_tPMVfastSearch8(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,			   const int start_y,				const int center_x,				const int center_y,			   const uint32_t MotionFlags,			   const uint32_t iQuant,			   const uint32_t iFcode,			   const MBParam * const pParam,			   const MACROBLOCK * const pMBs,			   const MACROBLOCK * const prevMBs,			   VECTOR * const currMV,			   VECTOR * const currPMV)

⌨️ 快捷键说明

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