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

📄 main.c

📁 This site include optimized H.264 baseline codec, SF IP Box Binary. PC version and TI DM6437 version
💻 C
字号:
/*!
 ************************************************************************
 * 
 *
 * The library contain AVC H.264 baseline codec,which can process video
 * less than 12 minutes. 
 *
 * (C) Copyright 2007 by Tonald DL
 * All rights reserved 
 *
 * Date: 2007-08-11
 * Version: 070811A
 * Contact Personal: Tonald DL
 * Email: dhcodec@hotmail.com
 * 
 ************************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>

#ifdef _WIN32
    #if (_MSC_VER >= 900 )
       #define	WIN32_LEAN_AND_MEAN  1
       #define 	INC_OLE2
       #define	NOSERVICE
    #endif 

    #include <windows.h>
    #include <stdio.h>
   
#endif


#include "..\common\S264_SYNTAX.h"	
#include "sd_pci64.h"


#define SQUARE(x)	(((int)(x))*((int)(x)))

/*!
 ************************************************************************
 * 
 * 
 *  
 ************************************************************************
 */
void WaitToken_S264(PCI64_HANDLE* pPCI_DM6437,S264_PCI_SYNTAX* pS264_PCI_SYNTAX)
{
	int TokenOwner;
	INT32 Error;
	
	do{
		Sleep(10);
		Error = PCI64_MemRead32(*pPCI_DM6437, 
								S264_PCI_SYNTAX_ADDR_BASE,
								(sizeof(S264_PCI_SYNTAX)>>2),
								(UINT32*)pS264_PCI_SYNTAX);

		assert(!Error);
		TokenOwner=pS264_PCI_SYNTAX->TokenOwner;
		
	}while(TokenOwner!=S264_PCI_OWNER_PC);

}

/*!
 ************************************************************************
 * 
 * 
 *  
 ************************************************************************
 */
void PassToken_S264(PCI64_HANDLE* pPCI_DM6437,S264_PCI_SYNTAX* pS264_PCI_SYNTAX)
{
	INT32 Error;
	
	pS264_PCI_SYNTAX->TokenOwner=S264_PCI_OWNER_DM6437;
	
	Error = PCI64_MemWrite32(*pPCI_DM6437, 
							S264_PCI_SYNTAX_ADDR_BASE,
							(sizeof(S264_PCI_SYNTAX)>>2),
							(UINT32*)pS264_PCI_SYNTAX);
	assert(!Error);
}
/*!
 ************************************************************************
 * 
 * 
 *  
 ************************************************************************
 */
void WriteCMD_S264(PCI64_HANDLE* pPCI_DM6437,S264_PCI_SYNTAX* pS264_PCI_SYNTAX)
{
	INT32 Error;

	Error = PCI64_MemWrite32(*pPCI_DM6437, 
							S264_PCI_DATA_ADDR_BASE,
							(pS264_PCI_SYNTAX->BufWordLen),
							(UINT32*)pS264_PCI_SYNTAX->BufAddr);	

	assert(!Error);

	Error = PCI64_MemWrite32(*pPCI_DM6437, 
							S264_PCI_SYNTAX_ADDR_BASE,
							(sizeof(S264_PCI_SYNTAX)>>2),
							(UINT32*)pS264_PCI_SYNTAX);	

	assert(!Error);
	
}

/*!
 ************************************************************************
 * 
 * 
 *  
 ************************************************************************
 */
void ReadCMD_S264(PCI64_HANDLE* pPCI_DM6437,S264_PCI_SYNTAX* pS264_PCI_SYNTAX)
{
	INT32 Error;

	Error=PCI64_MemRead32(*pPCI_DM6437, 
						S264_PCI_DATA_ADDR_BASE,
						(pS264_PCI_SYNTAX->BufWordLen),
						(UINT32*)pS264_PCI_SYNTAX->BufAddr);
	assert(!Error);
}


/*!
 ************************************************************************
 * 
 * 
 *  
 ************************************************************************
 */
