mot_est_comp.c

来自「实现在linux下的mpeg4编解码」· C语言 代码 · 共 643 行 · 第 1/2 页

C
643
字号
	/* Do motion estimation and store result in array */	halfpelflags=(SInt*)malloc(5*4*sizeof(SInt));	/*	halfpelflags=(SInt*)malloc(9*4*sizeof(SInt)); */	sad = 0;	for ( j=0; j< (br_height/MB_SIZE); j++)	{		hint_mv_w = hint_mv_h = 0.f;		for ( i=0; i< (br_width/MB_SIZE); i++)		{			/* Integer pel search */			Int min_error;			posmode =          j * imas_w +   i;			pos16   = pos8 = 2*j*2*imas_w + 2*i;			MBMotionEstimation(curr,				prev, br_x, br_y,				br_width, i, j, prev_x, prev_y,				vop_width, vop_height, enable_8x8_mv, edge,				f_code, sr_for, 				hint_mv_w, hint_mv_h, // the hint seeds				mv16_w, mv16_h,				mv8_w, mv8_h, &min_error, halfpelflags);			/* Inter/Intra decision */			Mode = ChooseMode(curr, 				i*MB_SIZE,j*MB_SIZE, min_error, br_width);			hint_mv_w = mv16_w[pos16];			hint_mv_h = mv16_h[pos16];			LoadArea(curr, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, (SInt *)curr_mb);			/* 0==MBM_INTRA,1==MBM_INTER16||MBM_INTER8 */			if ( Mode != 0)			{				FindSubPel (i*MB_SIZE,j*MB_SIZE, prev_ipol,					&curr_mb[0][0], 16, 16 , 0,					br_x-prev_x,br_y-prev_y,vop_width, vop_height,					edge, halfpelflags, &curr_comp_mb_16[0][0],					&mv16_w[pos16], &mv16_h[pos16], &min_error16);				/* sad16(0,0) already decreased by Nb/2+1 in FindHalfPel() */				sad16 = min_error16;				mode16[posmode] = MBM_INTER16;				if (enable_8x8_mv)				{					xsum = 0; ysum = 0;					FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,						&curr_mb[0][0], 8, 8 , 0,						br_x-prev_x,br_y-prev_y, vop_width, vop_height,						edge, halfpelflags, &curr_comp_mb_8[0][0],						&mv8_w[pos8], &mv8_h[pos8],	&min_error8_0);					xsum += (Int)(2*(mv8_w[pos8]));					ysum += (Int)(2*(mv8_h[pos8]));					FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,						&curr_mb[0][8], 8, 8 , 1,						br_x-prev_x,br_y-prev_y, vop_width,vop_height,						edge, halfpelflags, &curr_comp_mb_8[0][8],						&mv8_w[pos8+1], &mv8_h[pos8+1],	&min_error8_1);					xsum += (Int)(2*(mv8_w[pos8+1]));					ysum += (Int)(2*(mv8_h[pos8+1]));					pos8+=2*imas_w;					FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol,						&curr_mb[8][0], 8, 8 , 2,						br_x-prev_x,br_y-prev_y, vop_width,vop_height,						edge, halfpelflags, &curr_comp_mb_8[8][0], 						&mv8_w[pos8], &mv8_h[pos8],	&min_error8_2);					xsum += (Int)(2*(mv8_w[pos8]));					ysum += (Int)(2*(mv8_h[pos8]));					FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, 						&curr_mb[8][8], 8, 8 , 3,						br_x-prev_x,br_y-prev_y, vop_width,vop_height,						edge, halfpelflags, &curr_comp_mb_8[8][8], 						&mv8_w[pos8+1], &mv8_h[pos8+1],	&min_error8_3);					xsum += (Int)(2*(mv8_w[pos8+1]));					ysum += (Int)(2*(mv8_h[pos8+1]));					sad8 = min_error8_0+min_error8_1+min_error8_2+min_error8_3;					/* Choose 8x8 or 16x16 vectors */					if (sad8 < (sad16 -(128+1)))						mode16[posmode] = MBM_INTER8;				}							  /* end of enable_8x8_mv mode */				/* When choose 16x16 vectors */				/* sad16(0,0) was decreased by MB_Nb, now add it back */				if ((mv16_w[pos16]==0.0) && (mv16_h[pos16]==0.0) && (mode16[posmode]==MBM_INTER16))					sad16 += 128+1;				/* calculate motion vectors for chroma compensation */				if(mode16[posmode] == MBM_INTER8)				{					dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);					dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);					sad += sad8;				}				else /* mode == MBM_INTER16 */				{					dx = (Int)(2 * mv16_w[pos16]);					dy = (Int)(2 * mv16_h[pos16]);					dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );					dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );					sad += sad16;				}				GetPred_Chroma (i*MB_SIZE, j*MB_SIZE, dx, dy, 					prev_u, prev_v, curr_comp_u, curr_comp_v,					br_width, vop_width,					prev_x_min/4,prev_y_min/4,prev_x_max/4,prev_y_max/4, rounding_type);			}								  /* end of mode non zero */			else							  /* mode = 0 INTRA */			{				mode16[posmode] = MBM_INTRA;								for (k = 0; k < MB_SIZE*MB_SIZE; k++) 				{					// for INTRA MB, set compensated 0 to generate correct error image					curr_comp_mb_16[k/MB_SIZE][k%MB_SIZE] = 0;					// for INTRA_MB, SAD is recalculated from image instead of using min_error					sad += curr_mb[k/MB_SIZE][k%MB_SIZE];				}			}			if (mode16[posmode] == MBM_INTER8)				SetArea((SInt*)curr_comp_mb_8, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);			else				SetArea((SInt*)curr_comp_mb_16, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y);		}   /* end of i loop */	}	/* end of j loop */	*mad = (float)sad/(br_width*br_height);	free((Char*)halfpelflags);	return;}/***********************************************************CommentBegin****** * * unrestricted_MC_chro * * Purpose : *	To make unrestricted MC * ***********************************************************CommentEnd********//*Int unrestricted_MC_chro(Int x,Int y, Int npix,	Int prev_x_min,Int prev_y_min,	Int prev_x_max, Int prev_y_max){	if (x < prev_x_min) x = prev_x_min;	else if (x >=prev_x_max) x = prev_x_max-1;	if (y < prev_y_min) y = prev_y_min;	else if (y >=prev_y_max) y = prev_y_max-1;	return(x+y*npix);}*/#define unrestricted_MC_chro(x,y,npix,prev_x_min,prev_y_min,prev_x_max,prev_y_max) ((x)+(y)*(npix))/***********************************************************CommentBegin****** * * -- GetPred_Chroma -- Predicts chrominance macroblock * * Purpose : *	Does the chrominance prediction for P-frames * * Arguments in : *	current position in image, *	motionvectors, *	pointers to compensated and previous Vops, *	width of the compensated Vop *  width of the previous/reference Vop * ***********************************************************CommentEnd********/Void GetPred_Chroma (	Int x_curr,	Int y_curr,	Int dx,	Int dy,	SInt *prev_u,	SInt *prev_v,	SInt *comp_u,	SInt *comp_v,	Int width,	Int width_prev,	Int prev_x_min,	Int prev_y_min,	Int prev_x_max,	Int prev_y_max,	Int rounding_control){	Int m,n;	Int x, y, ofx, ofy, lx;	Int xint, yint;	Int xh, yh;	Int index1,index2,index3,index4;	lx = width_prev/2;	x = x_curr>>1;	y = y_curr>>1;	xint = dx>>1;	xh = dx & 1;	yint = dy>>1;	yh = dy & 1;	if (!xh && !yh)	{		for (n = 0; n < 8; n++)		{			for (m = 0; m < 8; m++)			{				ofx = x + xint + m;				ofy = y + yint + n;				index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				comp_u[(y+n)*width/2+x+m]					= *(prev_u+index1);				comp_v[(y+n)*width/2+x+m]					= *(prev_v+index1);			}		}	}	else if (!xh && yh)	{		for (n = 0; n < 8; n++)		{			for (m = 0; m < 8; m++)			{				ofx = x + xint + m;				ofy = y + yint + n;				index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				index2 =  unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				comp_u[(y+n)*width/2+x+m]					= (*(prev_u+index1) +					*(prev_u+index2) + 1- rounding_control)>>1;				comp_v[(y+n)*width/2+x+m]					= (*(prev_v+index1) +					*(prev_v+index2) + 1- rounding_control)>>1;			}		}	}	else if (xh && !yh)	{		for (n = 0; n < 8; n++)		{			for (m = 0; m < 8; m++)			{				ofx = x + xint + m;				ofy = y + yint + n;				index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				index2 =  unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				comp_u[(y+n)*width/2+x+m]					= (*(prev_u+index1) +					*(prev_u+index2) + 1- rounding_control)>>1;				comp_v[(y+n)*width/2+x+m]					= (*(prev_v+index1) +					*(prev_v+index2) + 1- rounding_control)>>1;			}		}	}	else	{											  /* xh && yh */		for (n = 0; n < 8; n++)		{			for (m = 0; m < 8; m++)			{				ofx = x + xint + m;				ofy = y + yint + n;				index1 =  unrestricted_MC_chro(ofx,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				index2 =  unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				index3 =  unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				index4 =  unrestricted_MC_chro(ofx+xh,ofy+yh,lx,prev_x_min,					prev_y_min,prev_x_max,prev_y_max);				comp_u[(y+n)*width/2+x+m]					= (*(prev_u+index1)+					*(prev_u+index2)+					*(prev_u+index3)+					*(prev_u+index4)+					2- rounding_control)>>2;				comp_v[(y+n)*width/2+x+m]					= (*(prev_v+index1)+					*(prev_v+index2)+					*(prev_v+index3)+					*(prev_v+index4)+					2- rounding_control)>>2;			}		}	}	return;}

⌨️ 快捷键说明

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