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

📄 fast_me.c

📁 H.264 codec source code
💻 C
📖 第 1 页 / 共 4 页
字号:
    else
    {
      pred_SAD = (list==1) ? (fastme_l1_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
      pred_SAD /= 2; 
    }
  }
  else pred_SAD = 0 ;  // pred_SAD_space

}

/*!
 ************************************************************************
 * \brief
 *    FastBipredIntegerPelBlockMotionSearch: fast pixel block motion search for bipred mode
 *    this algrithm is called UMHexagonS(see JVT-D016),which includes 
 *    four steps with different kinds of search patterns
 * \author
 *   Main contributors: (see contributors.h for copyright, address and affiliation details)
 *   - Zhibo Chen         <chenzhibo@tsinghua.org.cn>
 *   - JianFeng Xu        <fenax@video.mdc.tsinghua.edu.cn>
 *   - Xiaozhong Xu       <xxz@video.mdc.tsinghua.edu.cn>
 * \date   :
 *   2006.1
 ************************************************************************
 */
int                                                //  ==> minimum motion cost after search
FastBipredIntegerPelBlockMotionSearch (pel_t**   cur_pic,      // <--  original pixel values for the AxB block
                          short       ref,         // <--  reference frame (0... or -1 (backward))
                          int       list,
                          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)
                          short     pred_mv_x1,    // <--  motion vector predictor (x) in sub-pel units
                          short     pred_mv_y1,    // <--  motion vector predictor (y) in sub-pel units
                          short     pred_mv_x2,    // <--  motion vector predictor (x) in sub-pel units
                          short     pred_mv_y2,    // <--  motion vector predictor (y) in sub-pel units
                          short*    mv_x,          // <--> in: search center (x) / out: motion vector (x) - in pel units
                          short*    mv_y,          // <--> in: search center (y) / out: motion vector (y) - in pel units
                          short*    s_mv_x,        // <--> in: search center (x) / out: motion vector (x) - in pel units
                          short*    s_mv_y,        // <--> in: search center (y) / out: 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)
                          int       lambda_factor) // <--  lagrangian parameter for determining motion cost

