⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_par_reader.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_par_reader.h"

using namespace UMC;

//! Maximum size of parfile is limited to avoid processing of big wrong files
#define MAX_PARFILE_SIZE 16384

//! \def DELIMITER VM_STRING(";, \t")
/*! Separator characters for arguments */
#define DELIMITER VM_STRING(";, \t")

//! \def CODEC_SECTION_TITLE VM_STRING(";, \t")
/*! Codec specific section title */
#define CODEC_SECTION_TITLE VM_STRING("property")

/*!
 OptionInfo array is is used to provide ParamList class with descriptions about
 command line and parfile parameters. It is passed to addOptionInfo function.
 All entries in limits field are delimited with ";, \t" (see DELIMITER).
 When synonym field is not null, it points to base name, while field name is
 a synonym name, which can be used too. In this case the next fields are ignored.
 The array has to be terminated with a record containing null in field name.
 0-length name is valid and used for options without a key.
*/
//example
#if(0)
const ParamList::OptionInfo SomeOptions[] = {
  {VM_STRING("parfile"),   0, 1, ParamList::argStr, ParamList::checkNone, 0, VM_STRING("parameter file name")},
  {VM_STRING("bitrate"),   0, 1, ParamList::argFlt, ParamList::checkMinMax, VM_STRING("0,1.e8"), VM_STRING("bitrate in bps")},
  {VM_STRING("b"), VM_STRING("bitrate"), },
  {VM_STRING("width"),     0, 1, ParamList::argInt, ParamList::checkMinMax, VM_STRING("1;4096"), VM_STRING("frame width in pixels")},
  {VM_STRING("w"), VM_STRING("width"), },
  {VM_STRING("height"),    0, 1, ParamList::argInt, ParamList::checkMinMax, VM_STRING("1 4096"), VM_STRING("frame height in pixels")},
  {VM_STRING("h"), VM_STRING("height"), },
  {VM_STRING("codec"),     0, 1, ParamList::argStr, ParamList::checkSet, VM_STRING("mpeg2,mpeg4;264 263, 261;vc1 ;dv"), VM_STRING("codec name")},
  {VM_STRING("framerate"), 0, 1, ParamList::argFlt, ParamList::checkNone, 0, VM_STRING("frame rate in fps")},
  {0,} // list terminator
};
#endif

ParamList::ParamList() : m_plist(0), m_parfile_data(0), m_listOptionInfo(0)
{
  m_numParams = 0;
  m_parfile_size = 0;
  m_numOptionInfo = 0;
}

// destructor frees all allocated memory
ParamList::~ParamList()
{
  while (m_plist != 0) {
    Parameter* prev = m_plist;
    m_plist = m_plist->m_next;
    delete prev;
  }
  if(m_parfile_data != 0)
    delete m_parfile_data;
  while (m_listOptionInfo != 0) {
    OptionInfoGroup* pdescr = m_listOptionInfo;
    m_listOptionInfo = m_listOptionInfo->next;
    delete pdescr;
  }
}

// returns base name if name is known or is a known synonym
// returns 0 if the name is unknown
const vm_char* ParamList::getBaseName(const vm_char* name)
{
  const OptionInfo* info;
  Ipp32s index;

  if(name == 0 /*|| name[0] == 0*/)
    return 0;
  // find the name in description (incl. synonyms)
  for(index = 0; index < m_numOptionInfo; index++) {
    info = getOptionInfo(index);
    if(info==0 || info->name==0 /*|| info->name[0]==0*/)
      return 0;
    if(!vm_string_strcmp(name, info->name)) {
      if(info->synonym) {
        return info->synonym;
      }
      return info->name;
    }
  }
  return 0;
}

