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

📄 dsp_mot.c

📁 基于DM642平台的H.264编码器优化代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			  	}//最近if(!out)
				else
				{
					mv_x=mv_y=0;
					sad_min=MV_MAX_ERROR; //punish the OUTER blocks with MV_MAX_ERROR in order to be INTRA CODED 
				}
			
				min_error8 += sad_min;//ldm
				mv8_x[block]=mv_x; mv8_y[block]=mv_y;//ldm向量赋值8*8
			}  //for block

			if ((min_error16 -129) <min_error8 ){//判断MBmode
				MBmode = MBM_INTER16;
				min_error = min_error16;
			}else {
				MBmode = MBM_INTER8;
				min_error = min_error8;
			}
		}//if(!out)
	}//if(enable_8x8_mv==1)											  //enable_8x8_mv
*/

		if(MBmode != MBM_INTRA)
		{
			if(TryIntraMode(g_currMB,min_error))
			{
				MBmode = MBM_INTRA;//如果属于剧烈运动区域则进行帧内编码
			}
		}

		if(MBmode == MBM_INTRA)
		{
			for (k = 0; k < 256; k++)
			{
				min_error_intra += g_currMB[k];//recalculate the sad for intra MB
			}
		
			min_error =  min_error_intra;
		}


		if((MBmode == MBM_INTER16)&&(mv16_x==0)&&(mv16_y==0))
			min_error = min_error16 +129;

			mvm_width = (p_par->width)/MB_SIZE;//一行所含宏块数
			
			MB_md[j * mvm_width + i] = MBmode;
       //四个小快位置
			posBlock0 = 2*j*2*mvm_width + 2*i;
			posBlock1 = 2*j*2*mvm_width + 2*i+1;
			posBlock2 = (2*j+1)*2*mvm_width + 2*i;
			posBlock3 = (2*j+1)*2*mvm_width + 2*i+1;
     //如果是MBM_INTER16,则四个小块运动矢量一样
			if(MBmode == MBM_INTER16){
				motx[posBlock0]=mv16_x; moty[posBlock0]=mv16_y;
				motx[posBlock1]=mv16_x; moty[posBlock1]=mv16_y;
				motx[posBlock2]=mv16_x; moty[posBlock2]=mv16_y;
				motx[posBlock3]=mv16_x; moty[posBlock3]=mv16_y;

			}
	//如果是MBM_INTER8,则四个小块具有不同的运动矢量
	/*		
			else if(MBmode == MBM_INTER8){
				motx[posBlock0]=mv8_x[0]; moty[posBlock0]=mv8_y[0];
				motx[posBlock1]=mv8_x[1]; moty[posBlock1]=mv8_y[1];
				motx[posBlock2]=mv8_x[2]; moty[posBlock2]=mv8_y[2];
				motx[posBlock3]=mv8_x[3]; moty[posBlock3]=mv8_y[3];

			}
	*/
			//不进行运动估计
			else {
				motx[posBlock0]=0; moty[posBlock0]=0;
				motx[posBlock1]=0; moty[posBlock1]=0;
				motx[posBlock2]=0; moty[posBlock2]=0;
				motx[posBlock3]=0; moty[posBlock3]=0;
			}

	return min_error;
}

