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

📄 dsp_vop.c

📁 基于DM642平台的H.264编码器优化代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <std.h>
#include "dsp_type.h"
#include "dsp_global.h"
#include "dsp_stream.h"
#include "dsp_vop.h"
#include "dsp_vlc.h"

//static unsigned char * g_currMB1;
/*
void initVopPar()//初始化各参数
{
	p_par->prediction_type=I_VOP;
	p_par->rounding_type=0;
	p_par->width=720;
	p_par->height=576;
	p_par->hor_spat_ref=-16;
	p_par->ver_spat_ref=-16;
	p_par->quantizer=8;
	p_par->intra_quantizer=8;
	p_par->time_increment_resolution=30;
	p_par->sr_for=16;
	p_par->fcode_for=1;
	p_par->quant_precision=5;
	p_par->bits_per_pixel=8;
	p_par->modulo_time_base=0;

}
*/
void CodeVOVOLHeader()
{
	BitstreamPutBits(0x100,32);//VO_START_CODE
	BitstreamPutBits(0x120,32);//VOL_START_CODE
	BitstreamPutBits(0,1);//random_accessible_vol
	BitstreamPutBits(4,8);//video_object_type_indication,simple object
	BitstreamPutBits(0,1);//is_object_layer_identifier
	BitstreamPutBits(1,4);//aspect_ratio_info
	BitstreamPutBits(0,1);//vol_control_paramters
	BitstreamPutBits(0,2);//video_object_layer_shape
	BitstreamPutBits(1,1);//marker
	BitstreamPutBits(30,16);//vop_time_increment_resolution
	BitstreamPutBits(1,1);//marker
	BitstreamPutBits(0,1);//fixed_vop_rate
	BitstreamPutBits(1,1);//marker
	BitstreamPutBits(p_par->width,13);//video_object_layer_width
	BitstreamPutBits(1,1);//marker
	BitstreamPutBits(p_par->height,13);//video_object_layer_height
	BitstreamPutBits(1,1);//marker
	BitstreamPutBits(0,1);//interlaced
	BitstreamPutBits(1,1);//obmc_disable
	BitstreamPutBits(0,1);//sprite_enable
	BitstreamPutBits(0,1);//not_8_bit
	BitstreamPutBits(0,1);//quant_type
	BitstreamPutBits(1,1);//complexity_estimation_disable
	BitstreamPutBits(0,1);//resync_marker_disable
	BitstreamPutBits(0,1);//data_partitioned
	BitstreamPutBits(0,1);//scalability

}
char get_fcode (short search_range)
{
	if (search_range<=16) return 1;
	else if (search_range<=32) return 2;
	else if (search_range<=64) return 3;
	else if (search_range<=128) return 4;
	else if (search_range<=256) return 5;
	else if (search_range<=512) return 6;
	else if (search_range<=1024) return 7;
	else return (-1);
}

