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

📄 fast_me.c

📁 AVS视频编解码器 能实现视频图像的高效率压缩 能在VC上高速运行
💻 C
📖 第 1 页 / 共 5 页
字号:
  dfTim = dfMinus / dfFreq; 
  integer_time=integer_time + dfTim;//tmp_time;
#endif

 //==============================
  //=====   SUB-PEL SEARCH   =====
  //==============================
  if (input->hadamard)
  {
    min_mcost = max_value;
  }
 
#ifdef TimerCal 
  QueryPerformanceCounter(&litmp); 
  QPart1 = litmp.QuadPart; 
#endif


if(blocktype >3)
{
  min_mcost =  FastSubPelBlockMotionSearch (orig_pic, ref, center_x, center_y, blocktype,
                                        pred_mv_x, pred_mv_y, &mv_x, &mv_y, 9, 9,
                                        min_mcost, lambda, 0);
}
else
{
  min_mcost =  SubPelBlockMotionSearch (orig_pic, ref, center_x/*lgp*/, center_y/*lgp*/,/*pic_pix_x, pic_pix_y,*/ blocktype,
                                        pred_mv_x, pred_mv_y, &mv_x, &mv_y, 9, 9,
                                        min_mcost, lambda);
}


  for (i=0; i < (bsx>>2); i++)
  {
	  for (j=0; j < (bsy>>2); j++)
	  {
		  if (ref > -1)
		  {
			  all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][1] = mv_x;
			  all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][2] = mv_y;
		  }
		  else
		  {
			  all_bwmincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][0][blocktype][1] = mv_x;
			  all_bwmincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][0][blocktype][2] = mv_y;
		  }
	  }
  }

#ifdef TimerCal
  QueryPerformanceCounter(&litmp); 
  QPart2 = litmp.QuadPart; 
  dfMinus = (double)(QPart2 - QPart1); 
  dfTim = dfMinus / dfFreq; 
  fractional_time=fractional_time + dfTim;
#endif

  if (!input->rdopt)
  {
    // Get the skip mode cost
    if (blocktype == 1 && img->type == INTER_IMG)
    {
      int cost;

      FindSkipModeMotionVector ();

      cost  = GetSkipCostMB (lambda);
      cost -= (int)floor(8*lambda+0.4999);

      if (cost < min_mcost)
      {
        min_mcost = cost;
        mv_x      = img->all_mv [0][0][0][0][0];
        mv_y      = img->all_mv [0][0][0][0][1];
      }
    }
  }
   temp_x = 4*pic_pix_x + pred_mv_x+mv_x;                   //add by wuzhongmou 200612  
    temp_y = 4*pic_pix_y + pred_mv_y+mv_y;                   //add by wuzhongmou 200612
    if(temp_x<=-64)                 //add by wuzhongmou  200612
    {
  	  mv_x=-63-4*pic_pix_x-pred_mv_x;
    }
    if(temp_x >= 4*(img->width -1-blocksize_x+16))
    {
  	  mv_x=4*(img->width -1-blocksize_x+15-pic_pix_x)-pred_mv_x;
    }
    if(temp_y <=-64)
    {
  	   mv_y=-63-4*pic_pix_y-pred_mv_y;
    }
    if(temp_y >= 4*(img->height-1-blocksize_y+16))
    {
       mv_y=4*(img->height -1-blocksize_y+15-pic_pix_y)-pred_mv_y;
	}   
    MaxMVHRange= MAX_H_SEARCH_RANGE;   //add by wuzhongmou 
  MaxMVVRange= MAX_V_SEARCH_RANGE;
  	if(!img->picture_structure) //field coding
	{
		MaxMVVRange=MAX_V_SEARCH_RANGE_FIELD;
	}
	if(mv_x < -MaxMVHRange )
     mv_x = -MaxMVHRange;
	if( mv_x> MaxMVHRange-1)
		mv_x=MaxMVHRange-1;
   if( mv_y < -MaxMVVRange)
         mv_y = -MaxMVVRange;
	if( mv_y > MaxMVVRange-1)
		 mv_y = MaxMVVRange-1;        // add by wuzhongmou
  //===============================================
  //=====   SET MV'S AND RETURN MOTION COST   =====
  //===============================================
  /*lgp*/
  for (i=0; i < (bsx>>3); i++)
  {
    for (j=0; j < (bsy>>3); j++)
    {
      all_mv[b8_x+i][b8_y+j][refframe][blocktype][0] = mv_x;
      all_mv[b8_x+i][b8_y+j][refframe][blocktype][1] = mv_y;
    }
  }

  
  return min_mcost;
}

