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

📄 encode.c

📁 H.263+(VC++商业源代码)
💻 C
字号:
#include <windows.h>
#include <commdlg.h>
#include <assert.h>
#include <io.h>
#include "sim.h"
#include "public.h"

#define DEBUG_DENG // deng

void RGB565toYUV411();
void RGB555toYUV411();
void RGB888toYUV411();

//==================================================================
long  InitEncoder(unsigned  char **EncoderInput ,unsigned char **EncoderOutput,int PictureWidth , int PictureHeight)
{
	int i,j,k;
	MotionVector *curr_pos;
	if( (PictureWidth>352) || (PictureHeight>288) )
	return -1 ;
	DEF_INTRA_QUANT = 10 ;
	DEF_INTER_QUANT = 10 ;
	advanced = DEF_ADV_MODE; // deng: was YES ;   
	syntax_arith_coding = DEF_SAC_MODE; // DENG:  was YES ;

	bits = (Bits *)malloc(sizeof(Bits));
    total_bits = (Bits *)malloc(sizeof(Bits));
    intra_bits = (Bits *)malloc(sizeof(Bits));
    res = (Results *)malloc(sizeof(Results));
    total_res = (Results *)malloc(sizeof(Results));
    pic = (Pict *)malloc(sizeof(Pict));
	recon_data_P =(MB_Structure *)malloc(sizeof(MB_Structure)); 
    diff =(MB_Structure *)malloc(sizeof(MB_Structure)); 
    headerlength = DEF_HEADERLENGTH;
										/* Initalize idct_tables */
   init_idct();

 /* Init VLC_tables */
	initbits();
	memset(pic, 0, sizeof(Pict));
	memset(bits, 0, sizeof(Bits));

	pic->unrestricted_mv_mode = DEF_UMV_MODE;
	QP = DEF_INTER_QUANT;
	QPI = DEF_INTRA_QUANT; 
	ChangableQP = DEF_INTER_QUANT;
	
	ref_frame_rate = (float)DEF_REF_FRAME_RATE;
	chosen_frameskip = DEF_FRAMESKIP + 1;
	orig_frameskip = DEF_ORIG_SKIP + 1;

	pic->seek_dist = DEF_SEEK_DIST;
	pic->use_gobsync = DEF_INSERT_SYNC;
	pic->source_format = DEF_CODING_FORMAT;
	start = DEF_START_FRAME;
	end = DEF_STOP_FRAME;

	pic->target_frame_rate = (float)DEF_TARGET_FRAME_RATE;

	targetrate = 0; 
	frames = 0;
	total_frames_passed = 0;
	pic->TR = 0;
	pic->QP_mean = (float)0;
	user_pels = PictureWidth;
	user_lines = PictureHeight;
	if( user_pels % 16 != 0 )
	{	pels =( user_pels/16 + 1 ) * 16 ;
	}else{
		pels = PictureWidth;
	}

	if( user_lines % 16 != 0 )
	{	lines =( user_lines/16 + 1 ) * 16 ;
	}else{
		lines = PictureHeight;	
	}
	cpels = pels/2;
	mbc = pels/MB_SIZE;
	mbr = lines/MB_SIZE;
	lsize = (long)pels*lines;
	csize = lsize>>2;
	widthA = pels + 64 ;
	widthA2 = (widthA << 1 );
	heightA = lines +  64 ;

	pic->bit_rate = targetrate;
	pic->src_frame_rate = (int)(ref_frame_rate / orig_frameskip);
	DelayBetweenFramesInSeconds = (float) 1.0/(float)pic->src_frame_rate;
	InitializeRateControl();
	frame_rate =  ref_frame_rate / (float)(orig_frameskip * chosen_frameskip);

	bit_count = 0;

//	if(!(hCurrRGB = GlobalAlloc(GHND,lsize*2L)))
	if(!(hCurrRGB = GlobalAlloc(GHND,lsize*3L)))
		error_handler("\ncannot alloc memory");
	EncoderRGBInput = (unsigned char _huge *)GlobalLock(hCurrRGB) ;
    * EncoderInput = EncoderRGBInput ;


	if(!(hCurr_image = GlobalAlloc(GHND,lsize*3L/2L)))
 		error_handler("\ncannot alloc memory");
    curr_image.lum = (unsigned char _huge *)GlobalLock(hCurr_image);
	curr_image.Cb = curr_image.lum + lsize;
	curr_image.Cr = curr_image.Cb + csize;
	
	if(!(hRecon_image = GlobalAlloc(GHND,lsize*3L/2L)))
 		error_handler("\ncannot alloc memory");

	recon_image.lum = (unsigned char _huge *)GlobalLock(hRecon_image);
	recon_image.Cb = recon_image.lum + lsize;
	recon_image.Cr = recon_image.Cb + csize;


	B = 16; 
	if(!(hPr_edge = GlobalAlloc(GHND, (long)(pels+4*B)*(lines+4*B)*3L/2L)))
		error_handler("\ncannot alloc memory");

    pr_edge.lum = (unsigned char _huge *)GlobalLock(hPr_edge);
    pr_edge.Cr = pr_edge.lum + (long)(pels+4*B)*(lines+4*B);
    pr_edge.Cb = pr_edge.Cr + (long)(pels+4*B)*(lines+4*B)/4;

	prev_recon.lum = pr_edge.lum + (long)(pels + 4*B)*2*B + 2*B;
    prev_recon.Cr = pr_edge.Cr + (long)(pels/2 + 2*B)*B + B;
    prev_recon.Cb = pr_edge.Cb + (long)(pels/2 + 2*B)*B + B;

	if(!(hMV = GlobalAlloc(GHND,(long)6L*(MBR+1)*(MBC+2)*sizeof(MotionVector)+16L)))
		error_handler("\ncannot alloc memory");

	curr_pos = (MotionVector *)GlobalLock(hMV);
	for(i = 0; i < 6; i++)
	{
  		for(j = 0; j < mbr+1; j++)
  		{
  			for(k = 0; k  <  mbc+2; k++)
			{			   
				pMV[i][j][k] = curr_pos;
				curr_pos ++;
			}
  		}
	}

	if(!(hStreamBuf= GlobalAlloc(GHND,lsize*3L/2L)))
		error_handler("\ncannot alloc memory");
	InternalEncoderOutput = (unsigned char*)GlobalLock(hStreamBuf);
	* EncoderOutput = InternalEncoderOutput;
	return lsize ;
}


