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

📄 fast_me.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
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];
#ifdef  USE_HP_FILTER//BROUND
  if(input->UseHPFilter != 0)
  {
    img->bipred_rounding_control = (img->nal_reference_idc!=0);
    offsetBi    = offsetRpic + offsetSpic;
  }
  else
  {
    offsetBi    = (offsetRpic + offsetSpic + 1)>>1;
  }
#else
  offsetBi    = (offsetRpic + offsetSpic + 1)>>1;
#endif
  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 + -