Skip to content
Snippets Groups Projects
EncAppCfg.cpp 409 KiB
Newer Older
  • Learn to ignore specific revisions
  •     cfg_qpInValCb.values    = { 26 };
        cfg_qpInValCr.values    = { 26 };
        cfg_qpInValCbCr.values  = { 26 };
        cfg_qpOutValCb.values   = { 26 };
        cfg_qpOutValCr.values   = { 26 };
        cfg_qpOutValCbCr.values = { 26 };
    
    
      // Need to have at least 2 points in the set. Add second one if only one given
      if (cfg_qpInValCb.values.size() == 1)
      {
        cfg_qpInValCb.values.push_back(cfg_qpInValCb.values[0] + 1);
        cfg_qpOutValCb.values.push_back(cfg_qpOutValCb.values[0] + 1);
      }
      if (cfg_qpInValCr.values.size() == 1)
      {
        cfg_qpInValCr.values.push_back(cfg_qpInValCr.values[0] + 1);
        cfg_qpOutValCr.values.push_back(cfg_qpOutValCr.values[0] + 1);
      }
      if (cfg_qpInValCbCr.values.size() == 1)
      {
        cfg_qpInValCbCr.values.push_back(cfg_qpInValCbCr.values[0] + 1);
        cfg_qpOutValCbCr.values.push_back(cfg_qpOutValCbCr.values[0] + 1);
      }
    
    
      int qpBdOffsetC = 6 * (m_internalBitDepth[ChannelType::CHROMA] - 8);
    
      m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0].resize(cfg_qpInValCb.values.size());
      m_chromaQpMappingTableParams.m_deltaQpOutVal[0].resize(cfg_qpOutValCb.values.size());
    
      m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[0] = (int) cfg_qpOutValCb.values.size() - 2;
      m_chromaQpMappingTableParams.m_qpTableStartMinus26[0]    = -26 + cfg_qpInValCb.values[0];
    
      CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] > 36, "qpTableStartMinus26[0] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
      CHECK(cfg_qpInValCb.values[0] != cfg_qpOutValCb.values[0], "First qpInValCb value should be equal to first qpOutValCb value");
    
      for (int i = 0; i < cfg_qpInValCb.values.size() - 1; i++)
    
        CHECK(cfg_qpInValCb.values[i] < -qpBdOffsetC || cfg_qpInValCb.values[i] > MAX_QP, "Some entries cfg_qpInValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
        CHECK(cfg_qpOutValCb.values[i] < -qpBdOffsetC || cfg_qpOutValCb.values[i] > MAX_QP, "Some entries cfg_qpOutValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
    
        m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0][i] = cfg_qpInValCb.values[i + 1] - cfg_qpInValCb.values[i] - 1;
        m_chromaQpMappingTableParams.m_deltaQpOutVal[0][i] = cfg_qpOutValCb.values[i + 1] - cfg_qpOutValCb.values[i];
    
      if (!m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag)
    
        m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1].resize(cfg_qpInValCr.values.size());
        m_chromaQpMappingTableParams.m_deltaQpOutVal[1].resize(cfg_qpOutValCr.values.size());
    
        m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[1] = (int) cfg_qpOutValCr.values.size() - 2;
        m_chromaQpMappingTableParams.m_qpTableStartMinus26[1]    = -26 + cfg_qpInValCr.values[0];
    
        CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] > 36, "qpTableStartMinus26[1] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
        CHECK(cfg_qpInValCr.values[0] != cfg_qpOutValCr.values[0], "First qpInValCr value should be equal to first qpOutValCr value");
    
        for (int i = 0; i < cfg_qpInValCr.values.size() - 1; i++)
    
          CHECK(cfg_qpInValCr.values[i] < -qpBdOffsetC || cfg_qpInValCr.values[i] > MAX_QP, "Some entries cfg_qpInValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
          CHECK(cfg_qpOutValCr.values[i] < -qpBdOffsetC || cfg_qpOutValCr.values[i] > MAX_QP, "Some entries cfg_qpOutValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
    
          m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1][i] = cfg_qpInValCr.values[i + 1] - cfg_qpInValCr.values[i] - 1;
          m_chromaQpMappingTableParams.m_deltaQpOutVal[1][i] = cfg_qpOutValCr.values[i + 1] - cfg_qpOutValCr.values[i];
    
        m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2].resize(cfg_qpInValCbCr.values.size());
        m_chromaQpMappingTableParams.m_deltaQpOutVal[2].resize(cfg_qpOutValCbCr.values.size());
    
        m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[2] = (int) cfg_qpOutValCbCr.values.size() - 2;
        m_chromaQpMappingTableParams.m_qpTableStartMinus26[2]    = -26 + cfg_qpInValCbCr.values[0];
    
        CHECK(m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] < -26 - qpBdOffsetC || m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] > 36, "qpTableStartMinus26[2] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.")
        CHECK(cfg_qpInValCbCr.values[0] != cfg_qpInValCbCr.values[0], "First qpInValCbCr value should be equal to first qpOutValCbCr value");
    
        for (int i = 0; i < cfg_qpInValCbCr.values.size() - 1; i++)
    
          CHECK(cfg_qpInValCbCr.values[i] < -qpBdOffsetC || cfg_qpInValCbCr.values[i] > MAX_QP, "Some entries cfg_qpInValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
          CHECK(cfg_qpOutValCbCr.values[i] < -qpBdOffsetC || cfg_qpOutValCbCr.values[i] > MAX_QP, "Some entries cfg_qpOutValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
    
          m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2][i] = cfg_qpInValCbCr.values[i + 1] - cfg_qpInValCbCr.values[i] - 1;
          m_chromaQpMappingTableParams.m_deltaQpOutVal[2][i] = cfg_qpInValCbCr.values[i + 1] - cfg_qpInValCbCr.values[i];
    
      CHECK(m_cuChromaQpOffsetSubdiv < 0, "MaxCuChromaQpOffsetSubdiv shall be >= 0");
    
      CHECK(cfg_crQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size(), "Chroma QP offset lists shall be the same size");
    
      CHECK(cfg_cbCrQpOffsetList.values.size() != cfg_cbQpOffsetList.values.size() && cfg_cbCrQpOffsetList.values.size() > 0, "Chroma QP offset list for joint CbCr shall be either the same size as Cb and Cr or empty");
    
      if (m_cuChromaQpOffsetSubdiv > 0 && !cfg_cbQpOffsetList.values.size())
    
        msg(WARNING, "MaxCuChromaQpOffsetSubdiv has no effect when chroma QP offset lists are empty\n");
    
      }
      m_cuChromaQpOffsetList.resize(cfg_cbQpOffsetList.values.size());
      for (int i=0; i < cfg_cbQpOffsetList.values.size(); i++)
      {
    
    Frank Bossen's avatar
    Frank Bossen committed
        m_cuChromaQpOffsetList[i].u.comp.cbOffset = cfg_cbQpOffsetList.values[i];
        m_cuChromaQpOffsetList[i].u.comp.crOffset = cfg_crQpOffsetList.values[i];
        m_cuChromaQpOffsetList[i].u.comp.jointCbCrOffset =
          cfg_cbCrQpOffsetList.values.size() ? cfg_cbCrQpOffsetList.values[i] : 0;
    
      if (m_rprFunctionalityTestingEnabledFlag)
      {
        m_upscaledOutput = 2;
        if (m_scalingRatioHor == 1.0 && m_scalingRatioVer == 1.0)
        {
          m_scalingRatioHor = 2.0;
          m_scalingRatioVer = 2.0;
        }
    
        CHECK(cfg_rprSwitchingResolutionOrderList.values.size() > MAX_RPR_SWITCHING_ORDER_LIST_SIZE, "Length of RPRSwitchingResolutionOrderList exceeds maximum length");
        CHECK(cfg_rprSwitchingQPOffsetOrderList.values.size() > MAX_RPR_SWITCHING_ORDER_LIST_SIZE, "Length of RPRSwitchingQPOffsetOrderList exceeds maximum length");
        CHECK(cfg_rprSwitchingResolutionOrderList.values.size() != cfg_rprSwitchingQPOffsetOrderList.values.size(), "RPRSwitchingResolutionOrderList and RPRSwitchingQPOffsetOrderList shall be the same size");
        m_rprSwitchingListSize = (int)cfg_rprSwitchingResolutionOrderList.values.size();
        for (int k = 0; k < m_rprSwitchingListSize; k++)
    
          m_rprSwitchingResolutionOrderList[k] = cfg_rprSwitchingResolutionOrderList.values[k];
          m_rprSwitchingQPOffsetOrderList[k] = cfg_rprSwitchingQPOffsetOrderList.values[k];
    
        }
        if (m_rprSwitchingTime != 0.0)
        {
    
          const int segmentSize     = 8 * int(m_frameRate.getFloatVal() * m_rprSwitchingTime / 8 + 0.5);
    
          m_rprSwitchingSegmentSize = segmentSize;
        }
      }
    
        CHECK(m_ladfNumIntervals != cfg_ladfQpOffset.values.size(),
              "size of LadfQpOffset must be equal to LadfNumIntervals");
        CHECK(m_ladfNumIntervals - 1 != cfg_ladfIntervalLowerBound.values.size(),
              "size of LadfIntervalLowerBound must be equal to LadfNumIntervals - 1");
        m_ladfQpOffset              = cfg_ladfQpOffset.values;
        m_ladfIntervalLowerBound[0] = 0;
        for (int k = 1; k < m_ladfNumIntervals; k++)
    
          m_ladfIntervalLowerBound[k] = cfg_ladfIntervalLowerBound.values[k - 1];
    
      if (m_chromaFormatIdc != ChromaFormat::_420)
    
          if (m_horCollocatedChromaFlag == 0)
          {
            msg(WARNING, "WARNING: HorCollocatedChroma forced to 1 (chroma format is not 4:2:0)\n");
          }
          m_horCollocatedChromaFlag = 1;
    
          if (m_verCollocatedChromaFlag == 0)
          {
            msg(WARNING, "WARNING: VerCollocatedChroma is forced to 1 (chroma format is not 4:2:0)\n");
          }
          m_verCollocatedChromaFlag = 1;
    
      else
      {
        if (m_horCollocatedChromaFlag == -1)
        {
          if (m_chromaSampleLocType != Chroma420LocType::UNSPECIFIED)
          {
            m_horCollocatedChromaFlag = m_chromaSampleLocType == Chroma420LocType::LEFT
                                            || m_chromaSampleLocType == Chroma420LocType::TOP_LEFT
                                            || m_chromaSampleLocType == Chroma420LocType::BOTTOM_LEFT
                                          ? 1
                                          : 0;
          }
          else
          {
            m_horCollocatedChromaFlag = 1;
          }
        }
    
        if (m_verCollocatedChromaFlag == -1)
        {
          if (m_chromaSampleLocType != Chroma420LocType::UNSPECIFIED)
          {
            m_verCollocatedChromaFlag =
              m_chromaSampleLocType == Chroma420LocType::TOP_LEFT || m_chromaSampleLocType == Chroma420LocType::TOP ? 1 : 0;
          }
          else
          {
            m_verCollocatedChromaFlag = 0;
          }
        }
      }
    
      CHECK(m_verCollocatedChromaFlag != 0 && m_verCollocatedChromaFlag != 1, "m_verCollocatedChromaFlag should be 0 or 1");
      CHECK(m_horCollocatedChromaFlag != 0 && m_horCollocatedChromaFlag != 1, "m_horCollocatedChromaFlag should be 0 or 1");
    
    
    #if JVET_O0756_CONFIG_HDRMETRICS && !JVET_O0756_CALCULATE_HDRMETRICS
      if ( m_calculateHdrMetrics == true)
      {
        printf ("Warning: Configuration enables HDR metric calculations.  However, HDR metric support was not linked when compiling the VTM.\n");
        m_calculateHdrMetrics = false;
      }
    #endif
    
    
    Frank Bossen's avatar
    Frank Bossen committed
    #if GDR_ENABLED
    
      if (m_gdrEnabled)
      {
        m_virtualBoundariesEnabledFlag = 1;
        m_virtualBoundariesPresentFlag = 0;
      }
      else
      {
        m_virtualBoundariesEnabledFlag = 0;
      }
    
    #else
    
      m_virtualBoundariesEnabledFlag = 0;
    
    #endif
    
      if( m_numVerVirtualBoundaries > 0 || m_numHorVirtualBoundaries > 0 )
        m_virtualBoundariesEnabledFlag = 1;
    
      if( m_virtualBoundariesEnabledFlag )
    
        CHECK( m_subPicInfoPresentFlag && m_virtualBoundariesPresentFlag != 1, "When subpicture signalling is present, the signalling of virtual boundaries, if present, shall be in the SPS" );
    
    
        if( m_virtualBoundariesPresentFlag )
    
          CHECK( m_numVerVirtualBoundaries > 3, "Number of vertical virtual boundaries must be comprised between 0 and 3 included" );
          CHECK( m_numHorVirtualBoundaries > 3, "Number of horizontal virtual boundaries must be comprised between 0 and 3 included" );
          CHECK( m_numVerVirtualBoundaries != cfg_virtualBoundariesPosX.values.size(), "Size of VirtualBoundariesPosX must be equal to NumVerVirtualBoundaries");
          CHECK( m_numHorVirtualBoundaries != cfg_virtualBoundariesPosY.values.size(), "Size of VirtualBoundariesPosY must be equal to NumHorVirtualBoundaries");
          m_virtualBoundariesPosX = cfg_virtualBoundariesPosX.values;
          if (m_numVerVirtualBoundaries > 1)
    
            sort(m_virtualBoundariesPosX.begin(), m_virtualBoundariesPosX.end());
    
          for (unsigned i = 0; i < m_numVerVirtualBoundaries; i++)
    
            CHECK( m_virtualBoundariesPosX[i] == 0 || m_virtualBoundariesPosX[i] >= m_sourceWidth, "The vertical virtual boundary must be within the picture" );
    
            CHECK( m_virtualBoundariesPosX[i] % 8, "The vertical virtual boundary must be a multiple of 8 luma samples" );
            if (i > 0)
            {
    
    Frank Bossen's avatar
    Frank Bossen committed
              CHECK(
                m_virtualBoundariesPosX[i] - m_virtualBoundariesPosX[i - 1] < m_ctuSize,
                "The distance between any two vertical virtual boundaries shall be greater than or equal to the CTU size");
    
            }
          }
          m_virtualBoundariesPosY = cfg_virtualBoundariesPosY.values;
          if (m_numHorVirtualBoundaries > 1)
          {
            sort(m_virtualBoundariesPosY.begin(), m_virtualBoundariesPosY.end());
          }
          for (unsigned i = 0; i < m_numHorVirtualBoundaries; i++)
          {
    
            CHECK( m_virtualBoundariesPosY[i] == 0 || m_virtualBoundariesPosY[i] >= m_sourceHeight, "The horizontal virtual boundary must be within the picture" );
    
            CHECK( m_virtualBoundariesPosY[i] % 8, "The horizontal virtual boundary must be a multiple of 8 luma samples" );
            if (i > 0)
            {
    
    Frank Bossen's avatar
    Frank Bossen committed
              CHECK(m_virtualBoundariesPosY[i] - m_virtualBoundariesPosY[i - 1] < m_ctuSize,
                    "The distance between any two horizontal virtual boundaries shall be greater than or equal to the CTU "
                    "size");
    
        CHECK(m_maxNumAlfAlternativesChroma < 1 || m_maxNumAlfAlternativesChroma > ALF_MAX_NUM_ALTERNATIVES_CHROMA,
              std::string("The maximum number of ALF Chroma filter alternatives must be in the range (1-")
                + std::to_string(ALF_MAX_NUM_ALTERNATIVES_CHROMA) + std::string(", inclusive)"));
    
      // reading external dQP description from file
      if ( !m_dQPFileName.empty() )
      {
        FILE* fpt=fopen( m_dQPFileName.c_str(), "r" );
        if ( fpt )
        {
    
          int val;
          int poc = 0;
          m_frameDeltaQps.clear();
          while (poc < m_framesToBeEncoded)
    
            if (fscanf(fpt, "%d", &val) == EOF)
    
            m_frameDeltaQps.push_back(val);
            poc++;
    
          }
          fclose(fpt);
        }
      }
    
      if( m_masteringDisplay.colourVolumeSEIEnabled )
      {
        for(uint32_t idx=0; idx<6; idx++)
        {
          m_masteringDisplay.primaries[idx/2][idx%2] = uint16_t((cfg_DisplayPrimariesCode.values.size() > idx) ? cfg_DisplayPrimariesCode.values[idx] : 0);
        }
        for(uint32_t idx=0; idx<2; idx++)
        {
          m_masteringDisplay.whitePoint[idx] = uint16_t((cfg_DisplayWhitePointCode.values.size() > idx) ? cfg_DisplayWhitePointCode.values[idx] : 0);
        }
      }
    
      // set sei film grain parameters.
      CHECK(!m_fgcSEIEnabled && m_fgcSEIAnalysisEnabled, "FGC SEI must be enabled in order to perform film grain analysis!");
      if (m_fgcSEIEnabled)
      {
    
        if (m_iQP < 17 && m_fgcSEIAnalysisEnabled == true)
        {   // TODO: JVET_Z0047_FG_IMPROVEMENT: check this; the constraint may have gone
    
          msg(WARNING, "*************************************************************************\n");
          msg(WARNING, "* WARNING: Film Grain Estimation is disabled for Qp<17! FGC SEI will use default parameters for film grain! *\n");
          msg(WARNING, "*************************************************************************\n");
          m_fgcSEIAnalysisEnabled = false;
        }
    
    Frank Bossen's avatar
    Frank Bossen committed
        if (m_intraPeriod < 1)
        {   // low delay configuration
    
          msg(WARNING, "*************************************************************************\n");
          msg(WARNING, "* WARNING: For low delay configuration, FGC SEI is inserted for first frame only!*\n");
          msg(WARNING, "*************************************************************************\n");
          m_fgcSEIPerPictureSEI   = false;
          m_fgcSEIPersistenceFlag = true;
        }
    
    Frank Bossen's avatar
    Frank Bossen committed
        else if (m_intraPeriod == 1)
        {   // all intra configuration
          msg(WARNING, "*************************************************************************\n");
          msg(WARNING, "* WARNING: For Intra Period = 1, FGC SEI is inserted per frame!*\n");
          msg(WARNING, "*************************************************************************\n");
          m_fgcSEIPerPictureSEI   = true;
          m_fgcSEIPersistenceFlag = false;
    
        }
        if (!m_fgcSEIPerPictureSEI && !m_fgcSEIPersistenceFlag) {
          msg(WARNING, "*************************************************************************\n");
          msg(WARNING, "* WARNING: SEIPerPictureSEI is set to 0, SEIPersistenceFlag needs to be set to 1! *\n");
          msg(WARNING, "*************************************************************************\n");
          m_fgcSEIPersistenceFlag = true;
        }
        else if (m_fgcSEIPerPictureSEI && m_fgcSEIPersistenceFlag) {
          msg(WARNING, "*************************************************************************\n");
          msg(WARNING, "* WARNING: SEIPerPictureSEI is set to 1, SEIPersistenceFlag needs to be set to 0! *\n");
          msg(WARNING, "*************************************************************************\n");
          m_fgcSEIPersistenceFlag = false;
        }
    
        if (m_fgcSEIAnalysisEnabled && m_fgcSEITemporalFilterStrengths.empty())
        {
    
          // By default: in random-acces = filter RAPs, in all-intra = filter every frame, otherwise = filter every 2s
    
          int filteredFrame = m_intraPeriod < 1 ? 2 * m_frameRate.getIntValRound() : m_intraPeriod;
    
          m_fgcSEITemporalFilterStrengths[filteredFrame] = 1.5;
        }
    
        uint32_t numModelCtr;
        if (m_fgcSEICompModelPresent[0])
        {
          numModelCtr = 0;
          for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[0]; i++)
          {
            m_fgcSEIIntensityIntervalLowerBound[0][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp0.values[i] : 10);
            m_fgcSEIIntensityIntervalUpperBound[0][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp0.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp0.values[i] : 250);
            for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[0]; j++)
            {
              m_fgcSEICompModelValue[0][i][j] = uint32_t((cfg_FgcSEICompModelValueComp0.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp0.values[numModelCtr] : 24);
              numModelCtr++;
            }
          }
        }
        if (m_fgcSEICompModelPresent[1])
        {
          numModelCtr = 0;
          for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[1]; i++)
          {
            m_fgcSEIIntensityIntervalLowerBound[1][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp1.values[i] : 60);
            m_fgcSEIIntensityIntervalUpperBound[1][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp1.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp1.values[i] : 200);
    
            for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[1]; j++)
            {
              m_fgcSEICompModelValue[1][i][j] = uint32_t((cfg_FgcSEICompModelValueComp1.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp1.values[numModelCtr] : 16);
              numModelCtr++;
            }
          }
        }
        if (m_fgcSEICompModelPresent[2])
        {
          numModelCtr = 0;
          for (uint8_t i = 0; i <= m_fgcSEINumIntensityIntervalMinus1[2]; i++)
          {
            m_fgcSEIIntensityIntervalLowerBound[2][i] = uint32_t((cfg_FgcSEIIntensityIntervalLowerBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalLowerBoundComp2.values[i] : 60);
            m_fgcSEIIntensityIntervalUpperBound[2][i] = uint32_t((cfg_FgcSEIIntensityIntervalUpperBoundComp2.values.size() > i) ? cfg_FgcSEIIntensityIntervalUpperBoundComp2.values[i] : 250);
    
            for (uint8_t j = 0; j <= m_fgcSEINumModelValuesMinus1[2]; j++)
            {
              m_fgcSEICompModelValue[2][i][j] = uint32_t((cfg_FgcSEICompModelValueComp2.values.size() > numModelCtr) ? cfg_FgcSEICompModelValueComp2.values[numModelCtr] : 12);
              numModelCtr++;
            }
          }
        }
        m_fgcSEILog2ScaleFactor = m_fgcSEILog2ScaleFactor ? m_fgcSEILog2ScaleFactor : 2;
      }
    
      if (m_ctiSEIEnabled)
    
      {
        CHECK(!m_ctiSEICrossComponentFlag && m_ctiSEICrossComponentInferred, "CTI CrossComponentFlag is 0, but CTI CrossComponentInferred is 1 (must be 0 for CrossComponentFlag 0)");
        CHECK(!m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
        CHECK(m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred && !m_ctiSEINumberChromaLut, "For CTI CrossComponentFlag = 1 and CrossComponentInferred = 0, CTI NumberChromaLut needs to be specified (1 or 2) ");
    
        CHECK(cfg_SEICTILut0.values.empty(), "SEI CTI (SEICTIEnabled) but no LUT0 specified");
        m_ctiSEILut[0].presentFlag = true;
        m_ctiSEILut[0].numLutValues = (int)cfg_SEICTILut0.values.size();
        m_ctiSEILut[0].lutValues = cfg_SEICTILut0.values;
    
    
        if (!m_ctiSEICrossComponentFlag || (m_ctiSEICrossComponentFlag && !m_ctiSEICrossComponentInferred))
    
        {
          CHECK(cfg_SEICTILut1.values.empty(), "SEI CTI LUT1 not specified");
          m_ctiSEILut[1].presentFlag = true;
          m_ctiSEILut[1].numLutValues = (int)cfg_SEICTILut1.values.size();
          m_ctiSEILut[1].lutValues = cfg_SEICTILut1.values;
    
    
          if (m_ctiSEINumberChromaLut == 1)
    
          { // Cb lut the same as Cr lut
            m_ctiSEILut[2].presentFlag = true;
            m_ctiSEILut[2].numLutValues = m_ctiSEILut[1].numLutValues;
            m_ctiSEILut[2].lutValues = m_ctiSEILut[1].lutValues;
          }
    
          else if (m_ctiSEINumberChromaLut == 2)
    
          { // read from cfg
            CHECK(cfg_SEICTILut2.values.empty(), "SEI CTI LUT2 not specified");
            m_ctiSEILut[2].presentFlag = true;
            m_ctiSEILut[2].numLutValues = (int)cfg_SEICTILut2.values.size();
            m_ctiSEILut[2].lutValues = cfg_SEICTILut2.values;
          }
    
          {
            CHECK(m_ctiSEINumberChromaLut < 1 && m_ctiSEINumberChromaLut > 2, "Number of chroma LUTs is missing or out of range!");
          }
        }
        //  check if lut size is power of 2
    
        for (int idx = 0; idx < MAX_NUM_COMPONENT; idx++)
    
        {
          int n = m_ctiSEILut[idx].numLutValues - 1;
          CHECK(n > 0 && (n & (n - 1)) != 0, "Size of LUT minus 1 should be power of 2!");
          CHECK(n > MAX_CTI_LUT_SIZE, "LUT size minus 1 is larger than MAX_CTI_LUT_SIZE (64)!");
        }
      }
    
      if ( m_omniViewportSEIEnabled && !m_omniViewportSEICancelFlag )
      {
        CHECK (!( m_omniViewportSEICntMinus1 >= 0 && m_omniViewportSEICntMinus1 < 16 ), "SEIOmniViewportCntMinus1 must be in the range of 0 to 16");
        m_omniViewportSEIAzimuthCentre.resize  (m_omniViewportSEICntMinus1+1);
        m_omniViewportSEIElevationCentre.resize(m_omniViewportSEICntMinus1+1);
        m_omniViewportSEITiltCentre.resize     (m_omniViewportSEICntMinus1+1);
        m_omniViewportSEIHorRange.resize       (m_omniViewportSEICntMinus1+1);
        m_omniViewportSEIVerRange.resize       (m_omniViewportSEICntMinus1+1);
        for(int i=0; i<(m_omniViewportSEICntMinus1+1); i++)
        {
          m_omniViewportSEIAzimuthCentre[i]   = cfg_omniViewportSEIAzimuthCentre  .values.size() > i ? cfg_omniViewportSEIAzimuthCentre  .values[i] : 0;
          m_omniViewportSEIElevationCentre[i] = cfg_omniViewportSEIElevationCentre.values.size() > i ? cfg_omniViewportSEIElevationCentre.values[i] : 0;
          m_omniViewportSEITiltCentre[i]      = cfg_omniViewportSEITiltCentre     .values.size() > i ? cfg_omniViewportSEITiltCentre     .values[i] : 0;
          m_omniViewportSEIHorRange[i]        = cfg_omniViewportSEIHorRange       .values.size() > i ? cfg_omniViewportSEIHorRange       .values[i] : 0;
          m_omniViewportSEIVerRange[i]        = cfg_omniViewportSEIVerRange       .values.size() > i ? cfg_omniViewportSEIVerRange       .values[i] : 0;
        }
      }
    
      if(!m_rwpSEIRwpCancelFlag && m_rwpSEIEnabled)
      {
        CHECK (!( m_rwpSEINumPackedRegions > 0 && m_rwpSEINumPackedRegions <= std::numeric_limits<uint8_t>::max() ), "SEIRwpNumPackedRegions must be in the range of 1 to 255");
        CHECK (!(cfg_rwpSEIRwpTransformType.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIRwpTransformType values be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIRwpGuardBandFlag.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIRwpGuardBandFlag values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIProjRegionWidth.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIProjRegionWidth values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIProjRegionHeight.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIProjRegionHeight values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIRwpSEIProjRegionTop.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIRwpSEIProjRegionTop values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIProjRegionLeft.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIProjRegionLeft values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIPackedRegionWidth.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIPackedRegionWidth values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIPackedRegionHeight.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIPackedRegionHeight values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIPackedRegionTop.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIPackedRegionTop values must be equal to SEIRwpNumPackedRegions");
        CHECK (!(cfg_rwpSEIPackedRegionLeft.values.size() == m_rwpSEINumPackedRegions), "Number of must SEIPackedRegionLeft values must be equal to SEIRwpNumPackedRegions");
    
        m_rwpSEIRwpTransformType.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpGuardBandFlag.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIProjRegionWidth.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIProjRegionHeight.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpSEIProjRegionTop.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIProjRegionLeft.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIPackedRegionWidth.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIPackedRegionHeight.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIPackedRegionTop.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIPackedRegionLeft.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpLeftGuardBandWidth.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpRightGuardBandWidth.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpTopGuardBandHeight.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpBottomGuardBandHeight.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpGuardBandNotUsedForPredFlag.resize(m_rwpSEINumPackedRegions);
        m_rwpSEIRwpGuardBandType.resize(4*m_rwpSEINumPackedRegions);
        for( int i=0; i < m_rwpSEINumPackedRegions; i++ )
        {
          m_rwpSEIRwpTransformType[i]                     = cfg_rwpSEIRwpTransformType.values[i];
          CHECK (!( m_rwpSEIRwpTransformType[i] >= 0 && m_rwpSEIRwpTransformType[i] <= 7 ), "SEIRwpTransformType must be in the range of 0 to 7");
          m_rwpSEIRwpGuardBandFlag[i]                     = cfg_rwpSEIRwpGuardBandFlag.values[i];
          m_rwpSEIProjRegionWidth[i]                      = cfg_rwpSEIProjRegionWidth.values[i];
          m_rwpSEIProjRegionHeight[i]                     = cfg_rwpSEIProjRegionHeight.values[i];
          m_rwpSEIRwpSEIProjRegionTop[i]                  = cfg_rwpSEIRwpSEIProjRegionTop.values[i];
          m_rwpSEIProjRegionLeft[i]                       = cfg_rwpSEIProjRegionLeft.values[i];
          m_rwpSEIPackedRegionWidth[i]                    = cfg_rwpSEIPackedRegionWidth.values[i];
          m_rwpSEIPackedRegionHeight[i]                   = cfg_rwpSEIPackedRegionHeight.values[i];
          m_rwpSEIPackedRegionTop[i]                      = cfg_rwpSEIPackedRegionTop.values[i];
    
          m_rwpSEIPackedRegionLeft[i]                     = cfg_rwpSEIPackedRegionLeft.values[i];
    
          if( m_rwpSEIRwpGuardBandFlag[i] )
          {
            m_rwpSEIRwpLeftGuardBandWidth[i]              =  cfg_rwpSEIRwpLeftGuardBandWidth.values[i];
            m_rwpSEIRwpRightGuardBandWidth[i]             =  cfg_rwpSEIRwpRightGuardBandWidth.values[i];
            m_rwpSEIRwpTopGuardBandHeight[i]              =  cfg_rwpSEIRwpTopGuardBandHeight.values[i];
            m_rwpSEIRwpBottomGuardBandHeight[i]           =  cfg_rwpSEIRwpBottomGuardBandHeight.values[i];
            CHECK (! ( m_rwpSEIRwpLeftGuardBandWidth[i] > 0 || m_rwpSEIRwpRightGuardBandWidth[i] > 0 || m_rwpSEIRwpTopGuardBandHeight[i] >0 || m_rwpSEIRwpBottomGuardBandHeight[i] >0 ), "At least one of the RWP guard band parameters mut be greater than zero");
            m_rwpSEIRwpGuardBandNotUsedForPredFlag[i]     =  cfg_rwpSEIRwpGuardBandNotUsedForPredFlag.values[i];
            for( int j=0; j < 4; j++ )
            {
              m_rwpSEIRwpGuardBandType[i*4 + j]           =  cfg_rwpSEIRwpGuardBandType.values[i*4 + j];
            }
    
          }
        }
      }
    
      if (m_gcmpSEIEnabled && !m_gcmpSEICancelFlag)
      {
        int numFace = m_gcmpSEIPackingType == 4 || m_gcmpSEIPackingType == 5 ? 5 : 6;
        CHECK (!(cfg_gcmpSEIFaceIndex.values.size()                  == numFace), "Number of SEIGcmpFaceIndex must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
        CHECK (!(cfg_gcmpSEIFaceRotation.values.size()               == numFace), "Number of SEIGcmpFaceRotation must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
        m_gcmpSEIFaceIndex.resize(numFace);
        m_gcmpSEIFaceRotation.resize(numFace);
        if (m_gcmpSEIMappingFunctionType == 2)
        {
          CHECK (!(cfg_gcmpSEIFunctionCoeffU.values.size()           == numFace), "Number of SEIGcmpFunctionCoeffU must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
          CHECK (!(cfg_gcmpSEIFunctionUAffectedByVFlag.values.size() == numFace), "Number of SEIGcmpFunctionUAffectedByVFlag must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
          CHECK (!(cfg_gcmpSEIFunctionCoeffV.values.size()           == numFace), "Number of SEIGcmpFunctionCoeffV must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
          CHECK (!(cfg_gcmpSEIFunctionVAffectedByUFlag.values.size() == numFace), "Number of SEIGcmpFunctionVAffectedByUFlag must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
          m_gcmpSEIFunctionCoeffU.resize(numFace);
          m_gcmpSEIFunctionUAffectedByVFlag.resize(numFace);
          m_gcmpSEIFunctionCoeffV.resize(numFace);
          m_gcmpSEIFunctionVAffectedByUFlag.resize(numFace);
        }
        for (int i = 0; i < numFace; i++)
        {
          m_gcmpSEIFaceIndex[i]                = cfg_gcmpSEIFaceIndex.values[i];
          m_gcmpSEIFaceRotation[i]             = cfg_gcmpSEIFaceRotation.values[i];
          if (m_gcmpSEIMappingFunctionType == 2)
          {
            m_gcmpSEIFunctionCoeffU[i]           = cfg_gcmpSEIFunctionCoeffU.values[i];
            m_gcmpSEIFunctionUAffectedByVFlag[i] = cfg_gcmpSEIFunctionUAffectedByVFlag.values[i];
            m_gcmpSEIFunctionCoeffV[i]           = cfg_gcmpSEIFunctionCoeffV.values[i];
            m_gcmpSEIFunctionVAffectedByUFlag[i] = cfg_gcmpSEIFunctionVAffectedByUFlag.values[i];
          }
        }
      }
    
      if ( m_sdiSEIEnabled )
      {
        if (m_sdiSEIMultiviewInfoFlag || m_sdiSEIAuxiliaryInfoFlag)
        {
          m_sdiSEILayerId.resize(m_sdiSEIMaxLayersMinus1 + 1);
          m_sdiSEIViewIdVal.resize(m_sdiSEIMaxLayersMinus1 + 1);
          m_sdiSEIAuxId.resize(m_sdiSEIMaxLayersMinus1 + 1);
          m_sdiSEINumAssociatedPrimaryLayersMinus1.resize(m_sdiSEIMaxLayersMinus1 + 1);
    
    Jie Chen's avatar
    Jie Chen committed
    #if JVET_AI0153_OMI_SEI
          uint32_t associatedPrimaryLayerIdxListCnt = 0;
    #endif
    
          for (int i = 0; i <= m_sdiSEIMaxLayersMinus1; i++)
          {
            m_sdiSEILayerId[i] = cfg_sdiSEILayerId.values[i];
            if (m_sdiSEIMultiviewInfoFlag)
            {
              m_sdiSEIViewIdVal[i] = cfg_sdiSEIViewIdVal.values[i];
            }
            if (m_sdiSEIAuxiliaryInfoFlag)
            {
              m_sdiSEIAuxId[i] = cfg_sdiSEIAuxId.values[i];
              if (m_sdiSEIAuxId[i] > 0)
              {
                m_sdiSEINumAssociatedPrimaryLayersMinus1[i] = cfg_sdiSEINumAssociatedPrimaryLayersMinus1.values[i];
    
    Jie Chen's avatar
    Jie Chen committed
    #if JVET_AI0153_OMI_SEI
                m_sdiSEIAssociatedPrimaryLayerIdx.resize(associatedPrimaryLayerIdxListCnt + m_sdiSEINumAssociatedPrimaryLayersMinus1[i] + 1);
                for (uint32_t k = 0; k <= m_sdiSEINumAssociatedPrimaryLayersMinus1[i]; k++)
                {
                  m_sdiSEIAssociatedPrimaryLayerIdx[associatedPrimaryLayerIdxListCnt + k] = cfg_sdiSEIAssociatedPrimaryLayerIdx.values[associatedPrimaryLayerIdxListCnt + k];
                }
                associatedPrimaryLayerIdxListCnt += (m_sdiSEINumAssociatedPrimaryLayersMinus1[i] + 1);
    #endif
    
              }
            }
          }
        }
      }
      if ( m_maiSEIEnabled )
      {
        if (m_maiSEIIntrinsicParamFlag)
        {
          int numViews = m_maiSEIIntrinsicParamsEqualFlag ? 1 : m_maiSEINumViewsMinus1 + 1;
          m_maiSEISignFocalLengthX       .resize( numViews );
          m_maiSEIExponentFocalLengthX   .resize( numViews );
          m_maiSEIMantissaFocalLengthX   .resize( numViews );
          m_maiSEISignFocalLengthY       .resize( numViews );
          m_maiSEIExponentFocalLengthY   .resize( numViews );
          m_maiSEIMantissaFocalLengthY   .resize( numViews );
          m_maiSEISignPrincipalPointX    .resize( numViews );
          m_maiSEIExponentPrincipalPointX.resize( numViews );
          m_maiSEIMantissaPrincipalPointX.resize( numViews );
          m_maiSEISignPrincipalPointY    .resize( numViews );
          m_maiSEIExponentPrincipalPointY.resize( numViews );
          m_maiSEIMantissaPrincipalPointY.resize( numViews );
          m_maiSEISignSkewFactor         .resize( numViews );
          m_maiSEIExponentSkewFactor     .resize( numViews );
          m_maiSEIMantissaSkewFactor     .resize( numViews );
          for( int i = 0; i  <=  ( m_maiSEIIntrinsicParamsEqualFlag ? 0 : m_maiSEINumViewsMinus1 ); i++ )
          {
            m_maiSEISignFocalLengthX       [i] = cfg_maiSEISignFocalLengthX.values[i];
            m_maiSEIExponentFocalLengthX   [i] = cfg_maiSEIExponentFocalLengthX.values[i];
            m_maiSEIMantissaFocalLengthX   [i] = cfg_maiSEIMantissaFocalLengthX.values[i];
            m_maiSEISignFocalLengthY       [i] = cfg_maiSEISignFocalLengthY.values[i];
            m_maiSEIExponentFocalLengthY   [i] = cfg_maiSEIExponentFocalLengthY.values[i];
            m_maiSEIMantissaFocalLengthY   [i] = cfg_maiSEIMantissaFocalLengthY.values[i];
            m_maiSEISignPrincipalPointX    [i] = cfg_maiSEISignPrincipalPointX.values[i];
            m_maiSEIExponentPrincipalPointX[i] = cfg_maiSEIExponentPrincipalPointX.values[i];
            m_maiSEIMantissaPrincipalPointX[i] = cfg_maiSEIMantissaPrincipalPointX.values[i];
            m_maiSEISignPrincipalPointY    [i] = cfg_maiSEISignPrincipalPointY.values[i];
            m_maiSEIExponentPrincipalPointY[i] = cfg_maiSEIExponentPrincipalPointY.values[i];
            m_maiSEIMantissaPrincipalPointY[i] = cfg_maiSEIMantissaPrincipalPointY.values[i];
            m_maiSEISignSkewFactor         [i] = cfg_maiSEISignSkewFactor.values[i];
            m_maiSEIExponentSkewFactor     [i] = cfg_maiSEIExponentSkewFactor.values[i];
            m_maiSEIMantissaSkewFactor     [i] = cfg_maiSEIMantissaSkewFactor.values[i];
          }
        }
      }
    
      if (m_mvpSEIEnabled)
      {
        int numViews = m_mvpSEINumViewsMinus1 + 1;
        m_mvpSEIViewPosition.resize(numViews);
        for (int i = 0; i <= m_mvpSEINumViewsMinus1; i++)
        {
    
    Byeongdoo Choi's avatar
    Byeongdoo Choi committed
          m_mvpSEIViewPosition[i] = cfg_mvpSEIViewPosition.values[i];
    
      if ( m_driSEIEnabled )
      {
        m_driSEINonlinearModel.resize(m_driSEINonlinearNumMinus1+1);
        for(int i=0; i<(m_driSEINonlinearNumMinus1+1); i++)
        {
          m_driSEINonlinearModel[i]   = cfg_driSEINonlinearModel.values.size() > i ? cfg_driSEINonlinearModel.values[i] : 0;
        }
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_reshapeCW.binCW.resize(3);
    
      m_reshapeCW.rspFps     = m_frameRate.getIntValRound();
    
      m_reshapeCW.rspPicSize = m_sourceWidth*m_sourceHeight;
    
      m_reshapeCW.rspFpsToIp = std::max(16, 16 * (int) (round(m_frameRate.getFloatVal() / 16.0)));
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_reshapeCW.rspBaseQP = m_iQP;
    
      m_reshapeCW.updateCtrl = m_updateCtrl;
      m_reshapeCW.adpOption = m_adpOption;
      m_reshapeCW.initialCW = m_initialCW;
    
    #if ENABLE_TRACING
      g_trace_ctx = tracing_init(sTracingFile, sTracingRule);
      if( bTracingChannelsList && g_trace_ctx )
      {
        std::string sChannelsList;
        g_trace_ctx->getChannelsList( sChannelsList );
        msg( INFO, "\n Using tracing channels:\n\n%s\n", sChannelsList.c_str() );
      }
    #endif
    
    #if ENABLE_QPA
    
      if (m_bUsePerceptQPA && !m_bUseAdaptiveQP && m_dualTree && (m_cbQpOffsetDualTree != 0 || m_crQpOffsetDualTree != 0 || m_cbCrQpOffsetDualTree != 0))
    
      {
        msg( WARNING, "*************************************************************************\n" );
        msg( WARNING, "* WARNING: chroma QPA on, ignoring nonzero dual-tree chroma QP offsets! *\n" );
        msg( WARNING, "*************************************************************************\n" );
      }
    
    
      if ((m_iQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceWidth <= 2048) && (m_sourceHeight <= 1280)
    
    Frank Bossen's avatar
    Frank Bossen committed
    #if WCG_EXT && ER_CHROMA_QP_WCG_PPS
    
          && (!m_wcgChromaQpControl.enabled)
    
    Frank Bossen's avatar
    Frank Bossen committed
    #endif
          && ((1 << (m_log2MaxTbSize + 1)) == m_ctuSize) && (m_sourceWidth > 512 || m_sourceHeight > 320))
    
        m_cuQpDeltaSubdiv = 2;
    
    Frank Bossen's avatar
    Frank Bossen committed
      if ((m_iQP < 38) && (m_gopSize > 4) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceHeight <= 1280)
          && (m_sourceWidth <= 2048))
    
        msg( WARNING, "*************************************************************************\n" );
        msg( WARNING, "* WARNING: QPA on with large CTU for <=HD sequences, limiting CTU size! *\n" );
        msg( WARNING, "*************************************************************************\n" );
    
    Frank Bossen's avatar
    Frank Bossen committed
        m_ctuSize = m_maxCuWidth;
        if ((1u << m_log2MaxTbSize) > m_ctuSize)
        {
          m_log2MaxTbSize--;
        }
    
      m_ShutterFilterEnable = false;
      if (m_siiSEIEnabled)
      {
        assert(m_siiSEITimeScale >= 0 && m_siiSEITimeScale <= MAX_UINT);
        uint32_t sii_max_sub_layers = (uint32_t)cfg_siiSEIInputNumUnitsInSI.values.size();
        assert(sii_max_sub_layers > 0);
        if (sii_max_sub_layers > 1)
        {
          m_siiSEISubLayerNumUnitsInSI.resize(sii_max_sub_layers);
          for (int32_t i = 0; i < sii_max_sub_layers; i++)
          {
            m_siiSEISubLayerNumUnitsInSI[i] = cfg_siiSEIInputNumUnitsInSI.values[i];
            assert(m_siiSEISubLayerNumUnitsInSI[i] >= 0 && m_siiSEISubLayerNumUnitsInSI[i] <= MAX_UINT);
          }
        }
        else
        {
          m_siiSEINumUnitsInShutterInterval = cfg_siiSEIInputNumUnitsInSI.values[0];
          assert(m_siiSEINumUnitsInShutterInterval >= 0 && m_siiSEINumUnitsInShutterInterval <= MAX_UINT);
        }
        uint32_t siiMaxSubLayersMinus1 = sii_max_sub_layers - 1;
        int blending_ratio = (m_siiSEISubLayerNumUnitsInSI[0] / m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1]);
    
        if (sii_max_sub_layers > 1 && m_siiSEISubLayerNumUnitsInSI[0] ==
                                    (blending_ratio * m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1]))
        {
          m_ShutterFilterEnable = true;
    
          double  fpsHFR        = m_frameRate.getFloatVal();
    
          bool    checkEqualValuesOfSFR = true;
          bool    checkSubLayerSI       = false;
    
          double shutterAngleFactor = (fpsHFR * ((double)(m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1])))/((double)m_siiSEITimeScale);
    
    
          // If shutterAngleFactor = 1 indicates that shutterAngle = 360
    
          // If shutterAngleFactor = 0.5 indicates that shutterAngle = 180
          // If shutterAngleFactor = 0.25 indicates that shutterAngle = 90
    
          if (shutterAngleFactor < 0.5)
          {
            for (int i = 0; i < siiMaxSubLayersMinus1; i++)
            {
              m_siiSEISubLayerNumUnitsInSI[i] = m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1];
            }
            m_ShutterFilterEnable = false;
            printf("Warning: For the shutterAngle = %d, the blending can't be applied\n", (int)(shutterAngleFactor * 360));
          }
    
          // supports only the case of SFR = HFR / 2
    
          if (m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1] < m_siiSEISubLayerNumUnitsInSI[siiMaxSubLayersMinus1 - 1])
          {
    
            checkSubLayerSI = true;
    
          }
          // check shutter interval for all sublayer remains same for LFR pictures
          for (i = 1; i < siiMaxSubLayersMinus1; i++)
          {
            if (m_siiSEISubLayerNumUnitsInSI[0] != m_siiSEISubLayerNumUnitsInSI[i])
            {
    
              checkEqualValuesOfSFR = false;
    
            }
          }
          if (checkSubLayerSI && checkEqualValuesOfSFR)
          {
            setBlendingRatioSII(blending_ratio);
          }
          else
          {
            m_ShutterFilterEnable = false;
          }
        }
        else
        {
          printf("Warning: SII-processing is applied for multiple shutter intervals and number of LFR units should be 2 times of number of HFR units\n");
        }
      }
    
        CHECK(cfg_poSEIPayloadType.values.size() <= 1, "there should be at least 2 SEIPOPayLoadType");
        CHECK(cfg_poSEIProcessingOrder.values.size() != cfg_poSEIPayloadType.values.size(), "the number of SEIPOPayLoadType should be equal to the number of SEIPOProcessingOrder");
        CHECK(cfg_poSEIPrefixFlag.values.size() <= 1, "there should be at least 2 SEIPOPrefixFlag");
    
    Taoran Lu's avatar
    Taoran Lu committed
        CHECK(cfg_poSEIPayloadType.values.size() != m_poSEINumMinus2 + 2, "the number of SEIPOPayLoadType should be equal to the number of SEI messages");
        CHECK(cfg_poSEIWrappingFlag.values.size() != m_poSEINumMinus2 + 2, "the number of SEIPOWrappingFlag should be equal to the number of SEI messages");
        CHECK(cfg_poSEIImportanceFlag.values.size() != m_poSEINumMinus2 + 2, "the number of SEIImportanceFlag should be equal to the number of SEI messages");
        m_poSEIWrappingFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size());
        m_poSEIImportanceFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size());
    
        m_poSEIPrefixFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size());
    
        m_poSEIPayloadType.resize((uint32_t) cfg_poSEIPayloadType.values.size());
        m_poSEIProcessingOrder.resize((uint32_t) cfg_poSEIPayloadType.values.size());
    
        m_poSEINumOfPrefixBits.resize((uint32_t) cfg_poSEINumofPrefixBits.values.size());
    
        m_poSEIPrefixByte.resize((uint32_t) cfg_poSEIPayloadType.values.size());
    
    Taoran Lu's avatar
    Taoran Lu committed
        for (uint32_t i = 0; i < (m_poSEINumMinus2 + 2); i++)
    
          m_poSEIPrefixFlag[i] =      cfg_poSEIPrefixFlag.values[i];
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_poSEIWrappingFlag[i] = cfg_poSEIWrappingFlag.values[i];
          m_poSEIImportanceFlag[i] = cfg_poSEIImportanceFlag.values[i];
    
          m_poSEIPayloadType[i]     = cfg_poSEIPayloadType.values[i];
    
          if (m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::MASTERING_DISPLAY_COLOUR_VOLUME ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::CONTENT_LIGHT_LEVEL_INFO ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::ALTERNATIVE_TRANSFER_CHARACTERISTICS ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::AMBIENT_VIEWING_ENVIRONMENT ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::MULTIVIEW_ACQUISITION_INFO ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::MULTIVIEW_VIEW_POSITION ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::SEI_MANIFEST ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::SEI_PREFIX_INDICATION ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::VDI_SEI_ENVELOPE ||
              m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::SEI_PROCESSING_ORDER
            )
          {
    
            CHECK(m_poSEIPrefixFlag[i] == true, "The value of po_sei_prefix_flag shall be equal to 0 when po_sei_payload_type is equal to 137, 144, 147, 148, 179, 180, 200, 201, 208, and 213");
    
          m_poSEIProcessingOrder[i] = (uint16_t) cfg_poSEIProcessingOrder.values[i];
    
          if (m_poSEIPrefixFlag[i])
    
            m_poSEINumOfPrefixBits[i] = cfg_poSEINumofPrefixBits.values[i];
            m_poSEIPrefixByte[i].resize((cfg_poSEINumofPrefixBits.values[i] + 7) >> 3);
            for (uint32_t j = 0; j < (uint32_t)m_poSEIPrefixByte[i].size(); j++)
    
              m_poSEIPrefixByte[i][j] = (uint8_t) cfg_poSEIPrefixByte.values[prefixByteIdx++];
    
            cfg_poSEINumofPrefixBits.values[i] = 0;
            m_poSEINumOfPrefixBits[i] = 0;
    
          // Error check, to avoid same PayloadType and same prefix bytes when present with different PayloadOrder
    
            if (m_poSEIPrefixFlag[i])
            {
                if ((m_poSEIPayloadType[j] == m_poSEIPayloadType[i]) && m_poSEIPrefixFlag[j])
    
                  auto numofPrefixBytes = std::min((cfg_poSEINumofPrefixBits.values[i] + 7) >> 3, (cfg_poSEINumofPrefixBits.values[j] + 7) >> 3);
    
                  if (std::equal(m_poSEIPrefixByte[i].begin() + 1, m_poSEIPrefixByte[i].begin() + numofPrefixBytes - 1,
                                 m_poSEIPrefixByte[j].begin()))
    
                    CHECK(m_poSEIProcessingOrder[j] != m_poSEIProcessingOrder[i], "multiple SEI messages with the same po_sei_payload_type and prefix content present when present shall have the same value of po_sei_processing_order");
    
            }
            else
            {
              if (m_poSEIPayloadType[j] == m_poSEIPayloadType[i])
              {
    
                CHECK(m_poSEIProcessingOrder[j] != m_poSEIProcessingOrder[i], "multiple SEI messages with the same po_sei_payload_type without prefix content shall have the same value of po_sei_processing_order");
    
      if (m_postFilterHintSEIEnabled)
      {
    
        CHECK(cfg_postFilterHintSEIValues.values.size() <= 0, "The number of filter coefficient shall be greater than zero");
        CHECK(!(cfg_postFilterHintSEIValues.values.size() == ((m_postFilterHintSEIChromaCoeffPresentFlag ? 3 : 1) * m_postFilterHintSEISizeY * m_postFilterHintSEISizeX)), "The number of filter coefficient shall match the matrix size and considering whether filters for chroma is present of not");
    
        m_postFilterHintValues.resize(cfg_postFilterHintSEIValues.values.size());
    
        for (uint32_t i = 0; i < m_postFilterHintValues.size(); i++)
        {
          m_postFilterHintValues[i] = cfg_postFilterHintSEIValues.values[i];
        }
      }
    
    
      if( m_costMode == COST_LOSSLESS_CODING )
      {
    
        bool firstSliceLossless = false;
        if (m_mixedLossyLossless)
        {
          if (m_sliceLosslessArray.size() > 0)
          {
            for (uint32_t i = 0; i < m_sliceLosslessArray.size(); i++)
            {
              if (m_sliceLosslessArray[i] == 0)
              {
                firstSliceLossless = true;
                break;
              }
            }
          }
        }
        else
        {
          firstSliceLossless = true;
        }
    
    Frank Bossen's avatar
    Frank Bossen committed
        if (firstSliceLossless) // if first slice is lossless
    
          m_iQP = LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP - ((m_internalBitDepth[ChannelType::LUMA] - 8) * 6);
    
    Frank Bossen's avatar
    Frank Bossen committed
      m_maxCuWidth = m_maxCuHeight = m_ctuSize;
    
    #if JVET_AH0078_DPF
      CHECK(m_bimEnabled && m_dpfEnabled, "DPF is not compatible with BIM");
      CHECK(m_dpfEnabled && m_resChangeInClvsEnabled, "DPF is not compatible with resolution change in CLVS");
    #endif
    
    
      // check validity of input parameters
      if( xCheckParameter() )
      {
        // return check failed
        return false;
      }
    
      // print-out parameters
      xPrintParameter();
    
      return true;
    }
    
    #ifdef _MSC_VER
    // Restore optimizations
    
    #pragma optimize( "", on )
    #endif
    
    
    
    // ====================================================================================================================
    // Private member functions
    // ====================================================================================================================
    
    
    ///< auto determine the profile to use given the other configuration settings. Returns 1 if erred. Can select profile 'NONE'
    
    int EncAppCfg::xAutoDetermineProfile()
    {
    
      const int maxBitDepth =
        std::max(m_internalBitDepth[ChannelType::LUMA], m_internalBitDepth[getLastChannel(m_chromaFormatIdc)]);
    
      m_profile=Profile::NONE;
    
    
      switch (m_chromaFormatIdc)
    
      case ChromaFormat::_400:
      case ChromaFormat::_420:
    
        if (maxBitDepth <= 10)
        {
    
    Frank Bossen's avatar
    Frank Bossen committed
          if (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1)
          {
            m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10_STILL_PICTURE : Profile::MAIN_10_STILL_PICTURE;
          }
          else
          {
            m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10 : Profile::MAIN_10;
          }
    
    Frank Bossen's avatar
    Frank Bossen committed
          m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_STILL_PICTURE
                      : (m_intraPeriod == 1)                                    ? Profile::MAIN_12_INTRA
                                                                                : Profile::MAIN_12;
    
        }
        else if (maxBitDepth <= 16)
        {
          // Since there's no 16bit 420 profiles in VVC, we use 444 profiles.
    
    Frank Bossen's avatar
    Frank Bossen committed
          m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE
                      : (m_intraPeriod == 1)                                    ? Profile::MAIN_16_444_INTRA
                                                                                : Profile::MAIN_16_444;
    
      case ChromaFormat::_422:
      case ChromaFormat::_444:
    
        if (maxBitDepth <= 10)
        {
    
    Frank Bossen's avatar
    Frank Bossen committed
          if (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1)
          {
            m_profile =
              m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE : Profile::MAIN_10_444_STILL_PICTURE;
          }
          else
          {
            m_profile = m_maxLayers > 1 ? Profile::MULTILAYER_MAIN_10_444 : Profile::MAIN_10_444;
          }
    
    Frank Bossen's avatar
    Frank Bossen committed
          m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_12_444_STILL_PICTURE
                      : (m_intraPeriod == 1)                                    ? Profile::MAIN_12_444_INTRA
                                                                                : Profile::MAIN_12_444;
    
    Frank Bossen's avatar
    Frank Bossen committed
          m_profile = (m_level == Level::LEVEL15_5 && m_framesToBeEncoded == 1) ? Profile::MAIN_16_444_STILL_PICTURE
                      : (m_intraPeriod == 1)                                    ? Profile::MAIN_16_444_INTRA
                                                                                : Profile::MAIN_16_444;
    
        break;
    
      default: return 1;
      }
    
      if (m_profile == Profile::MAIN_12_INTRA || m_profile == Profile::MAIN_12_444_INTRA || m_profile == Profile::MAIN_16_444_INTRA ||
          m_profile == Profile::MAIN_12_STILL_PICTURE || m_profile == Profile::MAIN_12_444_STILL_PICTURE || m_profile == Profile::MAIN_16_444_STILL_PICTURE)
      {
        m_allRapPicturesFlag = 1;
      }
    
    bool EncAppCfg::xCheckParameter()
    {
      msg( NOTICE, "\n" );
    
      if (m_decodedPictureHashSEIType == HashType::NONE)
    
      {
        msg( DETAILS, "******************************************************************\n");
        msg( DETAILS, "** WARNING: --SEIDecodedPictureHash is now disabled by default. **\n");
        msg( DETAILS, "**          Automatic verification of decoded pictures by a     **\n");
        msg( DETAILS, "**          decoder requires this option to be enabled.         **\n");
        msg( DETAILS, "******************************************************************\n");
      }
      if( m_profile==Profile::NONE )
      {
        msg( DETAILS, "***************************************************************************\n");
        msg( DETAILS, "** WARNING: For conforming bitstreams a valid Profile value must be set! **\n");
        msg( DETAILS, "***************************************************************************\n");
      }
      if( m_level==Level::NONE )
      {
        msg( DETAILS, "***************************************************************************\n");
        msg( DETAILS, "** WARNING: For conforming bitstreams a valid Level value must be set!   **\n");
        msg( DETAILS, "***************************************************************************\n");
      }
    
      bool check_failed = false; /* abort if there is a fatal configuration problem */
    #define xConfirmPara(a,b) check_failed |= confirmPara(a,b)
    
    
      xConfirmPara(m_alfapsIDShift < 0, "ALF APSs shift should be positive");