// finds description for parameter name or synonym
// returns 0 if the name is unknown
const ParamList::OptionInfo* ParamList::findOptionInfo(const vm_char* name)
{
  const OptionInfo* info;
  const vm_char* basename;
  Ipp32s index;

  basename = getBaseName(name);
  if(basename == 0) // unknown name
    return 0;
  // find the name in description (incl. synonyms)
  for(index = 0; index < m_numOptionInfo; index++) {
    info = getOptionInfo(index);
    if(info==0 || info->name==0 /*|| info->name[0]==0*/)
      return 0;
    if(!vm_string_strcmp(basename, info->name)) {
      return info;
    }
  }
  // will never be here
  return 0;
}

// finds the parameter record read by name or synonym
// returns 0 if not found
ParamList::Parameter* ParamList::findParam(const vm_char* name)
{
  const vm_char* basename;
  Parameter* ppar;

  if(name == 0 /*|| name[0] == 0*/)
    return 0;
  basename = getBaseName(name);
  if(basename == 0)
    basename = name; // name without description, use as is

  for(ppar = m_plist; ppar != 0; ppar = ppar->m_next) {
    if( !vm_string_strcmp(basename, ppar->m_name))
      return ppar;
  }
  return 0;
}

// adds new parameter record by name or synonym
// fills record with name and info description exists
// synonym is translated to base name
// returns 0 if a record with the name is present already
ParamList::Parameter* ParamList::addParam(const vm_char* name)
{
  Parameter* ppar;
  Parameter* plast = 0;
  const OptionInfo* info;

  // just for debug, can be removed
  ppar = findParam(name);

  // append new record
  for(ppar = m_plist; ppar != 0; ppar = ppar->m_next) {
    plast = ppar;
  }
  ppar = new Parameter;
  if(ppar == 0)
    return 0; // malloc failed

  if(plast)
    plast->m_next = ppar;
  else
    m_plist = ppar;
  m_numParams++;

  // find the name in description (incl. synonyms) and set name
  info = findOptionInfo(name);
  ppar->m_info = info;
  if(info != 0) {
    ppar->m_name = info->name;
  } else {
    ppar->m_name = name;
  }

  return ppar;
}

// reads parameter file of the following format:
// first word in each line is parameter name
// name can be preceded with "-" and is followed by '=' sign or/and spaces
// then follow parameters, separated by DELIMITER
// symbol '#' comments to the end of line.
// CODEC_SECTION_TITLE codec_name separates the section which is only read
// when codec argument matches codec_name
// parameters from file don't override command line parameters
// should not be called before readCLine or second time
// Examples:
//  -property h263 # comment:encoder to be used
//   smth = 2.54,  1e-2  -7 ;0 # 4 Ipp32f values
// # completely commented line

