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

📄 q_matrix.c

📁 h.264官方测试软件
💻 C
📖 第 1 页 / 共 2 页
字号:

/*!
 *************************************************************************************
 * \file q_matrix.c
 *
 * \brief
 *    read q_matrix parameters from input file: q_matrix.cfg
 *
 *************************************************************************************
 */
#include <stdlib.h>
#include <string.h>

#include "global.h"
#include "memalloc.h"

extern char *GetConfigFileContent (char *Filename, int error_type);

#define MAX_ITEMS_TO_PARSE  1000

extern const int quant_coef[6][4][4];
extern const int dequant_coef[6][4][4];

extern const int quant_coef8[6][8][8];
extern const int dequant_coef8[6][8][8];


int matrix4x4_check[6] = {0, 0, 0, 0, 0, 0};
int matrix8x8_check[2] = {0, 0};

static const char MatrixType4x4[6][20] =
{
  "INTRA4X4_LUMA",
  "INTRA4X4_CHROMAU",
  "INTRA4X4_CHROMAV",
  "INTER4X4_LUMA",
  "INTER4X4_CHROMAU",
  "INTER4X4_CHROMAV"
};

static const char MatrixType8x8[2][20] =
{
  "INTRA8X8_LUMA",
  "INTER8X8_LUMA",
};

int ****LevelScale4x4Luma;
int *****LevelScale4x4Chroma;
int ****LevelScale8x8Luma;

int ****InvLevelScale4x4Luma;
int *****InvLevelScale4x4Chroma;
int ****InvLevelScale8x8Luma;

short ScalingList4x4input[6][16];
short ScalingList8x8input[2][64];
short ScalingList4x4[6][16];
short ScalingList8x8[2][64];

short UseDefaultScalingMatrix4x4Flag[6];
short UseDefaultScalingMatrix8x8Flag[2];


int *qp_per_matrix;
int *qp_rem_matrix;

static const short Quant_intra_default[16] =
{
 6,13,20,28,
13,20,28,32,
20,28,32,37,
28,32,37,42
};

static const short Quant_inter_default[16] =
{
10,14,20,24,
14,20,24,27,
20,24,27,30,
24,27,30,34
};

static const short Quant8_intra_default[64] =
{
 6,10,13,16,18,23,25,27,
10,11,16,18,23,25,27,29,
13,16,18,23,25,27,29,31,
16,18,23,25,27,29,31,33,
18,23,25,27,29,31,33,36,
23,25,27,29,31,33,36,38,
25,27,29,31,33,36,38,40,
27,29,31,33,36,38,40,42
};

static const short Quant8_inter_default[64] =
{
 9,13,15,17,19,21,22,24,
13,13,17,19,21,22,24,25,
15,17,19,21,22,24,25,27,
17,19,21,22,24,25,27,28,
19,21,22,24,25,27,28,30,
21,22,24,25,27,28,30,32,
22,24,25,27,28,30,32,33,
24,25,27,28,30,32,33,35
};


/*!
 ***********************************************************************
 * \brief
 *    Check the parameter name.
 * \param s
 *    parameter name string
 * \param type
 *    4x4 or 8x8 matrix type
 * \return
 *    the index number if the string is a valid parameter name,         \n
 *    -1 for error
 ***********************************************************************
 */
int CheckParameterName (char *s, int *type)
{
  int i = 0;

  *type = 0;
  while ((MatrixType4x4[i] != NULL) && (i<6))
  {
    if (0==strcmp (MatrixType4x4[i], s))
      return i;
    else
      i++;
  }

  i = 0;
  *type = 1;
  while ((MatrixType8x8[i] != NULL) && (i<2))
  {
    if (0==strcmp (MatrixType8x8[i], s))
      return i;
    else
      i++;
  }

  return -1;
};

/*!
 ***********************************************************************
 * \brief
 *    Parse the Q matrix values read from cfg file.
 * \param buf
 *    buffer to be parsed
 * \param bufsize
 *    buffer size of buffer
 ***********************************************************************
 */