void CodeVop(unsigned char * curr,
			unsigned char * reference,
			unsigned char * reconstruct,
//			short * error,
			short frame)
{
//	short *mvx, *mvy;	//mot
//	char * MB_md;	//mot
//	char      edge,f_code_for;
	int	  mad =0;//平均绝对差值准则
//	edge = 0;
//	mvx = mot_x; mvy = mot_y; MB_md = MB_decisions;//mot
//	f_code_for = p_par->fcode_for;


	if (p_par->prediction_type == P_VOP)//如果是P帧则进行运动估计 
	{

		/* Carry out motion estimation and compensation*/
		MotionEstimation(curr, reference, &mad, g_motion_x,g_motion_y,g_MB_Mode);

	}
	else
		mad = SCENE_CHANGE_THREADHOLD * 2;

	if (mad > SCENE_CHANGE_THREADHOLD) //如果属于剧烈运动
	{
		// mad is too large. 
		// the coding mode should be I_VOP
		p_par->prediction_type = I_VOP;
		p_par->rounding_type = 1;

		// We need to recalculate MAD here, since the last MAD was calculated by assuming
		// INTER coding, though the actual difference might not be significant to coding.
//?		mad = (Float) compute_MAD_unchar(curr);

		CodeVopHeader(frame);

		/* Code Texture in Intra mode */

		CodeIntraVOPTexture(curr,reconstruct);//进行帧内编码

//@			BitstreamPut(texture_bitstream,vo_id,vol_id);
	} 
	else 
	{
		// mad is fine. continue to code as P_VOP
		p_par->prediction_type = P_VOP;

		CodeVopHeader(frame);//进行帧间编码

//@		SubImage(curr->y_chan, reconstruct->y_chan, error->y_chan);
//@		SubImage(curr->u_chan, reconstruct->u_chan, error->u_chan);
//@		SubImage(curr->v_chan, reconstruct->v_chan, error->v_chan); 

		CodeInterVOP(curr, reconstruct, g_MB_Mode,g_motion_x, g_motion_y,reference);

//@		pnum_bits->syntax +=
//@			BitstreamPutVopHeader(vo_id,frame,vol_id);

//@		pnum_bits->mot_shape_text +=
//@			BitstreamPut(mottext_bitstream,vo_id,vol_id);
	}

//@	if (MB_decisions) FreeImage(MB_decisions);
//@	if (mot_x) FreeImage(mot_x);
//@	if (mot_y) FreeImage(mot_y);

	/* Deallocate memory for intermediate bitstreams */
//@	BitstreamFree(texture_bitstream);
//@	BitstreamFree(mottext_bitstream);

//@	ImageRepetitivePadding(reference->y_chan, 16);
//@	ImageRepetitivePadding(reference->u_chan, 8);
//@	ImageRepetitivePadding(reference->v_chan, 8);

//@	pnum_bits->texture+=
//@		NextStartCode(vo_id,vol_id);	  



	return;
}
void CodeVopHeader(short frame)//进行VOP头编码
{
	short time_modulo;
	unsigned short time_inc;
	UChar bits_inc;
	short   currSecond,t_resolution;

	BitstreamPutBits(VOP_START_CODE,VOP_START_CODE_LENGTH);
	BitstreamPutBits((UInt)p_par->prediction_type,2);/* vop_coding_type */

	t_resolution = p_par->time_increment_resolution;
	currSecond = (int)(frame/t_resolution);
	time_modulo = currSecond - p_par->modulo_time_base;
	BitstreamPutBits((UInt)0xfffffffe,time_modulo+1);/* modulo_time_base */

	p_par->modulo_time_base = currSecond;
	BitstreamPutBits( 1,1);/* marker bit */

	time_inc = frame - currSecond * t_resolution;
	for(bits_inc=1;bits_inc<16;bits_inc++)
	{
		if(t_resolution==1)
			break;
		t_resolution = t_resolution>>1;
	}
	BitstreamPutBits(time_inc,bits_inc);/* vop_time_increment */
	BitstreamPutBits( 1,1);/* marker bit */
	BitstreamPutBits( 1L,1L);/* vop_coded */
	if( p_par->prediction_type == P_VOP )
		BitstreamPutBits( p_par->rounding_type,1);/* vop_rounding_type */
	BitstreamPutBits(0,3);/* intra_dc_vlc_thr,force to zero */

	if (p_par->prediction_type == I_VOP)	  
		BitstreamPutBits( p_par->intra_quantizer,p_par->quant_precision);/* vop_quant */
	else   /* P_VOP */
		BitstreamPutBits( p_par->quantizer,p_par->quant_precision);/* vop_quant */

	if (p_par->prediction_type!=I_VOP)
	{
		BitstreamPutBits( p_par->fcode_for,3);/* vop_fcode_forward */
	}

}
//进行VOP纹理编码
void CodeIntraVOPTexture(unsigned char * curr,unsigned char * reference)
{
	char QP = p_par->intra_quantizer;
	char Mode = MODE_INTRA;
	short* qcoeff;
	register short i, j;
	Int CBP ;
	char COD;
	char CBPY;
//	char CBPC;
	short num_pixels = (p_par->width);
	short num_lines = (p_par->height);
	char vop_type;
	short ***DC_store_curr;
	short ***DC_store_above;
	short ***DC_store_tmp;

	char MB_width = num_pixels / MB_SIZE;
	char MB_height = num_lines / MB_SIZE;
	short m;
	char ACpred_flag=-1;
	char direction[6];
	char dc_scaler_lum,dc_scaler_chr;
	dc_scaler_lum = cal_dc_scaler(QP,1);
	dc_scaler_chr = cal_dc_scaler(QP,2);

	qcoeff = g_qcoeff;

	for (i = 0; i < 6; i++)
		direction[i] = 0;

	DC_store_above = g_DC_store[0];
	DC_store_curr = g_DC_store[1];

	vop_type = PCT_INTRA;

	for (j = 0; j < MB_height; j++)		  /* Macro Block loop */
	{
		for (i = 0; i < MB_width; i++)
		{
			loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);//g_currMB now is the source MB
			FromCharToShort();//from g_currMB to g_fblock
            //使用帧内量化模式
			DCT_Quant_Rec_MB (QP, MODE_INTRA);// g_currMB is finally the reconstructed MB
			CopyRecMBToRef(reference,i,j,p_par->width + 32, p_par->height + 32);//from g_currMB to reference vop
            CopyRecMBToResult(result,i,j,p_par->width, p_par->height);//获得重建图像
			if(i==0)
			{	paddingMBleft(reference,j,p_par->width + 32, p_par->height + 32);
				paddingMBleft1(result,j,p_par->width, p_par->height);
			}
			else if(i==(MB_width-1))
			{	paddingMBright(reference,j,p_par->width + 32, p_par->height + 32);
                paddingMBright1(result,j,p_par->width, p_par->height);
              }
			COD = 0;
			m =0;

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

			CBP = FindCBP(qcoeff,Mode,64);
            //对DC系数进行差分预测
			ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store_curr,
										DC_store_above, QP, direction);

//@			if (DQUANT) Mode=MODE_INTRA_Q;else Mode=MODE_INTRA;
//@			QP+=DQUANT;

			CBPY = CBP >> 2;
			CBPY = CBPY & 15;			  /* last 4 bits */
//			CBPC = CBP & 3;				  /* last 2 bits */

			Bits_CountMB_combined (Mode, COD, ACpred_flag, CBP,vop_type);

			//void MB_CodeCoeff(short *qcoeff,char Mode, Int CBP, char ncoeffs,char direction[]);
			MB_CodeCoeff( qcoeff, Mode, CBP, 64,direction);
		}
		if(j==0)
		{	paddingVOPTop(reference,p_par->width + 32, p_par->height + 32);
            paddingVOPTop1(result,p_par->width, p_par->height);
            }
		//exchange the DC_store_curr and DC_store_above
		DC_store_tmp = DC_store_curr;
		DC_store_curr = DC_store_above;
		DC_store_above = DC_store_tmp;

	}