Status ParamList::readPFile(const vm_char * fname, const vm_char * codec)
{
  vm_file*    InputFile;
  vm_char* pfdata;
  Ipp32s   filelen;

  Ipp32s p, t, endl, endt, next;
  Ipp32s comment;
  Ipp32s wrong_section = 0;
  Ipp32s narg;
  Parameter* rec;
  Status ret;

  if(m_parfile_data)
    return -2; // single parfile for now

  InputFile = vm_file_fopen(fname, VM_STRING("rt"));
  if(InputFile == 0)
    return UMC_ERR_NOT_FOUND;
  vm_file_fseek( InputFile, 0, VM_FILE_SEEK_END);
  filelen = (Ipp32s)vm_file_ftell(InputFile);
  if(filelen <= 0 || filelen > MAX_PARFILE_SIZE) {
    vm_file_fclose(InputFile);
    return UMC_ERR_INVALID_STREAM;
  }
  vm_file_fseek( InputFile, 0, VM_FILE_SEEK_SET);

  pfdata = new vm_char[filelen+1];
  if(!pfdata) {
    vm_file_fclose(InputFile);
    return UMC_ERR_ALLOC;
  }
  m_parfile_data = pfdata;
  m_parfile_size = filelen+1;

  filelen = vm_file_read(pfdata, sizeof(vm_char), filelen, InputFile);
  vm_file_close(InputFile);
  if(filelen > m_parfile_size) // can be less
    return UMC_ERR_FAILED;
  m_parfile_size = filelen;
  pfdata[filelen] = 0;

  // parse strings now
  endl = 0;
  for(next = 0;next<filelen;) {
    comment = 0;
    for(p=next; p<filelen && pfdata[p] != '\n'; p++) {// find end of line
      if(pfdata[p]=='#' && !comment) {// comment
        pfdata[p] = 0;
        comment = 1;
        endl = p;
      }
    }
    if(!comment)
      endl = p;
    pfdata[p] = 0; // change '\n' to 0
    for(t = next; isspace(pfdata[t]) || pfdata[t]=='-'; t++); // start of 1st token (name)
    next = p+1; // now points to the next line
    for(endt = t; !isspace(pfdata[endt]) && pfdata[endt]!=0 && pfdata[endt]!='='; endt++); // end of 1st token (name)
    if(t==endt)
      continue; // empty line or EOF
    pfdata[endt] = 0; // end of token

    // If start of codec specific section
    // Skip to next if doesn't match codec name
    if( !vm_string_strcmp(pfdata + t, CODEC_SECTION_TITLE)) {
      for(t = endt+1; t<endl && (isspace(pfdata[t]) || pfdata[t]=='='); t++); // start 1st token
      endt = vm_string_strcspn(pfdata+t, DELIMITER);
      endt+=t;
      pfdata[endt] = 0;
      // check if no codec name or if it matches
      if(codec == 0)
        getValue(VM_STRING("codec"), &codec); // if set in parfile
      if( endt == t || (codec != 0 && !vm_string_stricmp(pfdata + t, codec)) ) {
        wrong_section = 0; // enable till next section
      } else {
        wrong_section = 1; // disable till next section
      }
      continue;
    }
    if(wrong_section != 0)
      continue;

    // have token (name)
    rec = findParam(pfdata + t);
    if(rec == 0) {
      rec = addParam(pfdata + t); // add record if new
      if(rec == 0)
        return UMC_ERR_ALLOC; // only if malloc failed (or -3)
    }
    else {
      continue; // don't overwrite from par-file
    }

    for(t = endt+1; t<endl && (isspace(pfdata[t]) || pfdata[t]=='='); t++); // start 1st token
    // now fill the record
    for(narg = 0; ;narg++) {
      endt = vm_string_strcspn(pfdata+t, DELIMITER);
      if(endt==0)
        break; // no token
      endt+=t;
      pfdata[endt] = 0;
      if(rec->m_info) { // have description
        if(narg >= rec->m_info->numArgs)
          break; // ignore extra args
        ret = rec->appendValue(pfdata+t);
        if(ret != UMC_OK)
          return ret;
      }
      else { // unknown parameter name - just remember
        rec->appendValue(pfdata+t);
      }
      t = endt+1+vm_string_strspn(pfdata+endt+1, DELIMITER);
    }
  }
  return UMC_OK;
}

// reads command line of the following format:
// each parameter name has to be separated from values
// numeric values can start with '-' only for known names
// command line does override parameters from parameter file
// if meets -parfile parfilename then proceed it in the end
// Examples:
//   -codec h263 -smth  2.54  1e-2  -7 0