//进行帧间编码
void CodeInterVOP (
unsigned char * curr,//Vop *curr, 
unsigned char * rec,//Vop *comp, 
char *MB_decisions, char *mot_x, char *mot_y,
//Int f_code_for, 
//Int intra_acdc_pred_disable,
unsigned char * ref //Vop *rec_curr
//Image *mottext_bitstream,
//Bits *bits
)
{
	char Mode=0;
	char QP = p_par->quantizer;
	short* qcoeff;
	register short i, j;
	int CBP;
	char COD;
	char CBPY;
//	char CBPC;
	char MB_in_width, MB_in_height, B_in_width;
	short boff;
	char p;
	char *ptr=NULL;
	char *motx_ptr=NULL, *moty_ptr=NULL;
	short num_pixels;
	short num_lines;
	char vop_type=PCT_INTER;
	short ***DC_store_curr;
	short ***DC_store_above;
	short ***DC_store_tmp;
	short m, n;
	char ACpred_flag=-1;
	char direction[6];
	char dc_scaler_lum,dc_scaler_chr;

	num_pixels = p_par->width;
	num_lines = p_par->height;
	MB_in_width = num_pixels / MB_SIZE;
	MB_in_height = num_lines / MB_SIZE;
	B_in_width = 2 * MB_in_width;

	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_INTER;

	ptr = MB_decisions;
	motx_ptr = mot_x;
	moty_ptr = mot_y;
	dc_scaler_lum = cal_dc_scaler(QP,1);
	dc_scaler_chr = cal_dc_scaler(QP,2);

	for (j = 0; j < MB_in_height; j++)
	{
		for (i = 0; i < MB_in_width; i++)
		{
			p = *ptr;

			if(p != MBM_INTRA)
				for (m = 0; m < 6; m++)
				{
					DC_store_curr[i][m][0] = 1024;
					for (n = 1; n < 15; n++)
						DC_store_curr[i][m][n] = 0;
				}

			switch (p)
			{
				case MBM_INTRA:
					Mode =  MODE_INTRA;
					break;

				case MBM_INTER16:
					Mode = MODE_INTER ;
					break;
/*
				case MBM_INTER8:
					Mode = MODE_INTER4V;
					break;
*/
				default:
//					printf("invalid MB_decision value :%d\n", p);
					exit(0);
			}

			loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);//g_currMB now is the source MB
			if(Mode != MODE_INTRA){
			//采用帧间编码
				compensation(ref,i,j,Mode,motx_ptr,moty_ptr,p_par->rounding_type);//comp to  g_compMB
				diffMB();// g_currMB - g_compMB to g_fblock
			}else//采用帧内编码
				FromCharToShort();//from g_currMB to g_fblock

			DCT_Quant_Rec_MB (QP, Mode);// g_currMB is finally the reconstructed MB
			CopyRecMBToRef(rec,i,j,p_par->width + 32, p_par->height + 32);//frome g_currMB to reference vop
			CopyRecMBToResult(result,i,j,p_par->width, p_par->height);//获得重建图像
			if(i==0)
			{	paddingMBleft(rec,j,p_par->width + 32, p_par->height + 32);
				paddingMBleft1(result,j,p_par->width, p_par->height);
			}
			else if(i==(MB_in_width-1))
			{	paddingMBright(rec,j,p_par->width + 32, p_par->height + 32);
                paddingMBright1(result,j,p_par->width, p_par->height);
              }
				boff = (2 * j * B_in_width + 2 * i);
				CBP = FindCBP(qcoeff,Mode,64);

				if ((CBP == 0) && (p == 1) && (*(motx_ptr +boff) == 0)
					&& (*(moty_ptr +boff) == 0))
				{
					COD = 1;	  /* skipped macroblock */
					BitstreamPutBits((UInt)COD, 1L);	/* COD */
					*ptr = SKIPP;
					Mode = MODE_INTER;
				}
				else
				{
					COD = 0;	  /* coded macroblock */
				}

				if (COD == 0)
				{
					if (Mode == MODE_INTRA)
					{
						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];
						}
							
							ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store_curr,
										DC_store_above, QP, direction);
					}

					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);//对宏块类型进行判断

					Bits_CountMB_MV( mot_x, mot_y, Mode, i, j, p_par->fcode_for);//对矢量进行编码

					MB_CodeCoeff( qcoeff, Mode, CBP, 64,direction);//对系数进行编码
				}
			ptr++;
		} /* for i loop */
		
		if(j==0)
		{	paddingVOPTop(rec,p_par->width + 32, p_par->height + 32);
            paddingVOPTop1(result,p_par->width, p_par->height);
           }
		DC_store_tmp = DC_store_curr;
		DC_store_curr = DC_store_above;
		DC_store_above = DC_store_tmp;
	} /* for j loop */
	paddingVOPBottom(rec,p_par->width + 32, p_par->height + 32);
	paddingVOPBottom1(result,p_par->width, p_par->height);
}

