📄 main.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include "DHCODEC.h"
/*!
************************************************************************
*
*
* The library contain AVC H.264 baseline codec,which can process video
* less than 12 minutes.
*
*
* Date: 2007-05-05
* Version: 070505A
* Contact Personal: Tonald DL
* Email: dhcodec@hotmail.com
*
************************************************************************
*/
//global variables and define
//#define SHOW_PSNR
#define SQUARE(x) (((int)(x))*((int)(x)))
FILE *file_in,*file_out,*file_264;
unsigned char *psrc,*prec,*pdec,*pstream;
/*!
************************************************************************
* \brief
* Read syntax, this function is called by decoder.
* This function should be implemented by user.
* Input:
* void* _OutDat (data should fill into this buffer)
* int len (counted as byte).
* Output:
* TRUE (Return TRUE if data is available)
* FALSE (Return FALSE if data is not available)
*
************************************************************************
*/
int GetNewData(void* _OutDat,int _len)
{
//this function is accessing the stream, the stream can be stored as file or memory.
if((_OutDat)&&(_len>0))
{
// if _OutDat is not NULL and _len bigger than zero
// Decoder is asking for more data, so fill the bytes that decoder need.
// if there is no enough bytes availabe in stream, return FALSE otherwise return TRUE.
if(fread(_OutDat,1,_len,file_264)==_len)
return TRUE;
else
return FALSE;
}
else
{
// if _OutDat is NULL or _len less than zero
// Decoder is asking for rewind _len bytes.
// return TURE is rewind success, return FALSE, if rewind fail.
if(0==fseek(file_264,_len,SEEK_CUR))
return TRUE;
else
return FALSE;
}
};
void main(int argc, char **argv)
{
char *filein_path,*fileout_path;
int i,framesize,ysize,uvsize,framenum1,framenum2,bytenum,decstatus;
int ENC_TIMER,DEC_TIMER,TOTAL_BITS;
time_t ltime1,ltime2;
struct timeb tstruct1,tstruct2;
ENCFRAME_PROP ENCINPUT;
DECFRAME_PROP DECINPUT;
#ifdef SHOW_PSNR
int diff_y,diff_u,diff_v;
float snr_y,snr_u,snr_v,snr_ya,snr_ua,snr_va;
#endif
if(argc==8)
{
//Auto init setting encoder parameters.
//Setup the encoder parameters while first setup.
DHENC_SETUP(&ENCINPUT);
i=1;
filein_path = argv[i++];
fileout_path = argv[i++];
ENCINPUT.VideoQuality=atoi(argv[i++]);
ENCINPUT.IntraPeriod=atoi(argv[i++]);
ENCINPUT.BSPreset=atoi(argv[i++]);
ENCINPUT.ImageWidth=atoi(argv[i++]);
ENCINPUT.ImageHeight=atoi(argv[i++]);
//open the YUV420 file.
#if 1
fopen_s( &file_in, filein_path, "rb" );
#else
file_in=fopen(filein_path,"rb");
#endif
if(file_in==NULL)
{
printf("input file path error!\n");
return;
}
//open the output 264 file.
#if 1
fopen_s( &file_264, fileout_path, "wb" );
#else
file_264=fopen(fileout_path,"wb");
#endif
if(file_264==NULL)
{
printf("out file path error!\n");
return;
}
//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;
psrc=malloc(framesize);
prec=malloc(framesize);
pstream=malloc(framesize);
#ifdef SHOW_PSNR
snr_ya=snr_ua=snr_va=0;
#endif
framenum1=0;
////////////////////////////////////////////////////////////////////////////////////////
//ENC frame
////////////////////////////////////////////////////////////////////////////////////////
ENC_TIMER=0;
TOTAL_BITS=0;
//also compute the encoder speed
ftime (&tstruct1);
time (<ime1);
do{
//get one frame pixels into buffer psrc
bytenum=(int)fread(psrc,1,framesize,file_in);
if(bytenum!=framesize)
break;
//copy the frame pixels to prec
memcpy(prec,psrc,framesize);
//Encoding the frame
//ENCINPUT.VideoQuality can be changed frame by frame;
//ENCINPUT.IntraPeriod can be changed frame by frame;
//ENCINPUT.BSPreset can be changed frame by frame;
//ENCINPUT.FrameType can be changed frame by frame
//ENCINPUT.ImageWidth only can be changed while ENCINPUT.FrameType set to NEW_SEQ
//ENCINPUT.ImageHeight only can be changed while ENCINPUT.FrameType set to NEW_SEQ
//before call the function ,prec point to the input data, after call the function, prec stored the decode data.
//pstream will store the ouput stream,
//ENCINPUT have the input parameters and output parameters
DHENC_FRAME(prec,pstream,&ENCINPUT);
#ifdef SHOW_PSNR
////////////////////////////////////////////////////////////////////////////////////////
//Get PSNR
////////////////////////////////////////////////////////////////////////////////////////
diff_y = 0;
diff_u= 0;
diff_v= 0;
k=0;
for(i=0;i<ysize;i++,k++)
diff_y+= SQUARE(prec[k] - psrc[k]);
for(i=0;i<uvsize;i++,k++)
diff_u += SQUARE(prec[k] - psrc[k]);
for(i=0;i<uvsize;i++,k++)
diff_v += SQUARE(prec[k] - psrc[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;
printf ("%6d %6d %2d %7.3f %7.3f %7.3f\n", framenum1, ENCINPUT.CodeLength*8, ENCINPUT.VideoQuality, snr_y, snr_u, snr_v);
#else
printf(".");
#endif
//calculate the bits length
TOTAL_BITS+=ENCINPUT.CodeLength*8;
//write the bits to 264 file.
fwrite(pstream,1,ENCINPUT.CodeLength,file_264);
framenum1++;
}while (bytenum>0);
time (<ime2);
ftime (&tstruct2);
ENC_TIMER = (int)((ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm));
fprintf(stdout,"\n-----------------------------------------------------------------------\n");
fprintf(stdout, " Image format : %dx%d\n",ENCINPUT.ImageWidth,ENCINPUT.ImageHeight);
fprintf(stdout, " QP. : %d \n" ,ENCINPUT.VideoQuality);
fprintf(stdout, " ENC Speed. : %.2f fps\n",1000.0*framenum1/((float)ENC_TIMER));
#ifdef SHOW_PSNR
fprintf(stdout," SNR Y(dB) : %5.2f\n",snr_ya);
fprintf(stdout," SNR U(dB) : %5.2f\n",snr_ua);
fprintf(stdout," SNR V(dB) : %5.2f\n",snr_va);
#endif
fprintf(stdout, " Bit rate at 30fps (kbit/s) : %5.2f\n",((float)TOTAL_BITS*30.0*0.001)/((float) framenum1));
fprintf(stdout,"-----------------------------------------------------------------------\n");
fclose(file_264);
fclose(file_in);
free(psrc);
free(prec);
free(pstream);
}
else if((argc==3)||(argc==2))
{
i=1;
filein_path = argv[i++];
if(argc==3)
fileout_path = argv[i++];
////////////////////////////////////////////////////////////////////////////////////////
//DEC frame
////////////////////////////////////////////////////////////////////////////////////////
#if 1
fopen_s( &file_264, filein_path, "rb" );
#else
file_264=fopen(filein_path,"rb");
#endif
if(file_264==NULL)
{
printf("input file path error!\n");
return;
}
if(argc==3)
{
#if 1
fopen_s( &file_out, fileout_path, "wb" );
#else
file_out=fopen(fileout_path,"wb");
#endif
if(file_out==NULL)
{
printf("output file path error!\n");
return;
}
}
pdec=malloc(1024*768*2);
DEC_TIMER=0;
framenum2=0;
ftime (&tstruct1);
time (<ime1);
do{
//decode frame by frame
decstatus=DHDEC_FRAME(pdec,&DECINPUT);
//write the bits to 264 file.
if(argc==3)
fwrite(pdec,1,DECINPUT.ImageHeight*DECINPUT.ImageWidth*3/2,file_out);
printf(".");
framenum2++;
}while((decstatus!=DEC_END)&&(decstatus!=DEC_NOT_VALID));
framenum2--;
time (<ime2);
ftime (&tstruct2);
DEC_TIMER = (int)((ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm));
fprintf(stdout,"\n-----------------------------------------------------------------------\n");
fprintf(stdout, " Image format : %dx%d\n",DECINPUT.ImageWidth,DECINPUT.ImageHeight);
fprintf(stdout, " DEC Speed. : %.2f fps\n",1000.0*framenum2/((float)DEC_TIMER));
fprintf(stdout,"-----------------------------------------------------------------------\n");
free(pdec);
fclose(file_264);
if(argc==3)
fclose(file_out);
}
else
{
printf("Encode:\n");
printf("S264 foreman.yuv foreman.264 28 30 2 352 288\n");
printf("Decode without output to file:\n");
printf("S264 foreman.264\n");
printf("Decode with output to file:\n");
printf("S264 foreman.264 foreman_dec.yuv\n");
exit(-1);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -