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

📄 mv-search.c

📁 网络MPEG4IP流媒体开发源代码
💻 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) *********************************************************************** */voidSetupFastFullIntegerSearch (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) *********************************************************************** */intFastFullIntegerSearch (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 + -