void main(int argc, char **argv)
{
	PCI64_HANDLE PCI_DM6437;
	INT32 Error;
	S264_PCI_SYNTAX	SYNTAX_DM6437;
	ENCFRAME_PROP ENCINPUT;

	char *filein_path,*fileout_path,*fileout_rec;
	FILE *file_in,*file_264,*file_rec;
	unsigned char *porg,*prec_dm6437,*pstream_dm6437;
	byte *paddr_src,*paddr_dst;
	
	int i,k,framesize,ysize,uvsize,framenum1,framenum2,bytenum,OperationCode;
	int ENC_TIMER,TOTAL_BITS,DSPMIPS,DSPBITLEN;
	int FRAME2RUN;
	
	int diff_y,diff_u,diff_v;
	float snr_y,snr_u,snr_v,snr_ya,snr_ua,snr_va,mips_f,mips_a;

	file_in=NULL;
	file_264=NULL;
	file_rec=NULL;

	porg=NULL;
	prec_dm6437=NULL;
	pstream_dm6437=NULL;

	PCI_DM6437=NULL;

	snr_ya=0;
	snr_ua=0;
	snr_va=0;
	mips_a=0;
	
	if(argc==9)
	{
		i=1;
		filein_path=argv[i++];
		fileout_path=argv[i++];
		fileout_rec=argv[i++];	
		FRAME2RUN=atoi(argv[i++]);
		ENCINPUT.VideoQuality=atoi(argv[i++]);
		ENCINPUT.IntraPeriod=atoi(argv[i++]);
		ENCINPUT.ImageWidth=atoi(argv[i++]);
		ENCINPUT.ImageHeight=atoi(argv[i++]);

		//generate new stream, set it to NEW_SEQ;
		ENCINPUT.FrameType=NEW_SEQ;
		
		//calculate the Y and UV component size. Also calculate the whole frame size.
		ysize=ENCINPUT.ImageWidth*ENCINPUT.ImageHeight;
		uvsize=ysize>>2;
		framesize=ysize*3/2;
		
		//open the YUV420 file.
		file_in=fopen(filein_path,"rb");
		if(file_in==NULL)
		{
			printf("input file path error!\n");
			goto EXIT_MAIN;
		}

		//open the output 264 file.
		file_264=fopen(fileout_path,"wb");
		if(file_264==NULL)
		{
			printf("out file path error!\n");
			goto EXIT_MAIN;
		}

		//open the output yuv file.
	       file_rec=fopen(fileout_rec,"wb");
		if(file_rec==NULL)
		{
			printf("out file path error!\n");
			goto EXIT_MAIN;
		}

		porg=malloc(framesize);
		prec_dm6437=malloc(framesize);
		pstream_dm6437=malloc(framesize);

		//confirm DM6437 is opened.
		printf("Open PCI DM6437...\n");
		do{
			Sleep(50);
			Error = PCI64_Open( 0, &PCI_DM6437 );
		}while(Error);


		//Setup encoder parameters
		printf("Setup PCI DM6437 Codec...\n");
		WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);

		SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_PARA;
		SYNTAX_DM6437.BufAddr=(void*)&ENCINPUT;
		SYNTAX_DM6437.BufWordLen=(sizeof(ENCINPUT)>>2);
		WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
		
		PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
		

		
////////////////////////////////////////////////////////////////////////////////////////
//ENC frame
////////////////////////////////////////////////////////////////////////////////////////
		printf("\n-----------------------------------------------------------------------\n");
		printf( " Image format                    : %dx%d\n",ENCINPUT.ImageWidth,ENCINPUT.ImageHeight);
		printf(" QP.                             : %d \n" ,ENCINPUT.VideoQuality);
		printf(" File Name.                      : %s\n",filein_path);
		printf(" Frame Number.                   : %d\n",FRAME2RUN);
		printf(" InterPeriod.                    : %d\n",ENCINPUT.IntraPeriod);
		printf("-----------------------------------------------------------------------\n");


		ENC_TIMER=0;
		TOTAL_BITS=0;
		//also compute the encoder speed
	       for(framenum1=0;framenum1<FRAME2RUN;framenum1++)
       	{
			//get one frame pixels into buffer porg
			bytenum=fread(porg,1,framesize,file_in);

			if(bytenum!=framesize)
			{
				printf("Error While Read File !\n");
				goto EXIT_MAIN;
			}

			//pass data to DSP Internal Memory
			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_YUV420_IN_START;
			SYNTAX_DM6437.BufAddr=NULL;
			SYNTAX_DM6437.BufWordLen=0;
			WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
		
			
			bytenum=framesize;
			paddr_src=porg;
			do{
				WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
				if(bytenum>=S264_PCI_DATA_BYTE_LEN)
				{
					SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_YUV420_IN_PROC;
					SYNTAX_DM6437.BufAddr=(void*)paddr_src;
					SYNTAX_DM6437.BufWordLen=S264_PCI_DATA_WORD_LEN;
					
					bytenum-=(SYNTAX_DM6437.BufWordLen<<2);
					paddr_src+=(SYNTAX_DM6437.BufWordLen<<2);
				}
				else
				{
					assert((bytenum&0x3)==0);
					SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_YUV420_IN_PROC;
					SYNTAX_DM6437.BufAddr=(void*)paddr_src;
					SYNTAX_DM6437.BufWordLen=(bytenum>>2);

					bytenum-=(SYNTAX_DM6437.BufWordLen<<2);
					paddr_src+=(SYNTAX_DM6437.BufWordLen<<2);
				}
				
				assert(SYNTAX_DM6437.BufWordLen<=S264_PCI_DATA_WORD_LEN);
				WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
				PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			}while(bytenum>0);

			//pass data to DSP Internal Memory
			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_YUV420_IN_END;
			SYNTAX_DM6437.BufAddr=NULL;
			SYNTAX_DM6437.BufWordLen=0;
			WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			

			//Get YUV420 Data from DSP
			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_YUV420_OUT_START;
			SYNTAX_DM6437.BufAddr=NULL;
			SYNTAX_DM6437.BufWordLen=0;
			WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);

			paddr_dst=prec_dm6437;
			do{
				WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
				
				OperationCode=SYNTAX_DM6437.OpCode;
				SYNTAX_DM6437.BufAddr=paddr_dst;
				paddr_dst+=(SYNTAX_DM6437.BufWordLen<<2);
					
				if(OperationCode!=S264_PCI_OP_ENC_YUV420_OUT_END)
				ReadCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);

				PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			}while(OperationCode!=S264_PCI_OP_ENC_YUV420_OUT_END);
			

			//Get Bits Data from DSP
			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_BITS_OUT_START;
			SYNTAX_DM6437.BufAddr=NULL;
			SYNTAX_DM6437.BufWordLen=0;
			WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			

			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.BufAddr=&DSPBITLEN;
			SYNTAX_DM6437.BufWordLen=1;			
			ReadCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);


			paddr_dst=pstream_dm6437;
			do{
				WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
				
				OperationCode=SYNTAX_DM6437.OpCode;
				SYNTAX_DM6437.BufAddr=paddr_dst;
				paddr_dst+=(SYNTAX_DM6437.BufWordLen<<2);
				SYNTAX_DM6437.BufWordLen;
					
				if(OperationCode!=S264_PCI_OP_ENC_BITS_OUT_END)
				ReadCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);

				PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
				
			}while(OperationCode!=S264_PCI_OP_ENC_BITS_OUT_END);		



			//Get MIPS from DSP
			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_MIPS_OUT;
			SYNTAX_DM6437.BufAddr=NULL;
			SYNTAX_DM6437.BufWordLen=0;			
			WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
			PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);

			WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
			SYNTAX_DM6437.BufAddr=&DSPMIPS;
			SYNTAX_DM6437.BufWordLen=1;			
			ReadCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);

