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

📄 mot_est.c

📁 文件内包含H.263视频编码算法和解码算法2个文件
💻 C
字号:
#include"sim.h"#include "TMConfig.h"
#include "global_e.h"
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;    sxy = mmin(15, sxy);     lx = pels;    ilow = x_curr + xoff - sxy;  ihigh = x_curr + xoff + sxy;    jlow = y_curr + yoff - sxy;  jhigh = y_curr + yoff + sxy;    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_MY1(curr, x_curr, y_curr, 16, 16, pels);
  search_area = LoadArea_MY2(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;  }     /* Zero vector search*/  if (x_curr-ilow         < 0        || y_curr-jlow         < 0        ||      x_curr-ilow+MB_SIZE > h_length || y_curr-jlow+MB_SIZE > v_length) 
  {	  /* in case the zero vector is outside the loaded area in search_area */	  zero_area = LoadArea_MY1(prev, x_curr, y_curr, 16, 16, lx);	  *SAD_0 = SAD_Macroblock(zero_area, act_block, 16, Min_FRAME[0]) - PREF_NULL_VEC;
/*	  *SAD_0 = SAD_Macroblock_MY(zero_area, act_block, 16, Min_FRAME[0]) - PREF_NULL_VEC;*/	  free(zero_area);  }  else 
  {	  /* the zero vector is within 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;
/*	  *SAD_0 = SAD_Macroblock_MY(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]);
/*	  Min_FRAME[0] = SAD_Macroblock_MY(ii, act_block, h_length, Min_FRAME[0]);*/	  MV_FRAME[0].x = xoff;	  MV_FRAME[0].y = yoff;  }    /* Spiral search */  SAD_MY( search_area, act_block, h_length, &MV_FRAME[0], &Min_FRAME[0] );
  i = x_curr/MB_SIZE+1;  j = y_curr/MB_SIZE+1;    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];    free(act_block);  free(search_area);
  return;}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_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;}void SAD_MY(unsigned char *ii, unsigned char *act_block, int h_length, MotionVector *MV, int *min_sofar)
{
	int i, j;
	unsigned char x0=0, x1=0, x2=0, x3=0, x=0, y=0;
	unsigned short int sad;
	unsigned short int sad0, sad1, sad2, sad3, sad4, sad5, sad6, sad7;
	unsigned short int temp0, temp1, temp2, temp3, temp4, temp5;
	unsigned int * p1;
	unsigned int * p2;
	int ta0, ta1, ta2, ta3, ta4, ta5, ta6, ta7;	
	int tb0, tb1, tb2, tb3, tb4, tb5, tb6, tb7;
	int tc0, tc1, tc2, tc3, tc4, tc5, tc6, tc7;
	int td0, td1, td2, td3, td4, td5, td6, td7;
	int mb0, mb1, mb2, mb3, mb4, mb5, mb6, mb7;
	int mc0, mc1, mc2, mc3, mc4, mc5, mc6, mc7;
	int md0, md1, md2, md3, md4, md5, md6, md7;

	p1 = (unsigned int*)ii;

	for( j=0; j<9; j++ )
	{
		p2 = (unsigned int*)act_block;
		sad0=0;
		sad1=0;
		sad2=0;
		sad3=0;
		sad4=0;
		sad5=0;
		sad6=0;
		sad7=0;
		
		for( i=0; i<16; i++ )
		{
			mb0 = FUNSHIFT3( p1[1], p1[0] );
			mc0 = FUNSHIFT2( p1[1], p1[0] );
			md0 = FUNSHIFT1( p1[1], p1[0] );
			mb1 = FUNSHIFT3( p1[2], p1[1] );
			mc1 = FUNSHIFT2( p1[2], p1[1] );
			md1 = FUNSHIFT1( p1[2], p1[1] );
			mb2 = FUNSHIFT3( p1[3], p1[2] );
			mc2 = FUNSHIFT2( p1[3], p1[2] );
			md2 = FUNSHIFT1( p1[3], p1[2] );
			mb3 = FUNSHIFT3( p1[4], p1[3] );
			mc3 = FUNSHIFT2( p1[4], p1[3] );
			md3 = FUNSHIFT1( p1[4], p1[3] );
			
			ta0 = UME8UU( p1[0], p2[0] );
			ta1 = UME8UU( p1[1], p2[1] );
			ta2 = UME8UU( p1[2], p2[2] );
			ta3 = UME8UU( p1[3], p2[3] );
			sad0 += ta0 + ta1 + ta2 + ta3;
			
			tb0 = UME8UU( mb0, p2[0] );
			tb1 = UME8UU( mb1, p2[1] );
			tb2 = UME8UU( mb2, p2[2] );
			tb3 = UME8UU( mb3, p2[3] );
			sad1 += tb0 + tb1 + tb2 + tb3;
			
			tc0 = UME8UU( mc0, p2[0] );
			tc1 = UME8UU( mc1, p2[1] );
			tc2 = UME8UU( mc2, p2[2] );
			tc3 = UME8UU( mc3, p2[3] );
			sad2 += tc0 + tc1 + tc2 + tc3;
			
			td0 = UME8UU( md0, p2[0] );
			td1 = UME8UU( md1, p2[1] );
			td2 = UME8UU( md2, p2[2] );
			td3 = UME8UU( md3, p2[3] );
			sad3 += td0 + td1 + td2 + td3;
			
			mb4 = FUNSHIFT3( p1[2], p1[1] );
			mc4 = FUNSHIFT2( p1[2], p1[1] );
			md4 = FUNSHIFT1( p1[2], p1[1] );
			mb5 = FUNSHIFT3( p1[3], p1[2] );
			mc5 = FUNSHIFT2( p1[3], p1[2] );
			md5 = FUNSHIFT1( p1[3], p1[2] );
			mb6 = FUNSHIFT3( p1[4], p1[3] );
			mc6 = FUNSHIFT2( p1[4], p1[3] );
			md6 = FUNSHIFT1( p1[4], p1[3] );
			mb7 = FUNSHIFT3( p1[5], p1[4] );
			mc7 = FUNSHIFT2( p1[5], p1[4] );
			md7 = FUNSHIFT1( p1[5], p1[4] );
			
			
			ta4 = UME8UU( p1[1], p2[0]);
			ta5 = UME8UU( p1[2], p2[1] );
			ta6 = UME8UU( p1[3], p2[2] );
			ta7 = UME8UU( p1[4], p2[3] );
			sad4 += ta4 + ta5 + ta6 + ta7;
			
			tb4 = UME8UU( mb4, p2[0] );
			tb5 = UME8UU( mb5, p2[1] );
			tb6 = UME8UU( mb6, p2[2] );
			tb7 = UME8UU( mb7, p2[3] );
			sad5 += tb4 + tb5 + tb6 + tb7;
			
			tc4 = UME8UU( mc4, p2[0] );
			tc5 = UME8UU( mc5, p2[1] );
			tc6 = UME8UU( mc6, p2[2] );
			tc7 = UME8UU( mc7, p2[3] );
			sad6 += tc4 + tc5 + tc6 + tc7;
			
			td4 = UME8UU( md4, p2[0] );
			td5 = UME8UU( md5, p2[1] );
			td6 = UME8UU( md6, p2[2] );
			td7 = UME8UU( md7, p2[3] );
			sad7 += td4 + td5 + td6 + td7;
			
			p2 += 4;
			p1 += 6;
		}

		if( sad0<sad1 )
		{
			temp0 = sad0;
			x0 = 0;
		}
		else 
		{
			temp0 = sad1;
			x0 = 1;
		}
		if( sad2<sad3 )
		{
			temp1 = sad2;
			x1 = 2;
		}
		else 
		{
			temp1 = sad3;
			x1 = 3;
		}
		if( sad4<sad5 )
		{
			temp2 = sad4;
			x2 = 4;
		}
		else 
		{
			temp2 = sad5;
			x2 = 5;
		}
		if( sad6<sad7 )
		{
			temp3 = sad6;
			x3 = 6;
		}
		else 
		{
			temp3 = sad7;
			x3 = 7;
		}
		
		if( temp0<temp1 )
		{
			temp4 = temp0;
			x0 = x0;
		}
		else 
		{
			temp4 = temp1;
			x0 = x1;
		}
		if( temp2<temp3 )
		{
			temp5 = temp2;
			x1 = x2;
		}
		else 
		{
			temp5 = temp3;
			x1 = x3;
		}
		
		if( temp4<temp5 )
		{
			sad = temp4;
			x = x0;
		}
		else 
		{
			sad = temp5;
			x = x1;
		}
		
		if( sad<*min_sofar )
		{
			*min_sofar = sad;
			MV->x = x;
			MV->y = y;
		}
		p1 -= 90;
		y ++; 
	}

	return;
}

