[cvs] / xvidcore / examples / xvid_bstat.c Repository:
ViewVC logotype

Diff of /xvidcore/examples/xvid_bstat.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Sun Sep 29 16:38:06 2002 UTC revision 1.1.2.1, Sun Sep 29 16:38:06 2002 UTC
# Line 0  Line 1 
1    /**************************************************************************
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    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.1

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