mv-search.c

来自「包含了从MPEG4的视频解码到H.264的视频编码部分的源代码」· C语言 代码 · 共 1,913 行 · 第 1/5 页

C
1,913
字号
int                                                   //  ==> minimum motion cost after search
FastFullPelBlockMotionSearch (pel_t**   orig_pic,     // <--  not used
                              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,         //  --> motion vector (x) - in pel units
                              int*      mv_y,         //  --> motion vector (y) - in pel units
                              int       search_range, // <--  1-d search range in pel units
                              int       min_mcost,    // <--  minimum motion cost (cost for center or huge value)
                              double    lambda)       // <--  lagrangian parameter for determining motion cost
{
  int   pos, offset_x, offset_y, cand_x, cand_y, mcost;

  int   refindex      = (ref!=-1 ? ref : img->buf_cycle);                   // reference frame index (array entry)
  int   max_pos       = (2*search_range+1)*(2*search_range+1);              // number of search positions
  int   lambda_factor = LAMBDA_FACTOR (lambda);                             // factor for determining lagragian motion cost
  int   best_pos      = 0;                                                  // position with minimum motion cost
  int   block_index;                                                        // block index for indexing SAD array
  int*  block_sad;                                                          // pointer to SAD array
  int   pix_y;

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    pix_y = img->field_pix_y;
    block_index   = (pic_pix_y-pix_y)+((pic_pix_x-img->pix_x)>>2); 
    block_sad     = BlockSAD[refindex][blocktype][block_index];
  }
  else
  {
    block_index   = (pic_pix_y-img->pix_y)+((pic_pix_x-img->pix_x)>>2); // block index for indexing SAD array
    block_sad     = BlockSAD[refindex][blocktype][block_index];         // pointer to SAD array
    pix_y         = img->pix_y;
  }

  //===== set up fast full integer search if needed / set search center =====
  if (!search_setup_done[refindex])
  {
    SetupFastFullPelSearch (ref);
  }
  offset_x = search_center_x[refindex] - img->pix_x;
  offset_y = search_center_y[refindex] - pix_y;


  //===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====
  if (!input->rdopt)
  {
    mcost = block_sad[pos_00[refindex]] + MV_COST (lambda_factor, 2, 0, 0, pred_mv_x, pred_mv_y);

    if (mcost < min_mcost)
    {
      min_mcost = mcost;
      best_pos  = pos_00[refindex];
    }
  }

  //===== loop over all search positions =====
  for (pos=0; pos<max_pos; pos++, block_sad++)
  {
    //--- check residual cost ---
    if (*block_sad < min_mcost)
    {
      //--- get motion vector cost ---
      cand_x = offset_x + spiral_search_x[pos];
      cand_y = offset_y + spiral_search_y[pos];
      mcost  = *block_sad;
      mcost += MV_COST (lambda_factor, 2, cand_x, cand_y, pred_mv_x, pred_mv_y);

      //--- check motion cost ---
      if (mcost < min_mcost)
      {
        min_mcost = mcost;
        best_pos  = pos;
      }
    }
  }

  //===== set best motion vector and return minimum motion cost =====
  *mv_x = offset_x + spiral_search_x[best_pos];
  *mv_y = offset_y + spiral_search_y[best_pos];
  return min_mcost;
}
#endif


/*!
 ***********************************************************************
 * \brief
 *    Calculate SA(T)D
 ***********************************************************************
 */
