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

📄 motion_est.c

📁 mpeg4代码,比较具体
💻 C
📖 第 1 页 / 共 5 页
字号:
{	const uint32_t iWcount = pParam->mb_width;	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;	int32_t min_dx;	int32_t max_dx;	int32_t min_dy;	int32_t max_dy;	VECTOR pmv[4];	int32_t psad[4];	VECTOR newMV;	VECTOR backupMV;	VECTOR startMV;/*  const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount; */	const MACROBLOCK *const prevMB = prevMBs + (x >> 1) + (y >> 1) * iWcount;	 int32_t threshA, threshB;	int32_t iFound, bPredEq;	int32_t iMinSAD, iSAD;	int32_t iSubBlock = (y & 1) + (y & 1) + (x & 1);	MainSearch8FuncPtr MainSearchPtr;	/* Init variables */	startMV.x = start_x;	startMV.y = start_y;	/* Get maximum range */	get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight,			  iFcode);	if (!(MotionFlags & PMV_HALFPELDIAMOND8)) {		min_dx = EVEN(min_dx);		max_dx = EVEN(max_dx);		min_dy = EVEN(min_dy);		max_dy = EVEN(max_dy);	}	/* because we might use IF (dx>max_dx) THEN dx=max_dx; */	bPredEq = get_pmvdata2(pMBs, iWcount, 0, (x >> 1), (y >> 1), iSubBlock, pmv, psad);	if ((x == 0) && (y == 0)) {		threshA = 512 / 4;		threshB = 1024 / 4;	} else {		threshA = psad[0] / 4;	/* good estimate? */		threshB = threshA + 256 / 4;		if (threshA < 512 / 4)			threshA = 512 / 4;		if (threshA > 1024 / 4)			threshA = 1024 / 4;		if (threshB > 1792 / 4)			threshB = 1792 / 4;	}	iFound = 0;/* 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_USESQUARES8)      MainSearchPtr = Square8_MainSearch;  else	if (MotionFlags & PMV_ADVANCEDDIAMOND8)		MainSearchPtr = AdvDiamond8_MainSearch;	else		MainSearchPtr = Diamond8_MainSearch;	*currMV = startMV;	iMinSAD =		sad8(cur,			 get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV,						iEdgedWidth), iEdgedWidth);	iMinSAD +=		calc_delta_8(currMV->x - center_x, currMV->y - center_y,					 (uint8_t) iFcode, iQuant);	if ((iMinSAD < 256 / 4) || ((MVequal(*currMV, prevMB->mvs[iSubBlock]))								&& ((int32_t) iMinSAD <									prevMB->sad8[iSubBlock]))) {		if (MotionFlags & PMV_QUICKSTOP16)			goto PMVfast8_Terminate_without_Refine;		if (MotionFlags & PMV_EARLYSTOP16)			goto PMVfast8_Terminate_with_Refine;	}/* Step 2 (lazy eval): 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], prevMB->mvs[iSubBlock])))		iFound = 2;/* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.    Otherwise select large Diamond Search. */	if ((!MVzero(pmv[0])) || (threshB < 1536 / 4) || (bPredEq))		iDiamondSize = 1;		/* 1 halfpel! */	else		iDiamondSize = 2;		/* 2 halfpel = 1 full pixel! */	if (!(MotionFlags & PMV_HALFPELDIAMOND8))		iDiamondSize *= 2;/*    Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.    Also calculate (0,0) but do not subtract offset.    Let MinSAD be the smallest SAD up to this point.    If MV is (0,0) subtract offset. *//* the median prediction might be even better than mv16 */	if (!MVequal(pmv[0], startMV))		CHECK_MV8_CANDIDATE(center_x, center_y);/* (0,0) if needed */	if (!MVzero(pmv[0]))		if (!MVzero(startMV))			CHECK_MV8_ZERO;/* previous frame MV if needed */	if (!MVzero(prevMB->mvs[iSubBlock]))		if (!MVequal(prevMB->mvs[iSubBlock], startMV))			if (!MVequal(prevMB->mvs[iSubBlock], pmv[0]))				CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,									prevMB->mvs[iSubBlock].y);	if ((iMinSAD <= threshA) ||		(MVequal(*currMV, prevMB->mvs[iSubBlock]) &&		 ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {		if (MotionFlags & PMV_QUICKSTOP16)			goto PMVfast8_Terminate_without_Refine;		if (MotionFlags & PMV_EARLYSTOP16)			goto PMVfast8_Terminate_with_Refine;	}/* left neighbour, if allowed and needed */	if (!MVzero(pmv[1]))		if (!MVequal(pmv[1], startMV))			if (!MVequal(pmv[1], prevMB->mvs[iSubBlock]))				if (!MVequal(pmv[1], pmv[0])) {					if (!(MotionFlags & PMV_HALFPEL8)) {						pmv[1].x = EVEN(pmv[1].x);						pmv[1].y = EVEN(pmv[1].y);					}					CHECK_MV8_CANDIDATE(pmv[1].x, pmv[1].y);				}/* top neighbour, if allowed and needed */	if (!MVzero(pmv[2]))		if (!MVequal(pmv[2], startMV))			if (!MVequal(pmv[2], prevMB->mvs[iSubBlock]))				if (!MVequal(pmv[2], pmv[0]))					if (!MVequal(pmv[2], pmv[1])) {						if (!(MotionFlags & PMV_HALFPEL8)) {							pmv[2].x = EVEN(pmv[2].x);							pmv[2].y = EVEN(pmv[2].y);						}						CHECK_MV8_CANDIDATE(pmv[2].x, pmv[2].y);/* top right neighbour, if allowed and needed */						if (!MVzero(pmv[3]))							if (!MVequal(pmv[3], startMV))								if (!MVequal(pmv[3], prevMB->mvs[iSubBlock]))									if (!MVequal(pmv[3], pmv[0]))										if (!MVequal(pmv[3], pmv[1]))											if (!MVequal(pmv[3], pmv[2])) {												if (!													(MotionFlags &													 PMV_HALFPEL8)) {													pmv[3].x = EVEN(pmv[3].x);													pmv[3].y = EVEN(pmv[3].y);												}												CHECK_MV8_CANDIDATE(pmv[3].x,																	pmv[3].y);											}					}	if ((MVzero(*currMV)) &&		(!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )		iMinSAD -= MV8_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[iSubBlock]) &&		 ((int32_t) iMinSAD < prevMB->sad8[iSubBlock]))) {		if (MotionFlags & PMV_QUICKSTOP16)			goto PMVfast8_Terminate_without_Refine;		if (MotionFlags & PMV_EARLYSTOP16)			goto PMVfast8_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. */	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_EXTSEARCH8) {/* 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,								  pmv[0].x, pmv[0].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.   By performing an optional local half-pixel search, we can refine this result even further.*/  PMVfast8_Terminate_with_Refine:	if (MotionFlags & PMV_HALFPELREFINE8)	/* perform final half-pel step  */		iMinSAD =			Halfpel8_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);  PMVfast8_Terminate_without_Refine:	currPMV->x = currMV->x - center_x;	currPMV->y = currMV->y - center_y;	return iMinSAD;}int32_tEPZSSearch16(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){	const uint32_t iWcount = pParam->mb_width;	const uint32_t iHcount = pParam->mb_height;	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;/*  const MACROBLOCK * const pMB = pMBs + x + y * iWcount; */	const MACROBLOCK *const prevMB = prevMBs + x + y * iWcount;	MACROBLOCK *oldMB = NULL;	 int32_t thresh2;	int32_t bPredEq;	int32_t iMinSAD, iSAD = 9999;	MainSearch16FuncPtr MainSearchPtr;	if (oldMBs == NULL) {		oldMBs = (MACROBLOCK *) calloc(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);	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_pmvdata2(pMBs, iWcount, 0, x, y, 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->x = start_x;			currMV->y = start_y;			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 - center_x, currMV->y - center_y,					  (uint8_t) iFcode, iQuant);/* thresh1 is fixed to 256  */	if ((iMinSAD < 256) ||		((MVequal(*currMV, prevMB->mvs[0])) &&		 ((int32_t) iMinSAD < prevMB->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(prevMB->mvs[0].x, prevMB->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 neigh

⌨️ 快捷键说明

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