#ifdef WIN32
_inline int PartCalMad(pel_t *ref_pic,pel_t** orig_pic,pel_t *(*get_ref_line)(int, pel_t*, int, int), int blocksize_y,int blocksize_x, int blocksize_x4,int mcost,int min_mcost,int cand_x,int cand_y)
#else
inline int PartCalMad(pel_t *ref_pic,pel_t** orig_pic,pel_t *(*get_ref_line)(int, pel_t*, int, int), int blocksize_y,int blocksize_x, int blocksize_x4,int mcost,int min_mcost,int cand_x,int cand_y)
#endif
{
	int y,x4;
	pel_t *orig_line, *ref_line;
	for (y=0; y<blocksize_y; y++)
    {
		ref_line  = get_ref_line (blocksize_x, ref_pic, cand_y+y, cand_x);
		orig_line = orig_pic [y];
		
		for (x4=0; x4<blocksize_x4; x4++)
		{
			mcost += byte_abs[ *orig_line++ - *ref_line++ ];
			mcost += byte_abs[ *orig_line++ - *ref_line++ ];
			mcost += byte_abs[ *orig_line++ - *ref_line++ ];
			mcost += byte_abs[ *orig_line++ - *ref_line++ ];
		}
		if (mcost >= min_mcost)
		{
			break;
		}
    }
    return mcost;
}


/*
*************************************************************************
* Function: FastIntegerPelBlockMotionSearch: fast pixel block motion search 
      this algrithm is called UMHexagonS(see JVT-D016),which includes 
      four steps with different kinds of search patterns
* Input:
    pel_t**   orig_pic,     // <--  original picture
    int       ref,          // <--  reference frame (0... or -1 (backward))
    int       pic_pix_x,    // <--  absolute x-coordinate of regarded AxB block
    int       pic_pix_y,    // <--  absolute y-coordinate of regarded AxB block
	int       blocktype,    // <--  block type (1-16x16 ... 7-4x4)
	int       pred_mv_x,    // <--  motion vector predictor (x) in sub-pel units
	int       pred_mv_y,    // <--  motion vector predictor (y) in sub-pel units
	int*      mv_x,         //  --> motion vector (x) - in pel units
	int*      mv_y,         //  --> motion vector (y) - in pel units
	int       search_range, // <--  1-d search range in pel units                         
	int       min_mcost,    // <--  minimum motion cost (cost for center or huge value)
	double    lambda        // <--  lagrangian parameter for determining motion cost
* Output:
* Return: 
* Attention: in this function, three macro definitions is gives,
	 EARLY_TERMINATION: early termination algrithm, refer to JVT-D016.doc
	 SEARCH_ONE_PIXEL: search one pixel in search range
	 SEARCH_ONE_PIXEL1(value_iAbort): search one pixel in search range,
                                  but give a parameter to show if mincost refeshed
*************************************************************************
*/

