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

📄 mot_est.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		p1 = 2*MV[vec][yin1][xin1]->x;
		p2 = 2*MV[vec][yin2][xin2]->x;
		p3 = 2*MV[vec][yin3][xin3]->x;
	}
	if (newgob)
	{
		p2 = 2 * NO_VEC;   //!< MV above can not be accessed 
	}
	if (p2 == 2*NO_VEC)
	{
		p2 = p3 = p1;      //!< When MV above can not be accessed, use left MV instead 
	}
	
	*pmv0 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
   
	if (half_pel) 
	{
		p1 = 2*MV[vec][yin1][xin1]->y + MV[vec][yin1][xin1]->y_half;
		p2 = 2*MV[vec][yin2][xin2]->y + MV[vec][yin2][xin2]->y_half;
		p3 = 2*MV[vec][yin3][xin3]->y + MV[vec][yin3][xin3]->y_half;
	}
	else 
	{
		p1 = 2*MV[vec][yin1][xin1]->y;
		p2 = 2*MV[vec][yin2][xin2]->y;
		p3 = 2*MV[vec][yin3][xin3]->y;
	}    
	if (newgob)
	{
		p2 = 2 * NO_VEC;   //!< MV above can not be accessed 
	}
	if (p2 == 2*NO_VEC)
	{
		p2 = p3 = p1;      //!< When MV above can not be accessed, use left MV instead 
	}
	
	*pmv1 = p1+p2+p3 - mmax(p1,mmax(p2,p3)) - mmin(p1,mmin(p2,p3));
}
/*!
*******************************************************************************
*
*   Name:          mv_search_fs
*   Description:   find best integer motion vector for a block(Full Search)
*   Input:         position of current block
*                  current lum image and reference lum image
*   Output:        integer MV value
*   Last modified: 2002/12/17 by lcl
*
*******************************************************************************/

void mv_search_fs(H263VencStatus *encoder, MCParam *MC, int curr_x, int curr_y, int blocksize, int BACKWARD)
{
	int iMinSAD = (MC->mv)->min_sad;
	int iCurrSAD;
	int i;
	int iXCheckPt;
	int iYCheckPt;
	int iCenterX = curr_x + (MC->mv)->x;
	int iCenterY = curr_y + (MC->mv)->y;
    int iXDest = iCenterX;
	int iYDest = iCenterY;
	int search_range = (8 == blocksize ? MC->search_range_8x8 : MC->search_range); 
	int iNbr = (2*search_range + 1) * (2*search_range + 1);
	int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
	int lx1 = encoder->pels;
	int lx2 = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
	int index = BACKWARD ? encoder->zero_index : encoder->ref_index;
	unsigned char *p1 = (encoder->frameToEncode).pLum ;
	unsigned char *p2 = (encoder->frame_buf[index]).pLum ;

	if (encoder->PTYPE == B_IMG)
	{
		mv_out = 1;
		p1 = (encoder->BPicture[encoder->B_count]).pLum;
	}
	else
	{
		mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
	}

	for (i = 1; i < iNbr; i++)
	{
		iXCheckPt = iCenterX + MC->SpiralX[i];
		iYCheckPt = iCenterY + MC->SpiralY[i];

		if ( (iXCheckPt<0||iYCheckPt<0||
			  iXCheckPt>encoder->pels - blocksize ||
			  iYCheckPt>encoder->lines - blocksize)
		    && !mv_out)
            continue;
		
    	iCurrSAD = encoder->method.me_sad_a(lx1, lx2, curr_x, curr_y, iXCheckPt, iYCheckPt, p1, p2, iMinSAD, blocksize);
		if (iCurrSAD >= iMinSAD)
		    continue;
		
		iMinSAD= iCurrSAD;
		iXDest = iXCheckPt;
    	iYDest = iYCheckPt;
	}
	(MC->mv)->x = iXDest-curr_x;
	(MC->mv)->y = iYDest-curr_y;
	(MC->mv)->min_sad = iMinSAD;
}

