Skip to content
Snippets Groups Projects
EncAppCfg.cpp 293 KiB
Newer Older
  • Learn to ignore specific revisions
  •       m_tileColumnWidth.resize(m_numTileColumnsMinus1);
          for(uint32_t i=0; i<cfg_ColumnWidth.values.size(); i++)
          {
            m_tileColumnWidth[i]=cfg_ColumnWidth.values[i];
          }
        }
      }
      else
      {
        m_tileColumnWidth.clear();
      }
    
      if( !m_tileUniformSpacingFlag && m_numTileRowsMinus1 > 0 )
      {
        if (cfg_RowHeight.values.size() > m_numTileRowsMinus1)
        {
          EXIT( "Error: The number of rows whose height are defined is larger than the allowed number of rows." );
        }
        else if (cfg_RowHeight.values.size() < m_numTileRowsMinus1)
        {
          EXIT( "Error: The height of some rows is not defined." );
        }
        else
        {
          m_tileRowHeight.resize(m_numTileRowsMinus1);
          for(uint32_t i=0; i<cfg_RowHeight.values.size(); i++)
          {
            m_tileRowHeight[i]=cfg_RowHeight.values[i];
          }
        }
      }
      else
      {
        m_tileRowHeight.clear();
      }
    
    #endif
    
      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];
      }
    
    #if JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG
      if (m_subPicPartitionFlag)
      {
        m_singleSlicePerSubPicFlag = false;
      }
      else
      {
        m_singleSlicePerSubPicFlag = true;
      }
    #endif
    
    #if !JVET_P1004_REMOVE_BRICKS
    
      if (m_tileUniformSpacingFlag)
      {
        int uniformTileHeight = ((m_uniformTileRowHeightMinus1 + 1) * m_uiCTUSize);
        int uniformTileWidth = ((m_uniformTileColsWidthMinus1 + 1) * m_uiCTUSize);
        m_numTileRowsMinus1 = ((m_iSourceHeight + uniformTileHeight - 1) / uniformTileHeight) - 1;
        m_numTileColumnsMinus1 = ((m_iSourceWidth + uniformTileWidth - 1) / uniformTileWidth) - 1;
      }
    
    #endif
    
      /* 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  ];
      }
    
    #if !JVET_P0243_SINGLE_BIT_DEPTH
    
      if (m_internalBitDepth   [CHANNEL_TYPE_CHROMA] == 0)
      {
    
    #endif
    
        m_internalBitDepth   [CHANNEL_TYPE_CHROMA] = m_internalBitDepth   [CHANNEL_TYPE_LUMA  ];
    
    #if !JVET_P0243_SINGLE_BIT_DEPTH
    
    #endif
    
      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 >= 1000 && extendedProfile <= 12316)
      {
        m_profile = Profile::MAINREXT;
        if (m_bitDepthConstraint != 0 || tmpConstraintChromaFormat != 0)
        {
          EXIT( "Error: The bit depth and chroma format constraints are not used when an explicit RExt profile is specified");
        }
        m_bitDepthConstraint           = (extendedProfile%100);
        m_intraConstraintFlag          = ((extendedProfile%10000)>=2000);
        m_onePictureOnlyConstraintFlag = (extendedProfile >= 10000);
        switch ((extendedProfile/100)%10)
        {
          case 0:  tmpConstraintChromaFormat=400; break;
          case 1:  tmpConstraintChromaFormat=420; break;
          case 2:  tmpConstraintChromaFormat=422; break;
          default: tmpConstraintChromaFormat=444; break;
        }
      }
      else
      {
        m_profile = Profile::Name(extendedProfile);
      }
    
      if (m_profile == Profile::HIGHTHROUGHPUTREXT )
      {
        if (m_bitDepthConstraint == 0)
        {
          m_bitDepthConstraint = 16;
        }
        m_chromaFormatConstraint = (tmpConstraintChromaFormat == 0) ? CHROMA_444 : numberToChromaFormat(tmpConstraintChromaFormat);
      }
      else if (m_profile == Profile::MAINREXT)
      {
        if (m_bitDepthConstraint == 0 && tmpConstraintChromaFormat == 0)
        {
          // produce a valid combination, if possible.
          const bool bUsingGeneralRExtTools  = m_transformSkipRotationEnabledFlag        ||
                                               m_transformSkipContextEnabledFlag         ||
                                               m_rdpcmEnabledFlag[RDPCM_SIGNAL_IMPLICIT] ||
                                               m_rdpcmEnabledFlag[RDPCM_SIGNAL_EXPLICIT] ||
                                               !m_enableIntraReferenceSmoothing          ||
                                               m_persistentRiceAdaptationEnabledFlag     ||
                                               m_log2MaxTransformSkipBlockSize!=2;
    
          const bool bUsingChromaQPAdjustment= m_cuChromaQpOffsetSubdiv >= 0;
    
          const bool bUsingExtendedPrecision = m_extendedPrecisionProcessingFlag;
          if (m_onePictureOnlyConstraintFlag)
          {
            m_chromaFormatConstraint = CHROMA_444;
            if (m_intraConstraintFlag != true)
            {
              EXIT( "Error: Intra constraint flag must be true when one_picture_only_constraint_flag is true");
            }
            const int maxBitDepth = m_chromaFormatIDC==CHROMA_400 ? m_internalBitDepth[CHANNEL_TYPE_LUMA] : std::max(m_internalBitDepth[CHANNEL_TYPE_LUMA], m_internalBitDepth[CHANNEL_TYPE_CHROMA]);
            m_bitDepthConstraint = maxBitDepth>8 ? 16:8;
          }
          else
          {
            m_chromaFormatConstraint = NUM_CHROMA_FORMAT;
            automaticallySelectRExtProfile(bUsingGeneralRExtTools,
                                           bUsingChromaQPAdjustment,
                                           bUsingExtendedPrecision,
                                           m_intraConstraintFlag,
                                           m_bitDepthConstraint,
                                           m_chromaFormatConstraint,
                                           m_chromaFormatIDC==CHROMA_400 ? m_internalBitDepth[CHANNEL_TYPE_LUMA] : std::max(m_internalBitDepth[CHANNEL_TYPE_LUMA], m_internalBitDepth[CHANNEL_TYPE_CHROMA]),
                                           m_chromaFormatIDC);
          }
        }
        else if (m_bitDepthConstraint == 0 || tmpConstraintChromaFormat == 0)
        {
          EXIT( "Error: The bit depth and chroma format constraints must either both be specified or both be configured automatically");
        }
        else
        {
          m_chromaFormatConstraint = numberToChromaFormat(tmpConstraintChromaFormat);
        }
      }
      else
      {
        m_chromaFormatConstraint = (tmpConstraintChromaFormat == 0) ? m_chromaFormatIDC : numberToChromaFormat(tmpConstraintChromaFormat);
        m_bitDepthConstraint     = ( ( m_profile == Profile::MAIN10 || m_profile == Profile::NEXT ) ? 10 : 8 );
      }
    
    
      m_inputColourSpaceConvert = stringToInputColourSpaceConvert(inputColourSpaceConvert, true);
    
    #if JVET_P0517_ADAPTIVE_COLOR_TRANSFORM
    
      m_rgbFormat = (m_inputColourSpaceConvert == IPCOLOURSPACE_RGBtoGBR && m_chromaFormatIDC == CHROMA_444) ? true : false;
    #endif
    
    
      switch (m_conformanceWindowMode)
      {
      case 0:
        {
          // no conformance or padding
          m_confWinLeft = m_confWinRight = m_confWinTop = m_confWinBottom = 0;
          m_aiPad[1] = m_aiPad[0] = 0;
          break;
        }
      case 1:
        {
          // automatic padding to minimum CU size
          int minCuSize = m_uiMaxCUHeight >> (m_uiMaxCUDepth - 1);
          if (m_iSourceWidth % minCuSize)
          {
            m_aiPad[0] = m_confWinRight  = ((m_iSourceWidth / minCuSize) + 1) * minCuSize - m_iSourceWidth;
            m_iSourceWidth  += m_confWinRight;
          }
          if (m_iSourceHeight % minCuSize)
          {
            m_aiPad[1] = m_confWinBottom = ((m_iSourceHeight / minCuSize) + 1) * minCuSize - m_iSourceHeight;
            m_iSourceHeight += m_confWinBottom;
            if ( m_isField )
            {
              m_iSourceHeightOrg += m_confWinBottom << 1;
              m_aiPad[1] = m_confWinBottom << 1;
            }
          }
          if (m_aiPad[0] % SPS::getWinUnitX(m_chromaFormatIDC) != 0)
          {
            EXIT( "Error: picture width is not an integer multiple of the specified chroma subsampling");
          }
          if (m_aiPad[1] % SPS::getWinUnitY(m_chromaFormatIDC) != 0)
          {
            EXIT( "Error: picture height is not an integer multiple of the specified chroma subsampling");
          }
          break;
        }
      case 2:
        {
          //padding
          m_iSourceWidth  += m_aiPad[0];
          m_iSourceHeight += m_aiPad[1];
          m_confWinRight  = m_aiPad[0];
          m_confWinBottom = m_aiPad[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_aiPad[1] != 0) || (m_aiPad[0]!=0))
          {
            msg( ERROR, "Warning: Conformance window enabled, padding parameters will be ignored\n");
          }
          m_aiPad[1] = m_aiPad[0] = 0;
          break;
        }
      }
    
    
    #if !JVET_P1004_REMOVE_BRICKS
    
      if (tmpSliceMode<0 || tmpSliceMode>=int(NUMBER_OF_SLICE_CONSTRAINT_MODES))
      {
        EXIT( "Error: bad slice mode");
      }
      m_sliceMode = SliceConstraint(tmpSliceMode);
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      if (m_sliceMode==FIXED_NUMBER_OF_CTU || m_sliceMode==FIXED_NUMBER_OF_BYTES)
      {
        // note: slice mode 2 can be re-enabled using scan order tiles
        EXIT( "Error: slice mode 1 (fixed number of CTUs) and 2 (fixed number of bytes) are no longer supported");
      }
    
    
      m_topLeftBrickIdx.clear();
      m_bottomRightBrickIdx.clear();
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      m_sliceId.clear();
    
      bool singleTileInPicFlag = (m_numTileRowsMinus1 == 0 && m_numTileColumnsMinus1 == 0);
    
      if (!singleTileInPicFlag)
      {
        //if (!m_singleBrickPerSliceFlag && m_rectSliceFlag)
    
        if ( (m_sliceMode != 0 && m_sliceMode != 4 && m_rectSliceFlag) ||
             (m_numSlicesInPicMinus1 != 0 && m_rectSliceFlag) )
    
          int numSlicesInPic = m_numSlicesInPicMinus1 + 1;
    
          if (cfg_SliceIdx.values.size() > numSlicesInPic * 2)
          {
            EXIT("Error: The number of slice indices (RectSlicesBoundaryInPic) is greater than the NumSlicesInPicMinus1.");
          }
          else if (cfg_SliceIdx.values.size() < numSlicesInPic * 2)
          {
            EXIT("Error: The number of slice indices (RectSlicesBoundaryInPic) is less than the NumSlicesInPicMinus1.");
          }
    
            m_topLeftBrickIdx.resize(numSlicesInPic);
            m_bottomRightBrickIdx.resize(numSlicesInPic);
            for (uint32_t i = 0; i < numSlicesInPic; ++i)
            {
              m_topLeftBrickIdx[i] = cfg_SliceIdx.values[i * 2];
              m_bottomRightBrickIdx[i] = cfg_SliceIdx.values[i * 2 + 1];
            }
            //Validating the correctness of rectangular slice structure
            int **brickToSlice = (int **)malloc(sizeof(int *) * (m_numTileRowsMinus1 + 1));
            for (int i = 0; i <= m_numTileRowsMinus1; i++)
            {
              brickToSlice[i] = (int *)malloc(sizeof(int) * (m_numTileColumnsMinus1 + 1));
              memset(brickToSlice[i], -1, sizeof(int) * ((m_numTileColumnsMinus1 + 1)));
            }
    
            //Check overlap case
            for (int sliceIdx = 0; sliceIdx < numSlicesInPic; sliceIdx++)
            {
              int sliceStartRow = m_topLeftBrickIdx[sliceIdx] / (m_numTileColumnsMinus1 + 1);
              int sliceEndRow   = m_bottomRightBrickIdx[sliceIdx] / (m_numTileColumnsMinus1 + 1);
              int sliceStartCol = m_topLeftBrickIdx[sliceIdx] % (m_numTileColumnsMinus1 + 1);
              int sliceEndCol   = m_bottomRightBrickIdx[sliceIdx] % (m_numTileColumnsMinus1 + 1);
              for (int i = 0; i <= m_numTileRowsMinus1; i++)
              {
                for (int j = 0; j <= m_numTileColumnsMinus1; j++)
                {
                  if (i >= sliceStartRow && i <= sliceEndRow && j >= sliceStartCol && j <= sliceEndCol)
                  {
                    if (brickToSlice[i][j] != -1)
                    {
                      msg(ERROR, "Error: Values given in RectSlicesBoundaryInPic have conflict! Rectangular slice shall not have overlapped tile(s)\n");
                      EXIT(1);
                    }
                    else
                    {
                      brickToSlice[i][j] = sliceIdx;
                    }
                  }
                }
              }
              //Check violation to number of tiles per slice
              if (m_sliceMode == 3 && m_rectSliceFlag)
              {
                if ((sliceEndRow - sliceStartRow + 1) * (sliceEndCol - sliceStartCol + 1) > m_sliceArgument)
                {
                  EXIT("Error: One or more slices contain more tiles than the defined number of tiles per slice");
                }
              }
            }
            //Check gap case
            for (int i = 0; i <= m_numTileRowsMinus1; i++)
            {
              for (int j = 0; j <= m_numTileColumnsMinus1; j++)
              {
                if (brickToSlice[i][j] == -1)
                {
                  EXIT("Error: Values given in RectSlicesBoundaryInPic have conflict! Rectangular slice shall not have gap");
                }
              }
            }
    
            for (int i = 0; i <= m_numTileRowsMinus1; i++)
            {
              free(brickToSlice[i]);
              brickToSlice[i] = 0;
    
            free(brickToSlice);
            brickToSlice = 0;
    
    Karsten Suehring's avatar
    Karsten Suehring committed
          }
        }      // (!m_singleBrickPerSliceFlag && m_rectSliceFlag)
    
        else // single slice in picture
        {
          const int numSlicesInPic = m_numSlicesInPicMinus1 + 1;
          int numTilesInPic = (m_numTileRowsMinus1 + 1) * (m_numTileColumnsMinus1 + 1);
          m_topLeftBrickIdx.resize(numSlicesInPic);
          m_bottomRightBrickIdx.resize(numSlicesInPic);
          m_topLeftBrickIdx[0] = 0;
          m_bottomRightBrickIdx[0] = numTilesInPic - 1;
        }
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      }        // !singleTileInPicFlag
    
    
      if (m_rectSliceFlag && m_signalledSliceIdFlag)
      {
        int numSlicesInPic = m_numSlicesInPicMinus1 + 1;
    
        if (cfg_SignalledSliceId.values.size() > numSlicesInPic)
        {
          EXIT("Error: The number of Slice Ids are greater than the m_signalledTileGroupIdLengthMinus1.");
        }
        else if (cfg_SignalledSliceId.values.size() < numSlicesInPic)
        {
          EXIT("Error: The number of Slice Ids are less than the m_signalledTileGroupIdLengthMinus1.");
        }
        else
        {
          m_sliceId.resize(numSlicesInPic);
          for (uint32_t i = 0; i < cfg_SignalledSliceId.values.size(); ++i)
          {
            m_sliceId[i] = cfg_SignalledSliceId.values[i];
          }
        }
      }
      else if (m_rectSliceFlag)
      {
        int numSlicesInPic = m_numSlicesInPicMinus1 + 1;
        m_sliceId.resize(numSlicesInPic);
        for (uint32_t i = 0; i < numSlicesInPic; ++i)
        {
          m_sliceId[i] = i;
        }
      }
    
    #endif
    
      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);
      }
    
      // 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
    
      for(uint32_t ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
      {
        if (saoOffsetBitShift[ch]<0)
        {
          if (m_internalBitDepth[ch]>10)
          {
            m_log2SaoOffsetScale[ch]=uint32_t(Clip3<int>(0, m_internalBitDepth[ch]-10, int(m_internalBitDepth[ch]-10 + 0.165*m_iQP - 3.22 + 0.5) ) );
          }
          else
          {
            m_log2SaoOffsetScale[ch]=0;
          }
        }
        else
        {
          m_log2SaoOffsetScale[ch]=uint32_t(saoOffsetBitShift[ch]);
        }
      }
    
    #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 = { 0 };
        cfg_qpInValCr.values = { 0 };
        cfg_qpInValCbCr.values = { 0 };
    
        cfg_qpOutValCb.values = { 0 };
        cfg_qpOutValCr.values = { 0 };
        cfg_qpOutValCbCr.values = { 0 };
    
      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] = (cfg_qpOutValCb.values.size() > 1) ? (int)cfg_qpOutValCb.values.size() - 2 : 0;
      m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] = (cfg_qpOutValCb.values.size() > 1) ? -26 + cfg_qpInValCb.values[0] : 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++)
    #else
    
      m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[0] = (int)cfg_qpOutValCb.values.size()-1;
    
      for (int i = 0; i < cfg_qpInValCb.values.size(); 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.");
    
    #if JVET_P0410_CHROMA_QP_MAPPING
        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];
    #else
    
        m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0][i] = (i == 0) ? cfg_qpInValCb.values[i] + qpBdOffsetC : cfg_qpInValCb.values[i] - cfg_qpInValCb.values[i - 1] - 1;
        m_chromaQpMappingTableParams.m_deltaQpOutVal[0][i] = (i == 0) ? cfg_qpOutValCb.values[i] + qpBdOffsetC : cfg_qpOutValCb.values[i] - cfg_qpOutValCb.values[i - 1];
    
      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] = (cfg_qpOutValCr.values.size() > 1) ? (int)cfg_qpOutValCr.values.size() - 2 : 0;
        m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] = (cfg_qpOutValCr.values.size() > 1) ? -26 + cfg_qpInValCr.values[0] : 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++)
    #else
    
        m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[1] = (int)cfg_qpOutValCr.values.size()-1;
    
    Frank Bossen's avatar
    Frank Bossen committed
        for (int i = 0; i < cfg_qpInValCr.values.size(); 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.");
    
    #if JVET_P0410_CHROMA_QP_MAPPING
          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];
    #else
    
          m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1][i] = (i == 0) ? cfg_qpInValCr.values[i] + qpBdOffsetC : cfg_qpInValCr.values[i] - cfg_qpInValCr.values[i - 1] - 1;
          m_chromaQpMappingTableParams.m_deltaQpOutVal[1][i] = (i == 0) ? cfg_qpOutValCr.values[i] + qpBdOffsetC : cfg_qpOutValCr.values[i] - cfg_qpOutValCr.values[i - 1];
    
        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] = (cfg_qpOutValCbCr.values.size() > 1) ? (int)cfg_qpOutValCbCr.values.size() - 2 : 0;
        m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] = (cfg_qpOutValCbCr.values.size() > 1) ? -26 + cfg_qpInValCbCr.values[0] : 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++)
    #else
    
        m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[2] = (int)cfg_qpOutValCbCr.values.size()-1;
        for (int i = 0; i < cfg_qpInValCbCr.values.size(); 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.");
    
    #if JVET_P0410_CHROMA_QP_MAPPING
          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];
    #else
    
          m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2][i] = (i == 0) ? cfg_qpInValCbCr.values[i] + qpBdOffsetC : cfg_qpInValCbCr.values[i] - cfg_qpInValCbCr.values[i - 1] - 1;
          m_chromaQpMappingTableParams.m_deltaQpOutVal[2][i] = (i == 0) ? cfg_qpOutValCbCr.values[i] + qpBdOffsetC : cfg_qpOutValCbCr.values[i] - cfg_qpOutValCbCr.values[i - 1];
    
    #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
    
    
    Brian Heng's avatar
    Brian Heng committed
    #if !JVET_P1006_PICTURE_HEADER
    
      if (m_AccessUnitDelimiter == false)
      {
        printf ("Warning: Access unit delimiters are disabled. VVC requires the presence of access unit delimiters\n");
      }
    
    Brian Heng's avatar
    Brian Heng committed
    #endif
    
    #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
    
    
      if ( m_loopFilterAcrossVirtualBoundariesDisabledFlag )
      {
        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_iSourceWidth, "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_iSourceHeight, "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);
        }
      }
    
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if HEVC_SEI || JVET_P0337_PORTING_SEI
    
      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);
        }
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
    #if !JVET_P0337_PORTING_SEI
    
      if( m_toneMappingInfoSEIEnabled && !m_toneMapCancelFlag )
      {
        if( m_toneMapModelId == 2 && !cfg_startOfCodedInterval.values.empty() )
        {
          const uint32_t num = 1u<< m_toneMapTargetBitDepth;
          m_startOfCodedInterval = new int[num];
          for(uint32_t i=0; i<num; i++)
          {
            m_startOfCodedInterval[i] = cfg_startOfCodedInterval.values.size() > i ? cfg_startOfCodedInterval.values[i] : 0;
          }
        }
        else
        {
          m_startOfCodedInterval = NULL;
        }
        if( ( m_toneMapModelId == 3 ) && ( m_numPivots > 0 ) )
        {
          if( !cfg_codedPivotValue.values.empty() && !cfg_targetPivotValue.values.empty() )
          {
            m_codedPivotValue  = new int[m_numPivots];
            m_targetPivotValue = new int[m_numPivots];
            for(uint32_t i=0; i<m_numPivots; i++)
            {
              m_codedPivotValue[i]  = cfg_codedPivotValue.values.size()  > i ? cfg_codedPivotValue.values [i] : 0;
              m_targetPivotValue[i] = cfg_targetPivotValue.values.size() > i ? cfg_targetPivotValue.values[i] : 0;
            }
          }
        }
        else
        {
          m_codedPivotValue = NULL;
          m_targetPivotValue = NULL;
        }
      }
    
      if( m_kneeSEIEnabled && !m_kneeSEICancelFlag )
      {
        CHECK(!( m_kneeSEINumKneePointsMinus1 >= 0 && m_kneeSEINumKneePointsMinus1 < 999 ), "Inconsistent config");
        m_kneeSEIInputKneePoint  = new int[m_kneeSEINumKneePointsMinus1+1];
        m_kneeSEIOutputKneePoint = new int[m_kneeSEINumKneePointsMinus1+1];
        for(int i=0; i<(m_kneeSEINumKneePointsMinus1+1); i++)
        {
          m_kneeSEIInputKneePoint[i]  = cfg_kneeSEIInputKneePointValue.values.size()  > i ? cfg_kneeSEIInputKneePointValue.values[i]  : 1;
          m_kneeSEIOutputKneePoint[i] = cfg_kneeSEIOutputKneePointValue.values.size() > i ? cfg_kneeSEIOutputKneePointValue.values[i] : 0;
        }
      }
    
      if(m_timeCodeSEIEnabled)
      {
        for(int i = 0; i < m_timeCodeSEINumTs && i < MAX_TIMECODE_SEI_SETS; i++)
        {
          m_timeSetArray[i].clockTimeStampFlag    = cfg_timeCodeSeiTimeStampFlag        .values.size()>i ? cfg_timeCodeSeiTimeStampFlag        .values [i] : false;
          m_timeSetArray[i].numUnitFieldBasedFlag = cfg_timeCodeSeiNumUnitFieldBasedFlag.values.size()>i ? cfg_timeCodeSeiNumUnitFieldBasedFlag.values [i] : 0;
          m_timeSetArray[i].countingType          = cfg_timeCodeSeiCountingType         .values.size()>i ? cfg_timeCodeSeiCountingType         .values [i] : 0;
          m_timeSetArray[i].fullTimeStampFlag     = cfg_timeCodeSeiFullTimeStampFlag    .values.size()>i ? cfg_timeCodeSeiFullTimeStampFlag    .values [i] : 0;
          m_timeSetArray[i].discontinuityFlag     = cfg_timeCodeSeiDiscontinuityFlag    .values.size()>i ? cfg_timeCodeSeiDiscontinuityFlag    .values [i] : 0;
          m_timeSetArray[i].cntDroppedFlag        = cfg_timeCodeSeiCntDroppedFlag       .values.size()>i ? cfg_timeCodeSeiCntDroppedFlag       .values [i] : 0;
          m_timeSetArray[i].numberOfFrames        = cfg_timeCodeSeiNumberOfFrames       .values.size()>i ? cfg_timeCodeSeiNumberOfFrames       .values [i] : 0;
          m_timeSetArray[i].secondsValue          = cfg_timeCodeSeiSecondsValue         .values.size()>i ? cfg_timeCodeSeiSecondsValue         .values [i] : 0;
          m_timeSetArray[i].minutesValue          = cfg_timeCodeSeiMinutesValue         .values.size()>i ? cfg_timeCodeSeiMinutesValue         .values [i] : 0;
          m_timeSetArray[i].hoursValue            = cfg_timeCodeSeiHoursValue           .values.size()>i ? cfg_timeCodeSeiHoursValue           .values [i] : 0;
          m_timeSetArray[i].secondsFlag           = cfg_timeCodeSeiSecondsFlag          .values.size()>i ? cfg_timeCodeSeiSecondsFlag          .values [i] : 0;
          m_timeSetArray[i].minutesFlag           = cfg_timeCodeSeiMinutesFlag          .values.size()>i ? cfg_timeCodeSeiMinutesFlag          .values [i] : 0;
          m_timeSetArray[i].hoursFlag             = cfg_timeCodeSeiHoursFlag            .values.size()>i ? cfg_timeCodeSeiHoursFlag            .values [i] : 0;
          m_timeSetArray[i].timeOffsetLength      = cfg_timeCodeSeiTimeOffsetLength     .values.size()>i ? cfg_timeCodeSeiTimeOffsetLength     .values [i] : 0;
          m_timeSetArray[i].timeOffsetValue       = cfg_timeCodeSeiTimeOffsetValue      .values.size()>i ? cfg_timeCodeSeiTimeOffsetValue      .values [i] : 0;
        }
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
    #endif
    
    #if JVET_P0462_SEI360
      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];
            }
    
          }
        }
      }
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_reshapeCW.binCW.resize(3);
      m_reshapeCW.rspFps = m_iFrameRate;
      m_reshapeCW.rspPicSize = m_iSourceWidth*m_iSourceHeight;
    
    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_iSourceWidth <= 2048) && (m_iSourceHeight <= 1280)
    
      if (((int)m_fQP < 38) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && (m_iSourceWidth <= 2048) && (m_iSourceHeight <= 1280)
    
     #if WCG_EXT && ER_CHROMA_QP_WCG_PPS
          && (!m_wcgChromaQpControl.enabled)
     #endif
    
          && ((1 << (m_log2MaxTbSize + 1)) == m_uiCTUSize) && (m_iSourceWidth > 512 || m_iSourceHeight > 320))
    
        m_cuQpDeltaSubdiv = 2;
    
      if( ( m_iQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 2048 ) )
    
      if( ( ( int ) m_fQP < 38 ) && ( m_iGOPSize > 4 ) && m_bUsePerceptQPA && !m_bUseAdaptiveQP && ( m_iSourceHeight <= 1280 ) && ( m_iSourceWidth <= 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--;
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      const int minCuSize = 1 << MIN_CU_LOG2;
      m_uiMaxCodingDepth = 0;
      while( ( m_uiCTUSize >> m_uiMaxCodingDepth ) > minCuSize )
    
    Karsten Suehring's avatar
    Karsten Suehring committed
        m_uiMaxCodingDepth++;
      }
      m_uiLog2DiffMaxMinCodingBlockSize = m_uiMaxCodingDepth;
      m_uiMaxCUWidth = m_uiMaxCUHeight = m_uiCTUSize;
      m_uiMaxCUDepth = m_uiMaxCodingDepth;
    
    
      // check validity of input parameters
      if( xCheckParameter() )
      {
        // return check failed
        return false;
      }
    
      // print-out parameters
      xPrintParameter();
    
      return true;
    }
    
    
    // ====================================================================================================================
    // Private member functions
    // ====================================================================================================================
    
    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_profile != Profile::NEXT )
      {
        THROW( "Next profile with an alternative partitioner has to be enabled if HEVC_USE_RQT is off!" );
        xConfirmPara( m_LMChroma, "LMChroma only allowed with NEXT profile" );
        xConfirmPara( m_ImvMode, "IMV is only allowed with NEXT profile" );
    
    #if JVET_P0517_ADAPTIVE_COLOR_TRANSFORM
    
        xConfirmPara(m_useColorTrans, "ACT Mode only allowed with NEXT profile");
    #endif
    
        xConfirmPara( m_PLTMode, "PLT Mode only allowed with NEXT profile");
    
    Yu Han's avatar
    Yu Han committed
        xConfirmPara(m_IBCMode, "IBC Mode only allowed with NEXT profile");
    
        xConfirmPara( m_HashME, "Hash motion estimation only allowed with NEXT profile" );
    
        xConfirmPara( m_useFastLCTU, "Fast large CTU can only be applied when encoding with NEXT profile" );
    
    Tung Nguyen's avatar
    Tung Nguyen committed
        xConfirmPara( m_MTS, "MTS only allowed with NEXT profile" );
        xConfirmPara( m_MTSIntraMaxCand, "MTS only allowed with NEXT profile" );
        xConfirmPara( m_MTSInterMaxCand, "MTS only allowed with NEXT profile" );
    
        xConfirmPara( m_SMVD, "SMVD is only allowed with NEXT profile" );
    
        xConfirmPara( m_compositeRefEnabled, "Composite Reference Frame is only allowed with NEXT profile" );
    
        xConfirmPara( m_bcw, "Bcw is only allowed with NEXT profile" );
        xConfirmPara( m_BcwFast, "BcwFast is only allowed with NEXT profile" );
    
        xConfirmPara( m_Triangle, "Triangle is only allowed with NEXT profile" );
    
        xConfirmPara(m_DMVR, "DMVR only allowed with NEXT profile");
    
        xConfirmPara(m_MmvdDisNum, "Number of distance MMVD entry setting only allowed with NEXT profile");
    
        xConfirmPara(m_JointCbCrMode, "JointCbCr only allowed with NEXT profile");
    
        // ADD_NEW_TOOL : (parameter check) add a check for next tools here
      }
      else
      {
        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" );
        }
    
    
        xConfirmPara( m_wrapAroundOffset <= m_uiCTUSize + (m_uiMaxCUWidth >> m_uiLog2DiffMaxMinCodingBlockSize), "Wrap-around offset must be greater than CtbSizeY + MinCbSize" );
    
        xConfirmPara( m_wrapAroundOffset > m_iSourceWidth, "Wrap-around offset must not be greater than the source picture width" );
    
        int minCUSize =  m_uiCTUSize >> m_uiLog2DiffMaxMinCodingBlockSize;
        xConfirmPara( m_wrapAroundOffset % minCUSize != 0, "Wrap-around offset must be an integer multiple of the specified minimum CU size" );
    
      }
    
    #if ENABLE_SPLIT_PARALLELISM
      xConfirmPara( m_numSplitThreads < 1, "Number of used threads cannot be smaller than 1" );
      xConfirmPara( m_numSplitThreads > PARL_SPLIT_MAX_NUM_THREADS, "Number of used threads cannot be higher than the number of actual jobs" );
    #else
      xConfirmPara( m_numSplitThreads != 1, "ENABLE_SPLIT_PARALLELISM is disabled, numSplitThreads has to be 1" );
    #endif