void compensation(
	  unsigned char * ref,
	  short i,short j,char Mode,
	  char * motx_ptr,char * moty_ptr,
	  char rounding_type)//运动补偿函数
{
short xsum=0,ysum=0;
short dx,dy,xint,yint;
char  xh,yh;
short mvm_width,posBlock0,posBlock1,posBlock2,posBlock3;
short lenRefY,lenRefUV,ofx,ofy,offset_b;
unsigned int offset;
unsigned char *refU,*refV;
mvm_width = p_par->width/MB_SIZE;
lenRefY = (p_par->width +32);
lenRefUV = lenRefY/2;//UV分量是Y分量的一半

    posBlock0 = 2*j*2*mvm_width + 2*i;
	if(Mode == MODE_INTER4V)//如果分成四个小块
	{
		posBlock1 = posBlock0+1;
		posBlock2 = posBlock0 + 2*mvm_width ;
		posBlock3 = posBlock2 +1;
	//for blockY0
		ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock0] ;
		ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock0] ;
		offset = ofy * lenRefY + ofx; 
		loadCompData(ref+offset,lenRefY,8,g_compMB,16);
	//for blockY1
		ofx = 16 + (i*MB_SIZE) + 8 + motx_ptr[posBlock1] ;
		ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock1] ;
		offset = ofy * lenRefY + ofx; offset_b = 8;
		loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);
	//for blockY2
		ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock2] ;
		ofy = 16 + (j*MB_SIZE) + 8 + moty_ptr[posBlock2] ;
		offset = ofy * lenRefY + ofx;  offset_b = 8*16;
		loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);
	//for blockY3
		ofx = 16 + (i*MB_SIZE) + 8 + motx_ptr[posBlock3] ;
		ofy = 16 + (j*MB_SIZE) + 8 + moty_ptr[posBlock3] ;
		offset = ofy * lenRefY + ofx;  offset_b = 8*16+8;
		loadCompData(ref+offset,lenRefY,8,g_compMB + offset_b,16);

		xsum = 2*(motx_ptr[posBlock0])+2*(motx_ptr[posBlock1])
			+2*(motx_ptr[posBlock2])+2*(motx_ptr[posBlock3]);

		ysum = 2*(moty_ptr[posBlock0])+2*(moty_ptr[posBlock1])
			+2*(moty_ptr[posBlock2])+2*(moty_ptr[posBlock3]);

		dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2);
		dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2);
	}
	else /* Mode == MODE_INTER */
	{
	//for MBY
		ofx = 16 + (i*MB_SIZE) + motx_ptr[posBlock0] ;
		ofy = 16 + (j*MB_SIZE) + moty_ptr[posBlock0] ;
		offset = ofy * lenRefY + ofx;
		loadCompData(ref+offset,lenRefY,16,g_compMB,16);

		dx = (2 * motx_ptr[posBlock0]);
		dy = (2 * moty_ptr[posBlock0]);
		dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
		dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
	}

	refU = ref + (p_par->width +32)*(p_par->height +32);
	refV = refU + ((p_par->width +32)/2) * ((p_par->height +32)/2);

	xint = dx>>1;	xh = dx & 1;
	yint = dy>>1;	yh = dy & 1;
	ofx = 8 + ((i*MB_SIZE)>>1) + xint ;
	ofy = 8 + ((j*MB_SIZE)>>1) + yint ;
	offset = ofy * lenRefUV + ofx;
//色度	
	loadCompData(refU+offset,lenRefUV,9,g_tmpcomUV,9);//load to g_tmpcomUV[81]
	GetPredChroma(xh , yh , g_compMB+256,rounding_type);//compute from g_tmpcomUV[81] to g_compMB's blockU
	loadCompData(refV+offset,lenRefUV,9,g_tmpcomUV,9);//load to g_tmpcomUV[81]
	GetPredChroma(xh , yh , g_compMB+320,rounding_type);//compute from g_tmpcomUV[81] to g_compMB's blockV
}