Status ParamList::readCLine(vm_char ** cline, Ipp32s argc)
{
  Ipp32s arg, narg;
  Parameter* rec;
  Status ret;

  for(arg=0; arg<argc; arg++) {
    const vm_char* name;
    if(cline[arg][0]=='-') {
      // have token (name)
      name = cline[arg]+1;
    } else {
      name = VM_STRING(""); // will get without option key
      arg--;
    }

    rec = findParam(name);
    if(rec == 0) {
      rec = addParam(name);
      if(rec == 0)
        return UMC_ERR_ALLOC; // only if malloc failed (or -3)
    }
    // overwrites if exist
    for(narg = 0; arg+1<argc; arg++, narg++) {
      if(rec->m_info) { // have description
        if(narg >= rec->m_info->numArgs)
          break; // ignore extra args
        ret = rec->appendValue(cline[arg+1]);
        if(ret != UMC_OK)
          return ret;
      }
      else { // unknown parameter name - just remember till next option
        if(cline[arg+1][0]=='-')
          break;
        rec->appendValue(cline[arg+1]);
      }
    }
  }

  // read par-file if have met
  //rec = findParam(VM_STRING("parfile")); // name can be changed
  //if(rec != 0 && rec->m_nargs == 1) {
  //  ret = readPFile(rec->getValue(0));
  //  if(ret != UMC_OK)
  //    return ret;
  //}

  return UMC_OK;
}


// returns UMC_ERR_NOT_FOUND if no record,
//   UMC_ERR_NO_ARG if no such argument
// else sets *val and return UMC_OK if record type matches or
//   UMC_WRN_TYPE_MISMATCH otherwise
Status ParamList::getValue(const vm_char* name, Ipp32s* val, Ipp32s vnum)
{
  Parameter *rec = findParam(name);
  if(rec == 0)
    return UMC_ERR_NOT_FOUND;
  if(rec->m_nargs <= vnum)
    return UMC_ERR_NO_ARG;
  if(1 == vm_string_sscanf(rec->getValue(vnum), VM_STRING("%d"), val) &&
     (rec->m_info == 0 || rec->m_info->argType == argInt))
  {
    return UMC_OK;
  }
  return UMC_WRN_TYPE_MISMATCH;
}

// returns UMC_ERR_NOT_FOUND if no record,
//   UMC_ERR_NO_ARG if no such argument
// else sets *val and return UMC_OK if record type matches or
//   UMC_WRN_TYPE_MISMATCH otherwise
Status ParamList::getValue(const vm_char* name, Ipp64f* val, Ipp32s vnum)
{
  Parameter *rec = findParam(name);
  if(rec == 0)
    return UMC_ERR_NOT_FOUND;
  if(rec->m_nargs <= vnum)
    return UMC_ERR_NO_ARG;
  if(1 == vm_string_sscanf(rec->getValue(vnum), VM_STRING("%lf"), val) &&
    (rec->m_info == 0 || rec->m_info->argType == argFlt))
  {
    return UMC_OK;
  }
  return UMC_WRN_TYPE_MISMATCH;
}

// returns UMC_ERR_NOT_FOUND if no record,
//   UMC_ERR_NO_ARG if no such argument
// else sets *val and return UMC_OK if record type matches or
//   UMC_WRN_TYPE_MISMATCH otherwise
Status ParamList::getValue(const vm_char* name, Ipp32f* val, Ipp32s vnum)
{
  Parameter *rec = findParam(name);
  if(rec == 0)
    return UMC_ERR_NOT_FOUND;
  if(rec->m_nargs <= vnum)
    return UMC_ERR_NO_ARG;
  if(1 == vm_string_sscanf(rec->getValue(vnum), VM_STRING("%f"), val) &&
    (rec->m_info == 0 || rec->m_info->argType == argFlt))
  {
    return UMC_OK;
  }
  return UMC_WRN_TYPE_MISMATCH;
}

// returns UMC_ERR_NOT_FOUND if no record,
//   UMC_ERR_NO_ARG if no such argument
// else sets *val and return UMC_OK if record type matches or
//   UMC_WRN_TYPE_MISMATCH otherwise
Status ParamList::getValue(const vm_char* name, const vm_char** val, Ipp32s vnum)
{
  Parameter *rec = findParam(name);
  if(rec == 0)
    return UMC_ERR_NOT_FOUND;
  if(rec->m_nargs <= vnum)
    return UMC_ERR_NO_ARG;
  *val = rec->getValue(vnum);
  if(rec->m_info == 0 || rec->m_info->argType == argStr) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -