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

📄 fast_me.c

📁 h.264标准和jm
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
      if (mb_x+blockshape_x != 16)   block_available_upright = 1;
      else                           block_available_upright = 0;
    }
  }
  else if (mb_x+blockshape_x != MB_BLOCK_SIZE)
  {
    block_available_upright = block_available_up;
  }
  else
  {
    block_available_upright = mb_available_upright;
  }
  
  if (mb_x > 0)
  {
    block_available_upleft = (mb_y > 0 ? 1 : block_available_up);
  }
  else if (mb_y > 0)
  {
    block_available_upleft = block_available_left;
  }
  else
  {
    block_available_upleft = mb_available_upleft;
  }
  
  	//write refFrArr[][] for current subMB partition
		refFrArray[pic_block_y][pic_block_x]= ref;	//needed for other subMB partitions in this MB partition

//  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
//    block_available_upright = 0;      // temp fix for MB level field/frame coding

  mvPredType = MVPRED_MEDIAN;
  rFrameL    = block_available_left    ? refFrArray[pic_block_y]  [pic_block_x-1] : -1;
  rFrameU    = block_available_up      ? refFrArray[pic_block_y-1][pic_block_x]   : -1;
  rFrameUR   = block_available_upright ? refFrArray[pic_block_y-1][pic_block_x+blockshape_x/4] :
               block_available_upleft  ? refFrArray[pic_block_y-1][pic_block_x-1] : -1;
  
  
  
  /* Prediction if only one of the neighbors uses the reference frame
  * we are checking
  */
  
  if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
    mvPredType = MVPRED_L;
  else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
    mvPredType = MVPRED_U;
  else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
    mvPredType = MVPRED_UR;
  // Directional predictions 
  if(blockshape_x == 8 && blockshape_y == 16)
  {
    if(mb_x == 0)
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
    else
    {
      //if( block_available_upright && refFrArray[pic_block_y-1][pic_block_x+blockshape_x/4] == ref_frame)
      if(rFrameUR == ref_frame) 
        mvPredType = MVPRED_UR;
    }
  }
  else if(blockshape_x == 16 && blockshape_y == 8)
  {
    if(mb_y == 0)
    {
      if(rFrameU == ref_frame)
        mvPredType = MVPRED_U;
    }
    else
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
  }
  