/*!
*******************************************************************************
*
*   Name:          mv_search_dmd
*   Description:   find best integer motion vector for a block(Noval Diomand Search)
*   Input:         position of current block
*                  current lum image and reference lum image
*   Output:        integer MV value
*   Last modified: 2002/12/17 by lcl
*
*******************************************************************************/
void mv_search_dmd(H263VencStatus *encoder, MCParam *MC, int curr_x, int curr_y, int blocksize, int BACKWARD)
{
	int iMinSAD=(MC->mv)->min_sad;
	int mbDiff;
    int iTotalCheckPts, iCheckPts, iMotDirn=0, iPtNmbr=0;
    int MOTION_ACTIVITY;
    int stopFlag=0, stopDiamondMotion=0;
    int dXCentre=curr_x + (MC->mv)->x;
	int dYCentre=curr_y + (MC->mv)->y;
    int iXDest=dXCentre;
	int iYDest=dYCentre;
	int iXCheckPt, iYCheckPt;
	int dType;
	int L1=1, L2=2, L3=4;
	int LMotion = 0;
	int block = 0;
	int mb_x = curr_x/16;
	int mb_y = curr_y/16;
	int vec_x;
	int vec_y;
	int search_range = (8 == blocksize) ? MC->search_range_8x8 : MC->search_range;
	int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
	int lx1 = encoder->pels;
	int lx2 = encoder->mv_outside_frame ? encoder->pels+32 : encoder->pels;
	int index = BACKWARD ? encoder->zero_index : encoder->ref_index;
	unsigned char *p1 = (encoder->frameToEncode).pLum ;
	unsigned char *p2 = (encoder->frame_buf[index]).pLum ;

	if (encoder->PTYPE == B_IMG)
	{
		mv_out = 1;
		p1 = (encoder->BPicture[encoder->B_count]).pLum;
	}
	else
	{
		mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
	}

//! assign neighborhood MVs as points of diamond[2], which is MotAdaptPat
	FindNbrMV(MC->mv_frame, block, 0, mb_x, mb_y, &vec_x, &vec_y, BACKWARD);  //!< left
	diamond[2].dpoint[0].x = vec_x - (MC->mv)->x;
	diamond[2].dpoint[0].y = vec_y - (MC->mv)->y;
	FindNbrMV(MC->mv_frame, block, 1, mb_x, mb_y, &vec_x, &vec_y, BACKWARD);  //!< up
	diamond[2].dpoint[1].x = vec_x - (MC->mv)->x;
	diamond[2].dpoint[1].y = vec_y - (MC->mv)->y;
	FindNbrMV(MC->mv_frame, block, 2, mb_x, mb_y, &vec_x, &vec_y, BACKWARD);	//!< up-right 
	diamond[2].dpoint[2].x = vec_x - (MC->mv)->x;
	diamond[2].dpoint[2].y = vec_y - (MC->mv)->y;
//! compute motion activity
	MOTION_ACTIVITY = max(abs(diamond[2].dpoint[0].x)+abs(diamond[2].dpoint[0].y) , max( abs(diamond[2].dpoint[1].x)+abs(diamond[2].dpoint[1].y)  , abs(diamond[2].dpoint[2].x)+abs(diamond[2].dpoint[2].y)) );

	if (MOTION_ACTIVITY > L3)
		LMotion = 1;             //!> detect large motion
	dType=(MOTION_ACTIVITY > L2) ? MotAdaptPat : ((MOTION_ACTIVITY > L1) ? LDiamond : SDiamond);
	iTotalCheckPts=diamond[dType].no_check_pts;

			  while(stopFlag!=1)
			  {
				  iCheckPts=iTotalCheckPts;
				  do
				  {
					iXCheckPt=diamond[dType].dpoint[iPtNmbr].x+dXCentre;
					iYCheckPt=diamond[dType].dpoint[iPtNmbr].y+dYCentre;
					

	            	if ( (iXCheckPt < 0||iYCheckPt < 0||
		            	  iXCheckPt > (encoder->pels - blocksize)||
		             	  iYCheckPt > (encoder->lines - blocksize))
					   && !mv_out)
					   goto NEXT_POSITION;
					if ( (iXCheckPt-curr_x) < -search_range||
						(iXCheckPt-curr_x) > search_range||
 		                (iYCheckPt-curr_y) < -search_range||
						(iYCheckPt-curr_y) > search_range)
						goto NEXT_POSITION;   //!< skip this check point
					else
					{

		                mbDiff = encoder->method.me_sad_a(lx1, lx2, curr_x, curr_y, iXCheckPt, iYCheckPt, p1, p2, iMinSAD, blocksize);                       
						if (mbDiff < iMinSAD)
						{
							iMinSAD= mbDiff;
							iXDest = iXCheckPt;
							iYDest = iYCheckPt;
							iMotDirn=iPtNmbr;
						}
					}
NEXT_POSITION:
					iPtNmbr+=1;
					iPtNmbr=(dType==LDiamond) ? iPtNmbr % diamond[LDiamond].no_check_pts : iPtNmbr % diamond[SDiamond].no_check_pts;
					iCheckPts-=1;
				  }while(iCheckPts>0);

				  if(dType==MotAdaptPat)
				  {
					  dType = LMotion?LDiamond:SDiamond; //!> if large motion, Large Diamond used
					  iPtNmbr=0;
					  iTotalCheckPts=diamond[dType].no_check_pts;
				  }
				  else
				  {
					  if((iXDest==dXCentre)&&(iYDest==dYCentre))
						  stopDiamondMotion=1;
					  else
					  {
						  iTotalCheckPts=(((iXDest==dXCentre) || (iYDest==dYCentre))&&(dType==LDiamond)) ? 5 :3;
						  iPtNmbr=diamond[dType].dpoint[iMotDirn].iStartNmbr;
					  }
				  }
				  if(stopDiamondMotion)
				  {
					  if(dType==LDiamond)
					  {
						    dType = SDiamond;
						    iPtNmbr = 0;
						    iTotalCheckPts = diamond[dType].no_check_pts;
					  }
					  else
						  stopFlag=1;
				  }
				  dXCentre=iXDest;
				  dYCentre=iYDest;
			  }
	(MC->mv)->x = iXDest - curr_x;
	(MC->mv)->y = iYDest - curr_y;
	(MC->mv)->min_sad = iMinSAD;
}
/*!
*******************************************************************************
*
*   Name:          findhalfpel
*   Description:   find best motion vectors in half resolution
*   Input:         position of current block 
*                  current lum image and interpolated reference lum image
*   Output:        half MV value
*   Last modified: 2002/11/23 by lcl
*
*******************************************************************************/
void findhalfpel(H263VencStatus *encoder, MCParam *MC, int x, int y, int blocksize, int BACKWARD)
{
	int iXPos[9] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
	int iYPos[9] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
	int iMinSAD, iCurrSAD;
	int iCenterX;
	int iCenterY;
	int iCheckPtX;
	int iCheckPtY;
	int iPoint, iBestPt;
	int mv_out;
// added by lcl on 2003/2/22, parameter for calculation of SAD
	int lx1 = encoder->pels;
	int lx2 = encoder->mv_outside_frame ? encoder->pels*2+64 : encoder->pels*2;
	unsigned char *ipol = BACKWARD ? encoder->next_ipol : encoder->prev_ipol;
	unsigned char *p1 = (encoder->frameToEncode).pLum;
	unsigned char *p2 = ipol;
	if (encoder->PTYPE == B_IMG)
	{
		mv_out = 1;
		p1 = (encoder->BPicture[encoder->B_count]).pLum;
	}
	else
	{
		mv_out = encoder->annex.Advanced_Prediction || encoder->annex.Deblocking_Filter;
	}
	
	iBestPt = 0;
    iMinSAD = (MC->mv)->min_sad;
	iCenterX = (x + (MC->mv)->x)<<1;
	iCenterY = (y + (MC->mv)->y)<<1;

	for (iPoint = 1; iPoint < 9; iPoint++)
	{

		iCheckPtX = iCenterX + iXPos[iPoint];   //!< Current absolute X position in the reference pic
		iCheckPtY = iCenterY + iYPos[iPoint];   //!< Current absolute Y position in the reference pic

		if ( (iCheckPtX<0 ||
			  iCheckPtY<0 ||
			  iCheckPtX>(encoder->pels - blocksize)*2 ||  //!< keep in agreement with h.263 coder
			  iCheckPtY>(encoder->lines - blocksize)*2)   //!< should be considered later
		   && !mv_out)             
            continue;
        iCurrSAD = encoder->method.me_sad_b(lx1, lx2, x, y, iCheckPtX, iCheckPtY, p1, p2, iMinSAD, blocksize);
		if (iCurrSAD >= iMinSAD)
			continue;
		iMinSAD = iCurrSAD;
		iBestPt = iPoint;
	}
	(MC->mv)->x_half = iXPos[iBestPt];
	(MC->mv)->y_half = iYPos[iBestPt];
	(MC->mv)->min_sad = iMinSAD;
}
/*!
*******************************************************************************
*
*   Name:          zeroVec
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 2002/11/23 by lcl
*
*******************************************************************************/
void zeroVec(MotionVector *MV)
{
	MV->x = 0;
	MV->y = 0;
	MV->x_half = 0;
	MV->y_half = 0;
}

