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

📄 q_matrix.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:

        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(params->ScalingListPresentFlag[i+6])
    {
      ScalingList=ScalingList8x8input[i];
      if(matrix8x8_check[i])
      {
        fail=0;
        for(cnt=0; cnt<64; 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", MatrixType8x8[i]);
          printf("Setting default values for this matrix.");
          if(i==1 || i==3 || i==5)
            memcpy(ScalingList, Quant8_inter_default, sizeof(short)*64);
          else
            memcpy(ScalingList, Quant8_intra_default, sizeof(short)*64);
        }
      }
      else //matrix not found, pad with default value
      {
        printf("\n%s matrix definition not found. Setting default values.", MatrixType8x8[i]);
        if(i==1 || i==3 || i==5)
          memcpy(ScalingList, Quant8_inter_default, sizeof(short)*64);
        else
          memcpy(ScalingList, Quant8_intra_default, sizeof(short)*64);
      }
    }
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Allocate Q matrix arrays
 ***********************************************************************
 */
void allocate_QMatrix (void)
{
  int bitdepth_qp_scale = 6*(params->output.bit_depth[0] - 8);
  int i;

  if ((qp_per_matrix = (int*)malloc((MAX_QP + 1 +  bitdepth_qp_scale)*sizeof(int))) == NULL)
    no_mem_exit("init_global_buffers: qp_per_matrix");
  if ((qp_rem_matrix = (int*)malloc((MAX_QP + 1 +  bitdepth_qp_scale)*sizeof(int))) == NULL)
    no_mem_exit("init_global_buffers: qp_per_matrix");

  for (i = 0; i < MAX_QP + bitdepth_qp_scale + 1; i++)
  {
    qp_per_matrix[i] = i / 6;
    qp_rem_matrix[i] = i % 6;
  }

  get_mem5Dint(&LevelScale4x4Comp,    3, 2, 6, 4, 4);
  get_mem5Dint(&LevelScale8x8Comp,    3, 2, 6, 8, 8);

  get_mem5Dint(&InvLevelScale4x4Comp, 3, 2, 6, 4, 4);
  get_mem5Dint(&InvLevelScale8x8Comp, 3, 2, 6, 8, 8);
}

/*!
 ***********************************************************************
 * \brief
 *    Free Q matrix arrays
 ***********************************************************************
 */
void free_QMatrix ()
{
  free(qp_rem_matrix);
  free(qp_per_matrix);

  free_mem5Dint(LevelScale4x4Comp);
  free_mem5Dint(LevelScale8x8Comp);

  free_mem5Dint(InvLevelScale4x4Comp);
  free_mem5Dint(InvLevelScale8x8Comp);
}


/*!
 ***********************************************************************
 * \brief
 *    Initialise Q matrix values.
 ***********************************************************************
 */
void Init_QMatrix (void)
{
  char *content;


  allocate_QMatrix ();

  if(params->ScalingMatrixPresentFlag)
  {
    printf ("Parsing QMatrix file %s ", params->QmatrixFile);
    content = GetConfigFileContent(params->QmatrixFile, 0);
    if(content!='\0')
      ParseMatrix(content, strlen (content));
    else
      printf("\nError: %s\nProceeding with default values for all matrices.", errortext);

    PatchMatrix();
    printf("\n");

    memset(UseDefaultScalingMatrix4x4Flag, 0, 6 * sizeof(short));
    memset(UseDefaultScalingMatrix8x8Flag, 0, 6 * sizeof(short));

    free(content);
  }
}

/*!
 ************************************************************************
 * \brief
 *    For calculating the quantisation values at frame level
 *
 * \par Input:
 *    none
 *
 * \par Output:
 *    none
 ************************************************************************
 */
void CalculateQuantParam(void)
{
  int i, j, k, temp;
  int present[6];
  int no_q_matrix=FALSE;

  if(!active_sps->seq_scaling_matrix_present_flag && !active_pps->pic_scaling_matrix_present_flag) //set to no q-matrix
    no_q_matrix=TRUE;
  else
  {
    memset(present, 0, 6 * sizeof(int));

    if(active_sps->seq_scaling_matrix_present_flag)
      for(i=0; i<6; i++)
        present[i] = active_sps->seq_scaling_list_present_flag[i];

    if(active_pps->pic_scaling_matrix_present_flag)
      for(i=0; i<6; i++)
      {
        if((i==0) || (i==3))
          present[i] |= active_pps->pic_scaling_list_present_flag[i];
        else
          present[i] = active_pps->pic_scaling_list_present_flag[i];
      }
  }

  if(no_q_matrix==TRUE)
  {
    for(k=0; k<6; k++)
      for(j=0; j<4; j++)
        for(i=0; i<4; i++)
        {
          LevelScale4x4Comp[0][1][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[0][1][k][j][i] = dequant_coef[k][j][i]<<4;

          LevelScale4x4Comp[1][1][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[1][1][k][j][i] = dequant_coef[k][j][i]<<4;

          LevelScale4x4Comp[2][1][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[2][1][k][j][i] = dequant_coef[k][j][i]<<4;

          // Inter
          LevelScale4x4Comp[0][0][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[0][0][k][j][i] = dequant_coef[k][j][i]<<4;

          LevelScale4x4Comp[1][0][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[1][0][k][j][i] = dequant_coef[k][j][i]<<4;

          LevelScale4x4Comp[2][0][k][j][i]    = quant_coef[k][j][i];
          InvLevelScale4x4Comp[2][0][k][j][i] = dequant_coef[k][j][i]<<4;
        }
  }
  else
  {
    for(k=0; k<6; k++)
    {
      for(j=0; j<4; j++)
      {
        for(i=0; i<4; i++)
        {
          temp = (j<<2)+i;
          if((!present[0]) || UseDefaultScalingMatrix4x4Flag[0])
          {
            LevelScale4x4Comp[0][1][k][j][i]         = (quant_coef[k][j][i]<<4)/Quant_intra_default[temp];
            InvLevelScale4x4Comp[0][1][k][j][i]      = dequant_coef[k][j][i]*Quant_intra_default[temp];
          }
          else
          {
            LevelScale4x4Comp[0][1][k][j][i]         = (quant_coef[k][j][i]<<4)/ScalingList4x4[0][temp];
            InvLevelScale4x4Comp[0][1][k][j][i]      = dequant_coef[k][j][i]*ScalingList4x4[0][temp];
          }

          if(!present[1])
          {
            LevelScale4x4Comp[1][1][k][j][i]    = LevelScale4x4Comp[0][1][k][j][i];
            InvLevelScale4x4Comp[1][1][k][j][i] = InvLevelScale4x4Comp[0][1][k][j][i];
          }
          else
          {
            LevelScale4x4Comp[1][1][k][j][i]    = (quant_coef[k][j][i]<<4)/(UseDefaultScalingMatrix4x4Flag[1] ? Quant_intra_default[temp]:ScalingList4x4[1][temp]);
            InvLevelScale4x4Comp[1][1][k][j][i] = dequant_coef[k][j][i]*(UseDefaultScalingMatrix4x4Flag[1] ? Quant_intra_default[temp]:ScalingList4x4[1][temp]);
          }

          if(!present[2])
          {
            LevelScale4x4Comp[2][1][k][j][i]    = LevelScale4x4Comp[1][1][k][j][i];
            InvLevelScale4x4Comp[2][1][k][j][i] = InvLevelScale4x4Comp[1][1][k][j][i];
          }
          else
          {
            LevelScale4x4Comp[2][1][k][j][i]    = (quant_coef[k][j][i]<<4)/(UseDefaultScalingMatrix4x4Flag[2] ? Quant_intra_default[temp]:ScalingList4x4[2][temp]);
            InvLevelScale4x4Comp[2][1][k][j][i] = dequant_coef[k][j][i]*(UseDefaultScalingMatrix4x4Flag[2] ? Quant_intra_default[temp]:ScalingList4x4[2][temp]);
          }

          if((!present[3]) || UseDefaultScalingMatrix4x4Flag[3])
          {
            LevelScale4x4Comp[0][0][k][j][i]         = (quant_coef[k][j][i]<<4)/Quant_inter_default[temp];
            InvLevelScale4x4Comp[0][0][k][j][i]      = dequant_coef[k][j][i]*Quant_inter_default[temp];
          }
          else
          {
            LevelScale4x4Comp[0][0][k][j][i]         = (quant_coef[k][j][i]<<4)/ScalingList4x4[3][temp];
            InvLevelScale4x4Comp[0][0][k][j][i]      = dequant_coef[k][j][i]*ScalingList4x4[3][temp];
          }

          if(!present[4])
          {
            LevelScale4x4Comp[1][0][k][j][i]    = LevelScale4x4Comp[0][0][k][j][i];
            InvLevelScale4x4Comp[1][0][k][j][i] = InvLevelScale4x4Comp[0][0][k][j][i];
          }
          else
          {
            LevelScale4x4Comp[1][0][k][j][i]    = (quant_coef[k][j][i]<<4)/(UseDefaultScalingMatrix4x4Flag[4] ? Quant_inter_default[temp]:ScalingList4x4[4][temp]);
            InvLevelScale4x4Comp[1][0][k][j][i] = dequant_coef[k][j][i]*(UseDefaultScalingMatrix4x4Flag[4] ? Quant_inter_default[temp]:ScalingList4x4[4][temp]);
          }

          if(!present[5])
          {
            LevelScale4x4Comp[2][0][k][j][i]    = LevelScale4x4Comp[1][0][k][j][i];
            InvLevelScale4x4Comp[2][0][k][j][i] = InvLevelScale4x4Comp[1][0][k][j][i];
          }
          else
          {
            LevelScale4x4Comp[2][0][k][j][i]    = (quant_coef[k][j][i]<<4)/(UseDefaultScalingMatrix4x4Flag[5] ? Quant_inter_default[temp]:ScalingList4x4[5][temp]);
            InvLevelScale4x4Comp[2][0][k][j][i] = dequant_coef[k][j][i]*(UseDefaultScalingMatrix4x4Flag[5] ? Quant_inter_default[temp]:ScalingList4x4[5][temp]);
          }
        }
      }
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    Calculate the quantisation and inverse quantisation parameters
 *
 ************************************************************************
 */
void CalculateQuant8Param()
{
  int i, j, k, temp;
  int n_ScalingList8x8;
  int present[6];
  int no_q_matrix=FALSE;

  // maximum number of valid 8x8 scaling lists
  n_ScalingList8x8 = ( active_sps->chroma_format_idc != 3 ) ? 2 : 6;

  if(!active_sps->seq_scaling_matrix_present_flag && !active_pps->pic_scaling_matrix_present_flag) //set to default matrix
    no_q_matrix=TRUE;
  else
  {
    memset(present, 0, sizeof(int)*n_ScalingList8x8);

    if(active_sps->seq_scaling_matrix_present_flag)
      for(i=0; i<n_ScalingList8x8; i++)
        present[i] = active_sps->seq_scaling_list_present_flag[i+6];

      if(active_pps->pic_scaling_matrix_present_flag)
        for(i=0; i<n_ScalingList8x8; i++)
        {
          if( i==0 || i==1 )
            present[i] |= active_pps->pic_scaling_list_present_flag[i+6];
          else
            present[i] = active_pps->pic_scaling_list_present_flag[i+6];
        }
  }

  if(no_q_matrix==TRUE)
  {
    for(k=0; k<6; k++)
      for(j=0; j<8; j++)
        for(i=0; i<8; i++)
        {
          // intra Y
          LevelScale8x8Comp[0][1][k][j][i]      = quant_coef8[k][j][i];
          InvLevelScale8x8Comp[0][1][k][j][i]   = dequant_coef8[k][j][i]<<4;

          // inter Y
          LevelScale8x8Comp[0][0][k][j][i]      = quant_coef8[k][j][i];
          InvLevelScale8x8Comp[0][0][k][j][i]   = dequant_coef8[k][j][i]<<4;

          if( n_ScalingList8x8 > 2 )  // 4:4:4 case only
          {
            // intra U
            LevelScale8x8Comp[1][1][k][j][i]    = quant_coef8[k][j][i];
            InvLevelScale8x8Comp[1][1][k][j][i] = dequant_coef8[k][j][i]<<4;

            // intra V
            LevelScale8x8Comp[2][1][k][j][i]    = quant_coef8[k][j][i];
            InvLevelScale8x8Comp[2][1][k][j][i] = dequant_coef8[k][j][i]<<4;

            // inter U
            LevelScale8x8Comp[1][0][k][j][i]    = quant_coef8[k][j][i];
            InvLevelScale8x8Comp[1][0][k][j][i] = dequant_coef8[k][j][i]<<4;

            // inter V
            LevelScale8x8Comp[2][0][k][j][i]    = quant_coef8[k][j][i];
            InvLevelScale8x8Comp[2][0][k][j][i] = dequant_coef8[k][j][i]<<4;

          }
        }
  }
  else
  {
    for(k=0; k<6; k++)
      for(j=0; j<8; j++)
        for(i=0; i<8; i++)
        {
          temp = (j<<3)+i;
          if((!present[0]) || UseDefaultScalingMatrix8x8Flag[0])
          {
            LevelScale8x8Comp[0][1][k][j][i]    = (quant_coef8[k][j][i]<<4)/Quant8_intra_default[temp];
            InvLevelScale8x8Comp[0][1][k][j][i] = dequant_coef8[k][j][i]*Quant8_intra_default[temp];
          }
          else
          {
            LevelScale8x8Comp[0][1][k][j][i]    = (quant_coef8[k][j][i]<<4)/ScalingList8x8[0][temp];
            InvLevelScale8x8Comp[0][1][k][j][i] = dequant_coef8[k][j][i]*ScalingList8x8[0][temp];
          }

          if((!present[1]) || UseDefaultScalingMatrix8x8Flag[1])
          {
            LevelScale8x8Comp[0][0][k][j][i]    = (quant_coef8[k][j][i]<<4)/Quant8_inter_default[temp];
            InvLevelScale8x8Comp[0][0][k][j][i] = dequant_coef8[k][j][i]*Quant8_inter_default[temp];
          }
          else
          {
            LevelScale8x8Comp[0][0][k][j][i]    = (quant_coef8[k][j][i]<<4)/ScalingList8x8[1][temp];
            InvLevelScale8x8Comp[0][0][k][j][i] = dequant_coef8[k][j][i]*ScalingList8x8[1][temp];
          }

          if( n_ScalingList8x8 > 2 )
          {

            // Intra U
            if(!present[2])
            {
              LevelScale8x8Comp[1][1][k][j][i]    = LevelScale8x8Comp[0][1][k][j][i];
              InvLevelScale8x8Comp[1][1][k][j][i] = InvLevelScale8x8Comp[0][1][k][j][i];
            }
            else
            {
              LevelScale8x8Comp[1][1][k][j][i]    = (quant_coef8[k][j][i]<<4)/(UseDefaultScalingMatrix8x8Flag[2] ? Quant8_intra_default[temp]:ScalingList8x8[2][temp]);
              InvLevelScale8x8Comp[1][1][k][j][i] = dequant_coef8[k][j][i]*(UseDefaultScalingMatrix8x8Flag[2] ? Quant8_intra_default[temp]:ScalingList8x8[2][temp]);
            }

            // Inter U
            if(!present[3])
            {
              LevelScale8x8Comp[1][0][k][j][i]    = LevelScale8x8Comp[0][0][k][j][i];
              InvLevelScale8x8Comp[1][0][k][j][i] = InvLevelScale8x8Comp[0][0][k][j][i];
            }
            else
            {
              LevelScale8x8Comp[1][0][k][j][i]    = (quant_coef8[k][j][i]<<4)/(UseDefaultScalingMatrix8x8Flag[3] ? Quant8_inter_default[temp]:ScalingList8x8[3][temp]);
              InvLevelScale8x8Comp[1][0][k][j][i] = dequant_coef8[k][j][i]*(UseDefaultScalingMatrix8x8Flag[3] ? Quant8_inter_default[temp]:ScalingList8x8[3][temp]);
            }

            // Intra V
            if(!present[4])
            {
              LevelScale8x8Comp[2][1][k][j][i]    = LevelScale8x8Comp[1][1][k][j][i];
              InvLevelScale8x8Comp[2][1][k][j][i] = InvLevelScale8x8Comp[1][1][k][j][i];
            }
            else
            {
              LevelScale8x8Comp[2][1][k][j][i]    = (quant_coef8[k][j][i]<<4)/(UseDefaultScalingMatrix8x8Flag[4] ? Quant8_intra_default[temp]:ScalingList8x8[4][temp]);
              InvLevelScale8x8Comp[2][1][k][j][i] = dequant_coef8[k][j][i]*(UseDefaultScalingMatrix8x8Flag[4] ? Quant8_intra_default[temp]:ScalingList8x8[4][temp]);
            }

            // Inter V
            if(!present[5])
            {
              LevelScale8x8Comp[2][0][k][j][i]    = LevelScale8x8Comp[1][0][k][j][i];
              InvLevelScale8x8Comp[2][0][k][j][i] = InvLevelScale8x8Comp[1][0][k][j][i];
            }
            else
            {
              LevelScale8x8Comp[2][0][k][j][i]    = (quant_coef8[k][j][i]<<4)/(UseDefaultScalingMatrix8x8Flag[5] ? Quant8_inter_default[temp]:ScalingList8x8[5][temp]);
              InvLevelScale8x8Comp[2][0][k][j][i] = dequant_coef8[k][j][i]*(UseDefaultScalingMatrix8x8Flag[5] ? Quant8_inter_default[temp]:ScalingList8x8[5][temp]);
            }

          }
        }
  }
}

⌨️ 快捷键说明

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