//	paddingVOPTop(reference,p_par->width + 32, p_par->height + 32);
	paddingVOPBottom(reference,p_par->width + 32, p_par->height + 32);
    paddingVOPBottom1(result,p_par->width, p_par->height);
}
//loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);
void loadUCharMBdata(unsigned char * currvop, short mb_x, short mb_y, short width,short height,unsigned char * currMB)
{
	char ic;

	unsigned char* ppxlcCurrMBY = currMB;
	unsigned char* ppxlcCurrMBU = currMB + MB_SIZE * MB_SIZE;
	unsigned char* ppxlcCurrMBV = currMB+(MB_SIZE * MB_SIZE/4)*5;
	unsigned char* ppxlcCurrVopY = currvop + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
	unsigned char* ppxlcCurrVopU = currvop + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
	unsigned char* ppxlcCurrVopV = currvop + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);


	for (ic = 0; ic < 8; ic++) {
		memcpy (ppxlcCurrMBY, ppxlcCurrVopY, MB_SIZE);
		memcpy (ppxlcCurrMBU, ppxlcCurrVopU, BLOCK_SIZE);
		memcpy (ppxlcCurrMBV, ppxlcCurrVopV, BLOCK_SIZE);
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrVopY += width;
		ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrVopU += (width/2);
		ppxlcCurrMBV += BLOCK_SIZE;	ppxlcCurrVopV += (width/2);
		
		memcpy (ppxlcCurrMBY, ppxlcCurrVopY, MB_SIZE); // two rows for Y
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrVopY += width;
	}

}
/*****************************************************************/
void CopyRecMBToResult(unsigned char * result, short mb_x, short mb_y, short width,short height)
{
	char ic;
	//short offsetY,offsetUV;
	unsigned char *ppxlcCurrMBY= g_currMB;
	unsigned char *ppxlcCurrMBU= g_currMB + MB_SIZE * MB_SIZE;
	unsigned char *ppxlcCurrMBV= g_currMB+(MB_SIZE * MB_SIZE/4)*5;
	unsigned char *ppxlcCurrRefY=result + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
	unsigned char *ppxlcCurrRefU= result + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
	unsigned char *ppxlcCurrRefV= result + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
	//edge=16;
	//offsetY = width * edge + edge;
	//offsetUV = (width>>1) * (edge>>1) + (edge>>1);
/*
	ppxlcCurrMBY= g_currMB;
	ppxlcCurrMBU = g_currMB + MB_SIZE * MB_SIZE;
	ppxlcCurrMBV = g_currMB+(MB_SIZE * MB_SIZE/4)*5;
	
	
     ppxlcCurrRefY = result + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
	 ppxlcCurrRefU = result + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
	 ppxlcCurrRefV = result + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
*/
	for (ic = 0; ic < 8; ic++) {
		memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE);
		memcpy (ppxlcCurrRefU, ppxlcCurrMBU, BLOCK_SIZE);
		memcpy (ppxlcCurrRefV, ppxlcCurrMBV, BLOCK_SIZE);
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
		ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrRefU += (width/2);
		ppxlcCurrMBV += BLOCK_SIZE;	ppxlcCurrRefV += (width/2);
		
		memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE); // two rows for Y
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
	}
}