////////////////////////////////////////////////////////////////////////////////////////
//Get PSNR
////////////////////////////////////////////////////////////////////////////////////////
			diff_y = 0;
			diff_u= 0;
			diff_v= 0;
	               k=0;
			for(i=0;i<ysize;i++,k++)
			diff_y+= SQUARE(porg[k] - prec_dm6437[k]);

			for(i=0;i<uvsize;i++,k++)
			diff_u += SQUARE(porg[k] - prec_dm6437[k]);

			for(i=0;i<uvsize;i++,k++)
			diff_v += SQUARE(porg[k] - prec_dm6437[k]);		

			snr_y=(float)(10*log10(65025*(double)((double)ysize/diff_y)));
			snr_u=(float)(10*log10(65025*(double)((double)uvsize/diff_u)));
			snr_v=(float)(10*log10(65025*(double)((double)uvsize/diff_v)));

			snr_ya+=snr_y;
			snr_ua+=snr_u;
			snr_va+=snr_v;

////////////////////////////////////////////////////////////////////////////////////////
//End PSNR
////////////////////////////////////////////////////////////////////////////////////////

			//calculate the bits length
			TOTAL_BITS+=DSPBITLEN*8;
			//calculate the mips
			mips_f=((double)DSPMIPS*65536.0/1000000.0)+1;
			mips_a+=mips_f;

			printf("[%4d]   [%10d]   [%4d]  [%2.3f]\n",framenum1,DSPBITLEN*8,(int)mips_f,snr_y);


			//write the bits to 264 file.
			fwrite(pstream_dm6437,1,DSPBITLEN,file_264);
			fwrite(prec_dm6437,1,framesize,file_rec);

	                
	        };

EXIT_MAIN:


		printf("\n-----------------------------------------------------------------------\n");
		printf(" Image format                   : %dx%d\n",ENCINPUT.ImageWidth,ENCINPUT.ImageHeight);
		printf(" QP                             : %d\n" ,ENCINPUT.VideoQuality);
		printf(" Bit rate at 30fps (kbit/s)     : %5.2f\n",((float)TOTAL_BITS*30.0*0.001)/((float) framenum1));
		printf(" Average Speed(mips/frame)      : %2.3f\n",mips_a/((float) framenum1));
		printf(" Average Y PSNR                 : %2.3f\n",snr_ya/((float) framenum1));
		printf("-----------------------------------------------------------------------\n");


			
		if(file_in)
		fclose(file_in);	

		if(file_264)
		fclose(file_264);
		
		if(file_rec)
		fclose(file_rec);

		if(prec_dm6437)
		free(prec_dm6437);
		
		if(pstream_dm6437)
		free(pstream_dm6437);

		//Clean Up DSP, make it wait for next video
		WaitToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
		SYNTAX_DM6437.OpCode=S264_PCI_OP_ENC_CLEANUP;
		SYNTAX_DM6437.BufAddr=NULL;
		SYNTAX_DM6437.BufWordLen=0;
		WriteCMD_S264(&PCI_DM6437,&SYNTAX_DM6437);
		PassToken_S264(&PCI_DM6437,&SYNTAX_DM6437);
		
		//close DM6437 handler
		printf("Close PCI DM6437...\n");
		if(PCI_DM6437)
		PCI64_Close( PCI_DM6437 );
		
	}
	else
	{
		printf("Encode:\n");
		printf("S264 foreman_cif300.yuv foreman.264 foreman_rec.yuv Test.log 30 28 30 3 352 288\n");
		exit(-1);
	}

	return;    
}

⌨️ 快捷键说明

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