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

📄 mv-search.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 5 页
字号:

        search_step -= 2;
       iXMinNow = currmv_x + img->pix_x;
       iYMinNow = currmv_y + img->pix_y;
      }

      //store the prediction results by using the predicted motion vector 
      iMinPred_x = iXMinNow;
      iMinPred_y = iYMinNow;
      iMvPred_x = currmv_x;
      iMvPred_y = currmv_y;
      iSadMinPred = min_mcost;

      if(iUsePred && (-predict_mv_y + search_range)>0 && (-predict_mv_x + search_range)>0)
      {
        min_mcost= 1<<20;         
        if(SearchState[-predict_mv_y + search_range][-predict_mv_x + search_range])
            mcost0 = SearchState[-predict_mv_y + search_range][-predict_mv_x + search_range];
        else
        {
          orgptr = orig_blocks;

          mcost0 = CalMad(range_partly_outside,orgptr,ref_pic,16,16,pic_pix_x,pic_pix_y);
          SearchStateMaD[-predict_mv_y + search_range][-predict_mv_x + search_range] = mcost0;

          mcost0  += MV_COST (lambda_factor, mvshift, 0, 0, pred_mv_x, pred_mv_y);
          SearchState[-predict_mv_y + search_range][-predict_mv_x + search_range] = mcost0;
        }
        
        if (mcost0 < min_mcost)
        {
          min_mcost = mcost0;
          iXMinNow = pic_pix_x;
          iYMinNow = pic_pix_y; 
          currmv_x = 0;
          currmv_y = 0;
        }

        search_step = 2;
        while(search_step>0)
        {
          iDistortion0 = iDistortion1 = iDistortion2 = 65536; 
          search_index = 1;
          for(i=0;i<2*search_range_dynamic/search_step;i++)
          {
            iSADLayer = 65536;
            for (m = 0; m < 8; m++)
            {		
              orgptr = orig_blocks;	
              pos_x = iXMinNow + gpiHoriozntalPos[m]*search_step*search_index;
              pos_y = iYMinNow + gpiVerticalPos[m]*search_step*search_index;
              if(abs(pos_x - center_x) <32 && abs(pos_y - center_y)< 32)
              {
                if(SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range])
                  iSAD = SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range];
                else
                {
                  iSAD = CalMad(range_partly_outside,orgptr,ref_pic,16,16,pos_x,pos_y);
                  SearchStateMaD[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
                  iSAD += MV_COST (lambda_factor, mvshift, pos_x-img->pix_x, pos_y-img->pix_y, pred_mv_x, pred_mv_y);//Mv_cost;
                  SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
                }
                if (iSAD < min_mcost)
                  {
                    currmv_x = pos_x - img->pix_x;
                    currmv_y = pos_y - img->pix_y;
                    min_mcost = iSAD;
                  }
                  if (iSAD < iSADLayer)
                  {
                    iSADLayer = iSAD;
                    iXMinNext = pos_x;
                    iYMinNext = pos_y;
                  } 
              }
            }
            iDistortion2 = iDistortion1;
            iDistortion1 = iDistortion0;
            iDistortion0 = iSADLayer;
            if (iDistortion1 <= iDistortion0 && iDistortion2 <= iDistortion0)
            {
              break;
            }
            search_index += 1;  
          }
          search_step -= 2;
          iXMinNow = currmv_x + img->pix_x;
          iYMinNow = currmv_y + img->pix_y;
        }
        
      } //end of (0,0) search

       
     if(iUsePred)
     {
       if(min_mcost > iSadMinPred)
       {
         min_mcost = iSadMinPred;
         iXMinNow = iMinPred_x;
         iYMinNow = iMinPred_y;
         currmv_x =  iMvPred_x;
         currmv_y =  iMvPred_y;
       }
     }

     iDistortion0 = iDistortion1 = iDistortion2 = 65536;
     for(i=0;i<2*search_range_dynamic;i++)
      {
        iSADLayer = 65536;
        for (m = 0; m < 8; m++)
        {		
          orgptr = orig_blocks;	
          pos_x = iXMinNow + gpiHoriozntalPos[m];
          pos_y = iYMinNow + gpiVerticalPos[m];
          if(abs(pos_x - center_x) <32 && abs(pos_y - center_y)< 32)
          {
          if(SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range])
            iSAD = SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range];
          else
          {
            iSAD = CalMad(range_partly_outside,orgptr,ref_pic,16,16,pos_x,pos_y);
            SearchStateMaD[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
            iSAD += MV_COST (lambda_factor, mvshift, pos_x-img->pix_x, pos_y-img->pix_y, pred_mv_x, pred_mv_y);//Mv_cost;
            SearchState[pos_y-center_y+search_range][pos_x-center_x+search_range] = iSAD;
          }
          if (iSAD < min_mcost)
          {
            currmv_x = pos_x - img->pix_x;
            currmv_y = pos_y - img->pix_y;
            min_mcost = iSAD;
          }
          if (iSAD < iSADLayer)
          {
            iSADLayer = iSAD;
            iXMinNext = pos_x;
            iYMinNext = pos_y;
          }
          }
        } 
        iXMinNow = iXMinNext;
        iYMinNow = iYMinNext;
        iDistortion2 = iDistortion1;
        iDistortion1 = iDistortion0;
        iDistortion0 = iSADLayer;
        if (iDistortion1 <= iDistortion0 && iDistortion2 <= iDistortion0)
        {
          break;
        }
      }
     
      *mv_x = currmv_x;
      *mv_y = currmv_y; 
  return min_mcost;
  }

