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

📄 mpeg4_b.c

📁 用MPEG-4对YUV视频文件编码压缩成divx视频文件
💻 C
字号:
/* mpeg4encoder.cpp : Defines the entry point for the console application.*/



#include <stdio.h> 
#include <stdlib.h>
#include <time.h>

#include "user_macro.h"
#include "xvid.h"   
#include "encoder.h" 

#ifdef _TRIMEDIA
#include "clock.h"
#endif

#ifdef WIN32
#include <windows.h>
#include <mmsystem.h> 
#endif

/* global variable used by amvfast algorithm */
extern int SAD16_count,SAD8_count;
extern float factor1,factor2; 

XVID_ENC_PARAM encparam;/* encoding parameter struct variable */
XVID_ENC_FRAME encframe;/* encoding frame information struct variable */
/*XVID_ENC_STATS stats;*/
FILE *fdin,*fdout,*fconyuvout;/* file pointer */

/*********************************************************/
FILE *ftestlog;

char * FileName;
/************************************************************/


int framenum;/* encoding frame number */
unsigned char* PutBitsBuffer;/* bits streams buffer pointer */
unsigned char* ConstructYUVBuffer;/*construct image buffer pointer */
unsigned char *InYUVBuffer;/* input image buffer pointer */
static void* eHandle;/* point to global Encoder struct */

#ifdef _LOGFILE
FILE * encodelog;/*log file pointer */
#endif

/* 12.9 fyh add a global variable to counter memory useage */
extern int mem_useage;

/* function prototype declare */
int encoderrealse();

/*
  error process function
  
*/
void error(char* infor)
{
   printf("%s",infor);
   encoderrealse();
   exit(1);
}

/*
  read a frame data from YUV420 file 
*/
void readframe(FILE *fd,unsigned char *frame,int num)
{ long pos;
  int chrom_hsize, chrom_vsize,horizontal_size,vertical_size;
  int size;
  
  horizontal_size =	encparam.height ;
  vertical_size = 	encparam.width ;
  chrom_hsize =  horizontal_size>>1;
  chrom_vsize =  vertical_size>>1;
  size=horizontal_size*vertical_size+(chrom_hsize*chrom_vsize)*2;
  pos=num*size;
  fseek(fd,pos,SEEK_SET);
  fread(frame,1,size,fd);
}

/*
    write data from buffer to file
	
*/
void writefile(FILE *fd,unsigned char *buffer,int length)

{
	fwrite(buffer,1,length,fd);
}