int SAD_Macroblock_MY(unsigned char *ii, unsigned char *act_block, int h_length, int Min_FRAME)
{
	int sad=0;
	unsigned int *p1;
	unsigned int *p2;
	int t0, t1, t2, t3, t4, t5, t6, t7;
	int t8, t9, t10, t11, t12, t13, t14, t15;
	int i;
	int temp;

	p1 = (unsigned int*)ii;
	p2 = (unsigned int*)act_block;
	temp = h_length>>2;

	for( i=0; i<4; i++ )
	{
		t0 = UME8UU( p1[0], p2[0] );
		t1 = UME8UU( p1[1], p2[1] );
		t2 = UME8UU( p1[2], p2[2] );
		t3 = UME8UU( p1[3], p2[3] );
		p1 += temp;
		t4 = UME8UU( p1[0], p2[4] );
		t5 = UME8UU( p1[1], p2[5] );
		t6 = UME8UU( p1[2], p2[6] );
		t7 = UME8UU( p1[3], p2[7] );
		p1 += temp;
		t8 = UME8UU( p1[0], p2[8] );
		t9 = UME8UU( p1[1], p2[9] );
		t10 = UME8UU( p1[2], p2[10] );
		t11 = UME8UU( p1[3], p2[11] );
		p1 += temp;
		t12 = UME8UU( p1[0], p2[12] );
		t13 = UME8UU( p1[1], p2[13] );
		t14 = UME8UU( p1[2], p2[14] );
		t15 = UME8UU( p1[3], p2[15] );
		p1 += temp;
		p2 += 16;
		sad += t0 + t1 + t2 + t3;
		sad += t4 + t5 + t6 + t7;
		sad += t8 + t9 + t10 + t11;
		sad += t12 + t13 + t14 + t15;

		if (sad > Min_FRAME)
			return INT_MAX;
	}

	return sad;
}

