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

📄 dsp_vop.c

📁 基于DM642平台的H.264编码器优化代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	qcoeff_ind = g_qcoeff;

//		fdct_8x8(g_fblock[0],6);


	for (k = 0; k < 6; k++)
	{

//		fdct_enc(g_fblock[k]);
        IMG_fdct_8x8(g_fblock[k],1);//TI库函数调用

		if (k < 4) type = 1;
		else type = 2;

		BlockQuantH263(g_fblock[k],QP,Mode,type,qcoeff_ind);//量化

		BlockDequantH263(qcoeff_ind,QP,Mode,type,g_fblock[k]);//反量化

		qcoeff_ind += 64;
	}
	
//		idct_8x8(g_fblock[0],6);

	for (k = 0; k < 6; k++)
	{

//		idct_enc(g_fblock[k]);
        IMG_idct_8x8(g_fblock[k],1);

		switch (k)
		{
			case 0:
				offset = 0;
				xwidth = 16;
				break;
			case 1:
				offset = 8;
				xwidth = 16;
				break;
			case 2:
				offset = 8*MB_SIZE;
				xwidth = 16;
				break;
			case 3:
				offset = 8*MB_SIZE+8;
				xwidth = 16;
				break;
			case 4:
				offset = MB_SIZE*MB_SIZE;
				xwidth = 8;
				break;
			case 5:
				offset = (MB_SIZE*MB_SIZE/4)*5;
				xwidth = 8;
				break;
			default:
				break;
		}

		if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
		{

			for (i = 0; i < 8; i++)
			{
				for (j = 0; j < 8; j++)
				{
					g_currMB[offset+j] = (unsigned char)MIN(255, MAX(0, g_fblock[k][i*8 +j]) );
				}//copy from g_fblock to g_currMB
				offset += xwidth;
			}
	
		}else{
		
			for (i = 0; i < 8; i++)
			{
				for (j = 0; j < 8; j++)
				{
					g_currMB[offset+j] =(unsigned char)MIN(255, MAX(0, (g_fblock[k][i*8 +j]+g_compMB[offset+j]) ) );
				}//copy from (g_fblock + g_compMB) to g_currMB
				offset += xwidth;
			}
		}
	}
	return;
}
//量化函数
inline void
BlockQuantH263 (short *coeff, char QP, char mode, char type, short *qcoeff)
{
	short maxDC=255,level,dc_scaler;
	register short i;
	dc_scaler = cal_dc_scaler(QP,type);


		if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
		{										  
//			qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] >= 0) ? (coeff[0] + dc_scaler/2)/dc_scaler : (coeff[0] - dc_scaler/2) /dc_scaler));
			qcoeff[0] = MAX(1,MIN(maxDC-1,  (coeff[0] + dc_scaler/2)/dc_scaler) );

			for (i = 1; i < 64; i++)
			{
				level = (ABS(coeff[i])) / (2*QP);

				qcoeff[i] =  MIN(2047,MAX(-2048,SIGN(coeff[i]) * level));
			}
		}
		else /* non Intra */
		{										  
			for (i = 0; i < 64; i++)
			{
				level = (ABS(coeff[i])-QP/2)  / (2*QP);

				qcoeff[i] =  MIN(2047,MAX(-2048,SIGN(coeff[i]) * level));
			}
		}

	return;
}
char cal_dc_scaler (char QP, char type)
{

	char 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;
}

//反量化函数
inline void BlockDequantH263 (short *qcoeff, char QP, char mode, char type, short *rcoeff)
{

	register char i;
	char dc_scaler;
	short lim;
	lim = 2048; //(1 << (bits_per_pixel + 3));

		for (i = 0; i < 64; i++)
		{
			if (qcoeff[i])
			{
//@				qcoeff[i] =  MIN(2047, MAX(-2048, qcoeff[i] ));
				if ((QP % 2) == 1)
					rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
				else
					rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
				rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
			}
			else
				rcoeff[i] = 0;
		}
		if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
		{										  /* Intra */
//			if (short_video_header)
//				dc_scaler = 8;
//			else
				dc_scaler = cal_dc_scaler(QP,type);

			rcoeff[0] = qcoeff[0] * dc_scaler;
		}

	for (i=0;i<64;i++)
		if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
	else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);

	return;
}

Int FindCBP (short* qcoeff, char Mode, char ncoeffs)
{
	register short i,j;
	Int CBP = 0;
	char 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			 {CBP |= 1;}

				break;
			}
		}
	}

	return CBP;
}