/*****************************************************************/
void CopyRecMBToRef(unsigned char * reference, short mb_x, short mb_y, short width,short height)
{
	char ic,edge;
	short offsetY,offsetUV;
	unsigned char *ppxlcCurrMBY;
	unsigned char *ppxlcCurrMBU;
	unsigned char *ppxlcCurrMBV;
	unsigned char *ppxlcCurrRefY;
	unsigned char *ppxlcCurrRefU;
	unsigned char *ppxlcCurrRefV;
	edge=16;
	offsetY = width * edge + edge;
	offsetUV = (width>>1) * (edge>>1) + (edge>>1);

	ppxlcCurrMBY= g_currMB;
	ppxlcCurrMBU = g_currMB + MB_SIZE * MB_SIZE;
	ppxlcCurrMBV = g_currMB+(MB_SIZE * MB_SIZE/4)*5;
	
	
     ppxlcCurrRefY = reference + offsetY+ (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
	 ppxlcCurrRefU = reference + width*height + offsetUV + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
	 ppxlcCurrRefV = reference + (width*height/4)*5 + offsetUV + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);

	for (ic = 0; ic < 8; ic++) {
		memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE);
		memcpy (ppxlcCurrRefU, ppxlcCurrMBU, BLOCK_SIZE);
		memcpy (ppxlcCurrRefV, ppxlcCurrMBV, BLOCK_SIZE);
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
		ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrRefU += (width/2);
		ppxlcCurrMBV += BLOCK_SIZE;	ppxlcCurrRefV += (width/2);
		
		memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE); // two rows for Y
		ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
	}
}

void FromCharToShort()//from g_currMB to g_fblock
{
	register short k,i,j;
	short xwidth;
	unsigned char *pxl;
	for(k=0; k<6; k++)
	{
		switch (k)
		{
			case 0:
				pxl = g_currMB;
				xwidth = 16;
				break;
			case 1:
				pxl = g_currMB+8;
				xwidth = 16;
				break;
			case 2:
				pxl = g_currMB+8*MB_SIZE;
				xwidth = 16;
				break;
			case 3:
				pxl = g_currMB+8*MB_SIZE+8;
				xwidth = 16;
				break;
			case 4:
				pxl = g_currMB + MB_SIZE*MB_SIZE;
				xwidth = 8;
				break;
			case 5:
				pxl = g_currMB + (MB_SIZE*MB_SIZE/4)*5;
				xwidth = 8;
				break;
			default:
				break;
		}

		for (i = 0; i < 8; i++)
		{
			for (j = 0; j < 8; j++)
			{
				g_fblock[k][i*8 + j] = (short)pxl[j];
			}
			pxl+=xwidth;
		}
	}//end  k
}


void DCT_Quant_Rec_MB (char QP, char Mode)
{
	register char k;
	char type;
	short *qcoeff_ind,offset,xwidth;
	register short i,j;

⌨️ 快捷键说明

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