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

📄 mot_est.cpp

📁 263yasuoyuv.rar是把yuv-411格式文件压缩为*.263可直看
💻 CPP
字号:
#include"stdafx.h"
#include"Global.h"

/**********************************************************************
 *
 *	Name:        MotionEstimation
 *	Description:	Estimate all motionvectors for one MB
 *	
 *	Input:        pointers to current an previous image,
 *        pointers to current slice and current MB
 *	Returns:	
 *	Side effects:	motion vector imformation in MB changed
 *   
 ***********************************************************************/


void MotionEstimation(unsigned char *curr, unsigned char *prev, int x_curr,
              int y_curr, int xoff, int yoff, int seek_dist, 
              MotionVector *MV[6][MBR+1][MBC+2], int *SAD_0)

{

  int Min_FRAME[5];
  MotionVector MV_FRAME[5];
  unsigned char *act_block,*aa,*ii;
  unsigned char *search_area, *adv_search_area = NULL, *zero_area = NULL;
  int sxy,i,k,j,l;
  int ihigh,ilow,jhigh,jlow,h_length,v_length;
  int adv_ihigh,adv_ilow,adv_jhigh,adv_jlow,adv_h_length,adv_v_length;
  int xmax,ymax,block,sad,lx;
  int adv_x_curr, adv_y_curr,xvec,yvec;

  xmax = pels;
  ymax = lines;
  sxy = seek_dist;
  if (!long_vectors) {//以0矢量为中心的搜索范围
    sxy = mmin(15, sxy);  
  }
  else {
    /* Maximum extended search range centered around _predictor_ */
    sxy = mmin(15 - (2*DEF_8X8_WIN+1), sxy);
    xoff = mmin(16,mmax(-16,xoff));
    yoff = mmin(16,mmax(-16,yoff));
  }
  lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels);

  ilow = x_curr + xoff - sxy;
  ihigh = x_curr + xoff + sxy;

  jlow = y_curr + yoff - sxy;
  jhigh = y_curr + yoff + sxy;

  if (!mv_outside_frame) {
    if (ilow<0) ilow = 0;
    if (ihigh>xmax-16) ihigh = xmax-16;
    if (jlow<0) jlow = 0;
    if (jhigh>ymax-16) jhigh = ymax-16;
  }

  h_length = ihigh - ilow + 16;
  v_length = jhigh - jlow + 16;
  act_block = LoadArea(curr, x_curr, y_curr, 16, 16, pels);  //装入当前搜索块
  search_area = LoadArea(prev, ilow, jlow, h_length, v_length, lx);  //装入搜索范围块

  for (k = 0; k < 5; k++) {
    Min_FRAME[k] = INT_MAX;
    MV_FRAME[k].x = 0;
    MV_FRAME[k].y = 0;
    MV_FRAME[k].x_half = 0;
    MV_FRAME[k].y_half = 0;
  }

  /* 0运动矢量搜索 */
  if (x_curr-ilow         < 0        || y_curr-jlow         < 0        ||
      x_curr-ilow+MB_SIZE > h_length || y_curr-jlow+MB_SIZE > v_length) {
    /* 0运动矢量位置不在search_area内 */
    zero_area = LoadArea(prev, x_curr, y_curr, 16, 16, lx);  //装入0运动矢量块
    *SAD_0 = SAD_Macroblock(zero_area, act_block, 16, Min_FRAME[0]) -
       PREF_NULL_VEC;
    free(zero_area);
  }
  else {
    /* 0运动矢量位置在search_area内 */
    ii = search_area + (x_curr-ilow) + (y_curr-jlow)*h_length;
    *SAD_0 = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]) -
       PREF_NULL_VEC;
  }

  if (xoff == 0 && yoff == 0) {
    Min_FRAME[0] = *SAD_0;
    MV_FRAME[0].x = 0;
    MV_FRAME[0].y = 0;
  }
  else {
    ii = search_area + (x_curr+xoff-ilow) + (y_curr+yoff-jlow)*h_length;
    Min_FRAME[0] = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]);
    MV_FRAME[0].x = xoff;
    MV_FRAME[0].y = yoff;
  }
 
  /* 螺旋搜索 */
  for (l = 1; l <= sxy; l++) {
    i = x_curr + xoff - l;
    j = y_curr + yoff - l;
    for (k = 0; k < 8*l; k++) {
      if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {

        /* 16x16块的整象素MV */
        ii = search_area + (i-ilow) + (j-jlow)*h_length;
        sad = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]);
        if (sad < Min_FRAME[0]) {
          MV_FRAME[0].x = i - x_curr;
          MV_FRAME[0].y = j - y_curr;
          Min_FRAME[0] = sad;
        }

      }
      if      (k<2*l) i++;
      else if (k<4*l) j++;
      else if (k<6*l) i--;
      else            j--;
    }      
  }


  if (advanced) {

    /* 8x8块搜索以16x16矢量为中心,仍然采用全搜索方法。*/

    xvec = MV_FRAME[0].x;
    yvec = MV_FRAME[0].y;
    
    if (!long_vectors) {
      if (xvec > 15 - DEF_8X8_WIN) { xvec =  15 - DEF_8X8_WIN ;}
      if (yvec > 15 - DEF_8X8_WIN) { yvec =  15 - DEF_8X8_WIN ;}

      if (xvec < -15 + DEF_8X8_WIN) { xvec =  -15 + DEF_8X8_WIN ;}
      if (yvec < -15 + DEF_8X8_WIN) { yvec =  -15 + DEF_8X8_WIN ;}
    }

    adv_x_curr = x_curr  + xvec;
    adv_y_curr = y_curr  + yvec;

    sxy = DEF_8X8_WIN;

    adv_ilow = adv_x_curr - sxy;
    adv_ihigh = adv_x_curr + sxy;

    adv_jlow = adv_y_curr - sxy;
    adv_jhigh = adv_y_curr + sxy;

    adv_h_length = adv_ihigh - adv_ilow + 16;
    adv_v_length = adv_jhigh - adv_jlow + 16;

    adv_search_area = LoadArea(prev, adv_ilow, adv_jlow, 
               adv_h_length, adv_v_length, lx);

    for (block = 0; block < 4; block++) {
      ii = adv_search_area + (adv_x_curr-adv_ilow) + ((block&1)<<3) + 
        (adv_y_curr-adv_jlow + ((block&2)<<2) )*adv_h_length;
      aa = act_block + ((block&1)<<3) + ((block&2)<<2)*16;
      Min_FRAME[block+1] = SAD_Block(ii,aa,adv_h_length,Min_FRAME[block+1]);
      MV_FRAME[block+1].x = MV_FRAME[0].x;
      MV_FRAME[block+1].y = MV_FRAME[0].y;
    }

    /* 螺旋搜索 */
    for (l = 1; l <= sxy; l++) {
      i = adv_x_curr - l;
      j = adv_y_curr - l;
      for (k = 0; k < 8*l; k++) {
        if (i>=adv_ilow && i<=adv_ihigh && j>=adv_jlow && j<=adv_jhigh) {
          
          /* 8x8块的整象素MVs */
          for (block = 0; block < 4; block++) {
            ii = adv_search_area + (i-adv_ilow) + ((block&1)<<3) + 
              (j-adv_jlow + ((block&2)<<2) )*adv_h_length;
            aa = act_block + ((block&1)<<3) + ((block&2)<<2)*16;
            sad = SAD_Block(ii, aa, adv_h_length, Min_FRAME[block+1]);
            if (sad < Min_FRAME[block+1]) {
              MV_FRAME[block+1].x = i - x_curr;
              MV_FRAME[block+1].y = j - y_curr;
              Min_FRAME[block+1] = sad;
            }
          }
          
        }
        if      (k<2*l) i++;
        else if (k<4*l) j++;
        else if (k<6*l) i--;
        else            j--;
      }      
    }

  }

  i = x_curr/MB_SIZE+1;
  j = y_curr/MB_SIZE+1;

  if (!advanced) {
    MV[0][j][i]->x = MV_FRAME[0].x;
    MV[0][j][i]->y = MV_FRAME[0].y;
    MV[0][j][i]->min_error = Min_FRAME[0];
  }
  else {
    for (k = 0; k < 5; k++) {
      MV[k][j][i]->x = MV_FRAME[k].x;
      MV[k][j][i]->y = MV_FRAME[k].y;
      MV[k][j][i]->min_error = Min_FRAME[k];
    }
  }

  free(act_block);
  free(search_area);
  if (advanced)
    free(adv_search_area);
  return;
}