{
  int	temp_Big_Hexagon_x[16];// = Big_Hexagon_x;
  int	temp_Big_Hexagon_y[16];// = Big_Hexagon_y; 
  int   mvshift       = 2;                  // motion vector shift for getting sub-pel units

  int   search_step,iYMinNow, iXMinNow;
  int   i,m,j; 
  float betaFourth_1,betaFourth_2;
  int   pos, cand_x, cand_y,mcost;
  int   list_offset   = img->mb_data[img->current_mb_nr].list_offset; 
  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_x1        = (pic_pix_x << 2) + pred_mv_x1;       // predicted position x (in sub-pel units)
  int   pred_y1        = (pic_pix_y << 2) + pred_mv_y1;       // predicted position y (in sub-pel units)
  int   pred_x2        = (pic_pix_x << 2) + pred_mv_x2;       // predicted position x (in sub-pel units)
  int   pred_y2        = (pic_pix_y << 2) + pred_mv_y2;       // predicted position y (in sub-pel units)
  short center2_x      = pic_pix_x + *mv_x;                      // center position x (in pel units)
  short center2_y      = pic_pix_y + *mv_y;                      // center position y (in pel units)
  short center1_x	   = pic_pix_x + *s_mv_x;                      // mvx of second pred (in pel units)
  short center1_y	   = pic_pix_y + *s_mv_y;                      // mvy of second pred (in pel units)
  short apply_weights   = (active_pps->weighted_bipred_idc>0);  
  short offsetSpic = (apply_weights ? (list == 0?  wp_offset[list_offset    ][ref]     [0]:  wp_offset[list_offset + 1][0  ]     [0]) : 0);
  short offsetRpic = (apply_weights ? (list == 0?  wp_offset[list_offset + 1][ref]     [0]:  wp_offset[list_offset    ][0  ]     [0]) : 0);
  short mb_x = pic_pix_x - img->opix_x; 
  short mb_y = pic_pix_y - img->opix_y;
  short block_x = (mb_x >> 2);
  short block_y = (mb_y >> 2); 
  int   best_x = center2_x;
  int   best_y = center2_y;
  int ET_Thred = Median_Pred_Thd_MB[blocktype];
  offsetBi		= (offsetRpic + offsetSpic + 1)>>1;
  weightSpic	= (apply_weights ? (list == 0? wbp_weight[list_offset    ][ref][0  ][0]: wbp_weight[list_offset + 1][0  ][ref][0]) : 1<<luma_log_weight_denom);
  weightRpic	= (apply_weights ? (list == 0? wbp_weight[list_offset + 1][ref][0  ][0]: wbp_weight[list_offset    ][0  ][ref][0]) : 1<<luma_log_weight_denom);
  ref1_pic		= listX[list + list_offset          ][ref]->imgY_11;
  ref2_pic		= listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgY_11;  
  width			= listX[list+list_offset            ][ref]->size_x;
  height		= listX[list+list_offset            ][ref]->size_y;
  PartCalMadBiPred = apply_weights ? PartCalMadBiPred2 : PartCalMadBiPred1;
  
  //===== set function for getting reference picture lines =====
  if ((center2_x > search_range) && (center2_x < width -1-search_range-blocksize_x) &&
    (center2_y > search_range) && (center2_y < height-1-search_range-blocksize_y)   )
  {
    get_ref_line2 = FastLineX;
  }
  else
  {
    get_ref_line2 = UMVLineX2;
  }
  
  //===== set function for getting reference picture lines =====
  if ((center1_y > search_range) && (center1_y < height-1-search_range-blocksize_y)   )
  {
    get_ref_line1 = FastLineX;
  }
  else
  {
    get_ref_line1 = UMVLineX;
  }

//////////////////////////////////////////////////////////////////////////
   
  //////allocate memory for search state//////////////////////////
  memset(McostState[0],0,(2*search_range+1)*(2*search_range+1));


  //check the center median predictor
  cand_x = center2_x ;
  cand_y = center2_y ;
  mcost  = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
  mcost += MV_COST (lambda_factor, mvshift, cand_x,	   cand_y,	  pred_x2, pred_y2);
  mcost  = PartCalMadBiPred(cur_pic, blocksize_y, blocksize_x, blocksize_x4, mcost,INT_MAX,center1_x, center1_y, cand_x, cand_y);
  McostState[search_range][search_range] = 1;
  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_BIPRED
  } 

  if(center2_x != pic_pix_x || center2_y != pic_pix_y)
  {
    cand_x = pic_pix_x ;
    cand_y = pic_pix_y ;
    SEARCH_ONE_PIXEL_BIPRED

    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_BIPRED
    } 
  }  
/***********************************init process*************************/

  if( min_mcost < ET_Thred)	
  {
    goto terminate_step;
  }
  else
  {
    int  N_Bframe=0;
	int  n_Bframe=0;
    short****** bipred_mv = list ? img->bipred_mv1 : img->bipred_mv2;
    N_Bframe = input->successive_Bframe;
    n_Bframe = frame_ctr[B_SLICE]%(N_Bframe+1);


  /**************************** MV prediction **********************/ 
  //MV uplayer prediction
  // non for bipred mode
  
  //MV ref-frame prediction

		if(list==0)
		{
		  if (img->field_picture) 
		  {
			  pred_MV_ref[0] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
			  pred_MV_ref[1] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
		  }
		  else //frame case
		  {
			  pred_MV_ref[0] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
			  pred_MV_ref[1] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
		  }
		}
  /******************************SAD prediction**********************************/

        pred_SAD =min(min(SAD_a,SAD_b),SAD_c);  // pred_SAD_space
		ET_Thred = Big_Hexagon_Thd_MB[blocktype];

 ///////Threshold defined for early termination///////////////////  
	  if (pred_SAD == 0) 
	  {
		betaFourth_1=0;
		betaFourth_2=0;
	  }
	  else
	  {
		betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
		betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
 
	  }  

  }