/*
int
SATD (_int16* diff, int use_hadamard)
{
  _int16 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;
}
*/
//zdd
int
SATD (_int16* diff, int use_hadamard)
{
  _int16 *pt1=diff;
  _int32 satd = 0,ret;
  int k;
  
  if (use_hadamard)
  {
      _asm
	  {
		  mov eax,pt1		  
		  
		  movq mm0,[eax]
		  movq mm1,[eax+8]
		  movq mm2,[eax+16]
		  movq mm3,[eax+24]
		  movq mm4,mm0
		  paddw mm4,mm1 //a0+a1
		  movq mm6,mm2
		  paddw mm6,mm3 //a2+a3
		  movq mm5,mm4 
		  paddw mm4,mm6 //a0+a1+a2+a3
		  psubw mm5,mm6 //a0+a1-a2-a3
		  movq mm6,mm0
		  movq mm7,mm0
		  paddw mm6,mm3
		  psubw mm6,mm1
		  psubw mm6,mm2 //a0-a1-a2+a3
		  paddw mm7,mm2
		  psubw mm7,mm1
		  psubw mm7,mm3 //a0-a1+a2-a3
		  //转秩	
		  movq mm0,mm4
		  movq mm1,mm5
		  movq mm2,mm6 
		  movq mm3,mm7
		  PUNPCKLWD mm0,mm1
		  PUNPCKLWD mm2,mm3
		  movq mm1,mm0
		  PUNPCKLDQ mm0,mm2
		  PUNPCKHDQ mm1,mm2

		  PUNPCKHWD mm4,mm5
		  PUNPCKHWD mm6,mm3
		  movq mm3,mm4
		  PUNPCKLDQ mm4,mm6
		  PUNPCKHDQ mm3,mm6
		  movq mm2,mm4
		  //计算第二遍
		  movq mm4,mm0
		  paddw mm4,mm1 //a0+a1
		  movq mm6,mm2
		  paddw mm6,mm3 //a2+a3
		  movq mm5,mm4 
		  paddw mm4,mm6 //a0+a1+a2+a3
		  psubw mm5,mm6 //a0+a1-a2-a3
		  movq mm6,mm0
		  movq mm7,mm0
		  paddw mm6,mm3
		  psubw mm6,mm1
		  psubw mm6,mm2 //a0-a1-a2+a3
		  paddw mm7,mm2
		  psubw mm7,mm1
		  psubw mm7,mm3 //a0-a1+a2-a3
		  	
		  movq mm0,mm4
		  movq mm1,mm5
		  movq mm2,mm6 
		  movq mm3,mm7
		 
		  //求绝对值
		  MOVQ MM4, MM0 
		  PSRAW MM4, 15 
		  PXOR MM0, MM4 
		  PSUBW MM0, MM4 
		  MOVQ MM5, MM1 
		  PSRAW MM5, 15 
		  PXOR MM1, MM5 
		  PSUBW MM1, MM5
		  MOVQ MM6, MM2 
		  PSRAW MM6, 15 
		  PXOR MM2, MM6 
		  PSUBW MM2, MM6 
		  MOVQ MM7, MM3 
		  PSRAW MM7, 15 
		  PXOR MM3, MM7 
		  PSUBW MM3, MM7 

		  paddw mm0,mm1
		  paddw mm0,mm2
		  paddw mm0,mm3
		  PEXTRW eax,mm0,0
		  PEXTRW ebx,mm0,1
		  PEXTRW ecx,mm0,2
		  PEXTRW edx,mm0,3
		  add eax,ebx
		  add eax,ecx
		  add eax,edx
		  SAR eax,1
		  mov satd,eax

		  emms
	  }
	  
  }
  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       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
                         double    lambda         // <--  lagrangian parameter for determining motion cost
                         )
{
  _int16   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;
  int   incr            = ref==-1 ? ((!img->fld_type)&&(mref==mref_fld)&&(img->type==B_IMG)) : (mref==mref_fld)&&(img->type==B_IMG) ;
  pel_t **ref_pic;      
  int   lambda_factor   = LAMBDA_FACTOR (lambda);
  int   mv_shift        = 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);
  int apply_weights = ( (input->WeightedPrediction && img->type == INTER_IMG) ||
                 (input->WeightedBiprediction && (img->type == B_IMG || img->type == BS_IMG)));

  if (apply_weights)
    ref_pic = img->type==B_IMG? mref_w [ref+1+incr] : mref_w [ref];
  else
    ref_pic = img->type==B_IMG? mref [ref+1+incr] : mref [ref];


  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode && img->type == B_IMG)
  {
    incr    =  ref == -1 ? (img->top_field && img->field_mode):(img->field_mode);
    if (input->WeightedPrediction || input->WeightedBiprediction)
      ref_pic =  mref_w[ref+1+incr];
    else
      ref_pic =  mref[ref+1+incr];
  }


  
  /*********************************
   *****                       *****
   *****  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;
  }

⌨️ 快捷键说明

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