Skip to content
Snippets Groups Projects
EncAppCfg.cpp 314 KiB
Newer Older
  • Learn to ignore specific revisions
  •       }
        }
    
        // store raster-scan slice sizes
    
        {
          m_rasterSliceSize.resize(cfgRasterSliceSize.values.size());
          for(uint32_t i=0; i<cfgRasterSliceSize.values.size(); i++)
          {
            m_rasterSliceSize[i]=cfgRasterSliceSize.values[i];
          }
        }
      }
    
      {
        m_tileColumnWidth.clear();
        m_tileRowHeight.clear();
        m_rectSlicePos.clear();
        m_rasterSliceSize.clear();
        m_rectSliceFixedWidth = 0;
        m_rectSliceFixedHeight = 0;
      }
    
    
      m_numSubProfile = (uint8_t) cfg_SubProfile.values.size();
      m_subProfile.resize(m_numSubProfile);
      for (uint8_t i = 0; i < m_numSubProfile; ++i)
      {
        m_subProfile[i] = cfg_SubProfile.values[i];
      }
    
      /* rules for input, output and internal bitdepths as per help text */
      if (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ] == 0)
      {
        m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ] = m_inputBitDepth      [CHANNEL_TYPE_LUMA  ];
      }
      if (m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] == 0)
      {
        m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] = m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ];
      }
      if (m_internalBitDepth   [CHANNEL_TYPE_LUMA  ] == 0)
      {
        m_internalBitDepth   [CHANNEL_TYPE_LUMA  ] = m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ];
      }
        m_internalBitDepth   [CHANNEL_TYPE_CHROMA] = m_internalBitDepth   [CHANNEL_TYPE_LUMA  ];
      if (m_inputBitDepth      [CHANNEL_TYPE_CHROMA] == 0)
      {
        m_inputBitDepth      [CHANNEL_TYPE_CHROMA] = m_inputBitDepth      [CHANNEL_TYPE_LUMA  ];
      }
      if (m_outputBitDepth     [CHANNEL_TYPE_LUMA  ] == 0)
      {
        m_outputBitDepth     [CHANNEL_TYPE_LUMA  ] = m_internalBitDepth   [CHANNEL_TYPE_LUMA  ];
      }
      if (m_outputBitDepth     [CHANNEL_TYPE_CHROMA] == 0)
      {
        m_outputBitDepth     [CHANNEL_TYPE_CHROMA] = m_outputBitDepth     [CHANNEL_TYPE_LUMA  ];
      }
    
    
      m_InputChromaFormatIDC = numberToChromaFormat(tmpInputChromaFormat);
      m_chromaFormatIDC      = ((tmpChromaFormat == 0) ? (m_InputChromaFormatIDC) : (numberToChromaFormat(tmpChromaFormat)));
    #if EXTENSION_360_VIDEO
      m_ext360.processOptions(ext360CfgContext);
    #endif
    
      CHECK( !( tmpWeightedPredictionMethod >= 0 && tmpWeightedPredictionMethod <= WP_PER_PICTURE_WITH_HISTOGRAM_AND_PER_COMPONENT_AND_CLIPPING_AND_EXTENSION ), "Error in cfg" );
      m_weightedPredictionMethod = WeightedPredictionMethod(tmpWeightedPredictionMethod);
    
      CHECK( tmpFastInterSearchMode<0 || tmpFastInterSearchMode>FASTINTERSEARCH_MODE3, "Error in cfg" );
      m_fastInterSearchMode = FastInterSearchMode(tmpFastInterSearchMode);
    
      CHECK( tmpMotionEstimationSearchMethod < 0 || tmpMotionEstimationSearchMethod >= MESEARCH_NUMBER_OF_METHODS, "Error in cfg" );
      m_motionEstimationSearchMethod=MESearchMethod(tmpMotionEstimationSearchMethod);
    
    
      if (extendedProfile == ExtendedProfileName::AUTO)
      {
        if (xAutoDetermineProfile())
        {
          EXIT( "Unable to determine profile from configured settings");
        }
      }
    
        switch (extendedProfile)
        {
    
        case ExtendedProfileName::NONE: m_profile = Profile::NONE; break;
        case ExtendedProfileName::MAIN_10: m_profile = Profile::MAIN_10; break;
        case ExtendedProfileName::MAIN_10_444: m_profile = Profile::MAIN_10_444; break;
        case ExtendedProfileName::MAIN_10_STILL_PICTURE: m_profile = Profile::MAIN_10_STILL_PICTURE; break;
        case ExtendedProfileName::MAIN_10_444_STILL_PICTURE: m_profile = Profile::MAIN_10_444_STILL_PICTURE; break;
        case ExtendedProfileName::MULTILAYER_MAIN_10: m_profile = Profile::MULTILAYER_MAIN_10; break;
        case ExtendedProfileName::MULTILAYER_MAIN_10_444: m_profile = Profile::MULTILAYER_MAIN_10_444; break;
        case ExtendedProfileName::MULTILAYER_MAIN_10_STILL_PICTURE:
          m_profile = Profile::MULTILAYER_MAIN_10_STILL_PICTURE;
          break;
        case ExtendedProfileName::MULTILAYER_MAIN_10_444_STILL_PICTURE:
          m_profile = Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE;
          break;
        default: EXIT("Unable to determine profile from configured settings"); break;
    
      {
        m_chromaFormatConstraint       = (tmpConstraintChromaFormat == 0) ? m_chromaFormatIDC : numberToChromaFormat(tmpConstraintChromaFormat);
        if (m_bitDepthConstraint == 0)
        {
    
          if (m_profile != Profile::NONE)
          {
            const ProfileFeatures *features = ProfileFeatures::getProfileFeatures(m_profile);
            CHECK(features->profile != m_profile, "Profile not found");
            m_bitDepthConstraint = features->maxBitDepth;
          }
    
          else // m_profile == Profile::NONE
          {
    
            m_bitDepthConstraint = 16; // max value - unconstrained.
    
        CHECK(m_bitDepthConstraint < m_internalBitDepth[CHANNEL_TYPE_LUMA], "MaxBitDepthConstraint setting does not allow the specified luma bit depth to be coded.");
        CHECK(m_bitDepthConstraint < m_internalBitDepth[CHANNEL_TYPE_CHROMA], "MaxBitDepthConstraint setting does not allow the specified chroma bit depth to be coded.");
        CHECK(m_chromaFormatConstraint < m_chromaFormatIDC, "MaxChromaFormatConstraint setting does not allow the specified chroma format to be coded.");
        CHECK(m_chromaFormatConstraint >= NUM_CHROMA_FORMAT, "Bad value given for MaxChromaFormatConstraint setting.")
        CHECK(m_bitDepthConstraint < 8 || m_bitDepthConstraint>16, "MaxBitDepthConstraint setting must be in the range 8 to 16 (inclusive)");
    
    
      m_inputColourSpaceConvert = stringToInputColourSpaceConvert(inputColourSpaceConvert, true);
    
      m_rgbFormat = (m_inputColourSpaceConvert == IPCOLOURSPACE_RGBtoGBR && m_chromaFormatIDC == CHROMA_444) ? true : false;
    
      // Picture width and height must be multiples of 8 and minCuSize
      const int minResolutionMultiple = std::max(8, 1 << m_log2MinCuSize);
    
      switch (m_conformanceWindowMode)
      {
      case 0:
        {
          // no conformance or padding
          m_confWinLeft = m_confWinRight = m_confWinTop = m_confWinBottom = 0;
    
          m_sourcePadding[1] = m_sourcePadding[0] = 0;
    
          if (m_sourceWidth % minResolutionMultiple)
    
            m_sourcePadding[0] = m_confWinRight  = ((m_sourceWidth / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceWidth;
            m_sourceWidth  += m_confWinRight;
    
          if (m_sourceHeight % minResolutionMultiple)
    
            m_sourcePadding[1] = m_confWinBottom = ((m_sourceHeight / minResolutionMultiple) + 1) * minResolutionMultiple - m_sourceHeight;
            m_sourceHeight += m_confWinBottom;
    
            if ( m_isField )
            {
              m_iSourceHeightOrg += m_confWinBottom << 1;
    
              m_sourcePadding[1] = m_confWinBottom << 1;
    
          if (m_sourcePadding[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0)
    
          {
            EXIT( "Error: picture width is not an integer multiple of the specified chroma subsampling");
          }
    
          if (m_sourcePadding[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0)
    
          {
            EXIT( "Error: picture height is not an integer multiple of the specified chroma subsampling");
          }
    
          if (m_sourcePadding[0])
          {
            msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel horizontally\n", m_sourcePadding[0]);
          }
          if (m_sourcePadding[1])
          {
            msg( INFO, "Info: Conformance window automatically enabled. Adding %i lumal pel vertically\n", m_sourcePadding[1]);
          }
    
          m_sourceWidth  += m_sourcePadding[0];
          m_sourceHeight += m_sourcePadding[1];
          m_confWinRight  = m_sourcePadding[0];
          m_confWinBottom = m_sourcePadding[1];
    
          break;
        }
      case 3:
        {
          // conformance
          if ((m_confWinLeft == 0) && (m_confWinRight == 0) && (m_confWinTop == 0) && (m_confWinBottom == 0))
          {
            msg( ERROR, "Warning: Conformance window enabled, but all conformance window parameters set to zero\n");
          }
    
          if ((m_sourcePadding[1] != 0) || (m_sourcePadding[0]!=0))
    
          {
            msg( ERROR, "Warning: Conformance window enabled, padding parameters will be ignored\n");
          }
    
          m_sourcePadding[1] = m_sourcePadding[0] = 0;
    
      CHECK(((m_sourceWidth% minResolutionMultiple) || (m_sourceHeight % minResolutionMultiple)), "Picture width or height (after padding) is not a multiple of 8 or minCuSize, please use ConformanceWindowMode=1 for automatic adjustment or ConformanceWindowMode=2 to specify padding manually!!");
    
      if( m_conformanceWindowMode > 0 && m_subPicInfoPresentFlag )
      {
        for(int i = 0; i < m_numSubPics; i++)
        {
    
          CHECK( (m_subPicCtuTopLeftX[i] * m_uiCTUSize) >= (m_sourceWidth - m_confWinRight * SPS::getWinUnitX(m_chromaFormatIDC)),
    
              "No subpicture can be located completely outside of the conformance cropping window");
          CHECK( ((m_subPicCtuTopLeftX[i] + m_subPicWidth[i]) * m_uiCTUSize) <= (m_confWinLeft * SPS::getWinUnitX(m_chromaFormatIDC)),
    	  "No subpicture can be located completely outside of the conformance cropping window" );
    
          CHECK( (m_subPicCtuTopLeftY[i] * m_uiCTUSize) >= (m_sourceHeight  - m_confWinBottom * SPS::getWinUnitY(m_chromaFormatIDC)),
    
              "No subpicture can be located completely outside of the conformance cropping window");
          CHECK( ((m_subPicCtuTopLeftY[i] + m_subPicHeight[i]) * m_uiCTUSize) <= (m_confWinTop * SPS::getWinUnitY(m_chromaFormatIDC)),
              "No subpicture can be located completely outside of the conformance cropping window");
        }
      }
    
      if (tmpDecodedPictureHashSEIMappedType<0 || tmpDecodedPictureHashSEIMappedType>=int(NUMBER_OF_HASHTYPES))
      {
        EXIT( "Error: bad checksum mode");
      }
      // Need to map values to match those of the SEI message:
      if (tmpDecodedPictureHashSEIMappedType==0)
      {
        m_decodedPictureHashSEIType=HASHTYPE_NONE;
      }
      else
      {
        m_decodedPictureHashSEIType=HashType(tmpDecodedPictureHashSEIMappedType-1);
      }
    
      // Need to map values to match those of the SEI message:
      if (tmpSubpicDecodedPictureHashMappedType==0)
      {
        m_subpicDecodedPictureHashType=HASHTYPE_NONE;
      }
      else
      {
        m_subpicDecodedPictureHashType=HashType(tmpSubpicDecodedPictureHashMappedType-1);
      }
    
      // allocate slice-based dQP values
      m_aidQP = new int[ m_framesToBeEncoded + m_iGOPSize + 1 ];
      ::memset( m_aidQP, 0, sizeof(int)*( m_framesToBeEncoded + m_iGOPSize + 1 ) );
    
    #if QP_SWITCHING_FOR_PARALLEL
      if (m_qpIncrementAtSourceFrame.bPresent)
      {
        uint32_t switchingPOC = 0;
        if (m_qpIncrementAtSourceFrame.value > m_FrameSkip)
        {
          // if switch source frame (ssf) = 10, and frame skip (fs)=2 and temporal subsample ratio (tsr) =1, then
          //    for this simulation switch at POC 8 (=10-2).
          // if ssf=10, fs=2, tsr=2, then for this simulation, switch at POC 4 (=(10-2)/2): POC0=Src2, POC1=Src4, POC2=Src6, POC3=Src8, POC4=Src10
          switchingPOC = (m_qpIncrementAtSourceFrame.value - m_FrameSkip) / m_temporalSubsampleRatio;
        }
        for (uint32_t i = switchingPOC; i<(m_framesToBeEncoded + m_iGOPSize + 1); i++)
        {
          m_aidQP[i] = 1;
        }
      }
    #else
      // handling of floating-point QP values
      // if QP is not integer, sequence is split into two sections having QP and QP+1
      m_iQP = (int)( m_fQP );
      if ( m_iQP < m_fQP )
      {
        int iSwitchPOC = (int)( m_framesToBeEncoded - (m_fQP - m_iQP)*m_framesToBeEncoded + 0.5 );
    
        iSwitchPOC = (int)( (double)iSwitchPOC / m_iGOPSize + 0.5 )*m_iGOPSize;
        for ( int i=iSwitchPOC; i<m_framesToBeEncoded + m_iGOPSize + 1; i++ )
        {
          m_aidQP[i] = 1;
        }
      }
    #endif
    
    
    #if SHARP_LUMA_DELTA_QP
      CHECK( lumaLevelToDeltaQPMode >= LUMALVL_TO_DQP_NUM_MODES, "Error in cfg" );
    
      m_lumaLevelToDeltaQPMapping.mode=LumaLevelToDQPMode(lumaLevelToDeltaQPMode);
    
      if (m_lumaLevelToDeltaQPMapping.mode)
      {
        CHECK(  cfg_lumaLeveltoDQPMappingLuma.values.size() != cfg_lumaLeveltoDQPMappingQP.values.size(), "Error in cfg" );
        m_lumaLevelToDeltaQPMapping.mapping.resize(cfg_lumaLeveltoDQPMappingLuma.values.size());
        for(uint32_t i=0; i<cfg_lumaLeveltoDQPMappingLuma.values.size(); i++)
        {
          m_lumaLevelToDeltaQPMapping.mapping[i]=std::pair<int,int>(cfg_lumaLeveltoDQPMappingLuma.values[i], cfg_lumaLeveltoDQPMappingQP.values[i]);
        }
      }
    #endif
    
    
      CHECK(cfg_qpInValCb.values.size() != cfg_qpOutValCb.values.size(), "Chroma QP table for Cb is incomplete.");
      CHECK(cfg_qpInValCr.values.size() != cfg_qpOutValCr.values.size(), "Chroma QP table for Cr is incomplete.");
      CHECK(cfg_qpInValCbCr.values.size() != cfg_qpOutValCbCr.values.size(), "Chroma QP table for CbCr is incomplete.");
    
      if (m_useIdentityTableForNon420Chroma && m_chromaFormatIDC != CHROMA_420)
    
        m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag = true;
    
    
        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[CHANNEL_TYPE_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++)
      {
        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 LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
      if ( m_LadfEnabed )
      {
        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];
        }
      }
    #endif
    
    
      if (m_chromaFormatIDC != CHROMA_420)
      {
        if (!m_horCollocatedChromaFlag)
        {
          msg(WARNING, "\nWARNING: HorCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
          m_horCollocatedChromaFlag = true;
        }
        if (!m_verCollocatedChromaFlag)
        {
          msg(WARNING, "\nWARNING: VerCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
          m_verCollocatedChromaFlag = true;
        }
      }
    
    #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)
            {
              CHECK( m_virtualBoundariesPosX[i] - m_virtualBoundariesPosX[i-1] < m_uiCTUSize, "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)
            {
              CHECK( m_virtualBoundariesPosY[i] - m_virtualBoundariesPosY[i-1] < m_uiCTUSize, "The distance between any two horizontal virtual boundaries shall be greater than or equal to the CTU size" );
            }
    
        CHECK( m_maxNumAlfAlternativesChroma < 1 || m_maxNumAlfAlternativesChroma > MAX_NUM_ALF_ALTERNATIVES_CHROMA, std::string("The maximum number of ALF Chroma filter alternatives must be in the range (1-") + std::to_string(MAX_NUM_ALF_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 iValue;
          int iPOC = 0;
          while ( iPOC < m_framesToBeEncoded )
          {
            if ( fscanf(fpt, "%d", &iValue ) == EOF )
            {
              break;
            }
            m_aidQP[ iPOC ] = iValue;
            iPOC++;
          }
          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);
        }
      }
    
      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;
          }
          else 
          {
            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);
          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];
              }
            }
          }
        }
      }
      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_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_iFrameRate;
    
      m_reshapeCW.rspPicSize = m_sourceWidth*m_sourceHeight;
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_reshapeCW.rspFpsToIp = std::max(16, 16 * (int)(round((double)m_iFrameRate /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 ENABLE_QPA_SUB_CTU
     #if QP_SWITCHING_FOR_PARALLEL
    
      if ((m_iQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceWidth <= 2048) && (m_sourceHeight <= 1280)
    
      if (((int)m_fQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_sourceWidth <= 2048) && (m_sourceHeight <= 1280)
    
     #if WCG_EXT && ER_CHROMA_QP_WCG_PPS
          && (!m_wcgChromaQpControl.enabled)
     #endif
    
          && ((1 << (m_log2MaxTbSize + 1)) == m_uiCTUSize) && (m_sourceWidth > 512 || m_sourceHeight > 320))
    
        m_cuQpDeltaSubdiv = 2;
    
      if( ( m_iQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_sourceHeight <= 1280 ) && ( m_sourceWidth <= 2048 ) )
    
      if( ( ( int ) m_fQP < 38 ) && ( m_iGOPSize > 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" );
    
        if( ( 1u << m_log2MaxTbSize         ) > m_uiCTUSize ) m_log2MaxTbSize--;
    
      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[CHANNEL_TYPE_LUMA] - 8 ) * 6 );
      }
    
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      m_uiMaxCUWidth = m_uiMaxCUHeight = m_uiCTUSize;
    
    
      // check validity of input parameters
      if( xCheckParameter() )
      {
        // return check failed
        return false;
      }
    
      // print-out parameters
      xPrintParameter();
    
      return true;
    }
    
    
    // ====================================================================================================================
    // 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[CHANNEL_TYPE_LUMA], m_internalBitDepth[m_chromaFormatIDC==ChromaFormat::CHROMA_400 ? CHANNEL_TYPE_LUMA : CHANNEL_TYPE_CHROMA]);
      m_profile=Profile::NONE;
    
    
      switch (m_chromaFormatIDC)
      {
      case ChromaFormat::CHROMA_400:
      case ChromaFormat::CHROMA_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;
          }
    
        }
        break;
    
      case ChromaFormat::CHROMA_422:
      case ChromaFormat::CHROMA_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;
          }
    
    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)
    
    
    
      if( m_depQuantEnabledFlag )
      {
        xConfirmPara( !m_useRDOQ || !m_useRDOQTS, "RDOQ and RDOQTS must be equal to 1 if dependent quantization is enabled" );
        xConfirmPara( m_signDataHidingEnabledFlag, "SignHideFlag must be equal to 0 if dependent quantization is enabled" );
      }
    
        const int minCUSize = 1 << m_log2MinCuSize;
        xConfirmPara(m_wrapAroundOffset <= m_uiCTUSize + minCUSize, "Wrap-around offset must be greater than CtbSizeY + MinCbSize");
    
        xConfirmPara(m_wrapAroundOffset > m_sourceWidth, "Wrap-around offset must not be greater than the source picture width");
    
        xConfirmPara( m_wrapAroundOffset % minCUSize != 0, "Wrap-around offset must be an integer multiple of the specified minimum CU size" );
    
      }
    
    
    #if SHARP_LUMA_DELTA_QP && ENABLE_QPA
      xConfirmPara( m_bUsePerceptQPA && m_lumaLevelToDeltaQPMapping.mode >= 2, "QPA and SharpDeltaQP mode 2 cannot be used together" );
      if( m_bUsePerceptQPA && m_lumaLevelToDeltaQPMapping.mode == LUMALVL_TO_DQP_AVG_METHOD )
      {
        msg( WARNING, "*********************************************************************************\n" );
        msg( WARNING, "** WARNING: Applying custom luma-based QPA with activity-based perceptual QPA! **\n" );
        msg( WARNING, "*********************************************************************************\n" );
    
        m_lumaLevelToDeltaQPMapping.mode = LUMALVL_TO_DQP_NUM_MODES; // special QPA mode
      }
    #endif
    
    
    
      xConfirmPara( m_useAMaxBT && !m_SplitConsOverrideEnabledFlag, "AMaxBt can only be used with PartitionConstriantsOverride enabled" );
    
      xConfirmPara(m_bitstreamFileName.empty(), "A bitstream file name must be specified (BitstreamFile)");
    
      xConfirmPara(m_internalBitDepth[CHANNEL_TYPE_CHROMA] != m_internalBitDepth[CHANNEL_TYPE_LUMA], "The internalBitDepth must be the same for luma and chroma");
    
      if (m_profile != Profile::NONE)
    
      {
        xConfirmPara(m_log2MaxTransformSkipBlockSize>=6, "Transform Skip Log2 Max Size must be less or equal to 5 for given profile.");
        xConfirmPara(m_transformSkipRotationEnabledFlag==true, "UseResidualRotation must not be enabled for given profile.");
        xConfirmPara(m_transformSkipContextEnabledFlag==true, "UseSingleSignificanceMapContext must not be enabled for given profile.");
    
        xConfirmPara(m_rrcRiceExtensionEnableFlag == true, "Extention of the Golomb-Rice parameter derivation for RRC must not be enabled for given profile.");
    
        xConfirmPara(m_persistentRiceAdaptationEnabledFlag==true, "GolombRiceParameterAdaption must not be enabled for given profile.");
        xConfirmPara(m_extendedPrecisionProcessingFlag==true, "UseExtendedPrecision must not be enabled for given profile.");
    
        xConfirmPara(m_tsrcRicePresentFlag == true, "TSRCRicePresent must not be enabled for given profile.");
    
    #if JVET_W0046_RLSCP
        xConfirmPara(m_reverseLastSigCoeffEnabledFlag == true, "ReverseLastSigCoeff must not be enabled for given profile.");
    #endif
    
        xConfirmPara(m_highPrecisionOffsetsEnabledFlag==true, "UseHighPrecisionPredictionWeighting must not be enabled for given profile.");
        xConfirmPara(m_enableIntraReferenceSmoothing==false, "EnableIntraReferenceSmoothing must be enabled for given profile.");
        xConfirmPara(m_cabacBypassAlignmentEnabledFlag, "AlignCABACBeforeBypass cannot be enabled for given profile.");
      }
    
    
      // check range of parameters
      xConfirmPara( m_inputBitDepth[CHANNEL_TYPE_LUMA  ] < 8,                                   "InputBitDepth must be at least 8" );
      xConfirmPara( m_inputBitDepth[CHANNEL_TYPE_CHROMA] < 8,                                   "InputBitDepthC must be at least 8" );
    
    
      if( (m_internalBitDepth[CHANNEL_TYPE_LUMA] < m_inputBitDepth[CHANNEL_TYPE_LUMA]) || (m_internalBitDepth[CHANNEL_TYPE_CHROMA] < m_inputBitDepth[CHANNEL_TYPE_CHROMA]) )
      {
          msg(WARNING, "*****************************************************************************\n");
          msg(WARNING, "** WARNING: InternalBitDepth is set to the lower value than InputBitDepth! **\n");
    
    Takeshi Tsukuba's avatar
    Takeshi Tsukuba committed
          msg(WARNING, "**          min_qp_prime_ts_minus4 will be clipped to 0 at the low end!    **\n");
    
          msg(WARNING, "*****************************************************************************\n");
      }
    
    
      if (m_extendedPrecisionProcessingFlag)
      {
        for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
        {
          xConfirmPara((m_internalBitDepth[channelType] > 8) , "Model is not configured to support high enough internal accuracies - enable RExt__HIGH_BIT_DEPTH_SUPPORT to use increased precision internal data types etc...");
        }
      }
      else
      {
        for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
        {
          xConfirmPara((m_internalBitDepth[channelType] > 12) , "Model is not configured to support high enough internal accuracies - enable RExt__HIGH_BIT_DEPTH_SUPPORT to use increased precision internal data types etc...");
        }
      }
    
    
      xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_LUMA  ] < m_inputBitDepth[CHANNEL_TYPE_LUMA  ]), "MSB-extended bit depth for luma channel (--MSBExtendedBitDepth) must be greater than or equal to input bit depth for luma channel (--InputBitDepth)" );
      xConfirmPara( (m_MSBExtendedBitDepth[CHANNEL_TYPE_CHROMA] < m_inputBitDepth[CHANNEL_TYPE_CHROMA]), "MSB-extended bit depth for chroma channel (--MSBExtendedBitDepthC) must be greater than or equal to input bit depth for chroma channel (--InputBitDepthC)" );
    
    
    #if JVET_W0178_CONSTRAINTS_ON_REXT_TOOLS