void FindMB_MY(int x, int y, unsigned char *image, short int MB[16][16])
{
  register int n;
  register int t0=0, t1=0, t2=0, t3=0, t4=0, t5=0, t6=0, t7=0;

  int *p1, *p2;
  p1 = (int *)(image + x + y*pels);
  p2 = (int *)MB;
  for (n = 0; n < MB_SIZE; n++)
  {
      p2[0] = MERGELSB(t0,p1[0]);
	  p2[1] = MERGEMSB(t1,p1[0]);
	  p2[2] = MERGELSB(t2,p1[1]);
	  p2[3] = MERGEMSB(t3,p1[1]);
	  p2[4] = MERGELSB(t4,p1[2]);
	  p2[5] = MERGEMSB(t5,p1[2]);
	  p2[6] = MERGELSB(t6,p1[3]);
	  p2[7] = MERGEMSB(t7,p1[3]);
	  p2 += 8;
	  p1 += pels>>2;
  }
  return;
}

unsigned char *LoadArea_MY1(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 int *in;
  unsigned int *out;
  int i;

  in = (unsigned int*)(im + (y*lx) + x);
  out = (unsigned int*)res;
  
  for(i=0; i<16; i++)
  {
	  out[0] = in[0];
	  out[1] = in[1];
	  out[2] = in[2];
	  out[3] = in[3];
	  out += 4;
	  in += lx>>2;
  }

  return res;
}

unsigned char *LoadArea_MY2(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 int *in;
  unsigned int *out;
  int i;

  in = (unsigned int*)(im + (y*lx) + x);
  out = (unsigned int*)res;
  
  if( x_size==20 )
  {
	  for(i=0; i<y_size; i++)
	  {
		  out[0] = in[0];
		  out[1] = in[1];
		  out[2] = in[2];
		  out[3] = in[3];
		  out[4] = in[4];
		  out += 5;
		  in += lx>>2;
	  }
  }
  else if( x_size==24 )
  {
	  for(i=0; i<y_size; i++)
	  {
		  out[0] = in[0];
		  out[1] = in[1];
		  out[2] = in[2];
		  out[3] = in[3];
		  out[4] = in[4];
		  out[5] = in[5];
		  out += 6;
		  in += lx>>2;
	  }
  }
  else
  {
	  printf("x_size error!\n");
	  exit(37);
  }
  return res;
}

⌨️ 快捷键说明

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