home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / mpeg_stat-2.2 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  16.8 KB  |  588 lines

  1. /* MPEGSTAT - analyzing tool for MPEG-I video streams
  2.  * Most recently by Steve Smoot (see man page for history)
  3.  *
  4.  *  Copyright (c) 1995 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * Tcl interface by Keving Gong
  8.  *
  9.  * Copyright (c) 1995 The Regents of the University of California.
  10.  * 
  11.  * Technical University of Berlin, Germany, Dept. of Computer Science
  12.  * Tom Pfeifer - Multimedia systems project - pfeifer@fokus.gmd.de
  13.  *
  14.  * Jens Brettin, Harald Masche, Alexander Schulze, Dirk Schubert
  15.  *
  16.  * This program uses parts of the source code of the Berkeley MPEG player
  17.  *
  18.  * ---------------------------
  19.  *
  20.  * Copyright (c) 1993 Technical University of Berlin, Germany
  21.  *
  22.  * for the parts of the Berkeley player used:
  23.  *
  24.  * Copyright (c) 1992 The Regents of the University of California.
  25.  * All rights reserved.
  26.  *
  27.  * ---------------------------
  28.  *
  29.  * Permission to use, copy, modify, and distribute this software and its
  30.  * documentation for any purpose, without fee, and without written agreement is
  31.  * hereby granted, provided that the above copyright notices and the following
  32.  * two paragraphs appear in all copies of this software.
  33.  * 
  34.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA 
  35.  * or the Technical University of Berlin BE LIABLE TO ANY PARTY FOR
  36.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  37.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  38.  * CALIFORNIA or the Technical University of Berlin HAS BEEN ADVISED OF THE 
  39.  * POSSIBILITY OF SUCH DAMAGE.
  40.  * 
  41.  * THE UNIVERSITY OF CALIFORNIA and the Technical University of Berlin 
  42.  * SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  43.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  44.  * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE 
  45.  * UNIVERSITY OF CALIFORNIA and the Technical University of Berlin HAVE NO 
  46.  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 
  47.  * OR MODIFICATIONS.
  48.  */
  49.  
  50. /* MAIN.C CHANGED FOR MPEG ANALYZER, 1993 */
  51.  
  52. #include "video.h"
  53. #include "proto.h"
  54. #include <sys/types.h>
  55. #include <signal.h>
  56. #include <string.h>
  57. #include <stdlib.h>
  58. #include <netinet/in.h>
  59.  
  60. #include "util.h"
  61. #include "opts.h"
  62.  
  63. /* VERSION */
  64. #define VERSION "2.2"
  65.  
  66. /* Define buffer length. */
  67.  
  68. #define BUF_LENGTH 80000
  69.  
  70. /* External declaration of main decoding call. */
  71.  
  72. extern VidStream *mpegVidRsrc();
  73. extern VidStream *NewVidStream();
  74.  
  75. /* Declaration of global variable to hold dither info. */
  76.  
  77. int ditherType;
  78.  
  79. /* Global file pointer to incoming data. */
  80. FILE *input;
  81.  
  82. /* more global objects */
  83.  
  84. int LUM_RANGE;
  85. int CR_RANGE;
  86. int CB_RANGE;
  87.  
  88. int *lum_values;
  89. int *cr_values;
  90. int *cb_values;
  91.  
  92. /* global options state */
  93. int opts=LOUD;
  94. int start_opt=-1;
  95. int end_opt=-1;
  96. int rate_frames=0;
  97. int COLLECTING;
  98. FILE *block_fp;
  99. FILE *qscale_fp;
  100. FILE *size_fp;
  101. FILE *offs_fp;
  102. FILE *rate_fp;
  103. FILE *syslogOutput;
  104. FILE *hist_fp;
  105. FILE *userdat_fp;
  106.  
  107. /* End of File flag. */
  108. int EOF_flag = 0;
  109.  
  110. /* The video stream */
  111. static VidStream *theStream;
  112.  
  113. /*
  114.  *--------------------------------------------------------------
  115.  *
  116.  * int_handler --
  117.  *
  118.  *    Handles Cntl-C interupts..
  119.  *      (Two copies, to handle different signal types)
  120.  *
  121.  * Results:
  122.  *    None.
  123.  *
  124.  * Side effects:
  125.  *    None.
  126.  *
  127.  *--------------------------------------------------------------
  128.  */
  129. #ifndef SIG_ONE_PARAM
  130. void int_quit(){exit(1);}
  131. void
  132. int_handler()
  133. {
  134.   fprintf(stderr,"\nBreak!\n");
  135.   signal(SIGINT, int_quit);
  136.   /* If we havent done much, just exit */
  137.   if ((theStream==NULL) || (theStream->past == NULL)) exit(1);
  138.   fprintf(stderr,"Warning, some stats may not make sense with incomplete data!\n");
  139.   PrintAllStats();
  140.   if (curVidStream != NULL)
  141.     DestroyVidStream(curVidStream);
  142.   exit(1);
  143. }
  144. #else
  145. void int_quit(signum)int signum;{exit(1);}
  146. void int_handler(signum)
  147. int signum;
  148. {
  149.   fprintf(stderr,"\nBreak!\n");
  150.   signal(SIGINT, int_quit);
  151.   /* If we havent done much, just exit */
  152.   if ((theStream==NULL) || (theStream->past == NULL)) exit(1);
  153.   fprintf(stderr,"Warning, some stats may not make sense with incomplete data!\n");
  154.   PrintAllStats();
  155.   if (curVidStream != NULL)
  156.     DestroyVidStream(curVidStream);
  157.   exit(1);
  158. }
  159. #endif
  160.  
  161. /*
  162.  *--------------------------------------------------------------
  163.  *
  164.  * main --
  165.  *
  166.  *    Parses command line, starts decoding and displaying.
  167.  *
  168.  * Results:
  169.  *    None.
  170.  *
  171.  * Side effects:
  172.  *    None.
  173.  *
  174.  *--------------------------------------------------------------
  175.  */
  176.  
  177. void
  178. main(argc, argv)
  179.      int argc;
  180.      char **argv;
  181. {
  182.  
  183.   char *name;
  184.   char tmpstr[256];
  185.   int mark=1;
  186.   int i,index;
  187.  
  188.   input = stdin;
  189.   name = "<stdin>";
  190.   ditherType = ORDERED2_DITHER;
  191.   LUM_RANGE = 8;
  192.   CR_RANGE = CB_RANGE = 4;
  193.  
  194.   printf("\n%s -- MPEG Analyzer for MPEG I video streams (version %s)\n\n", 
  195.      argv[0],VERSION);
  196.   if (argc == 1) {
  197.     name = "<stdin>";
  198.     input = stdin;
  199.       }
  200.   else if (argc==2) {
  201.     if (strcmp(argv[1],"-") == 0) {
  202.       input = stdin;
  203.       name = "<stdin>";
  204.     } else {
  205.       input = fopen(argv[1], "r");
  206.       if (input == NULL) {
  207.     if (strcmp(argv[1],"-?") == 0 ||  strcmp(argv[1],"-help") == 0) {
  208.         Usage();
  209.       } else {
  210.         fprintf(stderr, "Could not open MPEG file %s\n", argv[1]);
  211.         Usage();
  212.       }
  213.       }
  214.       name = argv[1];
  215.     }
  216.   } else {
  217.     index = 1;
  218.     while (index<argc) {
  219.       BOOLEAN match;
  220.  
  221.       match=FALSE;
  222.  
  223.       if ( strncmp(argv[index], "-block_info",6) == 0 ) {
  224.     match = TRUE;
  225.     if (strcmp(argv[index+1],"-") == 0) {
  226.       printf("Writing block information to <stdout>\n");
  227.       block_fp=stdout;
  228.     } else if ((block_fp=fopen(argv[index+1],"w"))==NULL) {
  229.       fprintf(stderr,"Could not open block info file:  %s\n",argv[index+1]);
  230.       Usage();
  231.     } else {      
  232.       printf("Writing block information to %s\n",argv[index+1]);
  233.     }
  234.     opts ^= BLOCK_INFO;
  235.     index+=2; continue;
  236.       }
  237.       if ( strncmp(argv[index], "-qscale",5) == 0 ) {
  238.     match = TRUE;
  239.     if (strcmp(argv[index+1],"-") == 0) {
  240.     qscale_fp=stdout;
  241.     printf("Writing qscale information to <stdout>\n");
  242.     } else if ((qscale_fp=fopen(argv[index+1],"w"))==NULL) {
  243.       fprintf(stderr,"Could not open qscale output file:  %s\n",argv[index+1]);
  244.       Usage();
  245.     }  else {      
  246.       printf("Writing qscale information to %s\n",argv[index+1]);
  247.     }
  248.     opts ^= QSCALE_INFO;
  249.     index+=2; continue;
  250.       }
  251.       if ( strncmp(argv[index], "-userdat", 8) == 0 ) {
  252.     match = TRUE;
  253.     if (strcmp(argv[index+1],"-") == 0) {
  254.     userdat_fp = stdout;
  255.     printf("Writing user data information to <stdout>\n");
  256.     } else if ((userdat_fp = fopen(argv[index+1],"w"))==NULL) {
  257.       fprintf(stderr,"Could not open user data output file:  %s\n",argv[index+1]);
  258.       Usage();
  259.     }  else {      
  260.       printf("Writing user data information to %s\n",argv[index+1]);
  261.     }
  262.     opts ^= USERDAT_INFO;
  263.     index+=2; continue;
  264.       }
  265.       if ( strncmp(argv[index], "-offsets",7) == 0 ) {
  266.     match = TRUE;
  267.     if (strcmp(argv[index+1],"-") == 0) {
  268.     offs_fp=stdout;
  269.     printf("Writing offset information to <stdout>\n");
  270.     } else if ((offs_fp=fopen(argv[index+1],"w"))==NULL) {
  271.       fprintf(stderr,"Could not open offset output file:  %s\n",argv[index+1]);
  272.       Usage();
  273.     }  else {      
  274.       printf("Writing offset information to %s\n",argv[index+1]);
  275.     }
  276.     opts ^= OFFS_INFO;
  277.     index+=2; continue;
  278.       }
  279.       if ( strncmp(argv[index], "-size",5) == 0 ) {
  280.     match = TRUE;
  281.     if (strcmp(argv[index+1],"-") == 0) {
  282.       size_fp=stdout;
  283.       printf("Writing size information to <stdout>\n");
  284.     } else if ((size_fp=fopen(argv[index+1],"w"))==NULL) {
  285.       fprintf(stderr,"Could not open size output file:  %s\n",argv[index+1]);
  286.       Usage();
  287.     }  else {      
  288.       printf("Writing size information to %s\n",argv[index+1]);
  289.     }
  290.     opts ^= SIZE_INFO;
  291.     index+=2; continue;
  292.       }
  293.       if (strncmp(argv[index],"-ratelength",6) == 0) {
  294.     match = TRUE;
  295.     opts^=RATE_LENGTH_SET; 
  296.     rate_frames = atoi(argv[index+1]);
  297.     if (rate_frames == 0) Usage();
  298.     index+=2; continue;
  299.       }
  300.       if ( strncmp(argv[index], "-rate",5) == 0 ) {
  301.     match = TRUE;
  302.     if (strcmp(argv[index+1],"-") == 0) {
  303.       rate_fp=stdout;
  304.       printf("Writing rate information to <stdout>\n");
  305.     } else if ((rate_fp=fopen(argv[index+1],"w"))==NULL) {
  306.       fprintf(stderr,"Could not open rate output file:  %s\n",argv[index+1]);
  307.       Usage();
  308.     }  else {      
  309.       printf("Writing rate information to %s\n",argv[index+1]);
  310.     }
  311.     opts ^= RATE_INFO;
  312.     index+=2; continue;
  313.       }
  314.       if ( strncmp(argv[index], "-hist",5) == 0 ) {
  315.     match = TRUE;
  316.     if (strcmp(argv[index+1],"-") == 0) {
  317.       hist_fp=stdout;
  318.       printf("Writing histogram information to <stdout>\n");
  319.     } else if ((hist_fp=fopen(argv[index+1],"w"))==NULL) {
  320.       fprintf(stderr,"Could not open histogram output file:  %s\n",argv[index+1]);
  321.       Usage();
  322.     }  else {      
  323.       printf("Writing histogram information to %s\n",argv[index+1]);
  324.     }
  325.     opts ^= HIST_INFO;
  326.     index+=2; continue;
  327.       }
  328.       if ( strncmp(argv[index], "-syslog",7) == 0 ) {
  329.     match = TRUE;
  330.     if (strcmp(argv[index+1],"-") == 0) {
  331.       syslogOutput=stdout;
  332.       printf("Writing system layer information to <stdout>\n");
  333.     } else if ((syslogOutput=fopen(argv[index+1],"w"))==NULL) {
  334.       fprintf(stderr,"Could not open system layer output file:  %s\n",argv[index+1]);
  335.       Usage();
  336.     }  else {      
  337.       printf("Writing system layer information to %s\n",argv[index+1]);
  338.     }
  339.     opts ^= SYSLAYER_LOG;
  340.     index+=2; continue;
  341.       }
  342.       if ( strcmp(argv[index], "-all") == 0 ) {
  343.     match = TRUE;
  344.     if (strcmp(argv[index+1],"-") == 0) {
  345.       printf("Writing all information to <stdout>\n");
  346.       printf("Writing qscale information to <stdout>\n");
  347.       printf("Writing offset information to <stdout>\n");
  348.       printf("Writing size information to <stdout>\n");
  349.       printf("Writing rate information to <stdout>\n");
  350.       printf("Writing histogram information to <stdout>\n");
  351.       printf("Writing user data information to <stdout>\n");
  352.       offs_fp = stdout;
  353.       size_fp = stdout;
  354.       block_fp = stdout;
  355.       qscale_fp = stdout;
  356.       rate_fp = stdout;
  357.       hist_fp = stdout;
  358.       userdat_fp = stdout;
  359.       index++;
  360.     } else {
  361.       index++;
  362.       sprintf(tmpstr,"%s.blk",argv[index]);
  363.       if ((block_fp=fopen(tmpstr,"w")) == NULL) {
  364.         fprintf(stderr,"Could not open block info file:  %s\n",tmpstr);
  365.         Usage();
  366.       } else {      
  367.         printf("Writing block information to %s\n",tmpstr);
  368.       }
  369.       sprintf(tmpstr,"%s.qs",argv[index]);
  370.       if ((qscale_fp=fopen(tmpstr,"w")) == NULL) {
  371.         fprintf(stderr,"Could not open qscale output file:  %s\n",tmpstr);
  372.         Usage();
  373.       }  else {      
  374.         printf("Writing qscale information to %s\n",tmpstr);
  375.       }
  376.       sprintf(tmpstr,"%s.off",argv[index]);
  377.       if ((offs_fp=fopen(tmpstr,"w"))==NULL) {
  378.         fprintf(stderr,"Could not open offset output file:  %s\n",tmpstr);
  379.         Usage();
  380.       }  else {      
  381.         printf("Writing offset information to %s\n",tmpstr);
  382.       }
  383.       sprintf(tmpstr,"%s.sz",argv[index]);
  384.       if ((size_fp=fopen(tmpstr,"w"))==NULL) {
  385.         fprintf(stderr,"Could not open size output file:  %s\n",tmpstr);
  386.         Usage();
  387.       }  else {      
  388.         printf("Writing size information to %s\n",tmpstr);
  389.       }
  390.       sprintf(tmpstr,"%s.hist",argv[index]);
  391.       if ((hist_fp=fopen(tmpstr,"w"))==NULL) {
  392.         fprintf(stderr,"Could not open histogram output file:  %s\n",tmpstr);
  393.         Usage();
  394.       }  else {      
  395.         printf("Writing histogram information to %s\n",tmpstr);
  396.       }
  397.       sprintf(tmpstr,"%s.ud",argv[index]);
  398.       if ((hist_fp=fopen(tmpstr,"w"))==NULL) {
  399.         fprintf(stderr,"Could not open user data output file:  %s\n",tmpstr);
  400.         Usage();
  401.       }  else {      
  402.         printf("Writing user data information to %s\n",tmpstr);
  403.       }
  404.       sprintf(tmpstr,"%s.rt",argv[index]);
  405.       if ((rate_fp=fopen(tmpstr,"w"))==NULL) {
  406.         fprintf(stderr,"Could not open rate output file:  %s\n",tmpstr);
  407.         Usage();
  408.       }  else {      
  409.         printf("Writing rate information to %s\n",tmpstr);
  410.       }
  411.     }
  412.     index++;
  413.     opts ^= SIZE_INFO;
  414.     opts ^= QSCALE_INFO;
  415.     opts ^= BLOCK_INFO;
  416.     opts ^= OFFS_INFO;
  417.     opts ^= RATE_INFO;
  418.     opts ^= HIST_INFO;
  419.     opts ^= USERDAT_INFO;
  420.     continue;
  421.       }
  422.       
  423.       if (strcmp(argv[index],"-quiet") == 0) {
  424.     match = TRUE;
  425.     opts ^= LOUD;
  426.     index++; continue;
  427.       }
  428.       if (strcmp(argv[index],"-dct") == 0) {
  429.     match = TRUE;
  430.     opts ^= DCT_INFO;
  431.     index++; continue;
  432.       }
  433.       if (strncmp(argv[index],"-verif",6) == 0) {
  434.     match = TRUE;
  435.     opts ^= VERIFY;
  436.     index++; continue;
  437.       }
  438.       if (strcmp(argv[index],"-time") == 0) {
  439.     match = TRUE;
  440.     opts ^= TIME_MEASURE;
  441.     index++; continue;
  442.       }
  443.       if (strcmp(argv[index],"-start") == 0) {
  444.     match = TRUE;
  445.     opts^=START_F; 
  446.     start_opt = atoi(argv[index+1]);
  447.     if (start_opt == 0) Usage();
  448.     index+=2; continue;
  449.       }
  450.       if (strcmp(argv[index],"-end") == 0) {
  451.     match = TRUE;
  452.     opts ^= END_F; 
  453.     end_opt = atoi(argv[index+1]);
  454.     if (end_opt == 0) Usage();
  455.     index+=2; continue;
  456.       }
  457.       if (index == argc-1) {
  458.     match = TRUE;
  459.     if (strcmp(argv[index],"-") == 0) {
  460.       input = stdin;
  461.       name = "<stdin>";
  462.       index++;
  463.     } else {
  464.       input = fopen(argv[index], "r");
  465.       name = argv[index];
  466.       if (input == NULL) {
  467.         fprintf(stderr, "Could not open MPEG file:  %s\n", argv[index]);
  468.         Usage();
  469.       }
  470.       index++;
  471.     }} else {
  472.       input = stdin;
  473.       name = "<stdin>";
  474.     }
  475.       if (!match) {
  476.     fprintf(stderr,"Invalid argument %s\n",argv[index]);
  477.     Usage();
  478.       }
  479.     }}
  480.  
  481.   /* Check options for sanity */
  482.   if ((opts&END_F) && (end_opt<start_opt)) Usage();
  483.   if (start_opt<=1) COLLECTING=COLLECT_ON;
  484.   else COLLECTING=COLLECT_OFF;
  485.  
  486.   if ((RATE_LENGTH_SET&opts) && !(opts&RATE_INFO)){
  487.     fprintf(stderr,"You set ratelength, but no rate file.\n");
  488.     fprintf(stderr,"Tossing rate information, hope thats ok.\n");
  489.     opts^=RATE_INFO;
  490.     rate_fp=fopen("/dev/null","w");
  491.   }
  492.  
  493.   if ((opts&DCT_INFO) & !(opts&BLOCK_INFO)) {
  494.     fprintf(stderr, "DCT information is collected into Block file\n");
  495.     fprintf(stderr, "So -dct requires -block_info file (or -all file)\n");
  496.     exit(1);
  497.   }
  498.  
  499.   /* Ok, done parsing, lets go! */
  500.   
  501.   printf("Reading %s\n\n", name);
  502.  
  503.   if ((opts&START_F) || (opts&END_F)) {
  504.     sprintf(tmpstr,"output from %s (%d to ",
  505.         name,(start_opt>0)?start_opt:1);
  506.     if (end_opt>0) {sprintf(tmpstr,"%s%d) */\n",strdup(tmpstr),end_opt);}
  507.     else sprintf(tmpstr,"%send */\n",tmpstr);
  508.   } else {sprintf(tmpstr,"output from %s */\n",name);}
  509.  
  510.   if (opts&SIZE_INFO)   fprintf(size_fp,"/* Size file %s",tmpstr);
  511.   if (opts&QSCALE_INFO) fprintf(qscale_fp,"/* Qscale file %s",tmpstr);
  512.   if (opts&BLOCK_INFO)  fprintf(block_fp,"/* Block file %s",tmpstr);
  513.   if (opts&OFFS_INFO)   fprintf(offs_fp,"/* Offset file %s",tmpstr);
  514.   if (opts&USERDAT_INFO) fprintf(userdat_fp,"/* User data file %s",tmpstr);
  515.   if (opts&RATE_INFO)   fprintf(rate_fp,"/* Rate file %s",tmpstr); /*HI*/
  516.     
  517.   if ((opts&START_F) || (opts&END_F)) {
  518.     printf("Collecting statistics from frame %d to ",(start_opt>0)?start_opt:1);
  519.     if (end_opt>0) {printf("%d.\n",end_opt);} else {printf("end.\n");}
  520.   }
  521.   
  522.   if (opts&SIZE_INFO) fprintf(size_fp,"Num\tType\tSize\n");
  523.   lum_values = (int *) malloc(LUM_RANGE*sizeof(int));
  524.   cr_values = (int *) malloc(CR_RANGE*sizeof(int));
  525.   cb_values = (int *) malloc(CB_RANGE*sizeof(int));
  526.  
  527.   signal(SIGINT, int_handler);
  528.  
  529.   init_tables();
  530.   
  531.   EOF_flag = 0;
  532.   curBits = 0;
  533.   bitOffset = 0;
  534.   bufLength = 0;
  535.   bitBuffer = NULL;
  536.   totNumFrames = 0;
  537.  
  538.   theStream = NewVidStream(BUF_LENGTH);
  539.   if (theStream==NULL) {
  540.     fprintf(stderr,"Could not create Video Stream Object!\n");
  541.     exit(1);
  542.   }
  543.  
  544.   realTimeStart = ReadSysClock();
  545.   mpegVidRsrc(0, theStream);
  546. }
  547.  
  548.  
  549. /*
  550.  *--------------------------------------------------------------
  551.  *
  552.  * Usage --
  553.  *
  554.  *    Gives message describing options
  555.  *
  556.  * Results:
  557.  *    None.
  558.  *
  559.  * Side effects:
  560.  *    None.
  561.  *
  562.  *--------------------------------------------------------------
  563.  */
  564. void
  565. Usage()
  566. {
  567.     fprintf(stderr, "\nUsage:  mpeg_stat [options] [mpeg_file]\n");
  568.     fprintf(stderr, "Options:\n");
  569.     fprintf(stderr, "  -quiet: \t\t Turn off output of frame types/matricies as encountered\n");
  570.     fprintf(stderr, "  -verify: \t\t Do more work to help assure the validity of the stream\n\t\t\t (slows processing somewhat)\n");
  571.     fprintf(stderr, "  -start N: \t\t Begin collection at frame N (first frame is 1)\n");
  572.     fprintf(stderr, "  -end N: \t\t End collection at frame N (end >= start)\n");
  573.     fprintf(stderr, "  -histogram file:\t Put detailed histograms into file\n");
  574.     fprintf(stderr, "  -qscale file: \t Put qscale information into file\n");
  575.     fprintf(stderr, "  -size file: \t\t Write individual frame type and size into file\n");
  576.     fprintf(stderr, "  -offsets file: \t Write high level header offsets into file\n");
  577.     fprintf(stderr, "  -block_info file:\t Put macroblock usage into file\n");
  578.     fprintf(stderr, "  -dct \t\t\t Puts decoded DCT info into block file\n");
  579.     fprintf(stderr, "  -rate file: \t\t Put instantaneous rate information in file\n");
  580.     fprintf(stderr, "  -ratelength N: \t Measure bitrate per N frames, not one second's worth\n");
  581.     fprintf(stderr, "  -syslog file: \t Store parsing of systerm layer into file\n");
  582.     fprintf(stderr, "  -userdata file: \t Store user data information into file\n");
  583.     fprintf(stderr, "  -time: \t\t Measure time to decode frames\n");
  584.     fprintf(stderr, "  -all file: \t\t Put all information into files with basename file\n");
  585.     fprintf(stderr, "\nA single dash (-) may be used to denote standard in/out in place of a filename.\n");
  586.     exit(1);
  587. }
  588.