/***********************************end of init *************************/

 

// first_step: initial start point prediction 
  
//prediciton using mV of last ref moiton vector
 if(list == 0)	  		
  {
      cand_x = pic_pix_x + (pred_MV_ref[0]/4);
      cand_y = pic_pix_y + (pred_MV_ref[1]/4);
      SEARCH_ONE_PIXEL_BIPRED
  }


  //small 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_BIPRED
  } 

  //early termination alogrithm, refer to JVT-G016
    EARLY_TERMINATION
  
  
//sec_step: //Unsymmetrical-cross search 
  iXMinNow = best_x;
  iYMinNow = best_y;
  
  for(i = 1; i < search_range; i+=2)
  {
    search_step = i;
    cand_x = iXMinNow + search_step;
    cand_y = iYMinNow ;
    SEARCH_ONE_PIXEL_BIPRED    
    cand_x = iXMinNow - search_step;
    cand_y = iYMinNow ;
    SEARCH_ONE_PIXEL_BIPRED
  }
 
  for(i = 1; i < (search_range/2);i+=2)
  {
    search_step = i;
    cand_x = iXMinNow ;
    cand_y = iYMinNow + search_step;
    SEARCH_ONE_PIXEL_BIPRED
    cand_x = iXMinNow ;
    cand_y = iYMinNow - search_step;
    SEARCH_ONE_PIXEL_BIPRED
  }
  //early termination alogrithm, refer to JVT-G016
    EARLY_TERMINATION

		
//third_step:     // Uneven Multi-Hexagon-grid Search 
  iXMinNow = best_x;
  iYMinNow = best_y;
//sub step1: 5x5 square search
  for(pos=1;pos<25;pos++)
  {
    cand_x = iXMinNow + spiral_search_x[pos];
    cand_y = iYMinNow + spiral_search_y[pos];
    SEARCH_ONE_PIXEL_BIPRED
  }

  //early termination alogrithm, refer to JVT-G016
	EARLY_TERMINATION			//added back by xxz

//sub step2: multi-grid-hexagon-search
  memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
  memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);    		
  for(i=1;i<=(input->search_range>>2); i++)
  {

    for (m = 0; m < 16; m++)
    {
      cand_x = iXMinNow + temp_Big_Hexagon_x[m];
      cand_y = iYMinNow + temp_Big_Hexagon_y[m];
	  temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
	  temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];	

      SEARCH_ONE_PIXEL_BIPRED
    }
	if(min_mcost < ET_Thred)
	{
	   		  goto terminate_step;

	}
  }
//fourth step: Local Refinement: Extended Hexagon-based Search
fourth_1_step:  

      for(i=0; i < search_range; i++) 
      {
        iXMinNow = best_x;
        iYMinNow = best_y;
        for (m = 0; m < 6; m++)
        {   
          cand_x = iXMinNow + Hexagon_x[m];
          cand_y = iYMinNow + Hexagon_y[m];   
          SEARCH_ONE_PIXEL_BIPRED
        } 
        if(best_x == iXMinNow && best_y == iYMinNow)
            break;
      }
fourth_2_step: 

      for(i = 0; i < search_range; i++) 
      {
	    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_BIPRED
        } 
        if(best_x == iXMinNow && best_y == iYMinNow)
            break;
      }

terminate_step:
		  for (i=0; i < (blocksize_x>>2); i++)
		  {
			for (j=0; j < (blocksize_y>>2); j++)
			{
				if(list == 0) 
				{
				  fastme_l0_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
				}
				else
				{
				  fastme_l1_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
				}
			}
		  }

      *mv_x = best_x - pic_pix_x; 
      *mv_y = best_y - pic_pix_y; 


      return min_mcost;
}

⌨️ 快捷键说明

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