/*!
*******************************************************************************
*
*   Name:          me_sad_a16
*   Description:   compute sad for integer pel motion search
*   Input:         current lum image and reference lum image
*                  position of current block in current image
*                  position of reference block in reference image
*   Output:        sad returned
*   Optimization:  sadmmx.cpp
*   Last modified: 2003/02/20 by lcl
*
*******************************************************************************/
int me_sad_a_c(int lx1, int lx2, int x1, int y1, int x2,  int y2, 
			 unsigned char *P1, unsigned char *P2,  
			 int sad_last, int blocksize)
{
	int i, j;
	int sad = 0;
	unsigned char *p1 = P1 + y1*lx1 + x1;
	unsigned char *p2 = P2 + y2*lx2 +x2 ;

	for(i = 0; i < blocksize; i++)
	{
		for(j = 0; j < blocksize; j+=4)
		{
			sad+=absm(p1[j] - p2[j]);
			sad+=absm(p1[j+1] - p2[j+1]);
			sad+=absm(p1[j+2] - p2[j+2]);
			sad+=absm(p1[j+3] - p2[j+3]);
			if (sad > sad_last)
				return MAX_SAD;
		}
		p1+=lx1;
		p2+=lx2;
	}
	return sad;
}
/*!
*******************************************************************************
*
*   Name:          me_sad_b   
*   Description:   compute sad for half pel motion search
*   Input:         current lum image, interpolated image derived from reference frame
*                  position of current block in current lum image,
*                  position of reference block in interpolated reference image
*   Output:        sad returned
*   Optimization:  sadmmx.cpp
*   Last modified: 2002/12/17 by lcl
*
*******************************************************************************/
int me_sad_b_c(int lx1, int lx2,  int x1, int y1, int x2,  int y2, 
			 unsigned char *P1, unsigned char *P2,
			 int sad_last, int blocksize)
{
	int i, j, k;
	int sad = 0;
	unsigned char *p1 = P1 + y1*lx1 + x1;
	unsigned char *p2 = P2 + y2*lx2 + x2 ;

	for(i = 0; i < blocksize; i++)

⌨️ 快捷键说明

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