configfile.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:18k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  ***********************************************************************
  34.  * file
  35.  *    configfile.c
  36.  * brief
  37.  *    Configuration handling.
  38.  * author
  39.  *  Main contributors (see contributors.h for copyright, address and affiliation details)
  40.  *    - Stephan Wenger           <stewe@cs.tu-berlin.de>
  41.  * note
  42.  *    In the future this module should hide the Parameters and offer only
  43.  *    Functions for their access.  Modules which make frequent use of some parameters
  44.  *    (e.g. picture size in macroblocks) are free to buffer them on local variables.
  45.  *    This will not only avoid global variable and make the code more readable, but also
  46.  *    speed it up.  It will also greatly facilitate future enhancements such as the
  47.  *    handling of different picture sizes in the same sequence.                         n
  48.  *                                                                                      n
  49.  *    For now, everything is just copied to the inp_par structure (gulp)
  50.  *
  51.  **************************************************************************************
  52.  * par New configuration File Format
  53.  **************************************************************************************
  54.  * Format is line oriented, maximum of one parameter per line                           n
  55.  *                                                                                      n
  56.  * Lines have the following format:                                                     n
  57.  * <ParameterName> = <ParameterValue> # Comments \n                                    n
  58.  * Whitespace is space and \t
  59.  * par
  60.  * <ParameterName> are the predefined names for Parameters and are case sensitive.
  61.  *   See configfile.h for the definition of those names and their mapping to
  62.  *   configinput->values.
  63.  * par
  64.  * <ParameterValue> are either integers [0..9]* or strings.
  65.  *   Integers must fit into the wordlengths, signed values are generally assumed.
  66.  *   Strings containing no whitespace characters can be used directly.  Strings containing
  67.  *   whitespace characters are to be inclosed in double quotes ("string with whitespace")
  68.  *   The double quote character is forbidden (may want to implement something smarter here).
  69.  * par
  70.  * Any Parameters whose ParameterName is undefined lead to the termination of the program
  71.  * with an error message.
  72.  *
  73.  * par Known bug/Shortcoming:
  74.  *    zero-length strings (i.e. to signal an non-existing file
  75.  *    have to be coded as "".
  76.  *
  77.  * par Rules for using command files
  78.  *                                                                                      n
  79.  * All Parameters are initially taken from DEFAULTCONFIGFILENAME, defined in configfile.h.
  80.  * If an -f <config> parameter is present in the command line then this file is used to
  81.  * update the defaults of DEFAULTCONFIGFILENAME.  There can be more than one -f parameters
  82.  * present.  If -p <ParameterName = ParameterValue> parameters are present then these
  83.  * overide the default and the additional config file's settings, and are themselfes
  84.  * overridden by future -p parameters.  There must be whitespace between -f and -p commands
  85.  * and their respecitive parameters
  86.  ***********************************************************************
  87.  */
  88. #define INCLUDED_BY_CONFIGFILE_C
  89. #include <stdio.h>
  90. #include <stdlib.h>
  91. #include <string.h>
  92. #include <assert.h>
  93. #include "global.h"
  94. #include "configfile.h"
  95. static char *GetConfigFileContent (char *Filename);
  96. static void ParseContent (char *buf, int bufsize);
  97. static int ParameterNameToMapIndex (char *s);
  98. static void PatchInp ();
  99. #define MAX_ITEMS_TO_PARSE  10000
  100. /*!
  101.  ***********************************************************************
  102.  * brief
  103.  *    Parse the command line parameters and read the config files.
  104.  * param ac
  105.  *    number of command line parameters
  106.  * param av
  107.  *    command line parameters
  108.  ***********************************************************************
  109.  */
  110. void Configure (int ac, char *av[])
  111. {
  112.   char *content;
  113.   int CLcount, ContentLen, NumberParams;
  114.   memset (&configinput, 0, sizeof (InputParameters));
  115. #ifdef H26L_LIB
  116.   if (ac > 0) {
  117.     ParseContent (av[0], strlen(av[0]));
  118.   } else {
  119.     printf("Warning: no configuration givenn");
  120.   }
  121. #else
  122.   // Process default config file
  123.   printf ("Parsing Configfile %s", DEFAULTCONFIGFILENAME);
  124.   content = GetConfigFileContent (DEFAULTCONFIGFILENAME);
  125.   ParseContent (content, strlen(content));
  126.   printf ("n");
  127.   free (content);
  128.   // Parse the command line
  129.   CLcount = 1;
  130.   while (CLcount < ac)
  131.   {
  132.     if (0 == strncmp (av[CLcount], "-f", 2))  // A file parameter?
  133.     {
  134.       content = GetConfigFileContent (av[CLcount+1]);
  135.       printf ("Parsing Configfile %s", av[CLcount+1]);
  136.       ParseContent (content, strlen (content));
  137.       printf ("n");
  138.       free (content);
  139.       CLcount += 2;
  140.     } else
  141.     {
  142.       if (0 == strncmp (av[CLcount], "-p", 2))  // A config change?
  143.       {
  144.         // Collect all data until next parameter (starting with -<x> (x is any character)),
  145.         // put it into content, and parse content.
  146.         CLcount++;
  147.         ContentLen = 0;
  148.         NumberParams = CLcount;
  149.         // determine the necessary size for content
  150.         while (NumberParams < ac && av[NumberParams][0] != '-')
  151.           ContentLen += strlen (av[NumberParams++]);        // Space for all the strings
  152.         ContentLen += 1000;                     // Additional 1000 bytes for spaces and s
  153.         if ((content = malloc (ContentLen))==NULL) no_mem_exit("Configure: content");;
  154.         content[0] = '';
  155.         // concatenate all parameters itendified before
  156.         while (CLcount < NumberParams)
  157.         {
  158.           char *source = &av[CLcount][0];
  159.           char *destin = &content[strlen (content)];
  160.           while (*source != '')
  161.           {
  162.             if (*source == '=')  // The Parser expects whitespace before and after '='
  163.             {
  164.               *destin++=' '; *destin++='='; *destin++=' ';  // Hence make sure we add it
  165.             } else
  166.               *destin++=*source;
  167.             source++;
  168.           }
  169.           *destin = '';
  170.           CLcount++;
  171.         }
  172.         printf ("Parsing command line string '%s'", content);
  173.         ParseContent (content, strlen(content));
  174.         free (content);
  175.         printf ("n");
  176.       }
  177.       else
  178.       {
  179.         snprintf (errortext, ET_SIZE, "Error in command line, ac %d, around string '%s', missing -f or -p parameters?", CLcount, av[CLcount]);
  180.         error (errortext, 300);
  181.       }
  182.     }
  183.   }
  184.   printf ("n");
  185. #endif /* H26L_LIB */
  186. }
  187. /*!
  188.  ***********************************************************************
  189.  * brief
  190.  *    allocates memory buf, opens file Filename in f, reads contents into
  191.  *    buf and returns buf
  192.  * param Filename
  193.  *    name of config file
  194.  ***********************************************************************
  195.  */
  196. char *GetConfigFileContent (char *Filename)
  197. {
  198.   unsigned FileSize;
  199.   FILE *f;
  200.   char *buf;
  201.   if (NULL == (f = fopen (Filename, "r")))
  202.   {
  203.     snprintf (errortext, ET_SIZE, "Cannot open configuration file %s.n", Filename);
  204.     error (errortext, 300);
  205.   }
  206.   if (0 != fseek (f, 0, SEEK_END))
  207.   {
  208.     snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.n", Filename);
  209.     error (errortext, 300);
  210.   }
  211.   FileSize = ftell (f);
  212.   if (FileSize < 0 || FileSize > 60000)
  213.   {
  214.     snprintf (errortext, ET_SIZE, "Unreasonable Filesize %d reported by ftell for configuration file %s.n", FileSize, Filename);
  215.     error (errortext, 300);
  216.   }
  217.   if (0 != fseek (f, 0, SEEK_SET))
  218.   {
  219.     snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.n", Filename);
  220.     error (errortext, 300);
  221.   }
  222.   if ((buf = malloc (FileSize + 1))==NULL) no_mem_exit("GetConfigFileContent: buf");
  223.   // Note that ftell() gives us the file size as the file system sees it.  The actual file size,
  224.   // as reported by fread() below will be often smaller due to CR/LF to CR conversion and/or
  225.   // control characters after the dos EOF marker in the file.
  226.   FileSize = fread (buf, 1, FileSize, f);
  227.   buf[FileSize] = '';
  228.   fclose (f);
  229.   return buf;
  230. }
  231. /*!
  232.  ***********************************************************************
  233.  * brief
  234.  *    Parses the character array buf and writes global variable input, which is defined in
  235.  *    configfile.h.  This hack will continue to be necessary to facilitate the addition of
  236.  *    new parameters through the Map[] mechanism (Need compiler-generated addresses in map[]).
  237.  * param buf
  238.  *    buffer to be parsed
  239.  * param bufsize
  240.  *    buffer size of buffer
  241.  ***********************************************************************
  242.  */
  243. void ParseContent (char *buf, int bufsize)
  244. {
  245.   char *items[MAX_ITEMS_TO_PARSE];
  246.   int MapIdx;
  247.   int item = 0;
  248.   int InString = 0, InItem = 0;
  249.   char *p = buf;
  250.   char *bufend = &buf[bufsize];
  251.   int IntContent;
  252.   int i;
  253. // Stage one: Generate an argc/argv-type list in items[], without comments and whitespace.
  254. // This is context insensitive and could be done most easily with lex(1).
  255.   while (p < bufend)
  256.   {
  257.     switch (*p)
  258.     {
  259.       case 13:
  260.         p++;
  261.         break;
  262.       case '#':                 // Found comment
  263.         *p = '';              // Replace '#' with '' in case of comment immediately following integer or string
  264.         while (*p != 'n' && p < bufend)  // Skip till EOL or EOF, whichever comes first
  265.           p++;
  266.         InString = 0;
  267.         InItem = 0;
  268.         break;
  269.       case 'n':
  270.         InItem = 0;
  271.         InString = 0;
  272.         *p++='';
  273.         break;
  274.       case ' ':
  275.       case 't':              // Skip whitespace, leave state unchanged
  276.         if (InString)
  277.           p++;
  278.         else
  279.         {                     // Terminate non-strings once whitespace is found
  280.           *p++ = '';
  281.           InItem = 0;
  282.         }
  283.         break;
  284.       case '"':               // Begin/End of String
  285.         *p++ = '';
  286.         if (!InString)
  287.         {
  288.           items[item++] = p;
  289.           InItem = ~InItem;
  290.         }
  291.         else
  292.           InItem = 0;
  293.         InString = ~InString; // Toggle
  294.         break;
  295.       default:
  296.         if (!InItem)
  297.         {
  298.           items[item++] = p;
  299.           InItem = ~InItem;
  300.         }
  301.         p++;
  302.     }
  303.   }
  304.   item--;
  305.   for (i=0; i<item; i+= 3)
  306.   {
  307.     if (0 > (MapIdx = ParameterNameToMapIndex (items[i])))
  308.     {
  309.       snprintf (errortext, ET_SIZE, " Parsing error in config file: Parameter Name '%s' not recognized.", items[i]);
  310.       error (errortext, 300);
  311.     }
  312.     if (strcmp ("=", items[i+1]))
  313.     {
  314.       snprintf (errortext, ET_SIZE, " Parsing error in config file: '=' expected as the second token in each line.");
  315.       error (errortext, 300);
  316.     }
  317.     // Now interprete the Value, context sensitive...
  318.     switch (Map[MapIdx].Type)
  319.     {
  320.       case 0:           // Numerical
  321.         if (1 != sscanf (items[i+2], "%d", &IntContent))
  322.         {
  323.           snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]);
  324.           error (errortext, 300);
  325.         }
  326.         * (int *) (Map[MapIdx].Place) = IntContent;
  327.         printf (".");
  328.         break;
  329.       case 1:
  330.         strcpy ((char *) Map[MapIdx].Place, items [i+2]);
  331.         printf (".");
  332.         break;
  333.       default:
  334.         assert ("Unknown value type in the map definition of configfile.h");
  335.     }
  336.   }
  337.   memcpy (input, &configinput, sizeof (InputParameters));
  338.   PatchInp();
  339. }
  340. /*!
  341.  ***********************************************************************
  342.  * brief
  343.  *    Returns the index number from Map[] for a given parameter name.
  344.  * param s
  345.  *    parameter name string
  346.  * return
  347.  *    the index number if the string is a valid parameter name,         n
  348.  *    -1 for error
  349.  ***********************************************************************
  350.  */
  351. static int ParameterNameToMapIndex (char *s)
  352. {
  353.   int i = 0;
  354.   while (Map[i].TokenName != NULL)
  355.     if (0==strcmp (Map[i].TokenName, s))
  356.       return i;
  357.     else
  358.       i++;
  359.   return -1;
  360. };
  361. /*!
  362.  ***********************************************************************
  363.  * brief
  364.  *    Checks the input parameters for consistency.
  365.  ***********************************************************************
  366.  */
  367. static void PatchInp ()
  368. {
  369.   // consistency check of QPs
  370.   if (input->qp0 > 31 || input->qp0 < 0)
  371.   {
  372.     snprintf(errortext, ET_SIZE, "Error input parameter quant_0,check configuration file");
  373.     error (errortext, 400);
  374.   }
  375.   if (input->qpN > 31 || input->qpN < 0)
  376.   {
  377.     snprintf(errortext, ET_SIZE, "Error input parameter quant_n,check configuration file");
  378.     error (errortext, 400);
  379.   }
  380.   if (input->qpB > 31 || input->qpB < 0)
  381.   {
  382.     snprintf(errortext, ET_SIZE, "Error input parameter quant_B,check configuration file");
  383.     error (errortext, 400);
  384.   }
  385.   if (input->qpsp > 31 || input->qpsp < 0)
  386.   {
  387.     snprintf(errortext, ET_SIZE, "Error input parameter quant_sp,check configuration file");
  388.     error (errortext, 400);
  389.   }
  390.   if (input->qpsp_pred > 31 || input->qpsp_pred < 0)
  391.   {
  392.     snprintf(errortext, ET_SIZE, "Error input parameter quant_sp_pred,check configuration file");
  393.     error (errortext, 400);
  394.   }
  395.   if (input->sp_periodicity <0)
  396.   {
  397.     snprintf(errortext, ET_SIZE, "Error input parameter sp_periodicity,check configuration file");
  398.     error (errortext, 400);
  399.   }
  400.   // consistency check Search_range
  401.   if (input->search_range > 39)   // StW
  402.   {
  403.     snprintf(errortext, ET_SIZE, "Error in input parameter search_range, check configuration file");
  404.     error (errortext, 400);
  405.   }
  406.   // consistency check no_multpred
  407.   if (input->no_multpred<1) input->no_multpred=1;
  408.   // consistency check size information
  409.   if (input->img_height % 16 != 0 || input->img_width % 16 != 0)
  410.   {
  411.     snprintf(errortext, ET_SIZE, "Unsupported image format x=%d,y=%d, must be a multiple of 16",input->img_width,input->img_height);
  412.     error (errortext, 400);
  413.   }
  414. #ifdef _LEAKYBUCKET_
  415.   // consistency check for Number of Leaky Bucket parameters
  416.   if(input->NumberLeakyBuckets < 2 || input->NumberLeakyBuckets > 255) 
  417.   {
  418.     snprintf(errortext, ET_SIZE, "Number of Leaky Buckets should be between 2 and 255 but is %d n", input->NumberLeakyBuckets);
  419.     error(errortext, 400);
  420.   }
  421. #endif
  422.   // Set block sizes
  423.   // First, initialize input->blc_size to all zeros
  424.   memset (input->blc_size,0, 4*8*2);
  425.   // set individual items
  426.   if (input->InterSearch16x16)
  427.   {
  428.     input->blc_size[1][0]=16;
  429.     input->blc_size[1][1]=16;
  430.   }
  431.   if (input->InterSearch16x8)
  432.   {
  433.     input->blc_size[2][0]=16;
  434.     input->blc_size[2][1]= 8;
  435.   }
  436.   if (input->InterSearch8x16)
  437.   {
  438.     input->blc_size[3][0]= 8;
  439.     input->blc_size[3][1]=16;
  440.   }
  441.   if (input->InterSearch8x8)
  442.   {
  443.     input->blc_size[4][0]= 8;
  444.     input->blc_size[4][1]= 8;
  445.   }
  446.   if (input->InterSearch8x4)
  447.   {
  448.     input->blc_size[5][0]= 8;
  449.     input->blc_size[5][1]= 4;
  450.   }
  451.   if (input->InterSearch4x8)
  452.   {
  453.     input->blc_size[6][0]= 4;
  454.     input->blc_size[6][1]= 8;
  455.   }
  456.   if (input->InterSearch4x4)
  457.   {
  458.     input->blc_size[7][0]= 4;
  459.     input->blc_size[7][1]= 4;
  460.   }
  461.   if (input->partition_mode < 0 || input->partition_mode > 1)
  462.   {
  463.     snprintf(errortext, ET_SIZE, "Unsupported Partition mode, must be between 0 and 1");
  464.     error (errortext, 400);
  465.   }
  466.   if (input->of_mode < 0 || input->of_mode > 3)
  467.   {
  468.     snprintf(errortext, ET_SIZE, "Unsupported Outpout file mode, must be between 0 and 2");
  469.     error (errortext, 400);
  470.   }
  471.   // B picture consistency check
  472.   if(input->successive_Bframe > input->jumpd)
  473.   {
  474.     snprintf(errortext, ET_SIZE, "Number of B-frames %d can not exceed the number of frames skipped", input->successive_Bframe);
  475.     error (errortext, 400);
  476.   }
  477.   // Cabac/UVLC consistency check
  478.   if (input->symbol_mode != UVLC && input->symbol_mode != CABAC)
  479.   {
  480.     snprintf (errortext, ET_SIZE, "Unsupported symbol mode=%d, use UVLC=0 or CABAC=1",input->symbol_mode);
  481.     error (errortext, 400);
  482.   }
  483.   // Open Files
  484. #ifndef H26L_LIB
  485.   if ((p_in=fopen(input->infile,"rb"))==NULL)
  486.   {
  487.     snprintf(errortext, ET_SIZE, "Input file %s does not exist",input->infile);
  488.     error (errortext, 500);
  489.   }
  490. #endif
  491.   if (strlen (input->ReconFile) > 0 && (p_dec=fopen(input->ReconFile, "wb"))==NULL)
  492.   {
  493.     snprintf(errortext, ET_SIZE, "Error open file %s", input->ReconFile);
  494.     error (errortext, 500);
  495.   }
  496.   if (strlen (input->TraceFile) > 0 && (p_trace=fopen(input->TraceFile,"w"))==NULL)
  497.   {
  498.     snprintf(errortext, ET_SIZE, "Error open file %s", input->TraceFile);
  499.     error (errortext, 500);
  500.   }
  501. }