void loadCompData(unsigned char *src,short lenSrc,char size,unsigned char *dst,char lenDst)
{
	char ic;
	unsigned char* pSrc = src;
	unsigned char* pDst = dst;
	for (ic = 0; ic < size; ic++) {
		memcpy (pDst, pSrc, size);//size=8
		pSrc += lenSrc; pDst += lenDst;
	}

}
//获得预测色度函数
void GetPredChroma(char xh , char yh , unsigned char * dst, char rounding_control)
{
	register char m,n;

	if (!xh && !yh)
	{
		for (n = 0; n < 8; n++)
		{
			for (m = 0; m < 8; m++)
			{
				dst[n*8+m]= g_tmpcomUV[n*9+m];
			}
		}
	}
	else if (!xh && yh)
	{
		for (n = 0; n < 8; n++)
		{
			for (m = 0; m < 8; m++)
			{
				dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[(n+1)*9+m]+ 1- rounding_control) >>1;

			}
		}
	}
	else if (xh && !yh)
	{
		for (n = 0; n < 8; n++)
		{
			for (m = 0; m < 8; m++)
			{
				dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[n*9+m+1]+ 1- rounding_control)>>1;
			}
		}
	}
	else
	{											  /* xh && yh */
		for (n = 0; n < 8; n++)
		{
			for (m = 0; m < 8; m++)
			{
				dst[n*8+m] = (g_tmpcomUV[n*9+m] +g_tmpcomUV[n*9+m+1]
							+ g_tmpcomUV[(n+1)*9+m] +g_tmpcomUV[(n+1)*9+m+1]+ 2- rounding_control)>>2;
			}
		}
	}
	return;
}
//宏块差值
void diffMB()// g_currMB - g_compMB to g_fblock
{
	register short k,i,j;
	short xwidth;
	unsigned char *pxlcurr;
	unsigned char *pxlcomp;

	for(k=0; k<6; k++)
	{
		switch (k)
		{
			case 0:
				pxlcurr = g_currMB;	
				pxlcomp = g_compMB;
				xwidth = 16;
				break;
			case 1:
				pxlcurr = g_currMB+8;
				pxlcomp = g_compMB+8;
				xwidth = 16;
				break;
			case 2:
				pxlcurr = g_currMB+8*MB_SIZE;
				pxlcomp = g_compMB+8*MB_SIZE;
				xwidth = 16;
				break;
			case 3:
				pxlcurr = g_currMB+8*MB_SIZE+8;
				pxlcomp = g_compMB+8*MB_SIZE+8;
				xwidth = 16;
				break;
			case 4:
				pxlcurr = g_currMB + MB_SIZE*MB_SIZE;
				pxlcomp = g_compMB + MB_SIZE*MB_SIZE;
				xwidth = 8;
				break;
			case 5:
				pxlcurr = g_currMB + (MB_SIZE*MB_SIZE/4)*5;
				pxlcomp = g_compMB + (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)pxlcurr[j] - (short)pxlcomp[j];
			}
			pxlcurr+=xwidth;
			pxlcomp+=xwidth;

		}
	}//end  k
}

void				  /* MVP/Noel */
find_pmvs(
	char  *mot_x,	  /* x-motion vector field                             */
	char  *mot_y,	  /* y-motion vector field                             */
	short    x,		  /* xpos of the MB in multiples of 16 (hor coord)     */
	short    y,		  /* ypos of the MB in multiples of 16 (ver coord)     */
	char    block,	  /* block number (0 if one vector per MB, 1..4 else)  */
	short    *mvx,	  /* hor predicted motion vector [ in half-pixels units ]  */
	short    *mvy	  /* ver predicted motion vector [ in half-pixels units ]  */
)
{
	char   p1x,p2x,p3x;
	char   p1y,p2y,p3y;
	char     xin1, xin2, xin3;
	char     yin1, yin2, yin3;
	char     vec1, vec2, vec3;
	char     rule1, rule2, rule3;
	char     subdim=2;
	char   *motxdata = mot_x;
	char   *motydata = mot_y;
	short     xB = p_par->width/BLOCK_SIZE;

	switch (block)
	{
		case 0:
			vec1 = 1 ; yin1 = y  ; xin1 = x-1;
			vec2 = 2 ; yin2 = y-1; xin2 = x;
			vec3 = 2 ; yin3 = y-1; xin3 = x+1;
			break;
		case 1:
			vec1 = 1 ; yin1 = y  ; xin1 = x-1;
			vec2 = 2 ; yin2 = y-1; xin2 = x;
			vec3 = 2 ; yin3 = y-1; xin3 = x+1;
			break;
		case 2:
			vec1 = 0 ; yin1 = y  ; xin1 = x;
			vec2 = 3 ; yin2 = y-1; xin2 = x;
			vec3 = 2 ; yin3 = y-1; xin3 = x+1;
			break;
		case 3:
			vec1 = 3 ; yin1 = y  ; xin1 = x-1;
			vec2 = 0 ; yin2 = y  ; xin2 = x;
			vec3 = 1 ; yin3 = y  ; xin3 = x;
			break;
		case 4:
			vec1 = 2 ; yin1 = y  ; xin1 = x;

⌨️ 快捷键说明

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