text_code.c

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

C
981
字号
	free(DC_store);	free ((Char*)qcoeff);}/***********************************************************CommentBegin****** * * -- Bits_CountMB_combined -- texture encoding for combined texture/motion * * Purpose : *	Used for texture encoding in case of combined texture/motion * 		encoding. This function encodes the : *		- COD flag *		- MCBPC flag *		- CBPY flag *		- CBPC flag *		- DQUANT information * * Arguments in : *	SInt Mode : The macroblock encoding mode * 	Int CBP : Coded block pattern information * 	Int COD : Indicates whether this macroblock is coded or not *	Int ACpred_flag * 	Int vop_type : indicates the picture coding type *		(Intra,Inter) * * Arguments out : *	Bits* bits : a structure counting the number of bits * 	Image *bitstream : output texture bit stream * * ***********************************************************CommentEnd********/Void Bits_CountMB_combined(Int DQUANT, Int Mode, Int COD, Int ACpred_flag,Int CBP, Int vop_type,Bits* bits, Image *mottext_bitstream,Int *MB_transp_pattern){	Int   cbpy ,cbpc, length;	Int   MBtype=-1;	if ( Mode == MODE_INTRA ) MBtype = 3;	if ( Mode == MODE_INTER ) MBtype = 0;	if ( Mode == MODE_INTRA_Q) MBtype = 4;	if ( Mode == MODE_INTER_Q) MBtype = 1;	if ( Mode == MODE_INTER4V) MBtype = 2;	/* modified by NTT for GMC coding : start	  if ( Mode == MODE_DYN_SP) MBtype = 0;	  if ( Mode == MODE_DYN_SP_Q) MBtype = 1;	*/	if ( Mode == MODE_GMC) MBtype = 0;	if ( Mode == MODE_GMC_Q) MBtype = 1;	/* modified by NTT for GMC coding : end */	#ifdef D_TRACE	fprintf(ftrace, "DQUANT : %d\tMODE : %d\tVop Type : %d\n", DQUANT, Mode, vop_type);	fprintf(ftrace, "COD : %d\tCBP : %d\tAC Pred Flag : %d\n\n", COD, CBP, ACpred_flag);	#endif	cbpc = CBP & 3;	cbpy = CBP>>2;	/* COD */	if (vop_type != PCT_INTRA )	{		if (COD)		{			printf("COD = 1 in Bits_CountMB_combined \n");			printf("This function should not be used if COD is '1' \n");			exit(1);		}												  /* write COD */		BitstreamPutBits(mottext_bitstream, (long)(COD), 1L);		bits->COD++;	}	/* MCBPC */	if (vop_type == PCT_INTRA)		length = PutMCBPC_Intra (cbpc, MBtype, mottext_bitstream);	else		length = PutMCBPC_Inter (cbpc, MBtype, mottext_bitstream);	bits->MCBPC += length;	/* MCSEL syntax */	/* modified by NTT for GMC coding : start	 if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q))  && (vop_type == PCT_SPRITE))	*/	if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_GMC) || (Mode == MODE_GMC_Q))  && (vop_type == PCT_SPRITE))		/* modified by NTT for GMC coding : end */	{		if ((Mode == MODE_INTER) || (Mode == MODE_INTER_Q))			BitstreamPutBits(mottext_bitstream, (long) 0, 1L);		/* modified by NTT for GMC coding : start			  if ((Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q))		*/		if ((Mode == MODE_GMC) || (Mode == MODE_GMC_Q))			/* modified by NTT for GMC coding : end */			BitstreamPutBits(mottext_bitstream, (long) 1, 1L);		bits->MCBPC += 1;	}	/* ACpred_flag */	/* 17-Jan-97 JDL : correction no ACpred_flag in combined mode when intra_acdc_pred_disable is true */	if ((Mode == MODE_INTRA || Mode==MODE_INTRA_Q) && ACpred_flag != -1)	{		BitstreamPutBits(mottext_bitstream, (long)ACpred_flag, 1L);		bits->ACpred_flag += 1;	}	/* CBPY */	length = PutCBPY (cbpy, (Char)(Mode==MODE_INTRA||Mode==MODE_INTRA_Q),/*MB_transp_pattern*/NULL,mottext_bitstream);	bits->CBPY += length;	/* DQUANT */	/* modified by NTT for GMC coding : start	  if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_DYN_SP_Q))	*/	if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_GMC_Q))		/* modified by NTT for GMC coding : end */	{		switch (DQUANT)		{			case -1:				BitstreamPutBits(mottext_bitstream, 0L, 2L);				break;			case -2:				BitstreamPutBits(mottext_bitstream, 1L, 2L);				break;			case 1:				BitstreamPutBits(mottext_bitstream, 2L, 2L);				break;			case 2:				BitstreamPutBits(mottext_bitstream, 3L, 2L);				break;			default:				fprintf(stderr,"Invalid DQUANT\n");				exit(1);		}		bits->DQUANT += 2;	}}/***********************************************************CommentBegin****** * * -- doDCACpred -- Does DC/AC prediction. Changes qcoeff values as *		    appropriate. * * Purpose : *	Does DC/AC prediction. Changes qcoeff values as appropriate. * * Arguments in : *	Int CBP *	Int ncoeffs *	Int x_pos *	Int y_pos *	Int DC_store[][6][15]  	Stores coefficient values per MB for *			       	prediction (for one Vop) *	Int QP			QP value for this MB *	Int MB_width * * Arguments in/out : *	Int *qcoeff * * Return values : *	Int	The ACpred_flag, which is to be put into the bitstream * * Side effects : *	Modifies qcoeff if needed for the prediction. * ***********************************************************CommentEnd********/Int doDCACpred(Int *qcoeff, Int *CBP, Int ncoeffs, Int x_pos, Int y_pos,Int ***DC_store, Int QP, Int MB_width,Int direction[], Int mid_grey ){	Int i, m;	Int block_A, block_B, block_C;	Int Xpos[6] = {-1, 0, -1, 0, -1, -1};	Int Ypos[6] = {-1, -1, 0, 0, -1, -1};	Int Xtab[6] = {1, 0, 3, 2, 4, 5};	Int Ytab[6] = {2, 3, 0, 1, 4, 5};	Int Ztab[6] = {3, 2, 1, 0, 4, 5};	Int grad_hor, grad_ver, DC_pred;	Int pred_A[15], pred_C[15];	Int S = 0, S1, S2;	Int diff;	Int pcoeff[384];	Int ACpred_flag=-1;	/* Copy qcoeff to the prediction array pcoeff */	for (i = 0; i < (6*ncoeffs); i++)	{		pcoeff[i] = qcoeff[i];	}	for (i = 0; i < 6; i++)	{		if ((x_pos == 0) && y_pos == 0)			  /* top left corner */		{			block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8;			block_B = (i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;			block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8;		}		else if (x_pos == 0)					  /* left edge */		{			block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8;			block_B = (i == 1 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;			block_C = DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0];		}		else if (y_pos == 0)					  /* top row */		{			block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0];			block_B = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;			block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8;		}		else		{			block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0];			block_B = (DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])]				[Ztab[i]][0]);			block_C = DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0];		}		grad_hor = block_B - block_C;		grad_ver = block_A - block_B;		if ((ABS(grad_ver)) < (ABS(grad_hor)))		{			DC_pred = block_C;			direction[i] = 2;		}		else		{			DC_pred = block_A;			direction[i] = 1;		}		pcoeff[i*ncoeffs] = qcoeff[i*ncoeffs] - (DC_pred+cal_dc_scaler(QP,(i<4)?1:2)/2)/cal_dc_scaler(QP,(i<4)?1:2);		/* Find AC predictions */		if ((x_pos == 0) && y_pos == 0)			  /* top left corner */		{			if (i == 1 || i == 3)				for (m = 0; m < 15; m++)					pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);			else				nullfill(pred_A,mid_grey);			if (i == 2 || i == 3)				for (m = 0; m < 15; m++)					pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);			else				nullfill(pred_C,mid_grey);		}		else if (x_pos == 0)					  /* left edge */		{			if (i == 1 || i == 3)				for (m = 0; m < 15; m++)					pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);			else				nullfill(pred_A,mid_grey);			for (m = 0; m < 15; m++)				pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);		}		else if (y_pos == 0)					  /* top row */		{			for (m = 0; m < 15; m++)				pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);			if (i == 2 || i == 3)				for (m = 0; m < 15; m++)					pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);			else				nullfill(pred_C,mid_grey);		}		else		{			for (m = 0; m < 15; m++)			{				pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);				pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);			}		}		#if 1									  /* I think it should be like this, 14-NOV-1996 MW */		S1 = 0;		S2 = 0;		/* Now decide on AC prediction */		if (direction[i] == 1)					  /* Horizontal, left COLUMN of block A */		{			for (m = 0; m < 7; m++)			{				S1 += ABS(qcoeff[i*ncoeffs+(m+1)*8]);				diff = pcoeff[i*ncoeffs+(m+1)*8]					= qcoeff[i*ncoeffs+(m+1)*8] - pred_A[m+8];				S2 += ABS(diff);			}		}		else									  /* Vertical, top ROW of block C */		{			for (m = 1; m < 8; m++)			{				S1 += ABS(qcoeff[i*ncoeffs+m]);				diff = pcoeff[i*ncoeffs+m]					= qcoeff[i*ncoeffs+m] - pred_C[m];				S2 += ABS(diff);			}		}		S += (S1 - S2);		#endif	}	/* Now change qcoeff for DC pred or DC/AC pred */	if (S >=0)	{		for (i=0;i<ncoeffs*6; i++)			/* Modified due to N2171 Cl. 2.2.14 MW 25-MAR-1998 */			/* if ((i%64)&&(abs(pcoeff[i])>127)) { */			if ((i%64)&&(abs(pcoeff[i])>2047))		{			printf("predicted AC out of range");			S=-1;break;		}	}	if (S >= 0)									  /* Both DC and AC prediction */	{		ACpred_flag = 1;		for (i = 0; i < ncoeffs*6; i++)		{			qcoeff[i] = pcoeff[i];		}		/* Update CBP for predicted coeffs. */		*CBP = FindCBP(qcoeff, MODE_INTRA, 64);	}	else										  /* Only DC prediction */	{		ACpred_flag = 0;		for (i = 0; i < 6; i++)		{			qcoeff[i*ncoeffs] = pcoeff[i*ncoeffs];			direction[i] = 0;		}	}	return ACpred_flag;							  /* To be put into bitstream */}/** * Small routine to fill default prediction values into a DC_store entry */Void nullfill(Int pred[], Int mid_grey){	Int i;	pred[0] = mid_grey*8;	for (i = 1; i < 15; i++)	{		pred[i] = 0;	}}Int Idir_c(Int val, Int QP){	if (val<0) return (val-QP/2)/QP;	else return (val+QP/2)/QP;}/***********************************************************CommentBegin****** * * -- IntraDCSwitch_decisions -- * * Purpose : *	decide whether to use inter AC table to encode DC * * Arguments in : *	Int Mode * 	Int intra_dc_vlc_thr * 	Int Qp * ***********************************************************CommentEnd********/Int IntraDCSwitch_Decision(Int Mode,Int intra_dc_vlc_thr,Int Qp){	Int switched =0;	if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)	{		if (intra_dc_vlc_thr==0)			switched=0;		else if (intra_dc_vlc_thr==7)			switched=1;		else if (Qp>=intra_dc_vlc_thr*2+11)			switched=1;	}	return switched;}/***********************************************************CommentBegin****** * * -- cal_dc_scaler -- calculation of DC quantization scale according *					  to the incoming Q and type; * * Arguments in : *   Int Qp * ***********************************************************CommentEnd********/Int cal_dc_scaler (Int QP, Int type){	Int dc_scaler;	if (type == 1)	{		if (QP > 0 && QP < 5) dc_scaler = 8;		else if (QP > 4 && QP < 9) dc_scaler = 2 * QP;		else if (QP > 8 && QP < 25) dc_scaler = QP + 8;		else dc_scaler = 2 * QP - 16;	}	else	{		if (QP > 0 && QP < 5) dc_scaler = 8;		else if (QP > 4 && QP < 25) dc_scaler = (QP + 13) / 2;		else dc_scaler = QP - 6;	}	return dc_scaler;}/***********************************************************CommentBegin****** * * -- FindCBP -- Find the CBP for a macroblock * * Purpose : * Find the CBP for a macroblock * * Arguments in : * Int *qcoeff : pointer to quantized coefficients *  Int Mode : macroblock encoding mode information *  Int ncoeffs : the number of coefficients * * Return values : * Int CBP : The coded block pattern for a macroblock * ***********************************************************CommentEnd********/IntFindCBP (Int* qcoeff, Int Mode, Int ncoeffs){	Int i,j;	Int CBP = 0;	Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);	/* Set CBP for this Macroblock */	for (i = 0; i < 6; i++)	{		for (j = i*ncoeffs + intra; j < (i+1)*ncoeffs; j++)		{			if (qcoeff[j])			{				if (i == 0) {CBP |= 32;}				else if (i == 1) {CBP |= 16;}				else if (i == 2) {CBP |= 8;}				else if (i == 3) {CBP |= 4;}				else if (i == 4) {CBP |= 2;}				else if (i == 5) {CBP |= 1;}				else				{					fprintf (stderr, "Error in CBP assignment\n");					exit(-1);				}				break;			}		}	}	return CBP;}

⌨️ 快捷键说明

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