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

📄 mv-search.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	int     x, y, pos, blky, bindex;
	int	Absolute_X, Absolute_Y;
	int	LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
	int     range_partly_outside, offset_x, offset_y, ref_x, ref_y;
	int	refindex     = backward ? img->buf_cycle : refframe;
	int	max_width    = img->width  - 17;
	int	max_height   = img->height - 17;
	int	max_pos      = (2*search_range+1) * (2*search_range+1);
	int     mv_mul       = input->mv_res ? 2 : 1;
	int   **block_sad    = BlockSAD[refindex][7];
	pel_t   orig_blocks [256];

	register pel_t  *orgptr = orig_blocks;
	register pel_t  *refptr;


	/*===== get search center: predictor of 16x16 block =====*/
	SetMotionVectorPredictor (img_mv[0][0][refframe][1], refFrArr, tmp_mv,
				  refframe, 0, 0, 16, 16);
	search_center_x[refindex] = img_mv[0][0][refframe][1][0] / (mv_mul*4);
	search_center_y[refindex] = img_mv[0][0][refframe][1][1] / (mv_mul*4);
	if (!rdopt)
	  {
	    /* correct center so that (0,0) vector is inside */
	    search_center_x[refindex] = max(-search_range, min(search_range, search_center_x[refindex]));
	    search_center_y[refindex] = max(-search_range, min(search_range, search_center_y[refindex]));
	  }
	search_center_x[refindex] += img->pix_x;
	search_center_y[refindex] += img->pix_y;
	offset_x = search_center_x[refindex];
	offset_y = search_center_y[refindex];


	/*===== copy original block for fast access =====*/
	for   (y = img->pix_y; y < img->pix_y+16; y++)
	  for (x = img->pix_x; x < img->pix_x+16; x++)
	    *orgptr++ = imgY_org [y][x];


	/*===== check if whole search range is inside image =====*/
	if (offset_x >= search_range		  &&
	    offset_y >= search_range		  &&
	    offset_x <= max_width  - search_range &&
	    offset_y <= max_height - search_range)
	{
		range_partly_outside = 0;	PelYline_11 = FastLine16Y_11;
	}
	else
		range_partly_outside = 1;


	/*===== determine position of (0,0)-vector =====*/
	if (!rdopt)
	{
	  ref_x = img->pix_x - offset_x;
	  ref_y = img->pix_y - offset_y;
	  
	  for (pos = 0; pos < max_pos; pos++)
	    if (ref_x == SpiralX[pos] &&
		ref_y == SpiralY[pos])
	      {
		pos_00[refindex] = pos;
		break;
	      }
	}


	/*===== loop over search range (spiral search): get blockwise SAD =====*/
	for (pos = 0; pos < max_pos; pos++)
	{
		Absolute_Y = offset_y + SpiralY[pos];
		Absolute_X = offset_x + SpiralX[pos];

		if (range_partly_outside)
		{
			if (Absolute_Y >= 0 && Absolute_Y <= max_height &&
			    Absolute_X >= 0 && Absolute_X <= max_width    )
			  PelYline_11 = FastLine16Y_11;
			else
			  PelYline_11 = UMVLine16Y_11;
		}

		orgptr = orig_blocks;
		bindex = 0;
		for (blky = 0; blky < 4; blky++)
		{
			LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
			for (y = 0; y < 4; y++)
			{
				refptr = PelYline_11 (CurrRefPic, Absolute_Y++, Absolute_X);

				LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
				LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
			}
			block_sad[bindex++][pos] = LineSadBlk0;
			block_sad[bindex++][pos] = LineSadBlk1;
			block_sad[bindex++][pos] = LineSadBlk2;
			block_sad[bindex++][pos] = LineSadBlk3;
		}
	}


	/*===== combine SAD's for larger block types =====*/
	SetupLargerBlocks (refindex, max_pos);


	/*===== set flag marking that search setup have been done =====*/
	search_setup_done[refindex] = 1;
}



/*****
 ***** fast full integer search (SetupFastFullIntegerSearch have to be called before)
 *****
 */
