Mot_est.cpp
资源名称:263.rar [点击查看]
上传用户:szklck
上传日期:2007-01-22
资源大小:925k
文件大小:12k
源码类别:
图形图像处理
开发平台:
Visual C++
- #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);
- }
English