//==================================================================
int VideoFormat;

 void  SetVideoFormat(int NewVideoFormat)
{
	VideoFormat = NewVideoFormat;
}

void _Fill_current_image();


 int EncodeOneIntra(void)
{
    extern int arith_used;

#ifndef DEBUG_DENG  // orig
	switch(VideoFormat)
	{
	case 555: RGB555toYUV411(); break;
	case 565: RGB565toYUV411(); break;
	case 888: RGB888toYUV411(); break;
	default: RGB888toYUV411();
	}
#else  // deng modify
	_Fill_current_image();
#endif

	//advanced = NO ;
	//memcpy(curr_image.lum,EncoderRGBInput,lsize*3L/2L);
	bit_buf  =  InternalEncoderOutput ;
	bit_count = 0;

	pic->picture_coding_type = PCT_INTRA;
	pic->QUANT = QPI;
 	CodeOneIntra(&curr_image, &recon_image, QPI, bits, pic);
	if (arith_used) 
	{
		bits->header += encoder_flush();
		arith_used = 0;
	}
	bits->header += alignbits(); 
	AddBitsPicture(bits);
	memcpy(intra_bits,bits,sizeof(Bits));
	ZeroBits(total_bits);
	ZeroRes(total_res);
    pic->QUANT = QP;
    return bit_count ;
}

 int  EncodeOneInter(void)
{
    extern int arith_used;
	
#ifndef DEBUG_DENG // orig
	switch(VideoFormat)
	{
	case 555: RGB555toYUV411(); break;
	case 565: RGB565toYUV411(); break;
	case 888: RGB888toYUV411(); break;
	default: RGB888toYUV411();
	}
#else  // deng modify
	_Fill_current_image();

#endif
	
	//advanced = NO ;
	bit_buf  =  InternalEncoderOutput ;
	bit_count = 0;

	pic->picture_coding_type = PCT_INTER;
  
	
	//pic->TR += ((frameskip*orig_frameskip) % 256);    // DENG : was commented.                   
    
	QP = pic->QUANT;
 	CodeOneOrTwo(&curr_image, &recon_image, QP, 0 , bits, pic);

	if (arith_used) 
	{
		bits->header += encoder_flush();
		arith_used = 0;
	}

	bits->header += alignbits();  // pictures shall be byte aligned 
	AddBitsPicture(bits);
	AddBits(total_bits, bits);

	return bit_count ;
}

