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

📄 q_offsets.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 ***********************************************************************
 * \brief
 *    Initialise Q offset matrix values.
 ***********************************************************************
 */
void Init_QOffsetMatrix ()
{
  char *content;

  allocate_QOffsets ();

  if (params->OffsetMatrixPresentFlag)
  {
    printf ("Parsing Quantization Offset Matrix file %s ",
      params->QOffsetMatrixFile);
    content = GetConfigFileContent (params->QOffsetMatrixFile, 0);
    if (content != '\0')
      ParseQOffsetMatrix (content, strlen (content));
    else
    {
      printf
        ("\nError: %s\nProceeding with default values for all matrices.",
        errortext);
      params->OffsetMatrixPresentFlag = 0;
    }

    printf ("\n");

    free (content);
  }
  //! Now set up all offset params. This process could be reused if we wish to re-init offsets
  InitOffsetParam ();
}

/*!
 ************************************************************************
 * \brief
 *    Intit quantization offset params
 *
 * \par Input:
 *    none
 *
 * \par Output:
 *    none
 ************************************************************************
 */

void InitOffsetParam ()
{
  int i, k;
  int max_qp_luma = (4 + 6*(params->output.bit_depth[0]));
  int max_qp_cr   = (4 + 6*(params->output.bit_depth[1]));

  for (i = 0; i < (params->AdaptRoundingFixed ? 1 : imax(max_qp_luma, max_qp_cr)); i++)
  {
    if (params->OffsetMatrixPresentFlag)
    {
      memcpy(&(OffsetList4x4[i][0][0]),&(OffsetList4x4input[0][0]), 400 * sizeof(short)); // 25 * 16
      memcpy(&(OffsetList8x8[i][0][0]),&(OffsetList8x8input[0][0]), 960 * sizeof(short)); // 15 * 64
    }
    else
    {
      // 0 (INTRA4X4_LUMA_INTRA)
      memcpy(&(OffsetList4x4[i][0][0]),&(Offset_intra_default_intra[0]), 16 * sizeof(short));
      for (k = 1; k < 3; k++) // 1,2 (INTRA4X4_CHROMA_INTRA)
        memcpy(&(OffsetList4x4[i][k][0]),&(Offset_intra_default_chroma[0]),  16 * sizeof(short));
      for (k = 3; k < 9; k++) // 3,4,5,6,7,8 (INTRA4X4_LUMA/CHROMA_INTERP/INTERB)
        memcpy(&(OffsetList4x4[i][k][0]),&(Offset_intra_default_inter[0]),  16 * sizeof(short));
      for (k = 9; k < 25; k++) // 9,10,11,12,13,14 (INTER4X4)
        memcpy(&(OffsetList4x4[i][k][0]),&(Offset_inter_default[0]),  16 * sizeof(short));

      // 0 (INTRA8X8_LUMA_INTRA)
      memcpy(&(OffsetList8x8[i][0][0]),&(Offset8_intra_default_intra[0]), 64 * sizeof(short));
      for (k = 1; k < 3; k++)  // 1,2 (INTRA8X8_LUMA_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
      for (k = 3; k < 5; k++)  // 3,4 (INTER8X8_LUMA_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));

      // 5 (INTRA8X8_CHROMAU_INTRA)
      memcpy(&(OffsetList8x8[i][5][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short));
      for (k = 6; k < 8; k++)  // 6,7 (INTRA8X8_CHROMAU_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
      for (k = 8; k < 10; k++)  // 8,9 (INTER8X8_CHROMAU_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));

      // 10 (INTRA8X8_CHROMAV_INTRA)
      memcpy(&(OffsetList8x8[i][10][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short));
      for (k = 11; k < 13; k++)  // 11,12 (INTRA8X8_CHROMAV_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]),  64 * sizeof(short));
      for (k = 13; k < 15; k++)  // 8,9 (INTER8X8_CHROMAV_INTERP/INTERB)
        memcpy(&(OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]),  64 * sizeof(short));
    }
  }  
}


/*!
 ************************************************************************
 * \brief
 *    Calculation of the quantization offset params at the frame level
 *
 * \par Input:
 *    none
 *
 * \par Output:
 *    none
 ************************************************************************
 */
void CalculateOffsetParam ()
{
  int i, j, k, temp;  
  int qp_per, qp;
  short **OffsetList;
  static int **LevelOffsetCmp0Intra, **LevelOffsetCmp1Intra, **LevelOffsetCmp2Intra;
  static int **LevelOffsetCmp0Inter, **LevelOffsetCmp1Inter, **LevelOffsetCmp2Inter;
  int img_type = (img->type == SI_SLICE ? I_SLICE : (img->type == SP_SLICE ? P_SLICE : img->type));

  int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale);
  int max_qp = 51 + max_qp_scale;

  AdaptRndWeight = params->AdaptRndWFactor[img->nal_reference_idc != 0][img_type];
  AdaptRndCrWeight = params->AdaptRndCrWFactor[img->nal_reference_idc != 0][img_type];

  if (img_type == I_SLICE )
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      k = qp_per_matrix [qp];
      qp_per = Q_BITS + k - OffsetBits;
      OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
      LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
      LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
      LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];

      temp = 0;
      for (j = 0; j < 4; j++)
      {
        for (i = 0; i < 4; i++, temp++)
        {
          LevelOffsetCmp0Intra[j][i] = (int) OffsetList[0][temp] << qp_per;
          LevelOffsetCmp1Intra[j][i] = (int) OffsetList[1][temp] << qp_per;
          LevelOffsetCmp2Intra[j][i] = (int) OffsetList[2][temp] << qp_per;
        }
      }
    }
  }
  else if (img_type == B_SLICE)
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      k = qp_per_matrix [qp];
      qp_per = Q_BITS + k - OffsetBits;
      OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
      LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
      LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
      LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];
      LevelOffsetCmp0Inter = LevelOffset4x4Comp[0][0][qp];
      LevelOffsetCmp1Inter = LevelOffset4x4Comp[1][0][qp];
      LevelOffsetCmp2Inter = LevelOffset4x4Comp[2][0][qp];


      for (temp = 0, j = 0; j < 4; j++)
      {
        for (i = 0; i < 4; i++, temp++)
        {          
          // intra
          LevelOffsetCmp0Intra[j][i] = (int) OffsetList[6][temp] << qp_per;
          LevelOffsetCmp1Intra[j][i] = (int) OffsetList[7][temp] << qp_per;
          LevelOffsetCmp2Intra[j][i] = (int) OffsetList[8][temp] << qp_per;
        }
      }

      for (temp = 0, j = 0; j < 4; j++)
      {
        for (i = 0; i < 4; i++, temp++)
        {          
          // inter
          LevelOffsetCmp0Inter[j][i] = (int) OffsetList[12][temp] << qp_per;
          LevelOffsetCmp1Inter[j][i] = (int) OffsetList[13][temp] << qp_per;
          LevelOffsetCmp2Inter[j][i] = (int) OffsetList[14][temp] << qp_per;
        }
      }

    }
  }
  else
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      k = qp_per_matrix [qp];
      qp_per = Q_BITS + k - OffsetBits;
      OffsetList = OffsetList4x4[params->AdaptRoundingFixed ? 0 : qp];
      LevelOffsetCmp0Intra = LevelOffset4x4Comp[0][1][qp];
      LevelOffsetCmp1Intra = LevelOffset4x4Comp[1][1][qp];
      LevelOffsetCmp2Intra = LevelOffset4x4Comp[2][1][qp];
      LevelOffsetCmp0Inter = LevelOffset4x4Comp[0][0][qp];
      LevelOffsetCmp1Inter = LevelOffset4x4Comp[1][0][qp];
      LevelOffsetCmp2Inter = LevelOffset4x4Comp[2][0][qp];

      temp = 0;
      for (j = 0; j < 4; j++)
      {
        for (i = 0; i < 4; i++, temp++)
        {
          // intra
          LevelOffsetCmp0Intra[j][i] = (int) OffsetList[3][temp] << qp_per;
          LevelOffsetCmp1Intra[j][i] = (int) OffsetList[4][temp] << qp_per;
          LevelOffsetCmp2Intra[j][i] = (int) OffsetList[5][temp] << qp_per;
          // inter
          LevelOffsetCmp0Inter[j][i] = (int) OffsetList[9 ][temp] << qp_per;
          LevelOffsetCmp1Inter[j][i] = (int) OffsetList[10][temp] << qp_per;
          LevelOffsetCmp2Inter[j][i] = (int) OffsetList[11][temp] << qp_per;
        }
      }      
    }
  }

  // setting for 4x4 luma quantization offset
  if( IS_INDEPENDENT(params) )
  {
    if( img->colour_plane_id == 0 )
    {
      ptLevelOffset4x4 = LevelOffset4x4Comp[0];
    }
    else if( img->colour_plane_id == 1 )
    {
      ptLevelOffset4x4   = LevelOffset4x4Comp[1];
    }
    else if( img->colour_plane_id == 2 )
    {
      ptLevelOffset4x4   = LevelOffset4x4Comp[2];
    }
  }
  else
  {
    ptLevelOffset4x4 = LevelOffset4x4Comp[0];
  }
}