int                                     //  ==> minimum motion cost after search
FastIntegerPelBlockMotionSearch  (pel_t**   orig_pic,     // <--  not used
								  int       ref,          // <--  reference frame (0... or -1 (backward))
								  int       pic_pix_x,    // <--  absolute x-coordinate of regarded AxB block
								  int       pic_pix_y,    // <--  absolute y-coordinate of regarded AxB block
								  int       blocktype,    // <--  block type (1-16x16 ... 7-4x4)
								  int       pred_mv_x,    // <--  motion vector predictor (x) in sub-pel units
								  int       pred_mv_y,    // <--  motion vector predictor (y) in sub-pel units
								  int*      mv_x,         //  --> motion vector (x) - in pel units
								  int*      mv_y,         //  --> motion vector (y) - in pel units
								  int       search_range, // <--  1-d search range in pel units                         
								  int       min_mcost,    // <--  minimum motion cost (cost for center or huge value)
								  double    lambda)       // <--  lagrangian parameter for determining motion cost
{
	static int Diamond_x[4] = {-1, 0, 1, 0};
	static int Diamond_y[4] = {0, 1, 0, -1};
	static int Hexagon_x[6] = {2, 1, -1, -2, -1, 1};
	static int Hexagon_y[6] = {0, -2, -2, 0,  2, 2};
	static int Big_Hexagon_x[16] = {0,-2, -4,-4,-4, -4, -4, -2,  0,  2,  4,  4, 4, 4, 4, 2};
	static int Big_Hexagon_y[16] = {4, 3, 2,  1, 0, -1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3};

	int   pos, cand_x, cand_y,  mcost;
	pel_t *(*get_ref_line)(int, pel_t*, int, int);
	pel_t*  ref_pic       = img->type==B_IMG? Refbuf11 [ref+(!img->picture_structure) +1] : Refbuf11[ref];
	int   best_pos      = 0;                                        // position with minimum motion cost
	int   max_pos       = (2*search_range+1)*(2*search_range+1);    // number of search positions
	int   lambda_factor = LAMBDA_FACTOR (lambda);                   // factor for determining lagragian motion cost
	int   mvshift       = 2;                  // motion vector shift for getting sub-pel units
	int   blocksize_y   = input->blc_size[blocktype][1];            // vertical block size
	int   blocksize_x   = input->blc_size[blocktype][0];            // horizontal block size
	int   blocksize_x4  = blocksize_x >> 2;                         // horizontal block size in 4-pel units
	int   pred_x        = (pic_pix_x << mvshift) + pred_mv_x;       // predicted position x (in sub-pel units)
	int   pred_y        = (pic_pix_y << mvshift) + pred_mv_y;       // predicted position y (in sub-pel units)
	int   center_x      = pic_pix_x + *mv_x;                        // center position x (in pel units)
	int   center_y      = pic_pix_y + *mv_y;                        // center position y (in pel units)
	int    best_x, best_y;
	int   check_for_00  = (blocktype==1 && !input->rdopt && img->type!=B_IMG && ref==0);
	int   search_step,iYMinNow, iXMinNow;
	int   i,m, iSADLayer; 
	int   iAbort;
	float betaSec,betaThird;

	int   height        = img->height;/*lgp*/

	//===== set function for getting reference picture lines =====
	if ((center_x > search_range) && (center_x < img->width -1-search_range-blocksize_x) &&
		(center_y > search_range) && (center_y < height-1-search_range-blocksize_y)   )
	{
		get_ref_line = FastLineX;
	}
	else
	{
		get_ref_line = UMVLineX;
	}
	
	memset(McostState[0],0,(2*search_range+1)*(2*search_range+1)*4);
	
   ///////////////////////////////////////////////////////////////	
	if(ref>0) 
	{
		if(pred_SAD_ref!=0)
		{
			betaSec = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaSec[blocktype];
			betaThird = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaThird[blocktype];
		}
		else
		{
			betaSec = 0;
			betaThird = 0;
		}
	}
	else 
	{
		if(blocktype==1)
		{
			if(pred_SAD_space !=0)
			{
				betaSec = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaSec[blocktype];
				betaThird = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaThird[blocktype];
			}
			else
			{
				betaSec = 0;
				betaThird = 0;
			}
		}
		else
		{
			if(pred_SAD_uplayer !=0)
			{
				betaSec = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaSec[blocktype];
				betaThird = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaThird[blocktype];
			}
			else
			{
				betaSec = 0;
				betaThird = 0;
			}
		}
	}
	/*****************************/

	////////////search around the predictor and (0,0)
	//check the center median predictor
	cand_x = center_x ;
	cand_y = center_y ;
	mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
	mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,cand_x,cand_y);
	McostState[search_range][search_range] = mcost;
	if (mcost < min_mcost)
	{
		min_mcost = mcost;
		best_x = cand_x;
		best_y = cand_y;
	}

	iXMinNow = best_x;
	iYMinNow = best_y;
	for (m = 0; m < 4; m++)
	{		
		cand_x = iXMinNow + Diamond_x[m];
		cand_y = iYMinNow + Diamond_y[m];   
		SEARCH_ONE_PIXEL
	} 

	if(center_x != pic_pix_x || center_y != pic_pix_y)
	{
		cand_x = pic_pix_x ;
		cand_y = pic_pix_y ;
		SEARCH_ONE_PIXEL

		iXMinNow = best_x;
		iYMinNow = best_y;
		for (m = 0; m < 4; m++)
		{		
			cand_x = iXMinNow + Diamond_x[m];
			cand_y = iYMinNow + Diamond_y[m];   
			SEARCH_ONE_PIXEL
		} 
	}
	
    if(blocktype>1)
	{
		cand_x = pic_pix_x + (pred_MV_uplayer[0]/4);
		cand_y = pic_pix_y + (pred_MV_uplayer[1]/4);
		SEARCH_ONE_PIXEL
		if ((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaThird)
			goto third_step;
		else if((min_mcost-pred_SAD_uplayer)<pred_SAD_uplayer*betaSec)
			goto sec_step;
	} 

	//coordinate position prediction
	if ((img->number > 1 + ref && ref!=-1) || (ref == -1 && Bframe_ctr > 1))
	{
		cand_x = pic_pix_x + pred_MV_time[0]/4;
		cand_y = pic_pix_y + pred_MV_time[1]/4;
		SEARCH_ONE_PIXEL
  }

	//prediciton using mV of last ref moiton vector
	if ((ref > 0) || (img->type == B_IMG && ref == 0))
	{
		cand_x = pic_pix_x + pred_MV_ref[0]/4;
		cand_y = pic_pix_y + pred_MV_ref[1]/4;
		SEARCH_ONE_PIXEL
	}
	//strengthen local search
	iXMinNow = best_x;
	iYMinNow = best_y;
	for (m = 0; m < 4; m++)
	{		
		cand_x = iXMinNow + Diamond_x[m];
		cand_y = iYMinNow + Diamond_y[m];   
		SEARCH_ONE_PIXEL
	} 

	//early termination algrithm, refer to JVT-D016
    EARLY_TERMINATION

⌨️ 快捷键说明

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