int
FastFullIntegerSearch (int		mv_mul,
		       int		predicted_x,
		       int		predicted_y,
		       int		search_range,
		       int		refindex,
		       int		blocktype,
		       int		mb_x,
		       int		mb_y,
		       int		*center_h2,
		       int		*center_v2,
		       int		pic_pix_x,
		       int		pic_pix_y
#ifdef _RD_OPT_
		       ,double  lambda
#endif
		       )
{
// Note: All Vectors in this function are full pel only.  

  int Candidate_X, Candidate_Y, current_inter_sad;
  int mvres          = mv_mul==1 ? 4 : 8;
#ifdef _RD_OPT_
  int mvres_l        = mv_mul==1 ? 2 : 3;
#endif
  int	Offset_X     = search_center_x[refindex] - img->pix_x;
  int Offset_Y       = search_center_y[refindex] - img->pix_y;
  int best_inter_sad = MAX_VALUE;
  int bindex	      = mb_y + (mb_x >> 2);

  register int  pos;
  register int  max_pos   = (2*search_range+1)*(2*search_range+1);
  register int *block_sad = BlockSAD[refindex][blocktype][bindex];


  /*===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====*/
#ifdef _RD_OPT_
  if (!lambda)
#endif
    {
      *center_h2     = 0;
      *center_v2     = 0;
      best_inter_sad = block_sad[pos_00[refindex]] + MVCost(1, mvres, blocktype, img->qp, predicted_x, predicted_y, 0, 0);
    }

 
  /*===== loop over search range (spiral search) =====*/
#ifdef _RD_OPT_
  if (lambda)
    {
      for (pos = 0; pos < max_pos; pos++, block_sad++)
	if (*block_sad < best_inter_sad)
	  {
	    Candidate_X        = Offset_X + SpiralX[pos];
	    Candidate_Y        = Offset_Y + SpiralY[pos];
	    current_inter_sad  = *block_sad;				
	    current_inter_sad += MVCostLambda (mvres_l, lambda, predicted_x, predicted_y, Candidate_X, Candidate_Y);
				
	    if (current_inter_sad < best_inter_sad)
	      {
		*center_h2     = Candidate_X;
		*center_v2     = Candidate_Y;
		best_inter_sad = current_inter_sad;
	      }
	  }
    }
  else
#endif
    {
      for (pos = 0; pos < max_pos; pos++, block_sad++)
	if (*block_sad < best_inter_sad)
	  {
	    Candidate_X        = Offset_X + SpiralX[pos];
	    Candidate_Y        = Offset_Y + SpiralY[pos];
	    current_inter_sad  = *block_sad;				
	    current_inter_sad += MVCost (1, mvres, blocktype, img->qp, predicted_x, predicted_y, Candidate_X, Candidate_Y);
				
	    if (current_inter_sad < best_inter_sad)
	      {
		*center_h2     = Candidate_X;
		*center_v2     = Candidate_Y;
		best_inter_sad = current_inter_sad;
	      }
	  }
    }

  return best_inter_sad;
}



#endif // _FAST_FULL_ME_











// Integer Spiral Search
//
// Input: 
//
// Output:	best_inter_sad
// Output (through Parameter pointers):
//		center_h2, center_v2 (if better MV was found)
//
int IntegerSpiralSearch ( int mv_mul, int center_x, int center_y, 
			  int predicted_x, int predicted_y,
			  int blockshape_x, int blockshape_y,
			  int curr_search_range, int blocktype,
			  pel_t mo[16][16], pel_t *FullPelCurrRefPic,
			  int *center_h2, int *center_v2,
			  int pic_pix_x, int pic_pix_y
#ifdef _RD_OPT_
			  ,double lambda
#endif
			  )
{
// Note: All Vectors in this function are full pel only.  
						
  int numc, lv;
  int best_inter_sad = MAX_VALUE;
  int abort_search;
  int current_inter_sad;
  int Candidate_X, Candidate_Y, Absolute_X, Absolute_Y;
  int i, x, y;
  int Difference;
  pel_t SingleDimensionMo[16*16];
  pel_t *check;

  numc=(curr_search_range*2+1)*(curr_search_range*2+1);

  // Setup a fast access field for the original
  for (y=0, i=0; y<blockshape_y; y++)
    for (x=0; x<blockshape_x; x++)
      SingleDimensionMo[i++] = mo[y][x];

  for (lv=0; lv < numc; lv++) {
    Candidate_X = center_x + SpiralX[lv];
    Candidate_Y = center_y + SpiralY[lv];
    Absolute_X = pic_pix_x + Candidate_X;
    Absolute_Y = pic_pix_y + Candidate_Y;
	
#ifdef _RD_OPT_
    if (lambda)
      current_inter_sad = MVCostLambda (mv_mul==1?2:3, lambda, predicted_x, predicted_y, Candidate_X, Candidate_Y);
    else
#endif
      current_inter_sad = MVCost (1, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, Candidate_X,Candidate_Y);


    abort_search=FALSE;


    for (y=0, i=0; y < blockshape_y && !abort_search; y++) {
      check = PelYline_11 (FullPelCurrRefPic, Absolute_Y+y, Absolute_X);			// get pointer to line
      for (x=0; x < blockshape_x ;x++) {
	Difference = SingleDimensionMo[i++]- *check++;
	current_inter_sad += ByteAbs (Difference);
      }
      if (current_inter_sad >= best_inter_sad) {
	abort_search=TRUE;
      }
    }

    if(!abort_search) {
      *center_h2=Candidate_X;
      *center_v2=Candidate_Y;
      best_inter_sad=current_inter_sad;
    }
  }
  return best_inter_sad;
}