char doDCACpred(short *qcoeff, Int *CBP, char ncoeffs, short x_pos, short y_pos,
			short ***DC_store_curr, short ***DC_store_above, char QP, char direction[] )
{
	register short i, m;
	short block_A, block_B, block_C;
	short defaultDC;
	char Xpos[6] = {-1, 0, -1, 0, -1, -1};
//	char Ypos[6] = {-1, -1, 0, 0, -1, -1};
	char Xtab[6] = {1, 0, 3, 2, 4, 5};
	char Ytab[6] = {2, 3, 0, 1, 4, 5};
	char Ztab[6] = {3, 2, 1, 0, 4, 5};
	short grad_hor, grad_ver, DC_pred;
	short pred_A[15], pred_C[15];
	Int S = 0, S1, S2;
	Int diff;

	short diff_coeff[6][15];
	char ACpred_flag=-1;
	char dc_scaler,acPredOutOfRange;

	acPredOutOfRange =0;
	defaultDC=1024;

	for(i=0;i<8;i++)
	{
		diff_coeff[0][i]=qcoeff[i];
		diff_coeff[1][i]=qcoeff[64+i];
		diff_coeff[2][i]=qcoeff[128+i];
		diff_coeff[3][i]=qcoeff[192+i];	
		diff_coeff[4][i]=qcoeff[256+i];
		diff_coeff[5][i]=qcoeff[320+i];
	}
	for(i=0;i<7;i++)
	{
		diff_coeff[0][i+8]=qcoeff[(i+1)*8];
		diff_coeff[1][i+8]=qcoeff[ 64+(i+1)*8];
		diff_coeff[2][i+8]=qcoeff[128+(i+1)*8];		
		diff_coeff[3][i+8]=qcoeff[192+(i+1)*8];
		diff_coeff[4][i+8]=qcoeff[256+(i+1)*8];
		diff_coeff[5][i+8]=qcoeff[320+(i+1)*8];
	}

	S1 = 0;
	S2 = 0;

	for (i = 0; i < 6; i++)
	{
		if ((x_pos == 0) && (y_pos == 0))			  /* top left corner */
		{
			block_A = (i == 1 || i == 3) ? DC_store_curr[0][Xtab[i]][0] : defaultDC;
			block_B = (i == 3) ? DC_store_curr[0][Ztab[i]][0] : defaultDC;
			block_C = (i == 2 || i == 3) ? DC_store_curr[0][Ytab[i]][0] : defaultDC;
		}
		else if (x_pos == 0)					  /* left edge */
		{
			block_A = (i == 1 || i == 3) ? DC_store_curr[x_pos][Xtab[i]][0] : defaultDC;
			block_B = (i == 1) ? DC_store_above[x_pos][Ztab[i]][0] : (i == 3) ? DC_store_curr[x_pos][Ztab[i]][0] : defaultDC;
			block_C = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][0] : DC_store_above[x_pos][Ytab[i]][0];
		}
		else if (y_pos == 0)					  /* top row */
		{
			block_A = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][0];
			block_B = (i == 2 || i == 3) ? DC_store_curr[x_pos+Xpos[i] ][Ztab[i]][0] : defaultDC;
			block_C = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][0] : defaultDC;
		}
		else
		{
			block_A = DC_store_curr[x_pos+Xpos[i] ][Xtab[i]][0];
			block_B = (i == 2 || i == 3) ?	(DC_store_curr[(x_pos+Xpos[i])][Ztab[i]][0]):
											(DC_store_above[(x_pos+Xpos[i])][Ztab[i]][0]);
			block_C = (i == 2 || i == 3) ?	DC_store_curr[x_pos][Ytab[i]][0] : DC_store_above[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;
		}
		dc_scaler = cal_dc_scaler(QP,(i<4)?1:2);

		diff_coeff[i][0] = qcoeff[i*ncoeffs] - (DC_pred+dc_scaler/2)/dc_scaler;//DC_pred must be positive for intra MB

	if(acPredOutOfRange==0)	
	{
		/* 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] = DC_store_curr[0][Xtab[i]][m]  ;
			else
				for (m = 1; m < 15; m++)
				{
					pred_A[m] = 0;
				}

			if (i == 2 || i == 3)
				for (m = 0; m < 15; m++)
					pred_C[m] = DC_store_curr[0][Ytab[i]][m];
			else
				for (m = 1; m < 15; m++)
				{
					pred_C[m] = 0;
				}
		}
		else if (x_pos == 0)					  /* left edge */
		{
			if (i == 1 || i == 3)
				for (m = 0; m < 15; m++)
					pred_A[m] = DC_store_curr[0][Xtab[i]][m];
			else
				for (m = 1; m < 15; m++)
				{
					pred_A[m] = 0;
				}

			for (m = 0; m < 15; m++)
				pred_C[m] = (i == 2 || i == 3) ? DC_store_curr[0][Ytab[i]][m] : DC_store_above[0][Ytab[i]][m];
		}
		else if (y_pos == 0)					  /* top row */
		{
			for (m = 0; m < 15; m++)
				pred_A[m] = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][m];

			if (i == 2 || i == 3)
				for (m = 0; m < 15; m++)
					pred_C[m] = DC_store_curr[x_pos][Ytab[i]][m];
			else
				for (m = 1; m < 15; m++)
				{
					pred_C[m] = 0;
				}
		}
		else
		{
			for (m = 0; m < 15; m++)
			{
				pred_A[m] = DC_store_curr[x_pos+Xpos[i]][Xtab[i]][m];
				pred_C[m] = (i == 2 || i == 3) ? DC_store_curr[x_pos][Ytab[i]][m] : DC_store_above[x_pos][Ytab[i]][m];
			}
		}

		/* 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 =diff_coeff[i][m+8]
						= qcoeff[i*ncoeffs+(m+1)*8] - pred_A[m+8];

					//ldm I think the outOfRange should be done this way
					if(ABS(diff)>127) 
					{	acPredOutOfRange=1;
						break;
					}
					S2 += ABS(diff);
				}
			}
			else	  /* Vertical, top ROW of block C */
			{
				for (m = 1; m < 8; m++)
				{
					S1 += ABS(qcoeff[i*ncoeffs+m]);
					diff = diff_coeff[i][m]
						= qcoeff[i*ncoeffs+m] - pred_C[m];

					//ldm I think the outOfRange should be done this way
					if(ABS(diff)>127) 
					{	acPredOutOfRange=1;
						break;
					}
					S2 += ABS(diff);
				}
			}
			S += (S1 - S2);
	}

	}

	if( (S >= 0)&&(acPredOutOfRange==0) )	 /* Both DC and AC prediction */
	{
		ACpred_flag = 1;

		for(m=0;m<8;m++)
		{
			qcoeff[m]	 =diff_coeff[0][m];
			qcoeff[64+m] =diff_coeff[1][m];
			qcoeff[128+m]=diff_coeff[2][m];
			qcoeff[192+m]=diff_coeff[3][m];	
			qcoeff[256+m]=diff_coeff[4][m];
			qcoeff[320+m]=diff_coeff[5][m];
		}
		for(m=0;m<7;m++)
		{
			qcoeff[(m+1)*8]	   =diff_coeff[0][m+8];
			qcoeff[ 64+(m+1)*8]=diff_coeff[1][m+8];
			qcoeff[128+(m+1)*8]=diff_coeff[2][m+8];		
			qcoeff[192+(m+1)*8]=diff_coeff[3][m+8];
			qcoeff[256+(m+1)*8]=diff_coeff[4][m+8];
			qcoeff[320+(m+1)*8]=diff_coeff[5][m+8];
		}
		/* 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] = diff_coeff[i][0];
			direction[i] = 0;
		}
	}
	return ACpred_flag;							  /* To be put into bitstream */
}


void Bits_CountMB_combined(char Mode, char COD, char ACpred_flag,Int CBP, char vop_type)
{
	char   cbpy ,cbpc;
	char   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;
	if ( Mode == MODE_GMC) MBtype = 0;
	if ( Mode == MODE_GMC_Q) MBtype = 1;
	cbpc = CBP & 3;
	cbpy = CBP>>2;

	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);
//@		}

// if it is an interMB in PVOP, the COD here should be 0, if the COD is 1,
// it means the MB is not-coded, and the COD is put into stream outside of the function.
		BitstreamPutBits((UInt)COD, 1L);	/* COD */
	}

	/* MCBPC */
	if (vop_type == PCT_INTRA)
		PutMCBPC_Intra (cbpc, MBtype);
	else
		PutMCBPC_Inter (cbpc, MBtype);

	/* MCSEL syntax for sprite */
//@	if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_GMC) || (Mode == MODE_GMC_Q))  && (vop_type == PCT_SPRITE))
//@	{
//@		if ((Mode == MODE_INTER) || (Mode == MODE_INTER_Q))

⌨️ 快捷键说明

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