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

📄 coder.c

📁 h.263+ vc++商业源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 *                      pel prediction
 *	
 *	Input:	        pointer to image structure
 *	Returns:        pointer to interpolated image
 *	Side effects:   allocates memory to interpolated image
 *
 *	
 *
 ***********************************************************************/
//====================================================================
//void InterpolateImage(unsigned char _huge *image,unsigned char _huge *ipol_image, 
//					  int width, int height)
//{
//  unsigned char _huge *ii, _huge *oo;
//  int i,j;

//  ii = ipol_image;
//  oo = image;

  /* main image */
//  for (j = 0; j < height-1; j++) {
//    for (i = 0; i  < width-1; i++) {
//      *(ii + (i<<1)) = *(oo + i);
//      *(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
//      *(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1)>>1;
//      *(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) + 
//	    *(oo+i+width) + *(oo+i+1+width) + 2)>>2;
//    }
    /* last pels on each line */
//    *(ii+ (width<<1) - 2) = *(oo + width - 1);
//    *(ii+ (width<<1) - 1) = *(oo + width - 1);
//    *(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
//    *(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
//    ii += (width<<2);
//    oo += width;
//  }

  /* last lines */
//  for (i = 0; i < width-1; i++) {
//    *(ii+ (i<<1)) = *(oo + i);    
//    *(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
//    *(ii+ (width<<1)+ (i<<1)) = *(oo + i);    
//    *(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
				  
//  }

  /* bottom right corner pels */
//  *(ii + (width<<1) - 2) = *(oo + width -1);
//  *(ii + (width<<1) - 1) = *(oo + width -1);
//  *(ii + (width<<2) - 2) = *(oo + width -1);
//  *(ii + (width<<2) - 1) = *(oo + width -1);

//}

//====================================================================



//==================================================================
_inline unsigned char  InterpolatePel(unsigned char _huge *image,int xcurr , int ycurr)
{

  unsigned char _huge  *oo;
  int i,j;

  oo = image;

  j = (ycurr >> 1);
  i = (xcurr >> 1);
  
  oo +=  j * widthA ;

  if( (ycurr & 1 ) == 0 )
  {
	if( (xcurr & 1 ) == 0 )
	{
  		return ( *(oo + i) ) ;
   	}else{
		if( (i < widthA-1) && (j <= heightA -1) )
		return ((*(oo + i) + *(oo + i + 1) + 1)>>1) ;
		else
		return (*(oo + widthA -1));
	}
  }else{
	if( ( xcurr & 1 ) == 0 )
	{
		if( (i <= widthA-1) && (j < heightA -1) )
		return ((*(oo + i) + *(oo + i + widthA) + 1)>>1) ;
		else
		return (*(oo + widthA -1));
	}else{
		if( (i < widthA-1) && (j < heightA -1) )
		return ((*(oo+i) + *(oo+i+1) + *(oo+i+widthA) + *(oo+i+1+widthA) + 2)>>2 ) ;
		else if (( i == widthA - 1 )&&(j != heightA -1 ) )
		return ((*(oo+widthA-1)+ *(oo+widthA+widthA-1) + 1 )>>1);
		else if ( (i != widthA -1 ) && (j == heightA - 1 ) )
		return ((*(oo + i) + *(oo + i + 1) + 1)>>1);
		else
		return (*(oo + widthA -1));
	}
  }

	
}
//==================================================================

/**********************************************************************
 *
 *	Name:		MotionEstimatePicture
 *	Description:    Finds integer and half pel motion estimation
 *                      and chooses 8x8 or 16x16 
 *	
 *	Input:	       current image, previous image, interpolated
 *                     reconstructed previous image, seek_dist,
 *                     motion vector array
 *	Returns:       
 *	Side effects: allocates memory for MV structure
 *
 *	
 *
 ***********************************************************************/
void MotionEstimatePicture(unsigned char _huge *curr, unsigned char _huge *prev, 
			   int seek_dist, MotionVector *MV[6][MBR+1][MBC+2])
			   
{
  char * ii , * jj , * pp , * kk ;
  int m[5] ;
  int i,j,k,h;
  int pmv0,pmv1,xoff,yoff, sub_offx ,sub_offy;
  unsigned char curr_mb[16][16];
  int sad8 = INT_MAX, sad16, sad0;
  MotionVector *f0,*f[4] ;
  int offx=0,offy=0;
  int lx = pels + 64;
// Do motion estimation and store result in array 
  for ( j = 0; j < mbr; j++) 
  {
	offy = j*MB_SIZE;
    for ( i = 0; i < mbc; i++) 
	{
	  offx = i*MB_SIZE;
   	  FindMB(offx,offy ,curr, curr_mb);
	  sad0 = SAD_Macroblock(prev + offx + (long)offy*lx, &curr_mb[0][0],
							lx, INT_MAX,0) - PREF_NULL_VEC;
	  if(sad0 < 900)   //changable
	  {
		for (k = 0; k < 5; k++)
			ZeroVec(MV[k][j+1][i+1]);
		MV[0][j+1][i+1]->Mode =	MODE_INTER0;
	  }
// Integer pel search 
	  else
	  {
		f0 = MV[0][j+1][i+1];
		f[0] = MV[1][j+1][i+1];
		f[1] = MV[2][j+1][i+1];
		f[2] = MV[3][j+1][i+1];
		f[3] = MV[4][j+1][i+1];
/* integer pel search */
/* NBNB need to use newgob properly as last parameter */
		FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,0,0);
/* Here the PMV's are found using integer motion vectors */
/* (NB should add explanation for this )*/

		xoff = pmv0>>1; /* always divisable by two */
		yoff = pmv1>>1;
//this function perform inter Mv estimation      
		MotionEstimation(&curr_mb[0][0], prev, offx, offy, 
		       xoff, yoff, seek_dist, MV, &sad0 );

		sad16 = f0->min_error;
		m[0] = sad16 ;
// in order to reduce work
		if( sad16 < 256 ) continue ;
//f0 --> f4 are all MotionVectors 
		
		f0->Mode = ChooseMode(&curr_mb[0][0],sad16);
		
/* Half pel search */
		if (f0->Mode != MODE_INTRA) 
		{
			sub_offx = offx + f0->x ;
			sub_offy = offy + f0->y ;
		    ii = pp = prev + sub_offx + sub_offy * lx ; 

			jj = ii - lx ;
			m[1] = SAD_Macroblock(jj, &curr_mb[0][0], lx, INT_MAX,0);			
		
			jj = ii + lx ;
			m[2] = SAD_Macroblock(jj, &curr_mb[0][0], lx, INT_MAX,0);
			
			jj = ii - 1 ;
			m[3] = SAD_Macroblock(jj, &curr_mb[0][0], lx, INT_MAX,0);
			
			jj = ii + 1 ;
			m[4] = SAD_Macroblock(jj, &curr_mb[0][0], lx, INT_MAX,0);
			

			newFindHalfPel(f0, m );
			sad16 = f0->min_error;

			if (advanced) // advance mode is used as default 
			{

			for( h = 0; h < 4 ; h ++ )
			{	
				if( h == 0 ) 
				{
					ii = pp ;
					kk = &curr_mb[0][0] ;

				}else if( h == 1 )
				{
					ii =  pp + 8 ;
					kk = &curr_mb[0][0] + 8 ;
				}
				else if( h == 2 )
				{
					ii =  pp + 8 * lx ;
					kk = &curr_mb[0][0] + 8 * 16 ;
				}
				else if( h == 3 )
				{
					ii =  pp + 8 * lx + 8 ; //modified !!!!!org : + 8*lx+lx
					kk =  &curr_mb[0][0] + 8 * 16 + 8 ;
				}
				
				m[0] = SAD_Block(ii, kk, lx, INT_MAX);			
			
				jj = ii - lx ;
				m[1] = SAD_Block(jj, kk, lx, INT_MAX);			

				jj = ii + lx ;
				m[2] = SAD_Block(jj, kk, lx, INT_MAX);

				jj = ii - 1 ;
				m[3] = SAD_Block(jj, kk, lx, INT_MAX);

				jj = ii + 1 ;
				m[4] = SAD_Block(jj, kk, lx, INT_MAX);
			
				newFindHalfPel(f[h], m );
			}

				sad8 = f[0]->min_error +f[1]->min_error +f[2]->min_error +f[3]->min_error;
				sad8 += PREF_16_VEC;
	  
//Choose Zero Vector, 8x8 or 16x16 vectors 
				if (sad0 < sad8 && sad0 < sad16) 
				{
					f0->x = f0->y = 0;
					f0->x_half = f0->y_half = 0;
				}
				else 
				{
					if (sad8 < sad16) 
						f0->Mode = MODE_INTER4V;
				}
			}
			else 
			{
//Choose Zero Vector or 16x16 vectors 
				if (sad0 < sad16) 
				{
					f0->x = f0->y = 0;
					f0->x_half = f0->y_half = 0;
				}
			}
		}
		else 

			for (k = 0; k < 5; k++)
			ZeroVec(MV[k][j+1][i+1]);
 		
	  }
	}
  }
  return;
}

//=========================================================
_inline void  newFindHalfPel(MotionVector *fr, int m[5])
{
	int error = m[0] ;
	if( ( (m[3] - m[0]) <<1 ) < (m[4] - m[0]) )
	{
		fr->x_half = -1 ;
		error += m[3] ;
	}else if( ( (m[4] - m[0])<<1 ) < (m[3] - m[0]) )
	{
		fr->x_half = +1 ;
		error += m[4] ;
	}else{
		fr->x_half = 0 ;
		error += m[0] ;
	}

	if( ( (m[1] - m[0])<<1 ) < (m[2] - m[0]) )
	{
		fr->y_half = -1 ;
		error += m[1] ;
	}else if( ( (m[2] - m[0])<<1 ) < (m[1] - m[0]) )
	{
		fr->y_half = +1 ;
		error += m[2] ;
	}else{
		fr->y_half = 0 ;
		error += m[0] ;
	}
	fr->min_error = error /3 ;
}


/**********************************************************************
 *
 *	Name:		MakeEdgeImage
 *	Description:    Copies edge pels for use with unrestricted
 *                      motion vector mode
 *	
 *	Input:	        pointer to source image, destination image
 *                      width, height, edge
 *	Returns:       
 *	Side effects:
 *
 *	
 *
 ***********************************************************************/

void MakeEdgeImage(unsigned char _huge *src, unsigned char _huge *dst, int width,
		   int height, int edge)
{
  long i,j;
  unsigned char _huge *p1,_huge *p2,_huge *p3,_huge *p4;
  unsigned char _huge *o1,_huge *o2,_huge *o3,_huge *o4;

  /* center image */
  p1 = dst;
  o1 = src;
  for (j = 0; j < height;j++) 
  {
    for(i = 0; i < width; i++)
    	p1[i] = o1[i];
    p1 += width + (edge<<1);
    o1 += width;
  }

  /* left and right edges */
  p1 = dst-1;
  o1 = src;
  for (j = 0; j < height;j++) {
    for (i = 0; i < edge; i++) {
      *(p1 - i) = *o1;
      *(p1 + width + i + 1) = *(o1 + width - 1);
    }
    p1 += width + (edge<<1);
    o1 += width;
  }    
    
  /* top and bottom edges */
  p1 = dst;
  p2 = dst + (long)(width + (edge<<1))*(height-1);
  o1 = src;
  o2 = src + (long)width*(height-1);
  for (j = 0; j < edge;j++) {
    p1 = p1 - (width + (edge<<1));
    p2 = p2 + (width + (edge<<1));
    for (i = 0; i < width; i++) {
      *(p1 + i) = *(o1 + i);
      *(p2 + i) = *(o2 + i);
    }
  }    

  /* corners */
  p1 = dst - (width+(edge<<1)) - 1;
  p2 = p1 + width + 1;
  p3 = dst + (long)(width+(edge<<1))*(height)-1;
  p4 = p3 + width + 1;

  o1 = src;
  o2 = o1 + width - 1;
  o3 = src + (long)width*(height-1);
  o4 = o3 + width - 1;
  for (j = 0; j < edge; j++) {
    for (i = 0; i < edge; i++) {
      *(p1 - i) = *o1;
      *(p2 + i) = *o2;
      *(p3 - i) = *o3;
      *(p4 + i) = *o4; 
    }
    p1 = p1 - (width + (edge<<1));
    p2 = p2 - (width + (edge<<1));
    p3 = p3 + width + (edge<<1);
    p4 = p4 + width + (edge<<1);
  }
}


/**********************************************************************
 *
 *	Name:		Clip
 *	Description:    clips recontructed data 0-255
 *	
 *	Input:	        pointer to recon. data structure
 *	Side effects:   data structure clipped
 *
 *	
 *
 ***********************************************************************/

void Clip(MB_Structure *data)
{
  int m;
  int *lum = data->lum[0], *cr = data->Cr[0], *cb = data->Cb[0];
  for (m = 0; m < 256; m++,lum++) 
  {
      *lum = mmin(255,mmax(0,*lum));
  }
  for (m = 0; m < 64; m++,cr++,cb++) 
  {
      *cr = mmin(255,mmax(0,*cr));
      *cb = mmin(255,mmax(0,*cb));
  }
}

_inline void MeanMB(MB_Structure *data, int mean[6])
{
 int i;
 int *kk;

 kk = data->lum[0];
 mean[0] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[0] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 16;
 }
 mean[0] = mean[0]>>6;

 kk = data->lum[0] + 8;
 mean[1] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[1] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 16;
 }
 mean[1] = mean[1]>>6;

 kk = data->lum[0] + 128;
 mean[2] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[2] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 16;
 }
 mean[2] = mean[2]>>6;

 kk = data->lum[0] + 136;
 mean[3] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[3] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 16;
 }
 mean[3] = mean[3]>>6;

 kk = data->Cb[0];
 mean[4] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[4] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 8;
 }
 mean[4] = mean[4]>>6;

 kk = data->Cr[0];
 mean[5] = 0;
 for(i = 0; i < 8; i++)
 {
	mean[5] += *kk     + *(kk+1) + *(kk+2) + *(kk+3) + 
			   *(kk+4) + *(kk+5) + *(kk+6) + *(kk+7);
	kk += 8;
 }
 mean[5] = mean[5]>>6;
}

_inline int VarMB(MB_Structure *data, int mean)
{
 int sad = 0, i;
 int *ii = data->lum[0];
 for(i = 0; i< 16; i++)
 {
	ii += 16;
    sad += (abs(*ii		- mean) +abs(*(ii+1 ) - mean)
	    +	abs(*(ii+2) - mean) +abs(*(ii+3 ) - mean)
	    +	abs(*(ii+4) - mean) +abs(*(ii+5 ) - mean)
	    +	abs(*(ii+6) - mean) +abs(*(ii+7 ) - mean)
	    +	abs(*(ii+8) - mean) +abs(*(ii+9 ) - mean)
	    +	abs(*(ii+10)- mean) +abs(*(ii+11) - mean)
	    +	abs(*(ii+12)- mean) +abs(*(ii+13) - mean)
	    +	abs(*(ii+14)- mean) +abs(*(ii+15) - mean));
 }
 return sad>>8;
}

_inline void DiffMB(MB_Structure *diff, MB_Structure *orig, int symbol)
{
 int i;
 int *lum_in, *Cr_in, *Cb_in, *lum_out, *Cr_out, *Cb_out;

 lum_in = orig->lum[0];
 lum_out = diff->lum[0];
 Cr_in = orig->Cr[0];
 Cr_out = diff->Cr[0];
 Cb_in = orig->Cb[0];
 Cb_out = diff->Cb[0];

 if(symbol == 0)
 {
	for(i=0; i<256; i++,lum_in++,lum_out++)
		*lum_out  = *lum_out - *lum_in;
	for(i=0; i<64; i++,Cr_in++,Cr_out++,Cb_in++,Cb_out++)
	{
		*Cr_out	= *Cr_out - *Cr_in;
		*Cb_out	= *Cb_out - *Cb_in;
	}
 }
 else
 {
	for(i=0; i<256; i++,lum_in++,lum_out++)
		*lum_out  = *lum_out + *lum_in;
	for(i=0; i<64; i++,Cr_in++,Cr_out++,Cb_in++,Cb_out++)
	{
		*Cr_out	= *Cr_out + *Cr_in;
		*Cb_out	= *Cb_out + *Cb_in;
	}
 }
}
 

void error(text)
char *text;
{
	MessageBox( NULL ,text,"Error",MB_OK);
	exit(1);
}

/* compliance warning messages to user, but don't exit() */

void error_handler(char *error_info)
{
	MessageBox( NULL ,error_info,"Error",MB_OK);
	exit(0);
}

⌨️ 快捷键说明

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