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

📄 dsp_mp4svp_mot.c

📁 mpeg-4 SVP程序
💻 C
📖 第 1 页 / 共 3 页
字号:
						total_check_pts=3;
					pt_nmbr=diamond[d_type].point[mot_dirn].start_nmbr;
					d_centre_x = mv_x;
					d_centre_y = mv_y;
				}
			}
		}
		while(stop_flag!=1);
	#endif
	MBmode = MBM_INTER16;//@
	min_error16 = sad_min;//@
	min_error = min_error16;//@
	}
	else
	{
		mv_x=mv_y=0;
		sad_min=MV_MAX_ERROR;
	}

	mv16_x = mv_x; mv16_y = mv_y; //ldm
	min_error16 = sad_min;

	/* Compute 8x8 MVs */
	if(enable_8x8_mv==1)
	{
		if(!out)
		{
			for (block=0;block<4;block++)
			{
				/* Obtain range */
				if(block==0)
				{
					hb=vb=0;
				}
				else if (block==1)
				{
					hb=1;vb=0;
				}
				else if (block==2)
				{
					hb=0;vb=1;
				}
				else
				{
					hb=vb=1;
				}
				// restrict the search range based on the current 16x16 MV inside a window around it
				Obtain_Range(sr, MBM_INTER8,
					mv16_x, mv16_y, &mv_x_min,&mv_x_max, &mv_y_min, &mv_y_max);

				RangeInSearchArea(i,j, block+1, prev_x, prev_y,
					vop_width, vop_height, &mv_x_min, &mv_x_max, &mv_y_min,&mv_y_max,&out);

				if(!out)
				{
					sad_min=MV_MAX_ERROR;
					mv_x = mv_y = 2000;		  /* A very large MV */

					for (y= mv_y_min; y<= mv_y_max; y++)
						for (x= mv_x_min; x<= mv_x_max; x++)
					{
						sad=SAD_Block(prev+
							INDEX_BIG(x_curr + x + 8*(block==1||block==3)+rel_ori_x,
							y_curr + y + 8*(block==2||block==3)+rel_ori_y),
							g_currMB+INDEX_NOR(8*(block==1||block==3),
							8*(block==2||block==3)),
							(vop_width /*+2*edge*/), sad_min);

						if (sad<sad_min)
						{
							sad_min=sad;
							mv_x=x;
							mv_y=y;
						}
						else if (sad==sad_min)
						if((ABS(x)+ABS(y)) < (ABS(mv_x)+ABS(mv_y)))
						{
							sad_min=sad;
							mv_x=x;
							mv_y=y;
						}
					}						  /*for*/
				}
				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
			}  /*for block*/

			if ((min_error16 -129) <min_error8 ){
				MBmode = MBM_INTER16;
				min_error = min_error16;
			}else {
				MBmode = MBM_INTER8;
				min_error = min_error8;
			}
		}
	}											  /* 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;

			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;

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

//pvop pvop pvop pvop pvop pvop pvop
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;
	short i, j;
	Int CBP;
	char COD;
	char CBPY, 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
			if(i==0)
				paddingMBleft(rec,j,p_par->width + 32, p_par->height + 32);
			else if(i==(MB_in_width-1))
				paddingMBright(rec,j,p_par->width + 32, p_par->height + 32);

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

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

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;

		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);
		pSrc += lenSrc; pDst += lenDst;
	}

}
void GetPredChroma(char xh , char yh , unsigned char * dst, char rounding_control)
{
	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
{
	short k,i,j,xwidth;
	unsigned char *pxlcurr;
	unsigned char *pxlcomp;

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

⌨️ 快捷键说明

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