int HalfPelSearch(int pic4_pix_x, int pic4_pix_y, int mv_mul, int blockshape_x, int blockshape_y,
		  int *s_pos_x1, int *s_pos_y1, int *s_pos_x2, int *s_pos_y2, int center_h2, int center_v2,
		  int predicted_x, int predicted_y, int blocktype, pel_t mo[16][16], pel_t **CurrRefPic, int ***tmp_mv,
		  int *****all_mv, int block_x, int block_y, int ref_frame, int pic_block_x, int pic_block_y
#ifdef _RD_OPT_
		  ,double lambda
#endif
		  )
{
  int best_inter_sad=MAX_VALUE;
  int current_inter_sad;
  int lv, iy0, jy0, vec1_x, vec1_y, vec2_x, vec2_y, i, i22, j;
  int s_pos_x, s_pos_y;
  int  m7[16][16];
  
  for (lv=0; lv < 9; lv++) {
    s_pos_x=center_h2+SpiralX[lv]*2;
    s_pos_y=center_v2+SpiralY[lv]*2;
    iy0=pic4_pix_x+s_pos_x;
    jy0=pic4_pix_y+s_pos_y;

#ifdef _RD_OPT_
    if (lambda)
      current_inter_sad = MVCostLambda (mv_mul==1?0:1, lambda,
					predicted_x, predicted_y, s_pos_x, s_pos_y);
    else
#endif
      current_inter_sad = MVCost (4, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, s_pos_x, s_pos_y);

    for (vec1_x=0; vec1_x < blockshape_x; vec1_x += 4) {
      for (vec1_y=0; vec1_y < blockshape_y; vec1_y += 4) {
	for (i=0; i < BLOCK_SIZE; i++) {
	  vec2_x=i+vec1_x;
	  i22=iy0+vec2_x*4;
	  for (j=0; j < BLOCK_SIZE; j++) {
	    vec2_y=j+vec1_y;
	    m7[i][j]=mo[vec2_y][vec2_x]-PelY_14 (CurrRefPic, jy0+vec2_y*4, i22);
	  }
	}
	current_inter_sad += find_sad(input->hadamard, m7);
      }
    }
    if (current_inter_sad < best_inter_sad) {
      *s_pos_x1=s_pos_x;
      *s_pos_y1=s_pos_y;
      *s_pos_x2=s_pos_x;
      *s_pos_y2=s_pos_y;

      for (i=0; i < blockshape_x/BLOCK_SIZE; i++) {
	for (j=0; j < blockshape_y/BLOCK_SIZE; j++) {
	  all_mv[block_x+i][block_y+j][ref_frame][blocktype][0]=mv_mul**s_pos_x1;
	  all_mv[block_x+i][block_y+j][ref_frame][blocktype][1]=mv_mul**s_pos_y1;
	  
	  tmp_mv[0][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_x1;
	  tmp_mv[1][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_y1;
	}
      }
      best_inter_sad=current_inter_sad;
    }
  }
  return best_inter_sad;
}



int QuatorPelSearch(int pic4_pix_x, int pic4_pix_y, int mv_mul, int blockshape_x, int blockshape_y,
		    int *s_pos_x1, int *s_pos_y1, int *s_pos_x2, int *s_pos_y2, int center_h2, int center_v2,
		    int predicted_x, int predicted_y, int blocktype, pel_t mo[16][16], pel_t **CurrRefPic, int ***tmp_mv,
		    int *****all_mv, int block_x, int block_y, int ref_frame, 
		    int pic_block_x, int pic_block_y, int best_inter_sad
#ifdef _RD_OPT_
		    ,double lambda
#endif
		    )
{
  int current_inter_sad;
  int lv, s_pos_x, s_pos_y, iy0, jy0, vec1_x, vec1_y, vec2_x, vec2_y, i, i22, j;
  int  m7[16][16];

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

    s_pos_x=*s_pos_x2+SpiralX[lv];
    s_pos_y=*s_pos_y2+SpiralY[lv];
    
    iy0=pic4_pix_x+s_pos_x;
    jy0=pic4_pix_y+s_pos_y;

#ifdef _RD_OPT_
    if (lambda)
      current_inter_sad = MVCostLambda (mv_mul==1?0:1, lambda,
					predicted_x, predicted_y, s_pos_x, s_pos_y);
    else
#endif
      current_inter_sad = MVCost (4, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, s_pos_x, s_pos_y);
    
    for (vec1_x=0; vec1_x < blockshape_x; vec1_x += 4) {
      for (vec1_y=0; vec1_y < blockshape_y; vec1_y += 4) {
	for (i=0; i < BLOCK_SIZE; i++) {
	  vec2_x=i+vec1_x;
	  i22=iy0+vec2_x*4;
	  for (j=0; j < BLOCK_SIZE; j++) {
	    vec2_y=j+vec1_y;
	    m7[i][j]=mo[vec2_y][vec2_x]-PelY_14 (CurrRefPic, jy0+vec2_y*4, i22);
	  }
	}
	current_inter_sad += find_sad(input->hadamard, m7);

⌨️ 快捷键说明

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