/*!
 ************************************************************************
 * \brief
 *    Calculate the quantisation offset parameters
 *
 ************************************************************************
*/
void CalculateOffset8Param ()
{
  int i, j, k, temp;
  int q_bits, qp;

  int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale);
  int max_qp = 51 + max_qp_scale;

  if (img->type == I_SLICE || img->type == SI_SLICE )
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
      k = params->AdaptRoundingFixed ? 0 : qp;
      for (j = 0; j < 8; j++)
      {
        temp = (j << 3);
        for (i = 0; i < 8; i++)
        {          
          // INTRA8X8
          LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][0][temp] << q_bits;

          // INTRA8X8 CHROMAU
          LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][5][temp] << q_bits;

          // INTRA8X8 CHROMAV
          LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][10][temp++] << q_bits;
        }
      }
    }
  }
  else if ((img->type == P_SLICE) || (img->type == SP_SLICE))
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
      k = params->AdaptRoundingFixed ? 0 : qp;
      for (j = 0; j < 8; j++)
      {
        temp = (j << 3);
        for (i = 0; i < 8; i++)
        {
          // INTRA8X8
          LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][1][temp] << q_bits;

          // INTER8X8
          LevelOffset8x8Comp[0][0][qp][j][i] = (int) OffsetList8x8[k][3][temp] << q_bits;

          // INTRA8X8 CHROMAU
          LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][6][temp] << q_bits;

          // INTER8X8 CHROMAU
          LevelOffset8x8Comp[1][0][qp][j][i] = (int) OffsetList8x8[k][8][temp] << q_bits;

          // INTRA8X8 CHROMAV
          LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][11][temp] << q_bits;

          // INTER8X8 CHROMAV
          LevelOffset8x8Comp[2][0][qp][j][i] = (int) OffsetList8x8[k][13][temp++] << q_bits;
        }
      }
    }
  }
  else
  {
    for (qp = 0; qp < max_qp + 1; qp++)
    {
      q_bits = Q_BITS_8 + qp_per_matrix[qp] - OffsetBits;
      k = params->AdaptRoundingFixed ? 0 : qp;
      for (j = 0; j < 8; j++)
      {
        temp = (j << 3);
        for (i = 0; i < 8; i++)
        {
          // INTRA8X8
          LevelOffset8x8Comp[0][1][qp][j][i] = (int) OffsetList8x8[k][2][temp] << q_bits;
          // INTER8X8
          LevelOffset8x8Comp[0][0][qp][j][i] = (int) OffsetList8x8[k][4][temp] << q_bits;

          // INTRA8X8 CHROMAU
          LevelOffset8x8Comp[1][1][qp][j][i] = (int) OffsetList8x8[k][7][temp] << q_bits;

          // INTER8X8 CHROMAU
          LevelOffset8x8Comp[1][0][qp][j][i] = (int) OffsetList8x8[k][9][temp] << q_bits;

          // INTRA8X8 CHROMAV
          LevelOffset8x8Comp[2][1][qp][j][i] = (int) OffsetList8x8[k][12][temp] << q_bits;

          // INTER8X8 CHROMAV
          LevelOffset8x8Comp[2][0][qp][j][i] = (int) OffsetList8x8[k][14][temp++] << q_bits;
        }
      }
    }
  }

  // setting for 8x8 luma quantization offset
  if( IS_INDEPENDENT(params) )
  {
    if( img->colour_plane_id == 0 )
    {
      ptLevelOffset8x8 = LevelOffset8x8Comp[0];
    }
    else if( img->colour_plane_id == 1 )
    {
      ptLevelOffset8x8 = LevelOffset8x8Comp[1];
    }
    else if( img->colour_plane_id == 2 )
    {
      ptLevelOffset8x8 = LevelOffset8x8Comp[2];
    }
  }
  else
  {
    ptLevelOffset8x8 = LevelOffset8x8Comp[0];
  }
}

void SelectColorType (int colour_id)
{
  switch (colour_id)
  {
  case 0:
  default:
    ptLevelOffset8x8   = LevelOffset8x8Comp[0];
    break;
  case 1:
    ptLevelOffset8x8   = LevelOffset8x8Comp[1];
    break;
  case 2:
    ptLevelOffset8x8   = LevelOffset8x8Comp[2];
    break;
  }
}

⌨️ 快捷键说明

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