#endif

  int CalMad(int range_partly_outside,pel_t *orgptr,pel_t *ref_pic,int blocksize_x,int blocksize_y,int abs_x,int abs_y)
{
    int x,y;
    int SAD = 0;
    pel_t *refptr;

    int     max_width     = img->width  - 17;
    int     max_height    = img->height - 17;

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

     for (y = 0; y < blocksize_y; y++)
     {
       refptr = PelYline_11 (ref_pic, abs_y++, abs_x);
       for(x=0;x<blocksize_x;x++)
        SAD += byte_abs [*refptr++ - *orgptr++];
     }
     return SAD;
}




/*!
 ***********************************************************************
 * \brief
 *    Calculate SA(T)D
 ***********************************************************************
 */
int
SATD (int* diff, int use_hadamard)
{
  int k, satd = 0, m[16], dd, *d=diff;
  
  if (use_hadamard)
  {
    /*===== hadamard transform =====*/
    m[ 0] = d[ 0] + d[12];
    m[ 4] = d[ 4] + d[ 8];
    m[ 8] = d[ 4] - d[ 8];
    m[12] = d[ 0] - d[12];
    m[ 1] = d[ 1] + d[13];
    m[ 5] = d[ 5] + d[ 9];
    m[ 9] = d[ 5] - d[ 9];
    m[13] = d[ 1] - d[13];
    m[ 2] = d[ 2] + d[14];
    m[ 6] = d[ 6] + d[10];
    m[10] = d[ 6] - d[10];
    m[14] = d[ 2] - d[14];
    m[ 3] = d[ 3] + d[15];
    m[ 7] = d[ 7] + d[11];
    m[11] = d[ 7] - d[11];
    m[15] = d[ 3] - d[15];
    
    d[ 0] = m[ 0] + m[ 4];
    d[ 8] = m[ 0] - m[ 4];
    d[ 4] = m[ 8] + m[12];
    d[12] = m[12] - m[ 8];
    d[ 1] = m[ 1] + m[ 5];
    d[ 9] = m[ 1] - m[ 5];
    d[ 5] = m[ 9] + m[13];
    d[13] = m[13] - m[ 9];
    d[ 2] = m[ 2] + m[ 6];
    d[10] = m[ 2] - m[ 6];
    d[ 6] = m[10] + m[14];
    d[14] = m[14] - m[10];
    d[ 3] = m[ 3] + m[ 7];
    d[11] = m[ 3] - m[ 7];
    d[ 7] = m[11] + m[15];
    d[15] = m[15] - m[11];
    
    m[ 0] = d[ 0] + d[ 3];
    m[ 1] = d[ 1] + d[ 2];
    m[ 2] = d[ 1] - d[ 2];
    m[ 3] = d[ 0] - d[ 3];
    m[ 4] = d[ 4] + d[ 7];
    m[ 5] = d[ 5] + d[ 6];
    m[ 6] = d[ 5] - d[ 6];
    m[ 7] = d[ 4] - d[ 7];
    m[ 8] = d[ 8] + d[11];
    m[ 9] = d[ 9] + d[10];
    m[10] = d[ 9] - d[10];
    m[11] = d[ 8] - d[11];
    m[12] = d[12] + d[15];
    m[13] = d[13] + d[14];
    m[14] = d[13] - d[14];
    m[15] = d[12] - d[15];
    
    d[ 0] = m[ 0] + m[ 1];
    d[ 1] = m[ 0] - m[ 1];
    d[ 2] = m[ 2] + m[ 3];
    d[ 3] = m[ 3] - m[ 2];
    d[ 4] = m[ 4] + m[ 5];
    d[ 5] = m[ 4] - m[ 5];
    d[ 6] = m[ 6] + m[ 7];
    d[ 7] = m[ 7] - m[ 6];
    d[ 8] = m[ 8] + m[ 9];
    d[ 9] = m[ 8] - m[ 9];
    d[10] = m[10] + m[11];
    d[11] = m[11] - m[10];
    d[12] = m[12] + m[13];
    d[13] = m[12] - m[13];
    d[14] = m[14] + m[15];
    d[15] = m[15] - m[14];
    
    /*===== sum up =====*/
    for (dd=diff[k=0]; k<16; dd=diff[++k])
    {
      satd += (dd < 0 ? -dd : dd);
    }
    satd >>= 1;
  }
  else
  {
    /*===== sum up =====*/
    for (k = 0; k < 16; k++)
    {
      satd += byte_abs [diff [k]];
    }
  }
  
  return satd;
}