int  SetAdvancedMode(int mode)
{
	int tempmode = advanced ;
	if( mode != 0 && mode!= 1 )
		return tempmode ;
	advanced = mode ;
	return tempmode ;
}

 int  SetCompressRatio(int newQP)
{
	int tempQP = QP ;
	if( newQP < 1   || newQP > 31 )  return tempQP;
	ChangableQP  = newQP;
	QP = newQP;
	QPI = newQP; 

	return QP;
}


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

 void FreeEncoder(void)
{
  if(hCurr_image!=NULL)
  {
	GlobalUnlock(hCurr_image);
	GlobalFree(hCurr_image);
	hCurr_image = NULL ;
  }

  if(hRecon_image!=NULL)
  {
	GlobalUnlock(hRecon_image);
	GlobalFree(hRecon_image);
	hRecon_image = NULL ;
  }
 
  if( hPr_edge!=NULL )
  {
	GlobalUnlock(hPr_edge);
	GlobalFree(hPr_edge);
	hPr_edge = NULL ;
  }
  if( hCurrRGB!=NULL )
  {
	GlobalUnlock(hCurrRGB);
	GlobalFree(hCurrRGB);
	hCurrRGB = NULL ;
  }
  if( hStreamBuf != NULL )
  {
	GlobalUnlock(hStreamBuf);
	GlobalFree(hStreamBuf);
	hStreamBuf = NULL ;
  }

  if(hMV!=NULL)
  {
	GlobalUnlock(hMV);
	GlobalFree(hMV);
	hMV = NULL ;
  }
  if( bits != NULL )
  {
	free(bits);
	bits = NULL ;
  }
  if( total_bits != NULL )
  {
	free(total_bits);
	total_bits = NULL ;
  }
  if( intra_bits != NULL )
  {
	free(intra_bits);
	intra_bits = NULL ;
  }
  if( res != NULL )
  {
	free(res);
	res = NULL ;	
  }
  if( total_res != NULL )
  {
	free(total_res);
	total_res = NULL ;
  }
  if( pic != NULL )
  {
	free(pic); 	
	pic = NULL ;
  }
  if( recon_data_P != NULL )
  {
	free(recon_data_P);
	recon_data_P = NULL ;
  }
  if( diff != NULL )
  {
	free(diff);
	diff = NULL ;
  }

}

void RGB565toYUV411()
{
  	long rgbPos=0;
    int i,j;
	int y,r,g,b,u[4],v[4];
	int ImageH = lines ;
	int ImageW = pels ;
	unsigned int image = 0 ;
	unsigned short _huge * CodeSrc ;
	CodeSrc  = (unsigned short _huge *)EncoderRGBInput ;
    for(i=0;i<user_lines;i+=2)
  	{
        for(j=0;j<user_pels;j+=2)
		{
			rgbPos = i * ImageW +  j ;
			r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
			g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[0] = ((r - y)*743962)>>20;
			u[0] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char ) y;
			rgbPos ++ ;
			
			r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
			g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[1] = ((r - y)*743962)>>20;
			u[1] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) =(unsigned char ) y;
			rgbPos += pels - 1 ;

			
			r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
			g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[2] = ((r - y)*743962)>>20;
			u[2] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) = (unsigned char )y;
			rgbPos ++;

			r = (((*(CodeSrc + rgbPos))&0xf800)>>11)<<3;
			g = (((*(CodeSrc + rgbPos))&0x7e0)>>5)<<2;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[3] = ((r - y)*743962)>>20;
			u[3] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char ) y;
			curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
			curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
		}
	
  	}
	
}