/**********************************************************************
 *
 *	Name:        LoadArea
 *	Description:    fills array with a square of image-data
 *	
 *	Input:	       pointer to image and position, x and y size
 *	Returns:       pointer to area
 *	Side effects:  memory allocated to array
 *
 *	Date: 940203	Author: PGB
 *                      Mod: KOL
 *
 ***********************************************************************/


unsigned char *LoadArea(unsigned char *im, int x, int y, 
        int x_size, int y_size, int lx)
{
  unsigned char *res = (unsigned char *)malloc(sizeof(char)*x_size*y_size);
  unsigned char *in;
  unsigned char *out;
  int i = x_size;
  int j = y_size;

  in = im + (y*lx) + x;
  out = res;

  while (j--) {
    while (i--)
      *out++ = *in++;
    i = x_size;
    in += lx - x_size;
  };
  return res;
}

/**********************************************************************
 *
 *	Name:        SAD_Macroblock
 *	Description:    fast way to find the SAD of one vector
 *	
 *	Input:	        pointers to search_area and current block,
 *                      Min_F1/F2/FR
 *	Returns:        sad_f1/f2
 *	Side effects:
 *
 *	Date: 940203        Author: PGB
 *                      Mod:    KOL
 *
 ***********************************************************************/


int SAD_Macroblock(unsigned char *ii, unsigned char *act_block,
           int h_length, int Min_FRAME)
{
  int i;
  int sad = 0;
  unsigned char *kk;

  kk = act_block;
  i = 16;
  while (i--) {
    sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
            +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
            +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
            +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) )
            +abs(*(ii+8) - *(kk+8) ) +abs(*(ii+9 ) - *(kk+9) )
            +abs(*(ii+10)- *(kk+10)) +abs(*(ii+11) - *(kk+11))
            +abs(*(ii+12)- *(kk+12)) +abs(*(ii+13) - *(kk+13))
            +abs(*(ii+14)- *(kk+14)) +abs(*(ii+15) - *(kk+15)) );

    ii += h_length;
    kk += 16;
    if (sad > Min_FRAME)
      return INT_MAX;
  } 
  return sad;
}

int SAD_Block(unsigned char *ii, unsigned char *act_block,
              int h_length, int min_sofar)
{
  int i;
  int sad = 0;
  unsigned char *kk;

  kk = act_block;
  i = 8;
  while (i--) {
    sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
            +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
            +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
            +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) ));

    ii += h_length;
    kk += 16;
    if (sad > min_sofar)
      return INT_MAX;
  } 
  return sad;
}

int SAD_MB_Bidir(unsigned char *ii, unsigned char *aa, unsigned char *bb, 
         int width, int min_sofar)
{
  int i, sad = 0;
  unsigned char *ll, *kk;
  kk = aa;
  ll = bb;
  i = 16;
  while (i--) {
    sad += (abs(*ii     - ((*kk    + *ll    )>>1)) +
            abs(*(ii+1) - ((*(kk+1)+ *(ll+1))>>1)) +
            abs(*(ii+2) - ((*(kk+2)+ *(ll+2))>>1)) +
            abs(*(ii+3) - ((*(kk+3)+ *(ll+3))>>1)) +
            abs(*(ii+4) - ((*(kk+4)+ *(ll+4))>>1)) +
            abs(*(ii+5) - ((*(kk+5)+ *(ll+5))>>1)) +
            abs(*(ii+6) - ((*(kk+6)+ *(ll+6))>>1)) +
            abs(*(ii+7) - ((*(kk+7)+ *(ll+7))>>1)) +
            abs(*(ii+8) - ((*(kk+8)+ *(ll+8))>>1)) +
            abs(*(ii+9) - ((*(kk+9)+ *(ll+9))>>1)) +
            abs(*(ii+10) - ((*(kk+10)+ *(ll+10))>>1)) +
            abs(*(ii+11) - ((*(kk+11)+ *(ll+11))>>1)) +
            abs(*(ii+12) - ((*(kk+12)+ *(ll+12))>>1)) +
            abs(*(ii+13) - ((*(kk+13)+ *(ll+13))>>1)) +
            abs(*(ii+14) - ((*(kk+14)+ *(ll+14))>>1)) +
            abs(*(ii+15) - ((*(kk+15)+ *(ll+15))>>1)));

    ii += width;
    kk += width;
    ll += width;
    if (sad > min_sofar)
      return INT_MAX;
  } 
  return sad;
}

int SAD_MB_integer(int *ii, int *act_block, int h_length, int min_sofar)
{
  int i, sad = 0, *kk;

  kk = act_block;
  i = 16;
  while (i--) {
    sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
            +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
            +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
            +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) )
            +abs(*(ii+8) - *(kk+8) ) +abs(*(ii+9 ) - *(kk+9) )
            +abs(*(ii+10)- *(kk+10)) +abs(*(ii+11) - *(kk+11))
            +abs(*(ii+12)- *(kk+12)) +abs(*(ii+13) - *(kk+13))
            +abs(*(ii+14)- *(kk+14)) +abs(*(ii+15) - *(kk+15)) );

    ii += h_length;
    kk += 16;
    if (sad > min_sofar)
      return INT_MAX;
  } 
  return sad;
}

/**********************************************************************
 *
 *	Name:        FindMB
 *	Description:	Picks out one MB from picture
 *	
 *	Input:        position of MB to pick out,
 *        pointer to frame data, empty 16x16 array	
 *	Returns:	
 *	Side effects:	fills array with MB data
 *
 *	Date: 930119	Author: Karl Olav Lillevold
 *
 ***********************************************************************/

void FindMB(int x, int y, unsigned char *image, int MB[16][16])

{
  int n;
  register int m;

  for (n = 0; n < MB_SIZE; n++)
    for (m = 0; m < MB_SIZE; m++)
      MB[n][m] = *(image + x+m + (y+n)*pels);
}


⌨️ 快捷键说明

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