/*!
 ***********************************************************************
 * \brief
 *    Sub pixel block motion search
 ***********************************************************************
 */
int                                               //  ==> minimum motion cost after search
SubPelBlockMotionSearch (pel_t**   orig_pic,      // <--  original pixel values for the AxB block
                         int       ref,           // <--  reference frame (0... or -1 (backward))
                         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       pred_mv_x,     // <--  motion vector predictor (x) in sub-pel units
                         int       pred_mv_y,     // <--  motion vector predictor (y) in sub-pel units
                         int*      mv_x,          // <--> in: search center (x) / out: motion vector (x) - in pel units
                         int*      mv_y,          // <--> in: search center (y) / out: motion vector (y) - in pel units
                         int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
                         int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
                         int       search_pos8,   // <--  search positions for  eighth-pel search  (default: 9)
                         int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
                         double    lambda)        // <--  lagrangian parameter for determining motion cost
{
  int   diff[16], *d;
  int   pos, best_pos, mcost, abort_search;
  int   y0, x0, ry0, rx0, ry;
  int   cand_mv_x, cand_mv_y;
  pel_t *orig_line;

  pel_t **ref_pic       = (ref==-1 ? mref_P : mref [ref]);
  int   lambda_factor   = LAMBDA_FACTOR (lambda);
  int   mv_shift        = (input->mv_res ? 1 : 0);
  int   check_position0 = (blocktype==1 && *mv_x==0 && *mv_y==0 && input->hadamard && !input->rdopt && img->type!=B_IMG && ref==0);
  int   blocksize_x     = input->blc_size[blocktype][0];
  int   blocksize_y     = input->blc_size[blocktype][1];
  int   pic4_pix_x      = (pic_pix_x << 2);
  int   pic4_pix_y      = (pic_pix_y << 2);
  int   max_pos_x4      = ((img->width -blocksize_x+1)<<2);
  int   max_pos_y4      = ((img->height-blocksize_y+1)<<2);
  int   min_pos2        = (input->hadamard ? 0 : 1);
  int   max_pos2        = (input->hadamard ? max(1,search_pos2) : search_pos2);


  /*********************************
   *****                       *****
   *****  HALF-PEL REFINEMENT  *****
   *****                       *****
   *********************************/
  //===== convert search center to quarter-pel units =====
  *mv_x <<= 2;
  *mv_y <<= 2;
  //===== set function for getting pixel values =====
  if ((pic4_pix_x + *mv_x > 1) && (pic4_pix_x + *mv_x < max_pos_x4 - 2) &&
      (pic4_pix_y + *mv_y > 1) && (pic4_pix_y + *mv_y < max_pos_y4 - 2)   )
  {
    PelY_14 = FastPelY_14;
  }
  else
  {
    PelY_14 = UMVPelY_14;
  }
  //===== loop over search positions =====

⌨️ 快捷键说明

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