1 |
/************************************************************************** |
/***************************************************************************** |
2 |
* |
* |
3 |
* XVID MPEG-4 VIDEO CODEC - Example for encoding and decoding |
* XVID MPEG-4 VIDEO CODEC |
4 |
|
* - Console based test application - |
5 |
|
* |
6 |
|
* Copyright(C) 2002 Christoph Lampert |
7 |
|
* |
8 |
|
* This program is an implementation of a part of one or more MPEG-4 |
9 |
|
* Video tools as specified in ISO/IEC 14496-2 standard. Those intending |
10 |
|
* to use this software module in hardware or software products are |
11 |
|
* advised that its use may infringe existing patents or copyrights, and |
12 |
|
* any such use would be at such party's own risk. The original |
13 |
|
* developer of this software module and his/her company, and subsequent |
14 |
|
* editors and their companies, will have no liability for use of this |
15 |
|
* software or modifications or derivatives thereof. |
16 |
* |
* |
17 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
18 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
26 |
* |
* |
27 |
* You should have received a copy of the GNU General Public License |
* You should have received a copy of the GNU General Public License |
28 |
* along with this program; if not, write to the Free Software |
* along with this program; if not, write to the Free Software |
29 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
30 |
* |
* |
31 |
*************************************************************************/ |
* $Id: xvid_stat.c,v 1.5 2002-09-12 19:18:12 chl Exp $ |
32 |
|
* |
33 |
|
****************************************************************************/ |
34 |
|
|
35 |
/************************************************************************ |
/************************************************************************ |
36 |
* |
* |
79 |
#include <math.h> // needed for log10 |
#include <math.h> // needed for log10 |
80 |
#include <sys/time.h> // only needed for gettimeofday |
#include <sys/time.h> // only needed for gettimeofday |
81 |
|
|
82 |
#include "xvid.h" /* comes with XviD */ |
#include "../src/xvid.h" /* comes with XviD */ |
83 |
|
|
84 |
int motion_presets[7] = { |
int motion_presets[7] = { |
85 |
0, // Q 0 |
0, // Q 0 |
86 |
PMV_EARLYSTOP16, // Q 1 |
PMV_EARLYSTOP16, // Q 1 |
87 |
PMV_EARLYSTOP16, // Q 2 |
PMV_EARLYSTOP16, // Q 2 |
88 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, // Q 3 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, // Q 3 |
89 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8, // Q 4 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, // Q 4 |
90 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 // Q 5 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 // Q 5 |
91 |
| PMV_HALFPELREFINE8, |
| PMV_HALFPELREFINE8, |
92 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 // Q 6 |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 // Q 6 |
95 |
|
|
96 |
int general_presets[7] = { |
int general_presets[7] = { |
97 |
XVID_H263QUANT, /* or use XVID_MPEGQUANT */ // Q 0 |
XVID_H263QUANT, /* or use XVID_MPEGQUANT */ // Q 0 |
98 |
XVID_H263QUANT, // Q 1 |
XVID_MPEGQUANT, // Q 1 |
99 |
XVID_H263QUANT, // Q 2 |
XVID_H263QUANT, // Q 2 |
100 |
XVID_H263QUANT | XVID_HALFPEL, // Q 3 |
XVID_H263QUANT | XVID_HALFPEL, // Q 3 |
101 |
XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, // Q 4 |
XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, // Q 4 |
105 |
|
|
106 |
/* my default values for encoding */ |
/* my default values for encoding */ |
107 |
|
|
108 |
|
#define ABS_MAXFRAMENR 9999 // max number of frames |
109 |
|
|
110 |
int ARG_BITRATE=900; |
int ARG_BITRATE=900; |
111 |
int ARG_QUANTI=0; |
int ARG_QUANTI=0; |
112 |
|
|
115 |
int ARG_MAXQUANT=31; |
int ARG_MAXQUANT=31; |
116 |
float ARG_FRAMERATE=25.00; |
float ARG_FRAMERATE=25.00; |
117 |
|
|
118 |
|
int ARG_MAXFRAMENR=ABS_MAXFRAMENR; |
119 |
|
|
120 |
|
|
121 |
#define MAX(A,B) ( ((A)>(B)) ? (A) : (B) ) |
#define MAX(A,B) ( ((A)>(B)) ? (A) : (B) ) |
122 |
#define SMALL_EPS 1e-10 |
#define SMALL_EPS 1e-10 |
123 |
|
|
|
|
|
124 |
/* these are global variables. Not very elegant, but easy, and this is an easy program */ |
/* these are global variables. Not very elegant, but easy, and this is an easy program */ |
125 |
|
|
126 |
int XDIM=0; |
int XDIM=0; |
134 |
int pgmflag = 0; // a flag, if input is in PGM format, overwritten in init-phase |
int pgmflag = 0; // a flag, if input is in PGM format, overwritten in init-phase |
135 |
char filepath[256] = "./"; // the path where to save output |
char filepath[256] = "./"; // the path where to save output |
136 |
|
|
|
#define MAXFILENR 9999 // max number of frames (this should be made into an option!) |
|
|
|
|
137 |
void *enc_handle = NULL; // internal structures (handles) for encoding |
void *enc_handle = NULL; // internal structures (handles) for encoding |
138 |
void *dec_handle = NULL; // and decoding |
void *dec_handle = NULL; // and decoding |
139 |
|
|
155 |
} |
} |
156 |
|
|
157 |
|
|
|
|
|
158 |
double absdistq(int x,int y, unsigned char* buf1, int stride1, unsigned char* buf2, int stride2) |
double absdistq(int x,int y, unsigned char* buf1, int stride1, unsigned char* buf2, int stride2) |
159 |
/* returns the sum of squared distances (SSD) between two images of dimensions x times y */ |
/* returns the sum of squared distances (SSD) between two images of dimensions x times y */ |
160 |
{ |
{ |
274 |
#define FRAMERATE_INCR 1001 |
#define FRAMERATE_INCR 1001 |
275 |
|
|
276 |
|
|
277 |
int enc_init() |
int enc_init(int use_assembler) |
278 |
{ /* initialize encoder for first use, pass all needed parameters to the codec */ |
{ /* initialize encoder for first use, pass all needed parameters to the codec */ |
279 |
int xerr; |
int xerr; |
280 |
|
|
281 |
XVID_INIT_PARAM xinit; |
XVID_INIT_PARAM xinit; |
282 |
XVID_ENC_PARAM xparam; |
XVID_ENC_PARAM xparam; |
283 |
|
|
284 |
|
if(use_assembler) |
285 |
|
|
286 |
|
#ifdef ARCH_IA64 |
287 |
|
xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; |
288 |
|
#else |
289 |
|
xinit.cpu_flags = 0; |
290 |
|
#endif |
291 |
|
|
292 |
|
else |
293 |
xinit.cpu_flags = XVID_CPU_FORCE; |
xinit.cpu_flags = XVID_CPU_FORCE; |
294 |
|
|
295 |
xvid_init(NULL, 0, &xinit, NULL); |
xvid_init(NULL, 0, &xinit, NULL); |
296 |
|
|
297 |
xparam.width = XDIM; |
xparam.width = XDIM; |
306 |
xparam.fincr = FRAMERATE_INCR; |
xparam.fincr = FRAMERATE_INCR; |
307 |
xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE); |
xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE); |
308 |
} |
} |
309 |
xparam.bitrate = ARG_BITRATE*1000; |
xparam.rc_reaction_delay_factor = 16; |
310 |
|
xparam.rc_averaging_period = 100; |
311 |
|
xparam.rc_buffer = 10; |
312 |
|
xparam.rc_bitrate = ARG_BITRATE*1000; |
313 |
xparam.min_quantizer = 1; |
xparam.min_quantizer = 1; |
314 |
xparam.max_quantizer = 31; |
xparam.max_quantizer = 31; |
315 |
xparam.max_key_interval = (int)ARG_FRAMERATE*10; |
xparam.max_key_interval = (int)ARG_FRAMERATE*10; |
316 |
xparam.rc_buffersize = 2; |
|
317 |
/* I use a small value here, since will not encode whole movies, but short clips */ |
/* I use a small value here, since will not encode whole movies, but short clips */ |
318 |
|
|
319 |
xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL); |
xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL); |
372 |
/* Routines for decoding: init encoder, frame step, release encoder */ |
/* Routines for decoding: init encoder, frame step, release encoder */ |
373 |
/*********************************************************************/ |
/*********************************************************************/ |
374 |
|
|
375 |
int dec_init() /* init decoder before first run */ |
int dec_init(int use_assembler) /* init decoder before first run */ |
376 |
{ |
{ |
377 |
int xerr; |
int xerr; |
378 |
|
|
379 |
XVID_INIT_PARAM xinit; |
XVID_INIT_PARAM xinit; |
380 |
XVID_DEC_PARAM xparam; |
XVID_DEC_PARAM xparam; |
381 |
|
|
382 |
|
if(use_assembler) |
383 |
|
|
384 |
|
#ifdef ARCH_IA64 |
385 |
|
xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; |
386 |
|
#else |
387 |
xinit.cpu_flags = 0; |
xinit.cpu_flags = 0; |
388 |
|
#endif |
389 |
|
|
390 |
|
else |
391 |
|
xinit.cpu_flags = XVID_CPU_FORCE; |
392 |
|
|
393 |
xvid_init(NULL, 0, &xinit, NULL); |
xvid_init(NULL, 0, &xinit, NULL); |
394 |
xparam.width = XDIM; |
xparam.width = XDIM; |
395 |
xparam.height = YDIM; |
xparam.height = YDIM; |
444 |
int status; |
int status; |
445 |
|
|
446 |
int m4v_size; |
int m4v_size; |
447 |
int frame_type[MAXFILENR]; |
int frame_type[ABS_MAXFRAMENR]; |
448 |
int Iframes=0, Pframes=0, Bframes=0; |
int Iframes=0, Pframes=0, use_assembler=0; |
449 |
double framepsnr[MAXFILENR]; |
double framepsnr[ABS_MAXFRAMENR]; |
450 |
|
|
451 |
double Ipsnr=0.,Imaxpsnr=0.,Iminpsnr=999.,Ivarpsnr=0.; |
double Ipsnr=0.,Imaxpsnr=0.,Iminpsnr=999.,Ivarpsnr=0.; |
452 |
double Ppsnr=0.,Pmaxpsnr=0.,Pminpsnr=999.,Pvarpsnr=0.; |
double Ppsnr=0.,Pmaxpsnr=0.,Pminpsnr=999.,Pvarpsnr=0.; |
461 |
{ |
{ |
462 |
pgmflag = 1; |
pgmflag = 1; |
463 |
|
|
464 |
|
if (argc==2 && !strcmp(argv[1],"-asm")) |
465 |
|
use_assembler = 1; |
466 |
if (argc>=3) |
if (argc>=3) |
467 |
{ XDIM = atoi(argv[1]); |
{ XDIM = atoi(argv[1]); |
468 |
YDIM = atoi(argv[2]); |
YDIM = atoi(argv[2]); |
510 |
printf("Framerate %6.3f fps\n",ARG_FRAMERATE); |
printf("Framerate %6.3f fps\n",ARG_FRAMERATE); |
511 |
} |
} |
512 |
|
|
513 |
|
if (argc>=7) |
514 |
|
{ ARG_MAXFRAMENR = atoi(argv[6]); |
515 |
|
if ( (ARG_MAXFRAMENR <= 0) ) |
516 |
|
{ fprintf(stderr,"Wrong number of frames\n"); return -1; } |
517 |
|
printf("max. Framenr. %d\n",ARG_MAXFRAMENR); |
518 |
|
} |
519 |
|
|
520 |
/* now we know the sizes, so allocate memory */ |
/* now we know the sizes, so allocate memory */ |
521 |
|
|
522 |
in_buffer = (unsigned char *) malloc(XDIM*YDIM); |
in_buffer = (unsigned char *) malloc(XDIM*YDIM); |
539 |
/*********************************************************************/ |
/*********************************************************************/ |
540 |
|
|
541 |
|
|
542 |
status = enc_init(); |
status = enc_init(use_assembler); |
543 |
if (status) |
if (status) |
544 |
{ |
{ |
545 |
printf("Encore INIT problem, return value %d\n", status); |
printf("Encore INIT problem, return value %d\n", status); |
546 |
goto release_all; |
goto release_all; |
547 |
} |
} |
548 |
|
|
549 |
status = dec_init(); |
status = dec_init(use_assembler); |
550 |
if (status) |
if (status) |
551 |
{ |
{ |
552 |
printf("Decore INIT problem, return value %d\n", status); |
printf("Decore INIT problem, return value %d\n", status); |
634 |
|
|
635 |
filenr++; |
filenr++; |
636 |
|
|
637 |
} while ( (!status) && (filenr<MAXFILENR) ); |
} while ( (!status) && (filenr<ARG_MAXFRAMENR) ); |
638 |
|
|
639 |
|
|
640 |
|
|
658 |
Iframes++; |
Iframes++; |
659 |
Ipsnr += framepsnr[i]; |
Ipsnr += framepsnr[i]; |
660 |
break; |
break; |
|
case 2: |
|
661 |
default: |
default: |
|
Bframes++; |
|
|
Bpsnr += framepsnr[i]; |
|
662 |
break; |
break; |
663 |
} |
} |
664 |
} |
} |
667 |
Ppsnr /= Pframes; |
Ppsnr /= Pframes; |
668 |
if (Iframes) |
if (Iframes) |
669 |
Ipsnr /= Iframes; |
Ipsnr /= Iframes; |
|
if (Bframes) |
|
|
Bpsnr /= Bframes; |
|
|
|
|
670 |
|
|
671 |
for (i=0;i<filenr;i++) // calculate statistics for every frametype: P,I (and B) |
for (i=0;i<filenr;i++) // calculate statistics for every frametype: P,I (and B) |
672 |
{ |
{ |
685 |
if (framepsnr[i] < Pminpsnr) |
if (framepsnr[i] < Pminpsnr) |
686 |
Iminpsnr = framepsnr[i]; |
Iminpsnr = framepsnr[i]; |
687 |
Ivarpsnr += (framepsnr[i] - Ipsnr)*(framepsnr[i] - Ipsnr) /Iframes; |
Ivarpsnr += (framepsnr[i] - Ipsnr)*(framepsnr[i] - Ipsnr) /Iframes; |
688 |
break; |
default: |
|
case 2: |
|
|
if (framepsnr[i] > Bmaxpsnr) |
|
|
Bmaxpsnr = framepsnr[i]; |
|
|
if (framepsnr[i] < Pminpsnr) |
|
|
Bminpsnr = framepsnr[i]; |
|
|
Bvarpsnr += (framepsnr[i] - Bpsnr)*(framepsnr[i] - Bpsnr) /Bframes; |
|
689 |
break; |
break; |
690 |
} |
} |
691 |
} |
} |
699 |
printf("enc: %6.1f fps, dec: %6.1f fps \n",1/totalenctime, 1/totaldectime); |
printf("enc: %6.1f fps, dec: %6.1f fps \n",1/totalenctime, 1/totaldectime); |
700 |
printf("PSNR P(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Pframes,Ppsnr,Pminpsnr,Pmaxpsnr,sqrt(Pvarpsnr/filenr)); |
printf("PSNR P(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Pframes,Ppsnr,Pminpsnr,Pmaxpsnr,sqrt(Pvarpsnr/filenr)); |
701 |
printf("I(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Iframes,Ipsnr,Iminpsnr,Imaxpsnr,sqrt(Ivarpsnr/filenr)); |
printf("I(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Iframes,Ipsnr,Iminpsnr,Imaxpsnr,sqrt(Ivarpsnr/filenr)); |
|
if (Bframes) |
|
|
printf("B(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Bframes,Bpsnr,Bminpsnr,Bmaxpsnr,sqrt(Bvarpsnr/filenr)); |
|
702 |
printf("\n"); |
printf("\n"); |
703 |
|
|
704 |
/*********************************************************************/ |
/*********************************************************************/ |