Mot_est.cpp
上传用户:szklck
上传日期:2007-01-22
资源大小:925k
文件大小:12k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. #include"stdafx.h"
  2. #include"Global.h"
  3. /**********************************************************************
  4.  *
  5.  * Name:        MotionEstimation
  6.  * Description: Estimate all motionvectors for one MB
  7.  *
  8.  * Input:        pointers to current an previous image,
  9.  *        pointers to current slice and current MB
  10.  * Returns:
  11.  * Side effects: motion vector imformation in MB changed
  12.  *   
  13.  ***********************************************************************/
  14. void MotionEstimation(unsigned char *curr, unsigned char *prev, int x_curr,
  15.               int y_curr, int xoff, int yoff, int seek_dist, 
  16.               MotionVector *MV[6][MBR+1][MBC+2], int *SAD_0)
  17. {
  18.   int Min_FRAME[5];
  19.   MotionVector MV_FRAME[5];
  20.   unsigned char *act_block,*aa,*ii;
  21.   unsigned char *search_area, *adv_search_area = NULL, *zero_area = NULL;
  22.   int sxy,i,k,j,l;
  23.   int ihigh,ilow,jhigh,jlow,h_length,v_length;
  24.   int adv_ihigh,adv_ilow,adv_jhigh,adv_jlow,adv_h_length,adv_v_length;
  25.   int xmax,ymax,block,sad,lx;
  26.   int adv_x_curr, adv_y_curr,xvec,yvec;
  27.   xmax = pels;
  28.   ymax = lines;
  29.   sxy = seek_dist;
  30.   if (!long_vectors) {//以0矢量为中心的搜索范围
  31.     sxy = mmin(15, sxy);  
  32.   }
  33.   else {
  34.     /* Maximum extended search range centered around _predictor_ */
  35.     sxy = mmin(15 - (2*DEF_8X8_WIN+1), sxy);
  36.     xoff = mmin(16,mmax(-16,xoff));
  37.     yoff = mmin(16,mmax(-16,yoff));
  38.   }
  39.   lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels);
  40.   ilow = x_curr + xoff - sxy;
  41.   ihigh = x_curr + xoff + sxy;
  42.   jlow = y_curr + yoff - sxy;
  43.   jhigh = y_curr + yoff + sxy;
  44.   if (!mv_outside_frame) {
  45.     if (ilow<0) ilow = 0;
  46.     if (ihigh>xmax-16) ihigh = xmax-16;
  47.     if (jlow<0) jlow = 0;
  48.     if (jhigh>ymax-16) jhigh = ymax-16;
  49.   }
  50.   h_length = ihigh - ilow + 16;
  51.   v_length = jhigh - jlow + 16;
  52.   act_block = LoadArea(curr, x_curr, y_curr, 16, 16, pels);  //装入当前搜索块
  53.   search_area = LoadArea(prev, ilow, jlow, h_length, v_length, lx);  //装入搜索范围块
  54.   for (k = 0; k < 5; k++) {
  55.     Min_FRAME[k] = INT_MAX;
  56.     MV_FRAME[k].x = 0;
  57.     MV_FRAME[k].y = 0;
  58.     MV_FRAME[k].x_half = 0;
  59.     MV_FRAME[k].y_half = 0;
  60.   }
  61.   /* 0运动矢量搜索 */
  62.   if (x_curr-ilow         < 0        || y_curr-jlow         < 0        ||
  63.       x_curr-ilow+MB_SIZE > h_length || y_curr-jlow+MB_SIZE > v_length) {
  64.     /* 0运动矢量位置不在search_area内 */
  65.     zero_area = LoadArea(prev, x_curr, y_curr, 16, 16, lx);  //装入0运动矢量块
  66.     *SAD_0 = SAD_Macroblock(zero_area, act_block, 16, Min_FRAME[0]) -
  67.        PREF_NULL_VEC;
  68.     free(zero_area);
  69.   }
  70.   else {
  71.     /* 0运动矢量位置在search_area内 */
  72.     ii = search_area + (x_curr-ilow) + (y_curr-jlow)*h_length;
  73.     *SAD_0 = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]) -
  74.        PREF_NULL_VEC;
  75.   }
  76.   if (xoff == 0 && yoff == 0) {
  77.     Min_FRAME[0] = *SAD_0;
  78.     MV_FRAME[0].x = 0;
  79.     MV_FRAME[0].y = 0;
  80.   }
  81.   else {
  82.     ii = search_area + (x_curr+xoff-ilow) + (y_curr+yoff-jlow)*h_length;
  83.     Min_FRAME[0] = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]);
  84.     MV_FRAME[0].x = xoff;
  85.     MV_FRAME[0].y = yoff;
  86.   }
  87.  
  88.   /* 螺旋搜索 */
  89.   for (l = 1; l <= sxy; l++) {
  90.     i = x_curr + xoff - l;
  91.     j = y_curr + yoff - l;
  92.     for (k = 0; k < 8*l; k++) {
  93.       if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  94.         /* 16x16块的整象素MV */
  95.         ii = search_area + (i-ilow) + (j-jlow)*h_length;
  96.         sad = SAD_Macroblock(ii, act_block, h_length, Min_FRAME[0]);
  97.         if (sad < Min_FRAME[0]) {
  98.           MV_FRAME[0].x = i - x_curr;
  99.           MV_FRAME[0].y = j - y_curr;
  100.           Min_FRAME[0] = sad;
  101.         }
  102.       }
  103.       if      (k<2*l) i++;
  104.       else if (k<4*l) j++;
  105.       else if (k<6*l) i--;
  106.       else            j--;
  107.     }      
  108.   }
  109.   if (advanced) {
  110.     /* 8x8块搜索以16x16矢量为中心,仍然采用全搜索方法。*/
  111.     xvec = MV_FRAME[0].x;
  112.     yvec = MV_FRAME[0].y;
  113.     
  114.     if (!long_vectors) {
  115.       if (xvec > 15 - DEF_8X8_WIN) { xvec =  15 - DEF_8X8_WIN ;}
  116.       if (yvec > 15 - DEF_8X8_WIN) { yvec =  15 - DEF_8X8_WIN ;}
  117.       if (xvec < -15 + DEF_8X8_WIN) { xvec =  -15 + DEF_8X8_WIN ;}
  118.       if (yvec < -15 + DEF_8X8_WIN) { yvec =  -15 + DEF_8X8_WIN ;}
  119.     }
  120.     adv_x_curr = x_curr  + xvec;
  121.     adv_y_curr = y_curr  + yvec;
  122.     sxy = DEF_8X8_WIN;
  123.     adv_ilow = adv_x_curr - sxy;
  124.     adv_ihigh = adv_x_curr + sxy;
  125.     adv_jlow = adv_y_curr - sxy;
  126.     adv_jhigh = adv_y_curr + sxy;
  127.     adv_h_length = adv_ihigh - adv_ilow + 16;
  128.     adv_v_length = adv_jhigh - adv_jlow + 16;
  129.     adv_search_area = LoadArea(prev, adv_ilow, adv_jlow, 
  130.                adv_h_length, adv_v_length, lx);
  131.     for (block = 0; block < 4; block++) {
  132.       ii = adv_search_area + (adv_x_curr-adv_ilow) + ((block&1)<<3) + 
  133.         (adv_y_curr-adv_jlow + ((block&2)<<2) )*adv_h_length;
  134.       aa = act_block + ((block&1)<<3) + ((block&2)<<2)*16;
  135.       Min_FRAME[block+1] = SAD_Block(ii,aa,adv_h_length,Min_FRAME[block+1]);
  136.       MV_FRAME[block+1].x = MV_FRAME[0].x;
  137.       MV_FRAME[block+1].y = MV_FRAME[0].y;
  138.     }
  139.     /* 螺旋搜索 */
  140.     for (l = 1; l <= sxy; l++) {
  141.       i = adv_x_curr - l;
  142.       j = adv_y_curr - l;
  143.       for (k = 0; k < 8*l; k++) {
  144.         if (i>=adv_ilow && i<=adv_ihigh && j>=adv_jlow && j<=adv_jhigh) {
  145.           
  146.           /* 8x8块的整象素MVs */
  147.           for (block = 0; block < 4; block++) {
  148.             ii = adv_search_area + (i-adv_ilow) + ((block&1)<<3) + 
  149.               (j-adv_jlow + ((block&2)<<2) )*adv_h_length;
  150.             aa = act_block + ((block&1)<<3) + ((block&2)<<2)*16;
  151.             sad = SAD_Block(ii, aa, adv_h_length, Min_FRAME[block+1]);
  152.             if (sad < Min_FRAME[block+1]) {
  153.               MV_FRAME[block+1].x = i - x_curr;
  154.               MV_FRAME[block+1].y = j - y_curr;
  155.               Min_FRAME[block+1] = sad;
  156.             }
  157.           }
  158.           
  159.         }
  160.         if      (k<2*l) i++;
  161.         else if (k<4*l) j++;
  162.         else if (k<6*l) i--;
  163.         else            j--;
  164.       }      
  165.     }
  166.   }
  167.   i = x_curr/MB_SIZE+1;
  168.   j = y_curr/MB_SIZE+1;
  169.   if (!advanced) {
  170.     MV[0][j][i]->x = MV_FRAME[0].x;
  171.     MV[0][j][i]->y = MV_FRAME[0].y;
  172.     MV[0][j][i]->min_error = Min_FRAME[0];
  173.   }
  174.   else {
  175.     for (k = 0; k < 5; k++) {
  176.       MV[k][j][i]->x = MV_FRAME[k].x;
  177.       MV[k][j][i]->y = MV_FRAME[k].y;
  178.       MV[k][j][i]->min_error = Min_FRAME[k];
  179.     }
  180.   }
  181.   free(act_block);
  182.   free(search_area);
  183.   if (advanced)
  184.     free(adv_search_area);
  185.   return;
  186. }
  187. /**********************************************************************
  188.  *
  189.  * Name:        LoadArea
  190.  * Description:    fills array with a square of image-data
  191.  *
  192.  * Input:        pointer to image and position, x and y size
  193.  * Returns:       pointer to area
  194.  * Side effects:  memory allocated to array
  195.  *
  196.  * Date: 940203 Author: PGB
  197.  *                      Mod: KOL
  198.  *
  199.  ***********************************************************************/
  200. unsigned char *LoadArea(unsigned char *im, int x, int y, 
  201.         int x_size, int y_size, int lx)
  202. {
  203.   unsigned char *res = (unsigned char *)malloc(sizeof(char)*x_size*y_size);
  204.   unsigned char *in;
  205.   unsigned char *out;
  206.   int i = x_size;
  207.   int j = y_size;
  208.   in = im + (y*lx) + x;
  209.   out = res;
  210.   while (j--) {
  211.     while (i--)
  212.       *out++ = *in++;
  213.     i = x_size;
  214.     in += lx - x_size;
  215.   };
  216.   return res;
  217. }
  218. /**********************************************************************
  219.  *
  220.  * Name:        SAD_Macroblock
  221.  * Description:    fast way to find the SAD of one vector
  222.  *
  223.  * Input:         pointers to search_area and current block,
  224.  *                      Min_F1/F2/FR
  225.  * Returns:        sad_f1/f2
  226.  * Side effects:
  227.  *
  228.  * Date: 940203        Author: PGB
  229.  *                      Mod:    KOL
  230.  *
  231.  ***********************************************************************/
  232. int SAD_Macroblock(unsigned char *ii, unsigned char *act_block,
  233.            int h_length, int Min_FRAME)
  234. {
  235.   int i;
  236.   int sad = 0;
  237.   unsigned char *kk;
  238.   kk = act_block;
  239.   i = 16;
  240.   while (i--) {
  241.     sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
  242.             +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
  243.             +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
  244.             +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) )
  245.             +abs(*(ii+8) - *(kk+8) ) +abs(*(ii+9 ) - *(kk+9) )
  246.             +abs(*(ii+10)- *(kk+10)) +abs(*(ii+11) - *(kk+11))
  247.             +abs(*(ii+12)- *(kk+12)) +abs(*(ii+13) - *(kk+13))
  248.             +abs(*(ii+14)- *(kk+14)) +abs(*(ii+15) - *(kk+15)) );
  249.     ii += h_length;
  250.     kk += 16;
  251.     if (sad > Min_FRAME)
  252.       return INT_MAX;
  253.   } 
  254.   return sad;
  255. }
  256. int SAD_Block(unsigned char *ii, unsigned char *act_block,
  257.               int h_length, int min_sofar)
  258. {
  259.   int i;
  260.   int sad = 0;
  261.   unsigned char *kk;
  262.   kk = act_block;
  263.   i = 8;
  264.   while (i--) {
  265.     sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
  266.             +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
  267.             +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
  268.             +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) ));
  269.     ii += h_length;
  270.     kk += 16;
  271.     if (sad > min_sofar)
  272.       return INT_MAX;
  273.   } 
  274.   return sad;
  275. }
  276. int SAD_MB_Bidir(unsigned char *ii, unsigned char *aa, unsigned char *bb, 
  277.          int width, int min_sofar)
  278. {
  279.   int i, sad = 0;
  280.   unsigned char *ll, *kk;
  281.   kk = aa;
  282.   ll = bb;
  283.   i = 16;
  284.   while (i--) {
  285.     sad += (abs(*ii     - ((*kk    + *ll    )>>1)) +
  286.             abs(*(ii+1) - ((*(kk+1)+ *(ll+1))>>1)) +
  287.             abs(*(ii+2) - ((*(kk+2)+ *(ll+2))>>1)) +
  288.             abs(*(ii+3) - ((*(kk+3)+ *(ll+3))>>1)) +
  289.             abs(*(ii+4) - ((*(kk+4)+ *(ll+4))>>1)) +
  290.             abs(*(ii+5) - ((*(kk+5)+ *(ll+5))>>1)) +
  291.             abs(*(ii+6) - ((*(kk+6)+ *(ll+6))>>1)) +
  292.             abs(*(ii+7) - ((*(kk+7)+ *(ll+7))>>1)) +
  293.             abs(*(ii+8) - ((*(kk+8)+ *(ll+8))>>1)) +
  294.             abs(*(ii+9) - ((*(kk+9)+ *(ll+9))>>1)) +
  295.             abs(*(ii+10) - ((*(kk+10)+ *(ll+10))>>1)) +
  296.             abs(*(ii+11) - ((*(kk+11)+ *(ll+11))>>1)) +
  297.             abs(*(ii+12) - ((*(kk+12)+ *(ll+12))>>1)) +
  298.             abs(*(ii+13) - ((*(kk+13)+ *(ll+13))>>1)) +
  299.             abs(*(ii+14) - ((*(kk+14)+ *(ll+14))>>1)) +
  300.             abs(*(ii+15) - ((*(kk+15)+ *(ll+15))>>1)));
  301.     ii += width;
  302.     kk += width;
  303.     ll += width;
  304.     if (sad > min_sofar)
  305.       return INT_MAX;
  306.   } 
  307.   return sad;
  308. }
  309. int SAD_MB_integer(int *ii, int *act_block, int h_length, int min_sofar)
  310. {
  311.   int i, sad = 0, *kk;
  312.   kk = act_block;
  313.   i = 16;
  314.   while (i--) {
  315.     sad += (abs(*ii     - *kk     ) +abs(*(ii+1 ) - *(kk+1) )
  316.             +abs(*(ii+2) - *(kk+2) ) +abs(*(ii+3 ) - *(kk+3) )
  317.             +abs(*(ii+4) - *(kk+4) ) +abs(*(ii+5 ) - *(kk+5) )
  318.             +abs(*(ii+6) - *(kk+6) ) +abs(*(ii+7 ) - *(kk+7) )
  319.             +abs(*(ii+8) - *(kk+8) ) +abs(*(ii+9 ) - *(kk+9) )
  320.             +abs(*(ii+10)- *(kk+10)) +abs(*(ii+11) - *(kk+11))
  321.             +abs(*(ii+12)- *(kk+12)) +abs(*(ii+13) - *(kk+13))
  322.             +abs(*(ii+14)- *(kk+14)) +abs(*(ii+15) - *(kk+15)) );
  323.     ii += h_length;
  324.     kk += 16;
  325.     if (sad > min_sofar)
  326.       return INT_MAX;
  327.   } 
  328.   return sad;
  329. }
  330. /**********************************************************************
  331.  *
  332.  * Name:        FindMB
  333.  * Description: Picks out one MB from picture
  334.  *
  335.  * Input:        position of MB to pick out,
  336.  *        pointer to frame data, empty 16x16 array
  337.  * Returns:
  338.  * Side effects: fills array with MB data
  339.  *
  340.  * Date: 930119 Author: Karl Olav Lillevold
  341.  *
  342.  ***********************************************************************/
  343. void FindMB(int x, int y, unsigned char *image, int MB[16][16])
  344. {
  345.   int n;
  346.   register int m;
  347.   for (n = 0; n < MB_SIZE; n++)
  348.     for (m = 0; m < MB_SIZE; m++)
  349.       MB[n][m] = *(image + x+m + (y+n)*pels);
  350. }