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

📄 mv-search.c

📁 本源码是H.26L标准的Visual C++源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  _bo = BlockSAD[refindex][3];
  _bi = BlockSAD[refindex][4];
  _bj = _bi + 8;
  ADD_UP_BLOCKS(); INCREMENT(2);
  ADD_UP_BLOCKS();

  //--- blocktype 2 ---
  _bo = BlockSAD[refindex][2];
  _bi = BlockSAD[refindex][4];
  _bj = _bi + 2;
  ADD_UP_BLOCKS(); INCREMENT(8);
  ADD_UP_BLOCKS();

  //--- blocktype 1 ---
  _bo = BlockSAD[refindex][1];
  _bi = BlockSAD[refindex][3];
  _bj = _bi + 2;
  ADD_UP_BLOCKS();
}

/*!
 ***********************************************************************
 * \brief
 *    calculation of all SAD's (for all motion vectors and 4x4 blocks)
 ***********************************************************************
 */
void
SetupFastFullIntegerSearch (int      refframe,
                            int    **refFrArr,
                            int   ***tmp_mv,
                            int *****img_mv,
                            pel_t   *CurrRefPic,
                            int      search_range,
                            int      backward,
                            int      rdopt)
// Note: All Vectors in this function are full pel only.
{
  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;
}

/*!
 ***********************************************************************
 * \brief
 *    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,
                       double lambda)
{
// 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;
  int mvres_l        = mv_mul==1 ? 2 : 3;
  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 =====
  if (!lambda)
  {
    *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) =====
  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
  {
    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_


/*!
 ***********************************************************************
 * \brief
 *    Integer Spiral Search
 * \par Output:
 *    best_inter_sad
 * \par 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,
                          double lambda)
{
// 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;

    if (lambda)
      current_inter_sad = MVCostLambda (mv_mul==1?2:3, lambda, predicted_x, predicted_y, Candidate_X, Candidate_Y);
    else
      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;
}


/*!
 ***********************************************************************
 * \brief
 *    Half Pel Search
 ***********************************************************************
 */
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,
      double lambda)
{
  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;

    if (lambda)
      current_inter_sad = MVCostLambda (mv_mul==1?0:1, lambda,
      predicted_x, predicted_y, s_pos_x, s_pos_y);
    else
      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;
}


/*!
 ***********************************************************************
 * \brief
 *    Quarter Pel Search
 ***********************************************************************
 */
int QuarterPelSearch(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,
        double lambda
        )
{
  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];

⌨️ 快捷键说明

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