[svn] / branches / dev-api-3 / xvidcore / examples / xvid_bstat.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/examples/xvid_bstat.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 571 - (view) (download)

1 : chl 571 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC - Example for encoding and decoding
4 :     *
5 :     * This program is free software; you can redistribute it and/or modify
6 :     * it under the terms of the GNU General Public License as published by
7 :     * the Free Software Foundation; either version 2 of the License, or
8 :     * (at your option) any later version.
9 :     *
10 :     * This program is distributed in the hope that it will be useful,
11 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 :     * GNU General Public License for more details.
14 :     *
15 :     * You should have received a copy of the GNU General Public License
16 :     * along with this program; if not, write to the Free Software
17 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 :     *
19 :     *************************************************************************/
20 :    
21 :     /************************************************************************
22 :     *
23 :     * PSNR and Speed test routine for XviD using the XviD-API
24 :     * (C) Christoph Lampert, 2002/04/13
25 :     *
26 :     * This is programs isn't finished... it's just a quick hack because people
27 :     * asked for a version of xvid_bstat with bframe-support
28 :     *
29 :     * A sequence of YUV pics in PGM file format is encoded and decoded
30 :     * The speed is measured and PSNR of decoded picture is calculated.
31 :     *
32 :     * The program is plain C and needs no libraries except for libxvidcore,
33 :     * and maths-lib ,so with UN*X you simply compile by
34 :     *
35 :     * gcc xvid_bstat.c -lxvidcore -lm -o xvid_bstat
36 :     *
37 :     * Run without or with illegal parameters, then PGM input input is read
38 :     * from stdin.
39 :     *
40 :     * Parameters are: xvid_bstat XDIM YDIM QUALITY BITRATE/QUANTIZER FRAMERATE
41 :     * MAX_FRAMES MAX_BFRAMES BFRAME_QUANT
42 :     *
43 :     * if XDIM or YDIM are illegal (e.g. 0), they are ignored and input is
44 :     * considered to be PGM. Otherwise (X and Y both greater than 0) raw YUV
45 :     * is expected, as e.g. the standard MPEG test-files, like "foreman"
46 :     *
47 :     * 0 <= QUALITY <= 6 (default 5)
48 :     *
49 :     * BITRATE is in kbps (default 900),
50 :     * if BITRATE<32, then value is taken is fixed QUANTIZER
51 :     *
52 :     * FRAMERATE is a float (with or without decimal dot), default is 25.00
53 :     *
54 :     * MAX_FRAMEs is the total number of frames to be encoded (minimum 1)
55 :     *
56 :     * MAX_BFRAMES is the maximum number of bframes in a row (or -1)
57 :     *
58 :     * BFRAME_QUANT is the quantization ratio for B-frames (in percent)
59 :     *
60 :     * input/output and m4v-output is saved, if corresponding flags are set
61 :     *
62 :     * PGM input must in a very specific format, see read_pgmheader
63 :     * it can be generated e.g. from MPEG2 by mpeg2dec -o pgmpipe
64 :     *
65 :     ************************************************************************/
66 :    
67 :     /************************************************************************
68 :     *
69 :     * For EXAMPLES how to use this, see the seperate file xvid_bstat.examples
70 :     *
71 :     ************************************************************************/
72 :    
73 :     #define BFRAMES
74 :    
75 :     #include <stdio.h>
76 :     #include <stdlib.h>
77 :     #include <math.h> // needed for log10
78 :     #include <sys/time.h> // only needed for gettimeofday
79 :    
80 :     #include "xvid.h" /* comes with XviD */
81 :    
82 :     int motion_presets[7] = {
83 :     0, // Q 0
84 :     PMV_EARLYSTOP16, // Q 1
85 :     PMV_EARLYSTOP16, // Q 2
86 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, // Q 3
87 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, // Q 4
88 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 // Q 5
89 :     | PMV_HALFPELREFINE8,
90 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 // Q 6
91 :     | PMV_USESQUARES8 | PMV_USESQUARES16 | PMV_EARLYSTOP8 | PMV_HALFPELREFINE8
92 :     };
93 :    
94 :     int general_presets[7] = {
95 :     XVID_H263QUANT, /* or use XVID_MPEGQUANT */ // Q 0
96 :     XVID_H263QUANT, // Q 1
97 :     XVID_H263QUANT | XVID_HALFPEL, // Q 2
98 :     XVID_H263QUANT | XVID_HALFPEL, // Q 3
99 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, // Q 4
100 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, // Q 5
101 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V }; // Q 6
102 :    
103 :    
104 :     /* my default values for encoding */
105 :    
106 :     #define ABS_MAXFRAMENR 9999 // max number of frames
107 :    
108 :     int ARG_BITRATE=800;
109 :     int ARG_QUANTI=0;
110 :    
111 :     int ARG_QUALITY =6;
112 :     int ARG_MINQUANT=1;
113 :     int ARG_MAXQUANT=31;
114 :     float ARG_FRAMERATE=25.00;
115 :    
116 :     int ARG_MAX_BFRAMES=2;
117 :     int ARG_BQUANT_RATIO=200;
118 :     int NUMBUFFERS;
119 :    
120 :     int ARG_MAXFRAMENR=ABS_MAXFRAMENR;
121 :    
122 :    
123 :     #define MAX(A,B) ( ((A)>(B)) ? (A) : (B) )
124 :     #define SMALL_EPS 1e-10
125 :    
126 :     /* these are global variables. Not very elegant, but easy, and this is an easy program */
127 :    
128 :     int XDIM=0;
129 :     int YDIM=0; // will be set when reading first image
130 :     int i,filenr = 0;
131 :    
132 :     int save_m4v_flag = 0; // save MPEG4-bytestream?
133 :     int save_dec_flag = 1; // save decompressed bytestream?
134 :     int save_ref_flag = 0; //
135 :    
136 :     int pgmflag = 0; // a flag, if input is in PGM format, overwritten in init-phase
137 :     char filepath[256] = "./"; // the path where to save output
138 :    
139 :     void *enc_handle = NULL; // internal structures (handles) for encoding
140 :     void *dec_handle = NULL; // and decoding
141 :    
142 :    
143 :     /*********************************************************************/
144 :     /* "statistical" functions */
145 :     /* */
146 :     /* these are not needed for encoding or decoding, but for measuring */
147 :     /* time and quality, there in nothing specific to XviD in these */
148 :     /* */
149 :     /*********************************************************************/
150 :    
151 :     double msecond()
152 :     /* return the current time in seconds(!) */
153 :     {
154 :     struct timeval tv;
155 :     gettimeofday(&tv, 0);
156 :     return tv.tv_sec + tv.tv_usec * 1.0e-6;
157 :     }
158 :    
159 :    
160 :    
161 :     double absdistq(int x,int y, unsigned char* buf1, int stride1, unsigned char* buf2, int stride2)
162 :     /* returns the sum of squared distances (SSD) between two images of dimensions x times y */
163 :     {
164 :     double dist=0.;
165 :     int i,j,val;
166 :    
167 :     for (i=0;i<y;i++)
168 :     {
169 :     val=0;
170 :     for (j=0;j<x;j++)
171 :     val+= ((int)buf1[j]-(int)buf2[j])*((int)buf1[j]-(int)buf2[j]);
172 :    
173 :     dist += (double)val;
174 :     buf1 += stride1;
175 :     buf2 += stride2;
176 :     }
177 :     return dist/(x*y);
178 :     }
179 :    
180 :    
181 :     double PSNR(int x,int y, unsigned char* buf1, int stride1, unsigned char* buf2, int stride2 )
182 :     /* return the PSNR between to images */
183 :     /* this is a logarithmic measure for "quality" from the world of signal processing */
184 :     /* if you don't know what it is, simply accept that higher values are better */
185 :     {
186 :     return 10*(log10(255*255)-log10( absdistq(x, y, buf1, stride1, buf2, stride2) ));
187 :     }
188 :    
189 :    
190 :     /*********************************************************************/
191 :     /* input and output functions */
192 :     /* */
193 :     /* the are small and simple routines to read and write PGM and YUV */
194 :     /* image. It's just for convenience, again nothing specific to XviD */
195 :     /* */
196 :     /*********************************************************************/
197 :    
198 :     int read_pgmheader(FILE* handle)
199 :     {
200 :     int bytes,xsize,ysize,depth;
201 :     char dummy[2];
202 :    
203 :     bytes = fread(dummy,1,2,handle);
204 :    
205 :     if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' ))
206 :     return 1;
207 :     fscanf(handle,"%d %d %d",&xsize,&ysize,&depth);
208 :     if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) )
209 :     {
210 :     fprintf(stderr,"%d %d %d\n",xsize,ysize,depth);
211 :     return 2;
212 :     }
213 :     if ( (XDIM==0) || (YDIM==0) )
214 :     { XDIM=xsize;
215 :     YDIM=ysize;
216 :     }
217 :    
218 :     return 0;
219 :     }
220 :    
221 :     int read_pgmdata(FILE* handle, unsigned char *image)
222 :     {
223 :     int i,status;
224 :     char dummy;
225 :    
226 :     unsigned char* buff1_ptr2 = image + XDIM*YDIM;
227 :     unsigned char* buff1_ptr3 = image + XDIM*YDIM + XDIM/2*YDIM/2;
228 :    
229 :     fread(image,XDIM*YDIM,1,stdin); // read Y component of picture
230 :    
231 :     for (i=0;i<YDIM/2;i++)
232 :     {
233 :     fread(buff1_ptr2,XDIM/2,1,stdin); // read U
234 :     buff1_ptr2 += XDIM/2;
235 :     fread(buff1_ptr3,XDIM/2,1,stdin); // read V
236 :     buff1_ptr3 += XDIM/2;
237 :     }
238 :     fread(&dummy,1,1,handle); // I don't know why, but this seems needed
239 :     return 0;
240 :     }
241 :    
242 :     int read_yuvdata(FILE* handle, unsigned char *image)
243 :     { int i;
244 :     char dummy;
245 :    
246 :     unsigned char* buff1_ptr2 = image + XDIM*YDIM;
247 :     unsigned char* buff1_ptr3 = image + XDIM*YDIM + XDIM/2*YDIM/2;
248 :    
249 :     if (fread(image,XDIM,YDIM*3/2,stdin) != YDIM*3/2)
250 :     return 1;
251 :     else
252 :     return 0;
253 :     }
254 :    
255 :     int write_pgm(char *filename, unsigned char *image)
256 :     {
257 :     FILE *filehandle;
258 :     filehandle=fopen(filename,"wb");
259 :     if (filehandle)
260 :     {
261 :     fprintf(filehandle,"P5\n\n"); //
262 :     fprintf(filehandle,"%d %d 255\n",XDIM,YDIM*3/2);
263 :     fwrite(image,XDIM,YDIM*3/2,filehandle);
264 :     fclose(filehandle);
265 :     return 0;
266 :     }
267 :     else
268 :     return 1;
269 :     }
270 :    
271 :    
272 :    
273 :     /*********************************************************************/
274 :     /* Routines for encoding: init encoder, frame step, release encoder */
275 :     /*********************************************************************/
276 :    
277 :     #define FRAMERATE_INCR 1001
278 :    
279 :    
280 :     int enc_init(int use_assembler)
281 :     { /* initialize encoder for first use, pass all needed parameters to the codec */
282 :     int xerr;
283 :    
284 :     XVID_INIT_PARAM xinit;
285 :     XVID_ENC_PARAM xparam;
286 :    
287 :     if(use_assembler)
288 :    
289 :     #ifdef ARCH_IA64
290 :     xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
291 :     #else
292 :     xinit.cpu_flags = 0;
293 :     #endif
294 :    
295 :     else
296 :     xinit.cpu_flags = XVID_CPU_FORCE;
297 :    
298 :     xvid_init(NULL, 0, &xinit, NULL);
299 :    
300 :     xparam.width = XDIM;
301 :     xparam.height = YDIM;
302 :     if ((ARG_FRAMERATE - (int)ARG_FRAMERATE) < SMALL_EPS)
303 :     {
304 :     xparam.fincr = 1;
305 :     xparam.fbase = (int)ARG_FRAMERATE;
306 :     }
307 :     else
308 :     {
309 :     xparam.fincr = FRAMERATE_INCR;
310 :     xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE);
311 :     }
312 :     xparam.rc_reaction_delay_factor = 16;
313 :     xparam.rc_averaging_period = 100;
314 :     xparam.rc_buffer = 10;
315 :    
316 :     /* I use small values here, since we will not
317 :     encode whole movies, but short clips */
318 :    
319 :     xparam.rc_bitrate = ARG_BITRATE*1000;
320 :     xparam.min_quantizer = 1;
321 :     xparam.max_quantizer = 31;
322 :     xparam.max_key_interval = (int)ARG_FRAMERATE*10;
323 :    
324 :     xparam.global = XVID_GLOBAL_DX50BVOP;//XVID_GLOBAL_DEBUG; //XVID_GLOBAL_PACKED|XVID_GLOBAL_DX50BVOP;//|XVID_GLOBAL_DEBUG;
325 :     xparam.max_bframes = ARG_MAX_BFRAMES;
326 :     xparam.bquant_ratio = ARG_BQUANT_RATIO;
327 :    
328 :     xparam.frame_drop_ratio = 0;
329 :    
330 :     xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL);
331 :     enc_handle=xparam.handle;
332 :    
333 :     return xerr;
334 :     }
335 :    
336 :     int enc_stop()
337 :     { int xerr;
338 :    
339 :     xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);
340 :     return xerr;
341 :     }
342 :    
343 :     int enc_main(unsigned char* image, unsigned char* bitstream, int *streamlength, int* frametype)
344 :     { int xerr;
345 :    
346 :     XVID_ENC_FRAME xframe;
347 :     XVID_ENC_STATS xstats;
348 :    
349 :     xframe.bitstream = bitstream;
350 :     xframe.length = -1; // this is written by the routine
351 :    
352 :     xframe.image = image;
353 :     xframe.colorspace = XVID_CSP_YV12; // defined in <xvid.h>
354 :    
355 :     xframe.intra = -1; // let the codec decide between I-frame (1) and P-frame (0)
356 :    
357 :     xframe.quant = ARG_QUANTI; // if quant != 0, use a fixed quant (and ignore bitrate)
358 :     xframe.bquant = 0;
359 :    
360 :    
361 :     xframe.motion = motion_presets[ARG_QUALITY];
362 :     xframe.general = general_presets[ARG_QUALITY];
363 :     xframe.quant_intra_matrix = xframe.quant_inter_matrix = NULL;
364 :    
365 :     xerr = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xframe, &xstats);
366 :    
367 :     /* enc_result->is_key_frame = xframe.intra;
368 :     enc_result->quantizer = xframe.quant;
369 :     enc_result->total_bits = xframe.length * 8;
370 :     enc_result->motion_bits = xstats.hlength * 8;
371 :     enc_result->texture_bits = enc_result->total_bits - enc_result->motion_bits;
372 :     */
373 :    
374 :     /* This is statictical data, e.g. for 2-pass.
375 :     If you are not interested in any of this, you can use NULL instead of &xstats
376 :     */
377 :     *frametype = xframe.intra;
378 :     *streamlength = xframe.length;
379 :    
380 :     return xerr;
381 :     }
382 :    
383 :    
384 :     /*********************************************************************/
385 :     /* Routines for decoding: init encoder, frame step, release encoder */
386 :     /*********************************************************************/
387 :    
388 :     int dec_init(int use_assembler) /* init decoder before first run */
389 :     {
390 :     int xerr;
391 :    
392 :     XVID_INIT_PARAM xinit;
393 :     XVID_DEC_PARAM xparam;
394 :    
395 :     if(use_assembler)
396 :    
397 :     #ifdef ARCH_IA64
398 :     xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
399 :     #else
400 :     xinit.cpu_flags = 0;
401 :     #endif
402 :    
403 :     else
404 :     xinit.cpu_flags = XVID_CPU_FORCE;
405 :    
406 :     xvid_init(NULL, 0, &xinit, NULL);
407 :     xparam.width = XDIM;
408 :     xparam.height = YDIM;
409 :    
410 :     xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
411 :     dec_handle = xparam.handle;
412 :    
413 :     return xerr;
414 :     }
415 :    
416 :     int dec_main(unsigned char *m4v_buffer, unsigned char *out_buffer, int *m4v_size)
417 :     { /* decode one frame */
418 :    
419 :     int xerr;
420 :     XVID_DEC_FRAME xframe;
421 :    
422 :     xframe.bitstream = m4v_buffer;
423 :     xframe.length = 1234; // *m4v_size;
424 :     xframe.image = out_buffer;
425 :     xframe.stride = XDIM;
426 :     xframe.colorspace = XVID_CSP_YV12; // XVID_CSP_USER is fastest (no memcopy involved)
427 :    
428 :     xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, NULL);
429 :    
430 :     *m4v_size = xframe.length;
431 :     return xerr;
432 :     }
433 :    
434 :     int dec_stop() /* close decoder to release resources */
435 :     {
436 :     int xerr;
437 :     xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);
438 :    
439 :     return xerr;
440 :     }
441 :    
442 :    
443 :     /*********************************************************************/
444 :     /* Main program */
445 :     /*********************************************************************/
446 :    
447 :     int main(int argc, char *argv[])
448 :     {
449 :     unsigned char *divx_buffer = NULL;
450 :     unsigned char *divx_read = NULL;
451 :     unsigned char *divx_write = NULL;
452 :     unsigned char **in_buffer;
453 :     unsigned char *out_buffer = NULL;
454 :     unsigned char *divx_pos;
455 :    
456 :     int k;
457 :    
458 :     double enctime,dectime;
459 :     double totalenctime=0.;
460 :     double totaldectime=0.;
461 :    
462 :     long totalsize=0;
463 :     int status;
464 :    
465 :     int loop;
466 :     int m4v_size=0;
467 :     int enc_size=0;
468 :     int frame_type[ABS_MAXFRAMENR];
469 :     int Iframes=0, Pframes=0, Bframes=0, use_assembler=0;
470 :     double framepsnr[ABS_MAXFRAMENR];
471 :    
472 :     double Ipsnr=0.,Imaxpsnr=0.,Iminpsnr=999.,Ivarpsnr=0.;
473 :     double Ppsnr=0.,Pmaxpsnr=0.,Pminpsnr=999.,Pvarpsnr=0.;
474 :     double Bpsnr=0.,Bmaxpsnr=0.,Bminpsnr=999.,Bvarpsnr=0.;
475 :    
476 :     char filename[256];
477 :    
478 :     FILE *filehandle;
479 :    
480 :     /* read YUV in pgm format from stdin */
481 :     if (!pgmflag)
482 :     {
483 :     pgmflag = 1;
484 :    
485 :     if (argc==2 && !strcmp(argv[1],"-asm"))
486 :     use_assembler = 1;
487 :     if (argc>=3)
488 :     { XDIM = atoi(argv[1]);
489 :     YDIM = atoi(argv[2]);
490 :     if ( (XDIM <= 0) || (XDIM >= 2048) || (YDIM <=0) || (YDIM >= 2048) )
491 :     { fprintf(stderr,"Wrong frames size %d %d, trying PGM \n",XDIM, YDIM);
492 :     }
493 :     else
494 :     {
495 :     YDIM = YDIM*3/2; /* for YUV */
496 :     pgmflag = 0;
497 :     }
498 :     }
499 :     }
500 :    
501 :     if (pgmflag)
502 :     { if (read_pgmheader(stdin))
503 :     {
504 :     printf("Wrong input format, I want YUV encapsulated in PGM\n");
505 :     return 1;
506 :     }
507 :     }
508 :    
509 :     if (argc>=4)
510 :     { ARG_QUALITY = atoi(argv[3]);
511 :     if ( (ARG_QUALITY < 0) || (ARG_QUALITY > 6) )
512 :     { fprintf(stderr,"Wrong Quality\n"); return -1; }
513 :     else
514 :     printf("Quality %d\n",ARG_QUALITY);
515 :     }
516 :     if (argc>=5)
517 :     { ARG_BITRATE = atoi(argv[4]);
518 :     if ( (ARG_BITRATE <= 0) )
519 :     { fprintf(stderr,"Wrong Bitrate\n"); return -1; }
520 :     if ( (ARG_BITRATE <= 31) )
521 :     { ARG_QUANTI = ARG_BITRATE;
522 :     ARG_BITRATE=0;
523 :     printf("Quantizer %d\n",ARG_QUANTI);
524 :     }
525 :     else
526 :     printf("Bitrate %d kbps\n",ARG_BITRATE);
527 :     }
528 :     if (argc>=6)
529 :     { ARG_FRAMERATE = (float)atof(argv[5]);
530 :     if ( (ARG_FRAMERATE <= 0) )
531 :     { fprintf(stderr,"Wrong Fraterate %s \n",argv[5]); return -1; }
532 :     printf("Framerate %6.3f fps\n",ARG_FRAMERATE);
533 :     }
534 :    
535 :     if (argc>=7)
536 :     { ARG_MAXFRAMENR = atoi(argv[6]);
537 :     if ( (ARG_MAXFRAMENR <= 0) )
538 :     { fprintf(stderr,"Wrong number of frames\n"); return -1; }
539 :     printf("max. Framenr. %d\n",ARG_MAXFRAMENR);
540 :     }
541 :    
542 :     if (argc>=8)
543 :     { ARG_MAX_BFRAMES = atoi(argv[7]);
544 :     if ( (ARG_MAX_BFRAMES < -1) )
545 :     { fprintf(stderr,"Wrong number of bframes\n"); return -1; }
546 :     printf("max. B-Frames %d\n",ARG_MAX_BFRAMES);
547 :     }
548 :     NUMBUFFERS = ARG_MAX_BFRAMES+2;
549 :    
550 :     if (argc>=9)
551 :     { ARG_BQUANT_RATIO = atoi(argv[8]);
552 :     if ( (ARG_BQUANT_RATIO <= 0) )
553 :     { fprintf(stderr,"Wrong bquant ratio\n"); return -1; }
554 :     printf("bquant ratio %d\n",ARG_BQUANT_RATIO);
555 :     }
556 :    
557 :     /* now we know the sizes, so allocate memory */
558 :    
559 :     in_buffer = malloc( NUMBUFFERS*sizeof(unsigned char*) );
560 :     if (!in_buffer)
561 :     goto free_all_memory;
562 :    
563 :     for (k=0;k<NUMBUFFERS;k++)
564 :     in_buffer[k] = NULL;
565 :    
566 :     for (k=0;k<NUMBUFFERS;k++)
567 :     {
568 :     in_buffer[k] = (unsigned char *) malloc(XDIM*YDIM);
569 :     if (!in_buffer[k])
570 :     goto free_all_memory; // goto is one of the most underestimated instructions in C !!!
571 :     }
572 :    
573 :     #define DIVX_SIZE (XDIM*YDIM*200)
574 :     divx_buffer = (unsigned char *) malloc(2*DIVX_SIZE); // this should really be enough memory!
575 :     if (!divx_buffer)
576 :     goto free_all_memory;
577 :    
578 :     divx_write = divx_buffer;
579 :     divx_read = divx_buffer;
580 :    
581 :     YDIM = YDIM*2/3; // PGM is YUV 4:2:0 format, so real image height is *2/3 of PGM picture
582 :    
583 :     out_buffer = (unsigned char *) malloc(XDIM*YDIM*4);
584 :     if (!out_buffer)
585 :     goto free_all_memory;
586 :    
587 :    
588 :    
589 :    
590 :    
591 :     Iframes=0, Pframes=0, Bframes=0, use_assembler=1;
592 :     filenr=0;
593 :    
594 :     /*********************************************************************/
595 :     /* XviD PART Start */
596 :     /*********************************************************************/
597 :    
598 :    
599 :     status = enc_init(use_assembler);
600 :     if (status)
601 :     {
602 :     printf("Encore INIT problem, return value %d\n", status);
603 :     goto release_all;
604 :     }
605 :    
606 :     status = dec_init(use_assembler);
607 :     if (status)
608 :     {
609 :     printf("Decore INIT problem, return value %d\n", status);
610 :     goto release_all;
611 :     }
612 :    
613 :    
614 :     /*********************************************************************/
615 :     /* Main loop */
616 :     /*********************************************************************/
617 :    
618 :     do
619 :     {
620 :     if (pgmflag)
621 :     status = read_pgmdata(stdin, in_buffer[filenr%NUMBUFFERS]); // read PGM data (YUV-format)
622 :     else
623 :     status = read_yuvdata(stdin, in_buffer[filenr%NUMBUFFERS]); // read raw data (YUV-format)
624 :    
625 :     if (status)
626 :     {
627 :     // Couldn't read image, most likely end-of-file
628 :     continue;
629 :     }
630 :    
631 :    
632 :     if (save_ref_flag)
633 :     {
634 :     sprintf(filename, "%s%05d.pgm", filepath, filenr);
635 :     write_pgm(filename,in_buffer[filenr%NUMBUFFERS]);
636 :     }
637 :    
638 :    
639 :     /*********************************************************************/
640 :     /* analyse this frame before encoding */
641 :     /*********************************************************************/
642 :    
643 :     // nothing is done here at the moment, but you could e.g. create
644 :     // histograms or measure entropy or apply preprocessing filters...
645 :    
646 :     /*********************************************************************/
647 :     /* encode and decode this frame */
648 :     /*********************************************************************/
649 :    
650 :     enctime = -msecond();
651 :     status = enc_main(in_buffer[filenr%NUMBUFFERS], divx_write, &enc_size, &frame_type[filenr]);
652 :     enctime += msecond();
653 :    
654 :     if (status)
655 :     printf("Enc_main status: %d\n",status);
656 :     totalenctime += enctime;
657 :     totalsize += enc_size;
658 :    
659 :     printf("Frame %5d: intra %d, enctime =%6.1f ms length=%7d bytes \n",
660 :     filenr, frame_type[filenr], enctime*1000, enc_size);
661 :    
662 :     if (save_m4v_flag)
663 :     {
664 :     sprintf(filename, "%sframe%05d.m4v", filepath, filenr);
665 :     filehandle = fopen(filename, "wb");
666 :     fwrite(divx_write, enc_size, 1, filehandle);
667 :     fclose(filehandle);
668 :     }
669 :     divx_write += enc_size;
670 :     *divx_write=0; /* some kind of padding */
671 :     *(divx_write+1)=0;
672 :     *(divx_write+2)=0;
673 :     *(divx_write+3)=0;
674 :    
675 :     if (filenr<ARG_MAX_BFRAMES)
676 :     goto nextfile;
677 :    
678 :     do {
679 :     dectime = -msecond();
680 :     status = dec_main(divx_read, out_buffer, &m4v_size);
681 :     dectime += msecond();
682 :     divx_read += m4v_size;
683 :     printf("DecFrame %5d: length=%7d bytes (left: %7d)\n", filenr-(ARG_MAX_BFRAMES), m4v_size,
684 :     (divx_write-divx_read));
685 :    
686 :     } while (m4v_size<=7);
687 :    
688 :     if (status)
689 :     printf("dec_main Status =%d\n",status);
690 :     totaldectime += dectime;
691 :    
692 :     /*********************************************************************/
693 :     /* analyse the decoded frame and compare to original */
694 :     /*********************************************************************/
695 :    
696 :     if (filenr>ARG_MAX_BFRAMES) {
697 :     framepsnr[filenr-(ARG_MAX_BFRAMES+1)] = PSNR(XDIM,YDIM, in_buffer[(filenr-(ARG_MAX_BFRAMES+1))%NUMBUFFERS], XDIM, out_buffer, XDIM );
698 :    
699 :     printf("dectime =%6.1f ms PSNR %5.2f\n",dectime*1000, framepsnr[filenr-(ARG_MAX_BFRAMES+1)]);
700 :     }
701 :    
702 :     if (filenr>ARG_MAX_BFRAMES)
703 :     if (save_dec_flag)
704 :     {
705 :     sprintf(filename, "%sdec%05d.pgm", filepath, filenr-(ARG_MAX_BFRAMES+1));
706 :     write_pgm(filename,out_buffer);
707 :     }
708 :    
709 :     nextfile:
710 :    
711 :     filenr++;
712 :    
713 :     if ((int)(divx_read - divx_buffer) > DIVX_SIZE)
714 :     {
715 :     memmove(divx_buffer, divx_read, (int)(divx_buffer+2*DIVX_SIZE-divx_read));
716 :     divx_write -= (int)(divx_read-divx_buffer);
717 :     divx_read = divx_buffer;
718 :     fprintf(stderr,"DIVX-buffer copied\n");
719 :    
720 :     }
721 :    
722 :     if (pgmflag)
723 :     status = read_pgmheader(stdin); // because if this was the last PGM, stop now
724 :    
725 :     } while ( (!status) && (filenr<ARG_MAXFRAMENR) );
726 :    
727 :     printf("Status=%d filenr=%d\n",status,filenr);
728 :     filenr--;
729 :    
730 :    
731 :     /*********************************************************************/
732 :     /* calculate totals and averages for output, print results */
733 :     /*********************************************************************/
734 :    
735 :     if (filenr)
736 :     { totalsize /= filenr;
737 :     totalenctime /= filenr;
738 :     totaldectime /= filenr;
739 :     }
740 :    
741 :     for (i=0;i<filenr-(ARG_MAX_BFRAMES+1);i++)
742 :     {
743 :     switch (frame_type[i])
744 :     {
745 :     case 0:
746 :     Pframes++;
747 :     Ppsnr += framepsnr[i];
748 :     break;
749 :     case 1:
750 :     Iframes++;
751 :     Ipsnr += framepsnr[i];
752 :     break;
753 :     case 2:
754 :     default:
755 :     Bframes++;
756 :     Bpsnr += framepsnr[i];
757 :     break;
758 :     }
759 :     }
760 :    
761 :     if (Pframes)
762 :     Ppsnr /= Pframes;
763 :     if (Iframes)
764 :     Ipsnr /= Iframes;
765 :     if (Bframes)
766 :     Bpsnr /= Bframes;
767 :    
768 :    
769 :     for (i=0;i<filenr-(ARG_MAX_BFRAMES+1);i++) // calculate statistics for every frametype: P,I (and B)
770 :     {
771 :     switch (frame_type[i])
772 :     {
773 :     case 0:
774 :     if (framepsnr[i] > Pmaxpsnr)
775 :     Pmaxpsnr = framepsnr[i];
776 :     if (framepsnr[i] < Pminpsnr)
777 :     Pminpsnr = framepsnr[i];
778 :     Pvarpsnr += (framepsnr[i] - Ppsnr)*(framepsnr[i] - Ppsnr) /Pframes;
779 :     break;
780 :     case 1:
781 :     if (framepsnr[i] > Imaxpsnr)
782 :     Imaxpsnr = framepsnr[i];
783 :     if (framepsnr[i] < Pminpsnr)
784 :     Iminpsnr = framepsnr[i];
785 :     Ivarpsnr += (framepsnr[i] - Ipsnr)*(framepsnr[i] - Ipsnr) /Iframes;
786 :     break;
787 :     case 2:
788 :     if (framepsnr[i] > Bmaxpsnr)
789 :     Bmaxpsnr = framepsnr[i];
790 :     if (framepsnr[i] < Pminpsnr)
791 :     Bminpsnr = framepsnr[i];
792 :     Bvarpsnr += (framepsnr[i] - Bpsnr)*(framepsnr[i] - Bpsnr) /Bframes;
793 :     break;
794 :     }
795 :     }
796 :    
797 :     printf("Avg. Q%1d %2s ",ARG_QUALITY, (ARG_QUANTI ? " q" : "br"));
798 :     printf("%04d ",MAX(ARG_QUANTI,ARG_BITRATE));
799 :     printf("mbf %01d ",ARG_MAX_BFRAMES);
800 :     printf("bqr %03d ",ARG_MAX_BFRAMES>0 ? ARG_BQUANT_RATIO : 0);
801 :     printf("( %.3f bpp) ", (double)ARG_BITRATE*1000/XDIM/YDIM/ARG_FRAMERATE);
802 :     printf("size %6d ",totalsize);
803 :     printf("( %4d kbps ",(int)(totalsize*8*ARG_FRAMERATE/1000));
804 :     printf("/ %.3f bpp) ",(double)totalsize*8/XDIM/YDIM);
805 :     printf("enc: %6.1f fps, dec: %6.1f fps ",1/totalenctime, 1/totaldectime);
806 :     printf("PSNR P(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Pframes,Ppsnr,Pminpsnr,Pmaxpsnr,sqrt(Pvarpsnr/filenr));
807 :     printf("I(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Iframes,Ipsnr,Iminpsnr,Imaxpsnr,sqrt(Ivarpsnr/filenr));
808 :     if (Bframes)
809 :     printf("B(%d): %5.2f ( %5.2f , %5.2f ; %5.4f ) ",Bframes,Bpsnr,Bminpsnr,Bmaxpsnr,sqrt(Bvarpsnr/filenr));
810 :     printf("\n");
811 :    
812 :     /*********************************************************************/
813 :     /* XviD PART Stop */
814 :     /*********************************************************************/
815 :    
816 :     release_all:
817 :    
818 :     if (enc_handle)
819 :     {
820 :     status = enc_stop();
821 :     if (status)
822 :     printf("Encore RELEASE problem return value %d\n", status);
823 :     }
824 :    
825 :     if (dec_handle)
826 :     {
827 :     status = dec_stop();
828 :     if (status)
829 :     printf("Decore RELEASE problem return value %d\n", status);
830 :     }
831 :    
832 :    
833 :     free_all_memory:
834 :     free(out_buffer);
835 :     free(divx_buffer);
836 :     if (in_buffer)
837 :     for (k=0;k<NUMBUFFERS;k++)
838 :     free(in_buffer[k]);
839 :    
840 :     return 0;
841 :     }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4