?? mpeg4_b.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 + -