#define MEDIAN(a,b,c)  (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)
  
  for (hv=0; hv < 2; hv++)
  {
    mv_a = block_available_left    ? tmp_mv[hv][pic_block_y  ][4+pic_block_x-1]              : 0;
    mv_b = block_available_up      ? tmp_mv[hv][pic_block_y-1][4+pic_block_x]                : 0;
    mv_d = block_available_upleft  ? tmp_mv[hv][pic_block_y-1][4+pic_block_x-1]              : 0;
    mv_c = block_available_upright ? tmp_mv[hv][pic_block_y-1][4+pic_block_x+blockshape_x/4] : mv_d;
    
	SAD_a = block_available_left    ? ((list==1) ? all_bwmincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2)][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2)][ref_frame][blocktype][0]) : 0;
    SAD_b = block_available_up      ? ((list==1) ? all_bwmincost[((img->pix_x+mb_x)>>2)][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2)][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : 0;
    SAD_d = block_available_upleft  ? ((list==1) ? all_bwmincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : 0;
    SAD_c = block_available_upright ? ((list==1) ? all_bwmincost[((img->pix_x+mb_x)>>2) +1][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) +1][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : SAD_d;
	
    switch (mvPredType)
    {
    case MVPRED_MEDIAN:
      if(!(block_available_upleft || block_available_up || block_available_upright))
	  {
        pred_vec = mv_a;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
	  	  temp_pred_SAD[hv] = SAD_a;
		}
      else
        pred_vec = MEDIAN (mv_a, mv_b, mv_c);
	  if (pred_vec == mv_a && SAD_a != 0) temp_pred_SAD[hv] = SAD_a;
	  else if (pred_vec == mv_b && SAD_b!=0) temp_pred_SAD[hv] = SAD_b;
	  else temp_pred_SAD[hv] = SAD_c;
      break;
      
    case MVPRED_L:
      pred_vec = mv_a;
	  temp_pred_SAD[hv] = SAD_a;
      break;
    case MVPRED_U:
      pred_vec = mv_b;
	  temp_pred_SAD[hv] = SAD_b;
      break;
    case MVPRED_UR:
      pred_vec = mv_c;
	  temp_pred_SAD[hv] = SAD_c;
      break;
    default:
      break;
    }

    pmv[hv] = pred_vec;
  }
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  pred_SAD_space = temp_pred_SAD[0]>temp_pred_SAD[1]?temp_pred_SAD[1]:temp_pred_SAD[0];
#undef MEDIAN
}

int                                         //  ==> minimum motion cost after search
FME_BlockMotionSearch (int       ref,           // <--  reference frame (0... )
									 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)
                   int       search_range,  // <--  1-d search range for integer-position search
                   double    lambda         // <--  lagrangian parameter for determining motion cost
                   )
{
  static pel_t   orig_val [256];
  static pel_t  *orig_pic  [16] = {orig_val,     orig_val+ 16, orig_val+ 32, orig_val+ 48,
                                   orig_val+ 64, orig_val+ 80, orig_val+ 96, orig_val+112,
                                   orig_val+128, orig_val+144, orig_val+160, orig_val+176,
                                   orig_val+192, orig_val+208, orig_val+224, orig_val+240};

  int       pred_mv_x, pred_mv_y, mv_x, mv_y, i, j;

  int       max_value = (1<<20);
  int       min_mcost = max_value;
  int       mb_x      = pic_pix_x-img->pix_x;
  int       mb_y      = pic_pix_y-img->pix_y;
  int       block_x   = (mb_x>>2);
  int       block_y   = (mb_y>>2);
  int       bsx       = input->blc_size[blocktype][0];
  int       bsy       = input->blc_size[blocktype][1];
  int       refframe  = ref;		//why chage name?
  int*      pred_mv;
  //int**     refFrArray = ((img->type!=B_SLICE) ? refFrArr : list==0 ? fw_refFrArr : bw_refFrArr);
  //int***    tmp_mv_array  = ((img->type!=B_SLICE) ? tmp_mv   : list==0 ? tmp_fwMV    : tmp_bwMV);
  
  //sw 10.23
  int**     refFrArray    = enc_picture->ref_idx[list];
  int***    tmp_mv_array  = enc_picture->mv[list];
  
  int*****  all_bmv   = img->all_bmv;		//probably redundant g050
  int*****  all_mv    = (list ? img->all_bmv : img->all_mv);	
  byte**    imgY_org_pic = imgY_org;

//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  int       N_Bframe = input->successive_Bframe, n_Bframe =(N_Bframe) ? ((Bframe_ctr%N_Bframe)+1) : 0 ;
assert(ref>=0);
  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    mb_y    = pic_pix_y - img->field_pix_y;
    block_y = mb_y >> 2;
    if(img->top_field)
    {
      pred_mv   = ((img->type!=B_SLICE) ? img->pred_mv_top  : list==0 ? img->p_fwMV_top : img->p_bwMV_top)[mb_x>>2][mb_y>>2][refframe][blocktype];
      refFrArray = ((img->type!=B_SLICE) ? refFrArr_top : list==0 ? fw_refFrArr_top : bw_refFrArr_top);
      tmp_mv_array  = ((img->type!=B_SLICE) ? tmp_mv_top   : list==0 ? tmp_fwMV_top    : tmp_bwMV_top);
      all_bmv   = img->all_bmv_top;
      all_mv    = (list ? img->all_bmv_top    : img->all_mv_top);
      imgY_org_pic = imgY_org_top;
    }
    else
    {
      pred_mv   = ((img->type!=B_SLICE) ? img->pred_mv_bot   : list==0 ? img->p_fwMV_bot : img->p_bwMV_bot)[mb_x>>2][mb_y>>2][refframe][blocktype];
      refFrArray = ((img->type!=B_SLICE) ? refFrArr_bot  : list==0 ? fw_refFrArr_bot : bw_refFrArr_bot);
      tmp_mv_array  = ((img->type!=B_SLICE) ? tmp_mv_bot    : list==0 ? tmp_fwMV_bot    : tmp_bwMV_bot);
      all_bmv   = img->all_bmv_bot;
      all_mv    = (list ? img->all_bmv_bot    : img->all_mv_bot);
      imgY_org_pic = imgY_org_bot;
    }
  }
  else
	  pred_mv = ((img->type!=B_SLICE) ? img->pred_mv  : list==0 ? img->p_fwMV : img->p_bwMV)[mb_x>>2][mb_y>>2][refframe][blocktype];


											//NB  pred_mv is only 2D here

  //==================================
  //=====   GET ORIGINAL BLOCK   =====
  //==================================
  for (j = 0; j < bsy; j++)
  {
    for (i = 0; i < bsx; i++)
    {
      orig_pic[j][i] = imgY_org_pic[pic_pix_y+j][pic_pix_x+i];
    }
  }

//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  if(blocktype>6)
  {
	  pred_MV_uplayer[0] = all_mv[block_x][block_y][refframe][5][0];
	  pred_MV_uplayer[1] = all_mv[block_x][block_y][refframe][5][1];
	  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][5][0]);
	  pred_SAD_uplayer   /= 2; 
	  
  }
  else if(blocktype>4)
  {
	  pred_MV_uplayer[0] = all_mv[block_x][block_y][refframe][4][0];
	  pred_MV_uplayer[1] = all_mv[block_x][block_y][refframe][4][1];
	  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][4][0]);
	  pred_SAD_uplayer   /= 2; 
	  
  }
  else if(blocktype == 4)
  {
	  pred_MV_uplayer[0] = all_mv[block_x][block_y][refframe][2][0];
	  pred_MV_uplayer[1] = all_mv[block_x][block_y][refframe][2][1];
	  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][2][0]);
	  pred_SAD_uplayer   /= 2; 
  }
  else if(blocktype > 1)
  {
	  pred_MV_uplayer[0] = all_mv[block_x][block_y][refframe][1][0];
	  pred_MV_uplayer[1] = all_mv[block_x][block_y][refframe][1][1];
	  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][1][0]);
	  pred_SAD_uplayer   /= 2; 
  }
  
  if ((img->type==B_SLICE)&& (img->nal_reference_idc>0))
  {
	  if(blocktype>6)
	  {
		  pred_MV_uplayer[0] = all_bmv[block_x][block_y][refframe][5][0];
		  pred_MV_uplayer[1] = all_bmv[block_x][block_y][refframe][5][1];
		  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][5][0]);
		  pred_SAD_uplayer   /= 2; 
	  }
	  else if(blocktype>4)
	  {
		  pred_MV_uplayer[0] = all_bmv[block_x][block_y][refframe][4][0];
		  pred_MV_uplayer[1] = all_bmv[block_x][block_y][refframe][4][1];
		  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][4][0]);
		  pred_SAD_uplayer   /= 2; 
	  }
	  else if(blocktype == 4)
	  {
		  pred_MV_uplayer[0] = all_bmv[block_x][block_y][refframe][2][0];
		  pred_MV_uplayer[1] = all_bmv[block_x][block_y][refframe][2][1];
		  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][2][0]);
		  pred_SAD_uplayer   /= 2; 
	  }
	  else if(blocktype > 1)
	  {
		  pred_MV_uplayer[0] = all_bmv[block_x][block_y][refframe][1][0];
		  pred_MV_uplayer[1] = all_bmv[block_x][block_y][refframe][1][1];
		  pred_SAD_uplayer    = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][1][0]);
		  pred_SAD_uplayer   /= 2; 
	  }
  }

  pred_SAD_uplayer = flag_intra_SAD ? 0 : pred_SAD_uplayer;// for irregular motion
 
  //Coordinate prediction
  if (img->number > refframe+1)
  {
	  pred_SAD_time = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][0];
	  pred_MV_time[0] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][1];
	  pred_MV_time[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][2];
  }
 
  if(list==1 && (Bframe_ctr%N_Bframe) > 1) 
  {
	  pred_SAD_time = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][0];
	  pred_MV_time[0] = (int)(all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][blocktype][1] * ((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
	  pred_MV_time[1] = (int)(all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][blocktype][2] *((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
  }

  if (input->InterlaceCodingOption == FIELD_CODING) 
  {
	  if (img->type == P_SLICE && refframe > 1)
	  {
		  pred_SAD_ref = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-2)][blocktype][0];
		  pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
		  pred_MV_ref[0] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-2)][blocktype][1];
		  pred_MV_ref[0] = (int)(pred_MV_ref[0]*((refframe>>1)+1)/(float)((refframe>>1)));
		  pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-2)][blocktype][2];
		  pred_MV_ref[1] = (int)(pred_MV_ref[1]*((refframe>>1)+1)/(float)((refframe>>1)));
	  }
	  if (img->type == B_SLICE && list==0 && (refframe==0 || refframe==1) )
	  {
		  pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][blocktype][0];
		  pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
		  pred_MV_ref[0] =(int) (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); //should add a factor
		  pred_MV_ref[1] =(int) ( all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); 
	  }
  }
 else //frame case
  {
	  if (refframe > 0)
	  {//field_mode top_field
		  pred_SAD_ref = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-1)][blocktype][0];
		  pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
		  pred_MV_ref[0] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-1)][blocktype][1];
		  pred_MV_ref[0] = (int)(pred_MV_ref[0]*(refframe+1)/(float)(refframe));
		  pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(refframe-1)][blocktype][2];
		  pred_MV_ref[1] = (int)(pred_MV_ref[1]*(refframe+1)/(float)(refframe));
	  }
	  if (img->type == B_SLICE && (list==0 && refframe==0)) //B frame forward prediction, first ref
	  {
		  pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][blocktype][0];
		  pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
		  pred_MV_ref[0] =(int) (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); //should add a factor
		  pred_MV_ref[1] =(int) ( all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][refframe][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); 
	  }
  }
  //===========================================
  //=====   GET MOTION VECTOR PREDICTOR   =====
  //===========================================
											//NB  pred_mv is only 2D here
  FME_SetMotionVectorPredictor (pred_mv, refFrArray, tmp_mv_array, refframe, list, mb_x, mb_y, bsx, bsy, blocktype, ref);
  pred_mv_x = pred_mv[0];
  pred_mv_y = pred_mv[1];


  //==================================
  //=====   INTEGER-PEL SEARCH   =====
  //==================================

//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  mv_x = pred_mv_x / 4;
  mv_y = pred_mv_y / 4;
  if (!input->rdopt)
  {
    //--- adjust search center so that the (0,0)-vector is inside ---
    mv_x = max (-search_range, min (search_range, mv_x));
    mv_y = max (-search_range, min (search_range, mv_y));
  }

  min_mcost = FastIntegerPelBlockMotionSearch(orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
                                            pred_mv_x, pred_mv_y, &mv_x, &mv_y, search_range,
                                            min_mcost, lambda);



//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  for (i=0; i < (bsx>>2); i++)
  {

⌨️ 快捷键说明

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