void ParseMatrix (char *buf, int bufsize)
{
  char *items[MAX_ITEMS_TO_PARSE];
  int MapIdx;
  int item = 0;
  int InString = 0, InItem = 0;
  char *p = buf;
  char *bufend = &buf[bufsize];
  int IntContent;
  int i, j, range, type, cnt;
  short *ScalingList;

  while (p < bufend)
  {
    switch (*p)
    {
      case 13:
        p++;
        break;
      case '#':                 // Found comment
        *p = '\0';              // Replace '#' with '\0' in case of comment immediately following integer or string
        while (*p != '\n' && p < bufend)  // Skip till EOL or EOF, whichever comes first
          p++;
        InString = 0;
        InItem = 0;
        break;
      case '\n':
        InItem = 0;
        InString = 0;
        *p++='\0';
        break;
      case ' ':
      case '\t':              // Skip whitespace, leave state unchanged
        if (InString)
          p++;
        else
        {                     // Terminate non-strings once whitespace is found
          *p++ = '\0';
          InItem = 0;
        }
        break;

      case '"':               // Begin/End of String
        *p++ = '\0';
        if (!InString)
        {
          items[item++] = p;
          InItem = ~InItem;
        }
        else
          InItem = 0;
        InString = ~InString; // Toggle
        break;

      case ',':
        p++;
        InItem = 0;
        break;

      default:
        if (!InItem)
        {
          items[item++] = p;
          InItem = ~InItem;
        }
        p++;
    }
  }

  item--;

  for (i=0; i<item; i+=cnt)
  {
    cnt=0;
    if (0 > (MapIdx = CheckParameterName (items[i+cnt], &type)))
    {
      snprintf (errortext, ET_SIZE, " Parsing error in config file: Parameter Name '%s' not recognized.", items[i+cnt]);
      error (errortext, 300);
    }
    cnt++;
    if (strcmp ("=", items[i+cnt]))
    {
      snprintf (errortext, ET_SIZE, " Parsing error in config file: '=' expected as the second token in each item.");
      error (errortext, 300);
    }
    cnt++;

    if (!type) //4x4 Matrix
    {
      range = 16;
      ScalingList = ScalingList4x4input[MapIdx];
      matrix4x4_check[MapIdx] = 1; //to indicate matrix found in cfg file
    }
    else //8x8 matrix
    {
      range = 64;
      ScalingList = ScalingList8x8input[MapIdx];
      matrix8x8_check[MapIdx] = 1; //to indicate matrix found in cfg file
    }

    for(j=0; j<range; j++)
    {
      if (1 != sscanf (items[i+cnt+j], "%d", &IntContent))
      {
        snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+cnt+j]);
        error (errortext, 300);
      }

      ScalingList[j] = (short)IntContent; //save value in matrix
    }
    cnt+=j;
    printf (".");
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Check Q Matrix values. If invalid values found in matrix,
 *    whole matrix will be patch with default value 16.
 ***********************************************************************
 */
void PatchMatrix(void)
{
  short *ScalingList;
  int i, cnt, fail;

  for(i=0; i<6; i++)
  {
    if(input->ScalingListPresentFlag[i])
    {
      ScalingList=ScalingList4x4input[i];
      if(matrix4x4_check[i])
      {
        fail=0;
        for(cnt=0; cnt<16; cnt++)
        {
          if(ScalingList[cnt]<0 || ScalingList[cnt]>255) // ScalingList[0]=0 to indicate use default matrix
          {
            fail=1;
            break;
          }
        }

        if(fail) //value of matrix exceed range
        {
          printf("\n%s value exceed range. (Value must be 1 to 255)\n", MatrixType4x4[i]);
          printf("Setting default values for this matrix.");
          if(i>2)
            memcpy(ScalingList, Quant_inter_default, sizeof(short)*16);
          else
            memcpy(ScalingList, Quant_intra_default, sizeof(short)*16);
        }
      }
      else //matrix not found, pad with default value
      {
        printf("\n%s matrix definition not found. Setting default values.", MatrixType4x4[i]);
        if(i>2)
          memcpy(ScalingList, Quant_inter_default, sizeof(short)*16);
        else
          memcpy(ScalingList, Quant_intra_default, sizeof(short)*16);
      }
    }

    if((i<2) && input->ScalingListPresentFlag[i+6])
    {
      ScalingList=ScalingList8x8input[i];
      if(matrix8x8_check[i])
      {
        fail=0;
        for(cnt=0; cnt<64; cnt++)
        {

⌨️ 快捷键说明

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