void RGB555toYUV411()
{
  	long rgbPos=0;
    int i,j;
	int y,r,g,b,u[4],v[4];
	int ImageH = lines ;
	int ImageW = pels ;
	unsigned int image = 0 ;
	unsigned short _huge * CodeSrc ;
	CodeSrc  = (unsigned short _huge *)EncoderRGBInput ;
    for(i=0;i<user_lines;i+=2)
  	{
        for(j=0;j<user_pels;j+=2)
		{
			rgbPos = i * ImageW +  j ;
			r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
			g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[0] = ((r - y)*743962)>>20;
			u[0] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char ) y;
			rgbPos ++ ;
			
			r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
			g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[1] = ((r - y)*743962)>>20;
			u[1] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) =(unsigned char ) y;
			rgbPos += pels - 1 ;

			
			r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
			g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[2] = ((r - y)*743962)>>20;
			u[2] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) = (unsigned char )y;
			rgbPos ++;

			r = (((*(CodeSrc + rgbPos))&0x7c00)>>10)<<3;
			g = (((*(CodeSrc + rgbPos))&0x3e0)>>5)<<3;
			b = ((*(CodeSrc + rgbPos))&0x1f)<<3;

//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[3] = ((r - y)*743962)>>20;
			u[3] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char ) y;
			curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
			curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
		}
	
  	}
	
}

void RGB888toYUV411()
{
  	long rgbPos=0;
    int i,j;
	int y,r,g,b,u[4],v[4];
	int ImageH = lines ;
	int ImageW = pels ;
	unsigned int image = 0 ;
	BYTE _huge* CodeSrc ;
	CodeSrc  = (BYTE _huge *)EncoderRGBInput ;

	for(i=0;i<user_lines;i+=2)
  	{
        for(j=0;j<user_pels;j+=2)     //2*2
		{
			rgbPos = i*ImageW + j;
			r = *(CodeSrc + rgbPos*3);
			g = *(CodeSrc + rgbPos*3 + 1);
			b = *(CodeSrc + rgbPos*3 + 2);

//y = 0.299*r + 0.587*g + 0.114*b;
//v[0] = (r - y)*127/179;
//u[0] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[0] = ((r - y)*743962)>>20;
			u[0] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char)y;
			rgbPos ++;
			
			r = *(CodeSrc + rgbPos*3);
			g = *(CodeSrc + rgbPos*3 + 1);
			b = *(CodeSrc + rgbPos*3 + 2);

//y = 0.299*r + 0.587*g + 0.114*b;
//v[1] = (r - y)*127/179;
//u[1] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[1] = ((r - y)*743962)>>20;
			u[1] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) =(unsigned char ) y;
			rgbPos += pels - 1 ;
	
			r = *(CodeSrc + rgbPos*3);
			g = *(CodeSrc + rgbPos*3 + 1);
			b = *(CodeSrc + rgbPos*3 + 2);

//y = 0.299*r + 0.587*g + 0.114*b;
//v[2] = (r - y)*127/179;
//u[2] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[2] = ((r - y)*743962)>>20;
			u[2] = ((b - y)*589244)>>20;

			*(curr_image.lum+rgbPos) = (unsigned char )y;
			rgbPos ++;

			r = *(CodeSrc + rgbPos*3);
			g = *(CodeSrc + rgbPos*3 + 1);
			b = *(CodeSrc + rgbPos*3 + 2);

//y = 0.299*r + 0.587*g + 0.114*b;
//v[3] = (r - y)*127/179;
//u[3] = (b - y)*127/226;
			y = ((r*313524)>>20) + ((g*615514)>>20) + ((b*119538)>>20);
			v[3] = ((r - y)*743962)>>20;
			u[3] = ((b - y)*589244)>>20;

			*(curr_image.lum + rgbPos) =(unsigned char ) y;
			curr_image.Cb[i*ImageW/4 +j/2] =(unsigned char ) ((u[0]+u[1]+u[2]+u[3])/4 + 0x7f);
			curr_image.Cr[i*ImageW/4 +j/2] = (unsigned char )((v[0]+v[1]+v[2]+v[3])/4 + 0x7f);
		}
	
  	}
	
}

 int GetH263Version(void)
{
	VersionNum = 100 ;
	return VersionNum;
}

 //deng: add
 // fill the current image buffer with YUV 4:1:1, (e.g. QCIF source format)
void _Fill_current_image()
{
	int n = pels*lines;
	int i,k;
	k = 0;
	for ( i = 0;i< n; i++)
		curr_image.lum[i] = EncoderRGBInput[k++];
	for ( i = 0;i< n/4; i++)
		curr_image.Cb[i] = EncoderRGBInput[k++];
	for ( i = 0;i< n/4; i++)
		curr_image.Cr[i] = EncoderRGBInput[k++];
}

⌨️ 快捷键说明

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