/*
  encoder initialization
*/
int encoderinit()
{	
	int size;

	/* 
      vlc table initialization and function pointer initialization. 
    */
	xvid_init();

    /* initialize image resolution */
	encparam.width=352;
	encparam.height=288;
	framenum=50;/* encoding frame numbers */

	/* alloc global memory */
	mem_useage=0;
	size=encparam.width *encparam.height *3/2;
	mem_useage+=size;
	if (!(InYUVBuffer = (unsigned char *)malloc(size)))
	     error("malloc failed InYUVBuffer\n");

#ifdef _OUT_CONSTRUCT_IMAGE
	mem_useage+=size;
	if (!(ConstructYUVBuffer = (unsigned char *)malloc(size)))
       error("malloc failed ConstructYUVBuffer\n");
#endif

	size=encparam.width *encparam.height;
	mem_useage+=size;
	if(!(PutBitsBuffer= (unsigned char *)malloc(size)))
	    error("malloc failed PutBitsBuffer\n");

    /* initialize encoding frame structure */
	encframe.bitstream=PutBitsBuffer;
/*	encframe.colorspace=XVID_CSP_I420;*/
	encframe.image=InYUVBuffer;/* initialize input image poniter */
#ifdef _OUT_CONSTRUCT_IMAGE
	encframe.constructimage=ConstructYUVBuffer;/* initialize constructed image poniter */  
#endif
	encframe.stride =encparam.width ;/* image buffer stride */
/*	encframe.sequence_time=1;*/
	encframe.length=-1; /* bit streams length conter */
	encframe.intra =-1; /* intra frame flag */
	encframe.quant = 0; /* quantization step */   
	encframe.general = 0;
	encframe.motion  = 0;

	/* four motion vector mode */
//   	encframe.general |= XVID_INTER4V;
	/* use halfpel interpolation */
    encframe.general |= XVID_HALFPEL;
	/* half pixel search */
    encframe.motion |= HALFPELREFINE16; 
    /*encframe.motion |= HALFPELREFINE8; */

	/* amvfast sad threhold value parameter */
	factor1=(float)1.05;
	factor2=(float)1.5;
/*	factor1=(float)1.2;
	factor2=(float)1.8; */

/*	encframe.general |= XVID_MPEGQUANT; *//* MPEG quantization   */
/*	encframe.quant_inter_matrix=NULL;
	encframe.quant_intra_matrix=NULL;*/


    /* initialize encoding pararmeter structure */
	encparam.rc_bitrate=1000000;/* sequence bitrate (bps) */
    encparam.fbase=25; 
	encparam.fincr=1;
	encparam.min_quantizer=1;
	encparam.max_quantizer=31;
	encparam.sequence_time=1;

	encparam.framerate=encparam.fbase/encparam.fincr;/* sequence framerate (fps) */
	encparam.max_key_interval=encparam.framerate*encparam.sequence_time;/* gop frame number */

	/* initialize parameter related rate control */
	encparam.rc_reaction_delay_factor = 16;
	encparam.rc_averaging_period = 100;
	encparam.rc_buffer = 100;
/*	encparam.bquant_ratio=100;*/
/*	0-1表示使用位率控制模型0-为高位率模型,1-为低位率模型*/
	encparam.rc_type=0;
	/*encparam.rc_type=0;*/
	encparam.global=0;


	/* open in/out file */
//	if (!(fdin = fopen("e:/sequence/cif/singer.yuv","rb")))   

	FileName = "D:/作业/图像/compression/sequence/basket.yuv";
	if (!(fdin = fopen(FileName,"rb")))
 	    error("Couldn't open yuv file\n");

/******************************************************/
	if (!(ftestlog = fopen("testlog.dat","wb")))
		error("Couldn't open file testlog.dat\n");
    fprintf(ftestlog,"\n\nPicture:   %s\n",FileName);
/**********************************************************/

	
#ifdef _OUT_CONSTRUCT_IMAGE
	if(!(fconyuvout = fopen("construct.yuv","wb")))
		error("Couldn't open construct yuv file\n");
#endif

	if (!(fdout = fopen("result.divx","wb")))
		error("Couldn't open mpg file\n");

#ifdef _LOGFILE
	if(!(encodelog=fopen("encodelog.dat","a")))
		error("Couldn't open encodelog.dat file\n");
	encparam.pFile=(void *)encodelog;
#else
    encparam.pFile=NULL;
#endif	

	/* encoding parameter check and alloc memory resource */
	encoder_create(&encparam);
	printf("memory useage: %d byte \n",mem_useage);
	
	eHandle=encparam.handle ;
	
	return 0;
}
/*
  release encoder resource 
*/
int encoderrealse()
{
	if(eHandle)
	{
		encoder_destroy(eHandle);
		eHandle = NULL;
	}
	
	free(PutBitsBuffer);
    free(InYUVBuffer);

#ifdef _OUT_CONSTRUCT_IMAGE
	free(ConstructYUVBuffer);
#endif
	
	return 0;
}
/*
   Finish sequence encoding process.
   include :
   read source YUV file,encoding loop,
   output bitstreame and constructed YUV file,
   output encoding statistic inforamtion.
  
*/
void putseq()
{  

	int i,frame_num=0;
	float psnr=0.0;
	/*int max_brame=0;*/
    int total_length=0;/* statistics bit streams length */
        
#ifdef _TRIMEDIA                   
        tmTimeStamp_t begin,end;
        float total_time=0;
        float interval;
#endif       

#ifdef WIN32
	int tick1,tick2,interval;
	int total_time=0;
#endif		

	for(i=0;i<framenum;i++)
	{
		/* read source YUV data from file */
		readframe(fdin,InYUVBuffer,i);

		/* reset each frame bit streams length counter */
		encframe.length = 0;

		/* set time profile point */
#ifdef _TRIMEDIA		
	getClock(&begin);	
#endif	
#ifdef WIN32
	tick1 = timeGetTime ();
#endif
        
	    /* encoding */ 
		/*encoder_encode(eHandle, &encframe,&stats);*/

/********************************************************/
	    fprintf(ftestlog,"\n\nframe: %d\n",i);
/******************************************************************/
        encoder_encode(eHandle, &encframe);

		/* set time profile point */
#ifdef _TRIMEDIA        
        getClock(&end);
        interval=diffClock(&begin,&end);  
        total_time+=interval;
#endif
#ifdef WIN32
	tick2 = timeGetTime();
	interval=tick2-tick1;
	total_time+=interval;
#endif        
  
		/* output bitstream to file */
		writefile(fdout,PutBitsBuffer,encframe.length);

		/* output encoding information */
#ifndef _TRIMEDIA
#ifdef WIN32
		printf("frame num= %4d length= %8d intra= %4d psnr= %8.3f dB time=%d ms\n",
			i,encframe.length*8,encframe.intra,encframe.psnr,interval);	
#else
		printf("frame num= %4d length= %8d intra= %4d psnr= %8.3f dB\n",
			i,encframe.length*8,encframe.intra,encframe.psnr);
#endif
#else			
		printf("frame num= %4d length= %8d intra= %4d psnr= %8.3f dB time=%8.3f ms\n",
			i,encframe.length*8,encframe.intra,encframe.psnr,interval);	
#endif
		
#ifdef _LOGFILE
#ifndef _TRIMEDIA
#ifdef WIN32
		fprintf(encodelog,"frame num=%4d length=%8d intra=%4d psnr=%8.3f dB time=%d ms\n ",
			i,encframe.length*8,encframe.intra ,encframe.psnr,interval);
#else
		fprintf(encodelog,"frame num=%4d length=%8d intra=%4d psnr=%8.3f dB\n ",
			i,encframe.length*8,encframe.intra ,encframe.psnr);
#endif
#else			
		fprintf(encodelog,"frame num=%4d length=%8d intra=%4d psnr=%8.3f dB time=%8.3f ms\n ",
			i,encframe.length*8,encframe.intra ,encframe.psnr,interval);
#endif						
//		total_length+=encframe.length*8;
#endif

		total_length+=encframe.length*8;
		/* process skip frame */
		if(!encframe.flag_skipframe)
		{
#ifdef _OUT_CONSTRUCT_IMAGE
		   writefile(fconyuvout,ConstructYUVBuffer,encparam.width*encparam.height*3/2 );
#endif
			psnr+=encframe.psnr;
			frame_num++;
		}
	}

	/* After encoding finishing, output encoding statistic inforamtion */ 
	psnr/=frame_num; 
#ifndef _TRIMEDIA
#ifdef WIN32
	total_time/=frame_num;
	printf("Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d Time= %d ms\n ",psnr,total_length,frame_num,total_time);
#else	
	printf("Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d \n ",psnr,total_length,frame_num);
#endif
#else                                                                                                                                    
	total_time/=frame_num;
	printf("Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d Time= %8.3f ms\n ",psnr,total_length,frame_num,total_time);
#endif
	
#ifdef  _LOGFILE
#ifndef _TRIMEDIA
#ifdef WIN32
	fprintf(encodelog,"Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d Time= %d ms\n ",psnr,total_length,frame_num,total_time);
#else
	fprintf(encodelog,"Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d\n ",psnr,total_length,frame_num);
#endif
    fprintf(encodelog,"total check points: %d MB(16x16) %d block(8x8)\n",SAD16_count,SAD8_count);

#else
	fprintf(encodelog,"Total_PSNRY=%f dB   Total_bits= %d bit Total_frame_number= %d Time= %8.3f ms \n ",psnr,total_length,frame_num,total_time);
#endif
	fclose(encodelog);
#endif

#ifdef _OUT_CONSTRUCT_IMAGE
   fclose(fconyuvout);
#endif

	fclose(fdout);
	fclose(fdin);

/*********************************************************/
    fprintf(ftestlog,"Total_PSNRY=%f dB   Total_bits= %d bit   Total_framenum= %d\n",
		    psnr,total_length,frame_num);
	fclose(ftestlog);
/************************************************************/

}

/*
  Application entry function,
  agc and argv are no meaning.
 
*/
int main(int argc, char* argv[])
{
#ifndef _TRIMEDIA	
	time_t begin,end;
#else
	uint32_t begin; 
#endif

  /* 
	We must initialize timer before use trimedia timer.
  */
#ifdef _TRIMEDIA                     
        initClock();                     
#endif 

/****************************************************************/
	FileName=argv[1];
/*******************************************************************/
	/* encoder initialization */	
	encoderinit();

	/* encoding */ 
#ifndef _TRIMEDIA
	time(&begin);
#else
/*
   对于200MHzCPU,CYCLES()所使用的低分辨率时钟最大计时为21s
*/
	begin=CYCLES();
#endif
	
	putseq();

#ifndef _TRIMEDIA
	time(&end);
	printf("time use up %d second\n",end-begin);
#else
    printf("total time is %u cycles \n", CYCLES()-begin); 
#endif
	
	/* release encoder */
	encoderrealse();

   /* 
	 We must release timer after use trimedia timer.
   */
#ifdef _TRIMEDIA
	releaseClock();
#endif	
	
	return 0;   
}

⌨️ 快捷键说明

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