Skip to content
Snippets Groups Projects
EncLib.cpp 120 KiB
Newer Older
/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
 * Copyright (c) 2010-2023, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
 *    be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/** \file     EncLib.cpp
    \brief    encoder class
*/
#include "EncLib.h"

#include "EncModeCtrl.h"
#include "AQp.h"
#include "EncCu.h"

#include "CommonLib/Picture.h"
#include "CommonLib/CommonDef.h"
#include "CommonLib/ChromaFormat.h"
#if ENABLE_SPLIT_PARALLELISM
#include <omp.h>
#endif
#include "EncLibCommon.h"
#include "CommonLib/ProfileLevelTier.h"

//! \ingroup EncoderLib
//! \{

// ====================================================================================================================
// Constructor / destructor / create / destroy
// ====================================================================================================================

EncLib::EncLib( EncLibCommon* encLibCommon )
  : m_cListPic( encLibCommon->getPictureBuffer() )
  , m_cEncALF( encLibCommon->getApsIdStart() )
  , m_spsMap( encLibCommon->getSpsMap() )
  , m_ppsMap( encLibCommon->getPpsMap() )
  , m_apsMap( encLibCommon->getApsMap() )
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
  , m_cacheModel()
#endif
  , m_vps( encLibCommon->getVPS() )
{
  m_iPOCLast          = -1;
  m_iNumPicRcvd       =  0;
  m_uiNumAllPicCoded  =  0;

  m_iMaxRefPicNum     = 0;

#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
#if JVET_O0756_CALCULATE_HDRMETRICS
  m_metricTime = std::chrono::milliseconds(0);
#endif
Vadim Seregin's avatar
Vadim Seregin committed

Vadim Seregin's avatar
Vadim Seregin committed
  m_layerId = NOT_VALID;
  m_picIdInGOP = NOT_VALID;
Vadim Seregin's avatar
Vadim Seregin committed
void EncLib::create( const int layerId )
Vadim Seregin's avatar
Vadim Seregin committed
  m_layerId = layerId;
  m_iPOCLast = m_compositeRefEnabled ? -2 : -1;
  // create processing unit classes
  m_cGOPEncoder.        create( );
#if ENABLE_SPLIT_PARALLELISM
#if ENABLE_SPLIT_PARALLELISM
  m_numCuEncStacks  = m_numSplitThreads == 1 ? 1 : NUM_RESERVERD_SPLIT_JOBS;
#else
  m_numCuEncStacks  = 1;
#endif

  m_cCuEncoder      = new EncCu              [m_numCuEncStacks];
  m_cInterSearch    = new InterSearch        [m_numCuEncStacks];
  m_cIntraSearch    = new IntraSearch        [m_numCuEncStacks];
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
  m_bilateralFilter = new BilateralFilter    [m_numCuEncStacks];
#endif
  m_cTrQuant        = new TrQuant            [m_numCuEncStacks];
  m_CABACEncoder    = new CABACEncoder       [m_numCuEncStacks];
  m_cRdCost         = new RdCost             [m_numCuEncStacks];
Vadim Seregin's avatar
Vadim Seregin committed
  m_ctxCache        = new CtxCache           [m_numCuEncStacks];

  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
  {
    m_cCuEncoder[jId].         create( this );
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
    m_bilateralFilter[jId].    create();
#endif

#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
  m_bilateralFilter.    create();
#endif
#endif
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
  m_cInterSearch.cacheAssign( &m_cacheModel );
#endif
  m_cLoopFilter.create(floorLog2(m_maxCUWidth) - MIN_CU_LOG2);
Nan Hu's avatar
Nan Hu committed
  if (!m_bLoopFilterDisable && m_encDbOpt)
Nan Hu's avatar
Nan Hu committed
    m_cLoopFilter.initEncPicYuvBuffer(m_chromaFormatIDC, Size(getSourceWidth(), getSourceHeight()), getMaxCUWidth());
#if ENABLE_SPLIT_PARALLELISM
  m_cReshaper = new EncReshape[m_numCuEncStacks];
#endif
#if ENABLE_SPLIT_PARALLELISM
    for (int jId = 0; jId < m_numCuEncStacks; jId++)
    {
      m_cReshaper[jId].createEnc(getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);
    }
#else
    m_cReshaper.createEnc( getSourceWidth(), getSourceHeight(), m_maxCUWidth, m_maxCUHeight, m_bitDepth[COMPONENT_Y]);
#endif
#if JVET_AA0146_WRAP_AROUND_FIX
    m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_sourceWidth, m_sourceHeight,
      m_maxCUWidth, m_maxCUHeight, getBitDepth(CHANNEL_TYPE_LUMA), m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList);
#else
    m_cRateCtrl.init(m_framesToBeEncoded, m_RCTargetBitrate, (int)((double)m_iFrameRate / m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
      m_maxCUWidth, m_maxCUHeight, getBitDepth(CHANNEL_TYPE_LUMA), m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList);
Vadim Seregin's avatar
Vadim Seregin committed
  if (m_alf)
  {
#if JVET_AA0146_WRAP_AROUND_FIX
    m_cEncALF.create(this, m_sourceWidth, m_sourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, m_bitDepth, m_inputBitDepth);
#else
Vadim Seregin's avatar
Vadim Seregin committed
    m_cEncALF.create(this, m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, m_bitDepth, m_inputBitDepth);
Vadim Seregin's avatar
Vadim Seregin committed
  }
#if JVET_V0094_BILATERAL_FILTER
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#if JVET_W0066_CCSAO
#if JVET_X0071_CHROMA_BILATERAL_FILTER
  if (m_bUseSAO || m_BIF || m_CCSAO || m_chromaBIF)
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
  if (m_bUseSAO || m_BIF || m_CCSAO)
#endif
#else
#if JVET_X0071_CHROMA_BILATERAL_FILTER
  if (m_bUseSAO || m_BIF || m_chromaBIF)
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#else
Vadim Seregin's avatar
Vadim Seregin committed
  if (m_bUseSAO || m_BIF)
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#endif
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#else
#if JVET_W0066_CCSAO
#if JVET_X0071_CHROMA_BILATERAL_FILTER
  if (m_bUseSAO || m_CCSAO || m_chromaBIF)
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
  if (m_bUseSAO || m_CCSAO)
#else
#if JVET_X0071_CHROMA_BILATERAL_FILTER
  if (m_bUseSAO || m_chromaBIF)
Vadim Seregin's avatar
Vadim Seregin committed
#else
Vadim Seregin's avatar
Vadim Seregin committed
  if (m_bUseSAO)
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#endif
Vadim Seregin's avatar
Vadim Seregin committed
  {
#if JVET_AA0146_WRAP_AROUND_FIX
    const uint32_t widthInCtus = (m_sourceWidth + m_maxCUWidth - 1) / m_maxCUWidth;
    const uint32_t heightInCtus = (m_sourceHeight + m_maxCUHeight - 1) / m_maxCUHeight;
    const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
    m_cEncSAO.create(m_sourceWidth, m_sourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_LUMA] - MAX_SAO_TRUNCATED_BITDEPTH), (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_CHROMA] - MAX_SAO_TRUNCATED_BITDEPTH));
#else
Vadim Seregin's avatar
Vadim Seregin committed
    const uint32_t widthInCtus = (m_iSourceWidth + m_maxCUWidth - 1) / m_maxCUWidth;
    const uint32_t heightInCtus = (m_iSourceHeight + m_maxCUHeight - 1) / m_maxCUHeight;
    const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
    m_cEncSAO.create(m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_LUMA] - MAX_SAO_TRUNCATED_BITDEPTH), (uint32_t)std::max(0, m_bitDepth[CHANNEL_TYPE_CHROMA] - MAX_SAO_TRUNCATED_BITDEPTH));
Vadim Seregin's avatar
Vadim Seregin committed
    m_cEncSAO.createEncData(m_saoCtuBoundary, numCtuInFrame);
  }
}

void EncLib::destroy ()
{
  // destroy processing unit classes
  m_cGOPEncoder.        destroy();
  m_cSliceEncoder.      destroy();
#if ENABLE_SPLIT_PARALLELISM
  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
  {
    m_cCuEncoder[jId].destroy();
  }
#else
  m_cCuEncoder.         destroy();
#endif
  if( m_alf )
  {
    m_cEncALF.destroy();
  }
  m_cEncSAO.            destroy();
  m_cLoopFilter.        destroy();
  m_cRateCtrl.          destroy();
#if ENABLE_SPLIT_PARALLELISM
  for (int jId = 0; jId < m_numCuEncStacks; jId++)
  {
    m_cReshaper[jId].   destroy();
  }
#else
Taoran Lu's avatar
Taoran Lu committed
  m_cReshaper.          destroy();
#endif
#if ENABLE_SPLIT_PARALLELISM
  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
  {
    m_cInterSearch[jId].   destroy();
    m_cIntraSearch[jId].   destroy();
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
    m_bilateralFilter[jId].destroy();
#endif
  }
#else
  m_cInterSearch.       destroy();
  m_cIntraSearch.       destroy();
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
  m_bilateralFilter.    destroy();
#endif
#if ENABLE_SPLIT_PARALLELISM
  delete[] m_cCuEncoder;
  delete[] m_cInterSearch;
  delete[] m_cIntraSearch;
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
  delete[] m_bilateralFilter;
#endif
  delete[] m_cTrQuant;
  delete[] m_CABACEncoder;
  delete[] m_cRdCost;
Vadim Seregin's avatar
Vadim Seregin committed
  delete[] m_ctxCache;
#endif

  return;
}

void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
{
  m_AUWriterIf = auWriterIf;

  SPS &sps0 = *(m_spsMap.allocatePS( m_vps->getGeneralLayerIdx( m_layerId ) )); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues.
  PPS &pps0 = *( m_ppsMap.allocatePS( m_vps->getGeneralLayerIdx( m_layerId ) ) );
  APS &aps0 = *( m_apsMap.allocatePS( SCALING_LIST_APS ) );
  aps0.setAPSId( 0 );
  aps0.setAPSType( SCALING_LIST_APS );
  if (getAvoidIntraInDepLayer() && getNumRefLayers(m_vps->getGeneralLayerIdx( getLayerId())) > 0)
  {
    setIDRRefParamListPresent(true);
  }
  xInitSPS( sps0 );
  xInitVPS( sps0 );
  xInitDCI(m_dci, sps0);
#if ENABLE_SPLIT_PARALLELISM
  if( omp_get_dynamic() )
  {
    omp_set_dynamic( false );
  }
  omp_set_nested( true );
#endif

  if (getUseCompositeRef() || getDependentRAPIndicationSEIEnabled())

#if U0132_TARGET_BITS_SATURATION
  if (m_RCCpbSaturationEnabled)
  {
Xiang Ma's avatar
Xiang Ma committed
    m_cRateCtrl.initHrdParam(sps0.getGeneralHrdParameters(), sps0.getOlsHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);
#if ENABLE_SPLIT_PARALLELISM
  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
  {
    m_cRdCost[jId].setCostMode ( m_costMode );
  }
#else
  m_cRdCost.setCostMode ( m_costMode );
#endif

  // initialize PPS
#if JVET_AA0146_WRAP_AROUND_FIX
  pps0.setPicWidthInLumaSamples( m_sourceWidth );
  pps0.setPicHeightInLumaSamples( m_sourceHeight );
#else
  pps0.setPicWidthInLumaSamples( m_iSourceWidth );
  pps0.setPicHeightInLumaSamples( m_iSourceHeight );
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
  if (pps0.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps0.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
  {
    pps0.setConformanceWindow( sps0.getConformanceWindow() );
    pps0.setConformanceWindowFlag( false );
  }
  else
  {
    pps0.setConformanceWindow( m_conformanceWindow );
    pps0.setConformanceWindowFlag( m_conformanceWindow.getWindowEnabledFlag() );
  }
#else
  pps0.setConformanceWindow( m_conformanceWindow );
Hendry's avatar
Hendry committed
  // initialize APS
Hendry's avatar
Hendry committed
  xInitRPL(sps0, isFieldCoding);
#if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
  if (sps0.getUseAML())
  {
    sps0.setNumLambda(m_numQPOffset);
    int maxBits = 0;
    for (int idx = 0; idx < m_numQPOffset; idx++)
    {
      sps0.setQPOffsets(idx, m_qpOffsetList[idx]);
Tangi Poirier's avatar
Tangi Poirier committed
      const uint32_t lambda = (uint32_t)LAMBDA_DEC_SIDE[min(max(26 + pps0.getPicInitQPMinus26() + m_qpOffsetList[idx] - 4 * ((int)m_isRA), 0), MAX_QP)];
      sps0.setLambdaVal(idx, lambda);
      for (int shift = 0; shift < 16; shift++)
        if (lambda >> shift == 0)
        {
          if (shift > maxBits)
          {
            maxBits = shift;
          }
          break;
        }
    }
    sps0.setMaxbitsLambdaVal(maxBits);
  }
#endif
  if (m_resChangeInClvsEnabled)
Vadim Seregin's avatar
Vadim Seregin committed
    PPS &pps = *( m_ppsMap.allocatePS( ENC_PPS_ID_RPR ) );
    Window& inputScalingWindow = pps0.getScalingWindow();
    int scaledWidth = int( ( pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX( sps0.getChromaFormatIdc() ) * ( inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset() ) ) / m_scalingRatioHor );
    int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
Vadim Seregin's avatar
Vadim Seregin committed
    int temp = scaledWidth / minSizeUnit;
    int width = ( scaledWidth - ( temp * minSizeUnit) > 0 ? temp + 1 : temp ) * minSizeUnit;
    int scaledHeight = int( ( pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY( sps0.getChromaFormatIdc() ) * ( inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset() ) ) / m_scalingRatioVer );
Vadim Seregin's avatar
Vadim Seregin committed
    temp = scaledHeight / minSizeUnit;
    int height = ( scaledHeight - ( temp * minSizeUnit) > 0 ? temp + 1 : temp ) * minSizeUnit;

    pps.setPicWidthInLumaSamples( width );
    pps.setPicHeightInLumaSamples( height );
#if JVET_AC0096
    pps.setSliceChromaQpFlag(true);
#endif
    Window conformanceWindow;
    conformanceWindow.setWindow( 0, ( width - scaledWidth ) / SPS::getWinUnitX( sps0.getChromaFormatIdc() ), 0, ( height - scaledHeight ) / SPS::getWinUnitY( sps0.getChromaFormatIdc() ) );
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
    if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
    {
      pps.setConformanceWindow( sps0.getConformanceWindow() );
      pps.setConformanceWindowFlag( false );
    }
    else
    {
      pps.setConformanceWindow( conformanceWindow );
      pps.setConformanceWindowFlag( pps.getConformanceWindow().getWindowEnabledFlag() );
    }
#else
    pps.setConformanceWindow( conformanceWindow );
    scalingWindow.setWindow( 0, ( width - scaledWidth ) / SPS::getWinUnitX( sps0.getChromaFormatIdc() ), 0, ( height - scaledHeight ) / SPS::getWinUnitY( sps0.getChromaFormatIdc() ) );
    pps.setScalingWindow( scalingWindow );

    //register the width/height of the current pic into reference SPS
    if (!sps0.getPPSValidFlag(pps.getPPSId()))
    {
      sps0.setPPSValidFlag(pps.getPPSId(), true);
      sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
    }
    int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples();    // pic_width_max_in_luma_samples
    int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples();  // pic_height_max_in_luma_samples
    int curPicWidthY = width;                                       // pic_width_in_luma_samples
    int curPicHeightY = height;                                     // pic_height_in_luma_samples
    int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
    //Warning message of potential scaling window size violation
    for (int i = 0; i < 64; i++)
    {
      if (sps0.getPPSValidFlag(i))
      {
        if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
          printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
        if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
          printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
      }
    }

    // disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
    m_noPicPartitionFlag = true;

    xInitPPS( pps, sps0 ); // will allocate memory for and initialize pps.pcv inside
    
    if( pps.getWrapAroundEnabledFlag() )
    {
      int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
      pps.setPicWidthMinusWrapAroundOffset      ((pps.getPicWidthInLumaSamples()/minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY) );
      pps.setWrapAroundOffset                   (minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));

      pps.setPicWidthMinusWrapAroundOffset      (0);
      pps.setWrapAroundOffset                   ( 0 );       
    }
#if JVET_AC0096
#if JVET_AG0116
  if (m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag))
#else
  if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
  {
    // allocate PPS that can be used
    double scalingRatioHor = m_scalingRatioHor2;
    double scalingRatioVer = m_scalingRatioVer2;
    PPS& pps = *(m_ppsMap.allocatePS(ENC_PPS_ID_RPR2));
    Window& inputScalingWindow = pps0.getScalingWindow();
    int scaledWidth = int((pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset())) / scalingRatioHor);
    int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
    int temp = scaledWidth / minSizeUnit;
    int width = (scaledWidth - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;

    int scaledHeight = int((pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset())) / scalingRatioVer);
    temp = scaledHeight / minSizeUnit;
    int height = (scaledHeight - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;

    pps.setPicWidthInLumaSamples(width);
    pps.setPicHeightInLumaSamples(height);
    pps.setSliceChromaQpFlag(true);
    Window conformanceWindow;
    conformanceWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
    if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
    {
      pps.setConformanceWindow(sps0.getConformanceWindow());
      pps.setConformanceWindowFlag(false);
    }
    else
    {
      pps.setConformanceWindow(conformanceWindow);
      pps.setConformanceWindowFlag(pps.getConformanceWindow().getWindowEnabledFlag());
    }
#else
    pps.setConformanceWindow(conformanceWindow);
#endif
    Window scalingWindow;
    scalingWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
    pps.setScalingWindow(scalingWindow);

    //register the width/height of the current pic into reference SPS
    if (!sps0.getPPSValidFlag(pps.getPPSId()))
    {
      sps0.setPPSValidFlag(pps.getPPSId(), true);
      sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
    }
    int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples();    // pic_width_max_in_luma_samples
    int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples();  // pic_height_max_in_luma_samples
    int curPicWidthY = width;                                       // pic_width_in_luma_samples
    int curPicHeightY = height;                                     // pic_height_in_luma_samples
    int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
    //Warning message of potential scaling window size violation
    for (int i = 0; i < 64; i++)
    {
      if (sps0.getPPSValidFlag(i))
      {
        if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
        {
          printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
        }
        if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
        {
          printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
        }
      }
    }

    // disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
    m_noPicPartitionFlag = true;

    xInitPPS(pps, sps0); // will allocate memory for and initialize pps.pcv inside

    if (pps.getWrapAroundEnabledFlag())
    {
      int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
      pps.setPicWidthMinusWrapAroundOffset((pps.getPicWidthInLumaSamples() / minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY));
      pps.setWrapAroundOffset(minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));

    }
    else
    {
      pps.setPicWidthMinusWrapAroundOffset(0);
      pps.setWrapAroundOffset(0);
    }
  }
#if JVET_AG0116
  if (m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag))
#else
  if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
  {
    // allocate PPS that can be used
    double scalingRatioHor = m_scalingRatioHor3;
    double scalingRatioVer = m_scalingRatioVer3;
    PPS& pps = *(m_ppsMap.allocatePS(ENC_PPS_ID_RPR3));
    Window& inputScalingWindow = pps0.getScalingWindow();
    int scaledWidth = int((pps0.getPicWidthInLumaSamples() - SPS::getWinUnitX(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowLeftOffset() + inputScalingWindow.getWindowRightOffset())) / scalingRatioHor);
    int minSizeUnit = std::max(8, 1 << sps0.getLog2MinCodingBlockSize());
    int temp = scaledWidth / minSizeUnit;
    int width = (scaledWidth - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;

    int scaledHeight = int((pps0.getPicHeightInLumaSamples() - SPS::getWinUnitY(sps0.getChromaFormatIdc()) * (inputScalingWindow.getWindowTopOffset() + inputScalingWindow.getWindowBottomOffset())) / scalingRatioVer);
    temp = scaledHeight / minSizeUnit;
    int height = (scaledHeight - (temp * minSizeUnit) > 0 ? temp + 1 : temp) * minSizeUnit;

    pps.setPicWidthInLumaSamples(width);
    pps.setPicHeightInLumaSamples(height);
    pps.setSliceChromaQpFlag(true);

    Window conformanceWindow;
    conformanceWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
#if JVET_R0068_ASPECT6_ENC_RESTRICTION
    if (pps.getPicWidthInLumaSamples() == sps0.getMaxPicWidthInLumaSamples() && pps.getPicHeightInLumaSamples() == sps0.getMaxPicHeightInLumaSamples())
    {
      pps.setConformanceWindow(sps0.getConformanceWindow());
      pps.setConformanceWindowFlag(false);
    }
    else
    {
      pps.setConformanceWindow(conformanceWindow);
      pps.setConformanceWindowFlag(pps.getConformanceWindow().getWindowEnabledFlag());
    }
#else
    pps.setConformanceWindow(conformanceWindow);
#endif

    Window scalingWindow;
    scalingWindow.setWindow(0, (width - scaledWidth) / SPS::getWinUnitX(sps0.getChromaFormatIdc()), 0, (height - scaledHeight) / SPS::getWinUnitY(sps0.getChromaFormatIdc()));
    pps.setScalingWindow(scalingWindow);

    //register the width/height of the current pic into reference SPS
    if (!sps0.getPPSValidFlag(pps.getPPSId()))
    {
      sps0.setPPSValidFlag(pps.getPPSId(), true);
      sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight);
    }
    int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples();    // pic_width_max_in_luma_samples
    int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples();  // pic_height_max_in_luma_samples
    int curPicWidthY = width;                                       // pic_width_in_luma_samples
    int curPicHeightY = height;                                     // pic_height_in_luma_samples
    int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY)
    //Warning message of potential scaling window size violation
    for (int i = 0; i < 64; i++)
    {
      if (sps0.getPPSValidFlag(i))
      {
        if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY))
        {
          printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n");
        }
        if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY))
        {
          printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n");
        }
      }
    }

    // disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution)
    m_noPicPartitionFlag = true;

    xInitPPS(pps, sps0); // will allocate memory for and initialize pps.pcv inside

    if (pps.getWrapAroundEnabledFlag())
    {
      int minCbSizeY = (1 << sps0.getLog2MinCodingBlockSize());
      pps.setPicWidthMinusWrapAroundOffset((pps.getPicWidthInLumaSamples() / minCbSizeY) - (m_wrapAroundOffset * pps.getPicWidthInLumaSamples() / pps0.getPicWidthInLumaSamples() / minCbSizeY));
      pps.setWrapAroundOffset(minCbSizeY * (pps.getPicWidthInLumaSamples() / minCbSizeY - pps.getPicWidthMinusWrapAroundOffset()));

    }
    else
    {
      pps.setPicWidthMinusWrapAroundOffset(0);
      pps.setWrapAroundOffset(0);
    }
  }
#endif
#if ER_CHROMA_QP_WCG_PPS
  if (m_wcgChromaQpControl.isEnabled())
  {
    PPS &pps1=*(m_ppsMap.allocatePS(1));
    xInitPPS(pps1, sps0);
  }
#endif
  if (getUseCompositeRef())
  {
    PPS &pps2 = *(m_ppsMap.allocatePS(2));
    xInitPPS(pps2, sps0);
    xInitPPSforLT(pps2);
  }
Brian Heng's avatar
Brian Heng committed
  xInitPicHeader(m_picHeader, sps0, pps0);

  // initialize processing unit classes
  m_cGOPEncoder.  init( this );
  m_cSliceEncoder.init( this, sps0 );
#if ENABLE_SPLIT_PARALLELISM
  for( int jId = 0; jId < m_numCuEncStacks; jId++ )
  {
    // precache a few objects
    for( int i = 0; i < 10; i++ )
    {
Vadim Seregin's avatar
Vadim Seregin committed
      auto x = m_ctxCache[jId].get();
      m_ctxCache[jId].cache( x );
    }

    m_cCuEncoder[jId].init( this, sps0, jId );

    // initialize transform & quantization class
    m_cTrQuant[jId].init( jId == 0 ? nullptr : m_cTrQuant[0].getQuant(),
                          m_useRDOQ,
                          m_useRDOQTS,
#if T0196_SELECTIVE_RDOQ
                          m_useSelectiveRDOQ,
#endif
    );

    // initialize encoder search class
    CABACWriter* cabacEstimator = m_CABACEncoder[jId].getCABACEstimator( &sps0 );
    m_cIntraSearch[jId].init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
                             &m_bilateralFilter[jId],
#endif
                              getCtxCache( jId ), m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize
                            , &m_cReshaper[jId]
                            , sps0.getBitDepth(CHANNEL_TYPE_LUMA)
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
                             &m_bilateralFilter[jId],
#endif
                              &m_cTrQuant[jId],
                              m_iSearchRange,
                              m_bipredSearchRange,
                              m_motionEstimationSearchMethod,
                              getUseCompositeRef(),
                              m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, &m_cRdCost[jId], cabacEstimator, getCtxCache( jId )
                           , &m_cReshaper[jId]
    );

    // link temporary buffets from intra search with inter search to avoid unnecessary memory overhead
    m_cInterSearch[jId].setTempBuffers( m_cIntraSearch[jId].getSplitCSBuf(), m_cIntraSearch[jId].getFullCSBuf(), m_cIntraSearch[jId].getSaveCSBuf() );
  }
#else  // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
  m_cCuEncoder.   init( this, sps0 );

  // initialize transform & quantization class
  m_cTrQuant.init( nullptr,
                   1 << m_log2MaxTbSize,
                   m_useRDOQ,
                   m_useRDOQTS,
#if T0196_SELECTIVE_RDOQ
                   m_useSelectiveRDOQ,
#endif
  );

  // initialize encoder search class
  CABACWriter* cabacEstimator = m_CABACEncoder.getCABACEstimator(&sps0);
  m_cIntraSearch.init( this,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
                       &m_bilateralFilter,
#endif
                       getCtxCache(), m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize
Taoran Lu's avatar
Taoran Lu committed
                     , &m_cReshaper
                     , sps0.getBitDepth(CHANNEL_TYPE_LUMA)
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
Vadim Seregin's avatar
Vadim Seregin committed
                       &m_bilateralFilter,
#endif
                       &m_cTrQuant,
                       m_iSearchRange,
                       m_bipredSearchRange,
                       m_motionEstimationSearchMethod,
                       getUseCompositeRef(),
    m_maxCUWidth, m_maxCUHeight, floorLog2(m_maxCUWidth) - m_log2MinCUSize, &m_cRdCost, cabacEstimator, getCtxCache()
Taoran Lu's avatar
Taoran Lu committed
                     , &m_cReshaper
#if JVET_Z0153_IBC_EXT_REF
                     , pps0.getPicWidthInLumaSamples()
#endif

  // link temporary buffets from intra search with inter search to avoid unneccessary memory overhead
  m_cInterSearch.setTempBuffers( m_cIntraSearch.getSplitCSBuf(), m_cIntraSearch.getFullCSBuf(), m_cIntraSearch.getSaveCSBuf() );
#endif // ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM

#if JVET_AE0159_FIBC || JVET_AE0059_INTER_CCCM || JVET_AE0078_IBC_LIC_EXTENSION || JVET_AF0073_INTER_CCP_MERGE
  m_cInterSearch.setIntraPrediction(&m_cIntraSearch);
#endif
#if JVET_AH0200_INTRA_TMP_BV_REORDER
  m_cIntraSearch.setInterPrediction(&m_cInterSearch);
  m_iMaxRefPicNum = 0;

#if ER_CHROMA_QP_WCG_PPS
  if( m_wcgChromaQpControl.isEnabled() )
  {
    xInitScalingLists( sps0, *m_apsMap.getPS( 1 ) );
    xInitScalingLists( sps0, aps0 );
    xInitScalingLists( sps0, aps0 );
Seungwook Hong's avatar
Seungwook Hong committed

  if (m_resChangeInClvsEnabled)
    xInitScalingLists( sps0, *m_apsMap.getPS( ENC_PPS_ID_RPR ) );
Seungwook Hong's avatar
Seungwook Hong committed

  if (getUseCompositeRef())
Seungwook Hong's avatar
Seungwook Hong committed
#if JVET_Z0118_GDR
Seungwook Hong's avatar
Seungwook Hong committed
#endif
      sps0.getWrapAroundEnabledFlag(), sps0.getChromaFormatIdc(),
      Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(),
      sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());

    picBg->finalInit( m_vps, sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
    picBg->allocateNewSlice();
    picBg->createSpliceIdx(pps0.pcv->sizeInCtus);
    m_cGOPEncoder.setPicBg(picBg);
    Picture *picOrig = new Picture;
Seungwook Hong's avatar
Seungwook Hong committed
#if JVET_Z0118_GDR
Seungwook Hong's avatar
Seungwook Hong committed
#endif
      sps0.getWrapAroundEnabledFlag(), sps0.getChromaFormatIdc(),
      Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(),
      sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());

    picOrig->getOrigBuf().fill(0);
    m_cGOPEncoder.setPicOrig(picOrig);
  }
void EncLib::xInitScalingLists( SPS &sps, APS &aps )
{
  // Initialise scaling lists
  // The encoder will only use the SPS scaling lists. The PPS will never be marked present.
  const int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE] =
  {
    sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_LUMA),
    sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_CHROMA)
  };

  Quant* quant = getTrQuant()->getQuant();

  if(getUseScalingListId() == SCALING_LIST_OFF)
  {
    quant->setFlatScalingList(maxLog2TrDynamicRange, sps.getBitDepths());
    quant->setUseScalingList(false);
#if ENABLE_SPLIT_PARALLELISM
    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
    {
      getTrQuant( jId )->getQuant()->setFlatScalingList( maxLog2TrDynamicRange, sps.getBitDepths() );
      getTrQuant( jId )->getQuant()->setUseScalingList( false );
    }
  }
  else if(getUseScalingListId() == SCALING_LIST_DEFAULT)
  {
    aps.getScalingList().setDefaultScalingList ();
    quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );
#if ENABLE_SPLIT_PARALLELISM
    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
    {
      getTrQuant( jId )->getQuant()->setUseScalingList( true );
    }
    sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());
#endif
  }
  else if(getUseScalingListId() == SCALING_LIST_FILE_READ)
  {
    aps.getScalingList().setDefaultScalingList();
    CHECK( aps.getScalingList().xParseScalingList( getScalingListFileName() ), "Error Parsing Scaling List Input File" );
    aps.getScalingList().checkDcOfMatrix();
Kiyofumi Abe's avatar
Kiyofumi Abe committed
    if( aps.getScalingList().isNotDefaultScalingList() == false )
    {
      setUseScalingListId( SCALING_LIST_DEFAULT );
    }
    aps.getScalingList().setChromaScalingListPresentFlag((sps.getChromaFormatIdc()!=CHROMA_400));
    quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() );
#if ENABLE_SPLIT_PARALLELISM
    for( int jId = 1; jId < m_numCuEncStacks; jId++ )
    {
      getTrQuant( jId )->getQuant()->setUseScalingList( true );
    }
Kai Zhang's avatar
Kai Zhang committed

    sps.setDisableScalingMatrixForLfnstBlks(getDisableScalingMatrixForLfnstBlks());
  }
  else
  {
    THROW("error : ScalingList == " << getUseScalingListId() << " not supported\n");
  }

  if( getUseScalingListId() == SCALING_LIST_FILE_READ )
    for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++)
    {
      if (aps.getScalingList().getChromaScalingListPresentFlag()||aps.getScalingList().isLumaScalingList(scalingListId))
        aps.getScalingList().checkPredMode(scalingListId);
void EncLib::xInitPPSforLT(PPS& pps)
{
  pps.setOutputFlagPresentFlag(true);
  pps.setDeblockingFilterControlPresentFlag(true);
  pps.setPPSDeblockingFilterDisabledFlag(true);
}

// ====================================================================================================================
// Public member functions
// ====================================================================================================================

void EncLib::deletePicBuffer()
{
  PicList::iterator iterPic = m_cListPic.begin();
  int iSize = int( m_cListPic.size() );

  for ( int i = 0; i < iSize; i++ )
  {
    Picture* pcPic = *(iterPic++);

    pcPic->destroy();

    // get rid of the qpadaption layer
    while( pcPic->aqlayer.size() )
    {
      delete pcPic->aqlayer.back(); pcPic->aqlayer.pop_back();
    }

    delete pcPic;
    pcPic = NULL;
  }
Vadim Seregin's avatar
Vadim Seregin committed

  m_cListPic.clear();
bool EncLib::encodePrep(bool flush, PelStorage* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded
#if JVET_AG0116
    , PelStorage** ppcPicYuvRPR
#endif
)
{
  if( m_compositeRefEnabled && m_cGOPEncoder.getPicBg()->getSpliceFull() && m_iPOCLast >= 10 && m_iNumPicRcvd == 0 && m_cGOPEncoder.getEncodedLTRef() == false )
  {
    Picture* picCurr = NULL;
    xGetNewPicBuffer( rcListPicYuvRecOut, picCurr, 2 );
    const PPS *pps = m_ppsMap.getPS( 2 );
    const SPS *sps = m_spsMap.getPS( pps->getSPSId() );

    picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() );
    picCurr->finalInit( m_vps, *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
    picCurr->poc = m_iPOCLast - 1;
    m_iPOCLast -= 2;
    if( getUseAdaptiveQP() )
    {
      AQpPreanalyzer::preanalyze( picCurr );
    }
    if( m_RCEnableRateControl )
    {
      m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
    }

    m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, snrCSC,
                              m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
                              m_printMSSSIM,
#endif
                              true, 0);

#if JVET_O0756_CALCULATE_HDRMETRICS
    m_metricTime = m_cGOPEncoder.getMetricTime();
#endif
    m_cGOPEncoder.setEncodedLTRef( true );
    if( m_RCEnableRateControl )
    {
      m_cRateCtrl.destroyRCGOP();
    }

    iNumEncoded = 0;
    m_iNumPicRcvd = 0;
  }

  //PROF_ACCUM_AND_START_NEW_SET( getProfilerPic(), P_GOP_LEVEL );
  if( pcPicYuvOrg != NULL )
  {
    // get original YUV
    Picture* pcPicCurr = NULL;

    int ppsID = -1; // Use default PPS ID
#if ER_CHROMA_QP_WCG_PPS
    if( getWCGChromaQPControl().isEnabled() )
    {
      ppsID = getdQPs()[m_iPOCLast / ( m_compositeRefEnabled ? 2 : 1 ) + 1];
      ppsID += ( getSwitchPOC() != -1 && ( m_iPOCLast + 1 >= getSwitchPOC() ) ? 1 : 0 );
    }
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if !RPR_ENABLE
    if( m_resChangeInClvsEnabled && m_intraPeriod == -1 )
Philippe Bordes's avatar
Philippe Bordes committed
#endif
    {
      const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 );

Philippe Bordes's avatar
Philippe Bordes committed
#if RPR_ENABLE
#if JVET_AC0096
      if (!(m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag))
      {
        ppsID = 0;
      }
#else
Philippe Bordes's avatar
Philippe Bordes committed
      ppsID = 0;
Philippe Bordes's avatar
Philippe Bordes committed
      bool  bApplyRpr = false;
#if JVET_AC0096
      if (m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag)
      {
        if (poc % m_rprSwitchingSegmentSize == 0)
        {
          int currPoc = poc + m_FrameSkip;
          int rprSegment = getRprSwitchingSegment(currPoc);
          ppsID =  getRprSwitchingPPSID(rprSegment);
          m_gopRprPpsId = ppsID;
        }
        else
        {
          ppsID = m_gopRprPpsId;
        }
      }
#if JVET_AG0116
      else if (m_resChangeInClvsEnabled && m_gopBasedRPREnabledFlag && (m_iQP >= getGOPBasedRPRQPThreshold()))
      {
        double upscaledPSNR = 0.0;
        if (poc % getGOPSize() == 0)
        {
          int xScale = 32768;
          int yScale = 32768;
          std::pair<int, int> downScalingRatio = std::pair<int, int>(xScale, yScale);
          xScale = 8192;
          yScale = 8192;
          std::pair<int, int> upScalingRatio = std::pair<int, int>(xScale, yScale);

          const PPS* orgPPS = m_ppsMap.getPS(0);
          const SPS* orgSPS = m_spsMap.getPS(orgPPS->getSPSId());
          const ChromaFormat chFormatIdc = orgSPS->getChromaFormatIdc();

          const PPS* pTempPPS = m_ppsMap.getPS(ENC_PPS_ID_RPR);
          Picture::rescalePicture(downScalingRatio, *pcPicYuvOrg, orgPPS->getScalingWindow(), *ppcPicYuvRPR[1], pTempPPS->getScalingWindow(), chFormatIdc, orgSPS->getBitDepths(), true, true,
            orgSPS->getHorCollocatedChromaFlag(), orgSPS->getVerCollocatedChromaFlag());
          Picture::rescalePicture(upScalingRatio, *ppcPicYuvRPR[1], orgPPS->getScalingWindow(), *ppcPicYuvRPR[0], pTempPPS->getScalingWindow(), chFormatIdc, orgSPS->getBitDepths(), true, false,
            orgSPS->getHorCollocatedChromaFlag(), orgSPS->getVerCollocatedChromaFlag());
          // Calculate PSNR
          const  Pel* pSrc0 = pcPicYuvOrg->get(COMPONENT_Y).bufAt(0, 0);
          const  Pel* pSrc1 = ppcPicYuvRPR[0]->get(COMPONENT_Y).bufAt(0, 0);

          uint64_t totalDiff = 0;
          for (int y = 0; y < pcPicYuvOrg->get(COMPONENT_Y).height; y++)
          {
            for (int x = 0; x < pcPicYuvOrg->get(COMPONENT_Y).width; x++)
            {
              int diff = pSrc0[x] - pSrc1[x];
              totalDiff += uint64_t(diff) * uint64_t(diff);
            }
            pSrc0 += pcPicYuvOrg->get(COMPONENT_Y).stride;
            pSrc1 += ppcPicYuvRPR[0]->get(COMPONENT_Y).stride;
          }

          const uint32_t maxval = 255 << (orgSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
          upscaledPSNR = totalDiff ? 10.0 * log10((double)maxval * maxval * orgPPS->getPicWidthInLumaSamples() * orgPPS->getPicHeightInLumaSamples() / (double)totalDiff) : 999.99;
        }

        if (poc % getGOPSize() == 0)
        {
          const int qpBias = 37;
          if ((m_psnrThresholdRPR - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
          {
            ppsID = ENC_PPS_ID_RPR;
          }
          else
          {
            if ((m_psnrThresholdRPR2 - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
            {
              ppsID = ENC_PPS_ID_RPR2;
            }
            else
            {
              if ((m_psnrThresholdRPR3 - (m_iQP - qpBias) * 0.5) < upscaledPSNR)
              {
                ppsID = ENC_PPS_ID_RPR3;
              }
              else
              {
                ppsID = 0;
              }
            }
          }
          m_gopRprPpsId = ppsID;
        }
        else
        {
          ppsID = m_gopRprPpsId;
        }

      }
#endif
      else
      {
        bApplyRpr |= (m_switchPocPeriod < 0);                                   // RPR applied for all pictures
        bApplyRpr |= (m_switchPocPeriod > 0) && (poc / m_switchPocPeriod % 2);  // RPR applied for periods RA or LDB
      }
#else
Philippe Bordes's avatar
Philippe Bordes committed
      bApplyRpr |= (m_switchPocPeriod < 0);                                   // RPR applied for all pictures
      bApplyRpr |= (m_switchPocPeriod > 0) && (poc / m_switchPocPeriod % 2);  // RPR applied for periods RA or LDB
Philippe Bordes's avatar
Philippe Bordes committed
      if( bApplyRpr )
#else
      if( poc / m_switchPocPeriod % 2 )
Philippe Bordes's avatar
Philippe Bordes committed
#endif
#if JVET_AC0096
#if JVET_AG0116
        if (!(m_resChangeInClvsEnabled && (m_rprFunctionalityTestingEnabledFlag || (m_gopBasedRPREnabledFlag && (m_iQP >= getGOPBasedRPRQPThreshold())))))
#else
        if (!(m_resChangeInClvsEnabled && m_rprFunctionalityTestingEnabledFlag))
    if( m_vps->getMaxLayers() > 1 )
      ppsID = m_vps->getGeneralLayerIdx( m_layerId );
    }

    xGetNewPicBuffer( rcListPicYuvRecOut, pcPicCurr, ppsID );

    const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
    const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );

    if (m_resChangeInClvsEnabled)
    {
      pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Y ) );
      pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cb ) );
      pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cr ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cr ) );

      const ChromaFormat chromaFormatIDC = pSPS->getChromaFormatIdc();

      const PPS *refPPS = m_ppsMap.getPS( 0 );
      const Window& curScalingWindow = pPPS->getScalingWindow();
      int curPicWidth = pPPS->getPicWidthInLumaSamples()   - SPS::getWinUnitX( pSPS->getChromaFormatIdc() ) * ( curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset() );
      int curPicHeight = pPPS->getPicHeightInLumaSamples() - SPS::getWinUnitY( pSPS->getChromaFormatIdc() ) * ( curScalingWindow.getWindowTopOffset()  + curScalingWindow.getWindowBottomOffset() );

      const Window& refScalingWindow = refPPS->getScalingWindow();
      int refPicWidth = refPPS->getPicWidthInLumaSamples()   - SPS::getWinUnitX( pSPS->getChromaFormatIdc() ) * ( refScalingWindow.getWindowLeftOffset() + refScalingWindow.getWindowRightOffset() );
      int refPicHeight = refPPS->getPicHeightInLumaSamples() - SPS::getWinUnitY( pSPS->getChromaFormatIdc() ) * ( refScalingWindow.getWindowTopOffset()  + refScalingWindow.getWindowBottomOffset() );

      int xScale = ( ( refPicWidth << SCALE_RATIO_BITS ) + ( curPicWidth >> 1 ) ) / curPicWidth;
      int yScale = ( ( refPicHeight << SCALE_RATIO_BITS ) + ( curPicHeight >> 1 ) ) / curPicHeight;
      std::pair<int, int> scalingRatio = std::pair<int, int>( xScale, yScale );

      Picture::rescalePicture( scalingRatio, *pcPicYuvOrg, refPPS->getScalingWindow(), pcPicCurr->getOrigBuf(), pPPS->getScalingWindow(), chromaFormatIDC, pSPS->getBitDepths(), true, true,
        pSPS->getHorCollocatedChromaFlag(), pSPS->getVerCollocatedChromaFlag() );
    }
    else
    {
      pcPicCurr->M_BUFS( 0, PIC_ORIGINAL ).swap( *pcPicYuvOrg );
    }
    pcPicCurr->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );

    pcPicCurr->poc = m_iPOCLast;

    // compute image characteristics
    if( getUseAdaptiveQP() )
    {
      AQpPreanalyzer::preanalyze( pcPicCurr );
    }
  }

  if( ( m_iNumPicRcvd == 0 ) || ( !flush && ( m_iPOCLast != 0 ) && ( m_iNumPicRcvd != m_iGOPSize ) && ( m_iGOPSize != 0 ) ) )
  {
    iNumEncoded = 0;
    return true;
  }

  if( m_RCEnableRateControl )
  {
    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
  }

  m_picIdInGOP = 0;

  return false;
/**
 - Application has picture buffer list with size of GOP + 1
 - Picture buffer list acts like as ring buffer
 - End of the list has the latest picture
 .
 \param   flush               cause encoder to encode a partial GOP
 \param   pcPicYuvOrg         original YUV picture
 \param   pcPicYuvTrueOrg
 \param   snrCSC
 \retval  rcListPicYuvRecOut  list of reconstruction YUV pictures
 \retval  accessUnitsOut      list of output access units
 \retval  iNumEncoded         number of encoded pictures
 */

bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded )
  // compress GOP
  m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, snrCSC,
                            m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
                            m_printMSSSIM,
#endif
                            false, m_picIdInGOP);

  m_picIdInGOP++;

  // go over all pictures in a GOP excluding the first IRAP
  if( m_picIdInGOP != m_iGOPSize && m_iPOCLast )
  {
    return true;
  }

#if JVET_O0756_CALCULATE_HDRMETRICS
  m_metricTime = m_cGOPEncoder.getMetricTime();
#endif

  if( m_RCEnableRateControl )
  {
    m_cRateCtrl.destroyRCGOP();
  }

  iNumEncoded = m_iNumPicRcvd;
  m_iNumPicRcvd = 0;
  m_uiNumAllPicCoded += iNumEncoded;

  return false;
}
#if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
void EncLib::setQPOffsetList(const int QPOffset[MAX_GOP])
{
  std::memcpy(m_qpOffsetList, QPOffset,(MAX_GOP) * sizeof(int));
}
#endif

/**------------------------------------------------
 Separate interlaced frame into two fields
 -------------------------------------------------**/
void separateFields(Pel* org, Pel* dstField, uint32_t stride, uint32_t width, uint32_t height, bool isTop)
{
  if (!isTop)
  {
    org += stride;
  }
  for (int y = 0; y < height>>1; y++)
  {
    for (int x = 0; x < width; x++)
    {
      dstField[x] = org[x];
    }

    dstField += stride;
    org += stride*2;
  }

}

bool EncLib::encodePrep(bool flush, PelStorage* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut,
  int& iNumEncoded, bool isTff)
{
  iNumEncoded = 0;
  bool keepDoing = true;

  for( int fieldNum = 0; fieldNum < 2; fieldNum++ )
  {
    if( pcPicYuvOrg )
    {
      /* -- field initialization -- */
      const bool isTopField = isTff == ( fieldNum == 0 );

      Picture *pcField;
      xGetNewPicBuffer( rcListPicYuvRecOut, pcField, -1 );

      for( uint32_t comp = 0; comp < ::getNumberValidComponents( pcPicYuvOrg->chromaFormat ); comp++ )
      {
        const ComponentID compID = ComponentID( comp );
        {
          PelBuf compBuf = pcPicYuvOrg->get( compID );
          separateFields( compBuf.buf,
            pcField->getOrigBuf().get( compID ).buf,
            compBuf.stride,
            compBuf.width,
            compBuf.height,
            isTopField );
        }
      }

      int ppsID = -1; // Use default PPS ID
      const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
      const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );

      pcField->finalInit( m_vps, *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );

      pcField->poc = m_iPOCLast;
      pcField->reconstructed = false;

      pcField->setBorderExtension( false );// where is this normally?

      pcField->topField = isTopField;                  // interlaced requirement

      // compute image characteristics
      if( getUseAdaptiveQP() )
      {
        AQpPreanalyzer::preanalyze( pcField );
      }
    }

  }

Haiwei Sun's avatar
Haiwei Sun committed
  if( m_iNumPicRcvd && ( flush || m_iPOCLast == 1 || m_iNumPicRcvd == m_iGOPSize ) )
  {
    m_picIdInGOP = 0;
    keepDoing = false;
  }

  return keepDoing;
}

bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff )
{
  iNumEncoded = 0;

Haiwei Sun's avatar
Haiwei Sun committed
  for( int fieldNum = 0; fieldNum < 2; fieldNum++ )
  {
    m_iPOCLast = m_iPOCLast < 2 ? fieldNum : m_iPOCLast;
Haiwei Sun's avatar
Haiwei Sun committed

    // compress GOP
    m_cGOPEncoder.compressGOP(m_iPOCLast, m_iPOCLast < 2 ? m_iPOCLast + 1 : m_iNumPicRcvd, m_cListPic,
                              rcListPicYuvRecOut, true, isTff, snrCSC, m_printFrameMSE,
#if MSSIM_UNIFORM_METRICS_LOG
                              m_printMSSSIM,
#endif
                              false, m_picIdInGOP);
Haiwei Sun's avatar
Haiwei Sun committed
#if JVET_O0756_CALCULATE_HDRMETRICS
    m_metricTime = m_cGOPEncoder.getMetricTime();
#endif

    m_picIdInGOP++;
  }
Haiwei Sun's avatar
Haiwei Sun committed
  // go over all pictures in a GOP excluding first top field and first bottom field
  if( m_picIdInGOP != m_iGOPSize && m_iPOCLast > 1 )
  {
    return true;
  }

  iNumEncoded += m_iNumPicRcvd;
  m_uiNumAllPicCoded += m_iNumPicRcvd;
  m_iNumPicRcvd = 0;
Haiwei Sun's avatar
Haiwei Sun committed
  return false;

// ====================================================================================================================
// Protected member functions
// ====================================================================================================================

/**
 - Application has picture buffer list with size of GOP + 1
 - Picture buffer list acts like as ring buffer
 - End of the list has the latest picture
 .
 \retval rpcPic obtained picture buffer
 */
void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId )
{
Haiwei Sun's avatar
Haiwei Sun committed
  // rotate the output buffer
  rcListPicYuvRecOut.push_back( rcListPicYuvRecOut.front() ); rcListPicYuvRecOut.pop_front();

  rpcPic=0;

  // At this point, the SPS and PPS can be considered activated - they are copied to the new Pic.
  const PPS *pPPS=(ppsId<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsId);
  CHECK(!(pPPS!=0), "Unspecified error");
  const PPS &pps=*pPPS;

  const SPS *pSPS=m_spsMap.getPS(pps.getSPSId());
  CHECK(!(pSPS!=0), "Unspecified error");
  const SPS &sps=*pSPS;

  Slice::sortPicList(m_cListPic);

  // use an entry in the buffered list if the maximum number that need buffering has been reached:
  int maxDecPicBuffering = ( m_vps == nullptr || m_vps->m_numLayersInOls[m_vps->m_targetOlsIdx] == 1 ) ? sps.getMaxDecPicBuffering( MAX_TLAYER - 1 ) : m_vps->getMaxDecPicBuffering( MAX_TLAYER - 1 );

  if( m_cListPic.size() >= (uint32_t)( m_iGOPSize + maxDecPicBuffering + 2 ) )
    PicList::iterator iterPic = m_cListPic.begin();
    for( int i = 0; i < iSize; i++ )
      if( !rpcPic->referenced && rpcPic->layerId == m_layerId )
      else
      {
        rpcPic = nullptr;
      }
      iterPic++;
    }

    // If PPS ID is the same, we will assume that it has not changed since it was last used
    // and return the old object.
    if( rpcPic && pps.getPPSId() != rpcPic->cs->pps->getPPSId() )
    {
      // the IDs differ - free up an entry in the list, and then create a new one, as with the case where the max buffering state has not been reached.
      rpcPic->destroy();
      delete rpcPic;
      m_cListPic.erase(iterPic);
      rpcPic=0;
    }
  }

  if (rpcPic==0)
  {
    rpcPic = new Picture;
Seungwook Hong's avatar
Seungwook Hong committed
#if JVET_Z0118_GDR
      sps.getWrapAroundEnabledFlag(), sps.getChromaFormatIdc(),
      Size(pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples()), sps.getMaxCUWidth(),
      sps.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
Seungwook Hong's avatar
Seungwook Hong committed

    if (m_resChangeInClvsEnabled)
      const PPS &pps0 = *m_ppsMap.getPS(0);
      rpcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).create(sps.getChromaFormatIdc(), Area(Position(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples())));
Brian Heng's avatar
Brian Heng committed
      const uint32_t iMaxDQPLayer = m_picHeader.getCuQpDeltaSubdivIntra()/2+1;
      rpcPic->aqlayer.resize( iMaxDQPLayer );
      for (uint32_t d = 0; d < iMaxDQPLayer; d++)
      {
        rpcPic->aqlayer[d] = new AQpLayer( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples(), sps.getMaxCUWidth() >> d, sps.getMaxCUHeight() >> d );
      }
    }

    m_cListPic.push_back( rpcPic );
  }

  rpcPic->setBorderExtension( false );
  rpcPic->reconstructed = false;
  rpcPic->referenced = true;
  rpcPic->getHashMap()->clearAll();
  m_iPOCLast += (m_compositeRefEnabled ? 2 : 1);
void EncLib::xInitVPS( const SPS& sps )
{
  // The SPS must have already been set up.
  // set the VPS profile information.

Xiang Ma's avatar
Xiang Ma committed
  m_vps->m_olsHrdParams.clear();
  m_vps->m_olsHrdParams.resize(m_vps->getNumOlsHrdParamsMinus1(), std::vector<OlsHrdParams>(m_vps->getMaxSubLayers()));
  ProfileLevelTierFeatures profileLevelTierFeatures;
  profileLevelTierFeatures.extractPTLInformation( sps );

  m_vps->deriveOutputLayerSets();
  m_vps->deriveTargetOutputLayerSet( m_vps->m_targetOlsIdx );

  // number of the DPB parameters is set equal to the number of OLS containing multi layers
  if( !m_vps->getEachLayerIsAnOlsFlag() )
    m_vps->m_numDpbParams = m_vps->getNumMultiLayeredOlss();
  }

  if( m_vps->m_dpbParameters.size() != m_vps->m_numDpbParams )
  {
    m_vps->m_dpbParameters.resize( m_vps->m_numDpbParams );
  }

  if( m_vps->m_dpbMaxTemporalId.size() != m_vps->m_numDpbParams )
  {
    m_vps->m_dpbMaxTemporalId.resize( m_vps->m_numDpbParams );
  }

  for( int olsIdx = 0, dpbIdx = 0; olsIdx < m_vps->m_numOutputLayersInOls.size(); olsIdx++ )
    if ( m_vps->getNumLayersInOls(olsIdx) > 1 )
    { 
      if( std::find( m_vps->m_layerIdInOls[olsIdx].begin(), m_vps->m_layerIdInOls[olsIdx].end(), m_layerId ) != m_vps->m_layerIdInOls[olsIdx].end() )
      {
        m_vps->setOlsDpbPicWidth( olsIdx, std::max<int>( sps.getMaxPicWidthInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).width ) );
        m_vps->setOlsDpbPicHeight( olsIdx, std::max<int>( sps.getMaxPicHeightInLumaSamples(), m_vps->getOlsDpbPicSize( olsIdx ).height ) );
        m_vps->setOlsDpbChromaFormatIdc( olsIdx, std::max<int>(sps.getChromaFormatIdc(), m_vps->getOlsDpbChromaFormatIdc( olsIdx )));
        m_vps->setOlsDpbBitDepthMinus8( olsIdx, std::max<int>(sps.getBitDepth(CHANNEL_TYPE_LUMA) - 8, m_vps->getOlsDpbBitDepthMinus8( olsIdx )));
      m_vps->setOlsDpbParamsIdx( olsIdx, dpbIdx );
      dpbIdx++;
    }
  //for( int i = 0; i < m_vps->m_numDpbParams; i++ )
  for( int i = 0; i < m_vps->m_numOutputLayersInOls.size(); i++ )
    if ( m_vps->getNumLayersInOls(i) > 1 )
    { 
      int dpbIdx = m_vps->getOlsDpbParamsIdx( i );
        // When vps_max_sublayers_minus1 is equal to 0, the value of dpb_max_temporal_id[ dpbIdx ] is inferred to be equal to 0.
        m_vps->m_dpbMaxTemporalId[dpbIdx] = 0;
        if( m_vps->getAllLayersSameNumSublayersFlag() )
        {
          // When vps_max_sublayers_minus1 is greater than 0 and vps_all_layers_same_num_sublayers_flag is equal to 1, the value of dpb_max_temporal_id[ dpbIdx ] is inferred to be equal to vps_max_sublayers_minus1.
          m_vps->m_dpbMaxTemporalId[dpbIdx] = m_vps->getMaxSubLayers() - 1;
        }
        else
        {
#if JVET_S0100_ASPECT3
          m_vps->m_dpbMaxTemporalId[dpbIdx] = m_vps->getMaxSubLayers() - 1;
#else
          m_vps->m_dpbMaxTemporalId[dpbIdx] = m_maxTempLayer;
        }
      }
    
      for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? 0 : m_vps->m_dpbMaxTemporalId[dpbIdx] ); j <= m_vps->m_dpbMaxTemporalId[dpbIdx]; j++ )
      {
        m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j] = profileLevelTierFeatures.getMaxDpbSize( m_vps->getOlsDpbPicSize( i ).width * m_vps->getOlsDpbPicSize( i ).height );
        m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[j] = m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j];
        m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[j] = 0;
      for( int j = ( m_vps->m_sublayerDpbParamsPresentFlag ? m_vps->m_dpbMaxTemporalId[dpbIdx] : 0 ); j < m_vps->m_dpbMaxTemporalId[dpbIdx]; j++ )
      {
        // When max_dec_pic_buffering_minus1[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ].
        m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[j] = m_vps->m_dpbParameters[dpbIdx].m_maxDecPicBuffering[m_vps->m_dpbMaxTemporalId[dpbIdx]];
        // When max_num_reorder_pics[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ].
        m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[j] = m_vps->m_dpbParameters[dpbIdx].m_numReorderPics[m_vps->m_dpbMaxTemporalId[dpbIdx]];
        // When max_latency_increase_plus1[ dpbIdx ] is not present for dpbIdx in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ].
        m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[j] = m_vps->m_dpbParameters[dpbIdx].m_maxLatencyIncreasePlus1[m_vps->m_dpbMaxTemporalId[dpbIdx]];
      }
#if JVET_S0100_ASPECT3
  for (int i = 0; i < m_vps->getNumOutputLayerSets(); i++)
  {
    m_vps->setHrdMaxTid(i, m_vps->getMaxSubLayers() - 1);
  }
#endif

  if (m_cfgVPSParameters.m_maxTidILRefPicsPlus1 >= 0)
  {
    for (int i = 0; i < m_vps->getMaxLayers(); i++)
    {
      m_vps->setMaxTidIlRefPicsPlus1(i, m_cfgVPSParameters.m_maxTidILRefPicsPlus1);
    }
  }
void EncLib::xInitDCI(DCI& dci, const SPS& sps)
{
  dci.setMaxSubLayersMinus1(sps.getMaxTLayers() - 1);
  std::vector<ProfileTierLevel> ptls;
  ptls.resize(1);
  ptls[0] = *sps.getProfileTierLevel();
  dci.setProfileTierLevel(ptls);
}
void EncLib::xInitSPS( SPS& sps )
  ProfileTierLevel* profileTierLevel = sps.getProfileTierLevel();
  ConstraintInfo* cinfo = profileTierLevel->getConstraintInfo();

#if JVET_S0179_CONDITIONAL_SIGNAL_GCI
  cinfo->setGciPresentFlag(m_gciPresentFlag);
#endif
#if !JVET_S0266_VUI_length
  cinfo->setNonPackedConstraintFlag     (m_nonPackedConstraintFlag);
  cinfo->setNonProjectedConstraintFlag(m_nonProjectedConstraintFlag);
#endif
#if JVET_Q0114_ASPECT5_GCI_FLAG
  cinfo->setNoRprConstraintFlag(m_noRprConstraintFlag);
  cinfo->setNoResChangeInClvsConstraintFlag(m_noResChangeInClvsConstraintFlag);
  cinfo->setOneTilePerPicConstraintFlag(m_oneTilePerPicConstraintFlag);
bdchoi's avatar
bdchoi committed
  cinfo->setPicHeaderInSliceHeaderConstraintFlag(m_picHeaderInSliceHeaderConstraintFlag);
  cinfo->setOneSlicePerPicConstraintFlag(m_oneSlicePerPicConstraintFlag);
#if JVET_S0113_S0195_GCI
  cinfo->setNoIdrRplConstraintFlag(m_noIdrRplConstraintFlag);
  cinfo->setNoRectSliceConstraintFlag(m_noRectSliceConstraintFlag);
  cinfo->setOneSlicePerSubpicConstraintFlag(m_oneSlicePerSubpicConstraintFlag);
  cinfo->setNoSubpicInfoConstraintFlag(m_noSubpicInfoConstraintFlag);
#else
  cinfo->setOneSubpicPerPicConstraintFlag(m_oneSubpicPerPicConstraintFlag);
  cinfo->setFrameOnlyConstraintFlag     (m_frameOnlyConstraintFlag);
  cinfo->setOnePictureOnlyConstraintFlag(m_onePictureOnlyConstraintFlag);
  cinfo->setIntraOnlyConstraintFlag         (m_intraOnlyConstraintFlag);
  cinfo->setMaxBitDepthConstraintIdc    (m_maxBitDepthConstraintIdc);
  cinfo->setMaxChromaFormatConstraintIdc((int)m_maxChromaFormatConstraintIdc);
  cinfo->setSingleLayerConstraintFlag (m_singleLayerConstraintFlag);
  cinfo->setAllLayersIndependentConstraintFlag (m_allLayersIndependentConstraintFlag);
  cinfo->setNoMrlConstraintFlag (m_noMrlConstraintFlag);
  cinfo->setNoIspConstraintFlag (m_noIspConstraintFlag);
  cinfo->setNoMipConstraintFlag (m_noMipConstraintFlag);
  cinfo->setNoLfnstConstraintFlag (m_noLfnstConstraintFlag);
  cinfo->setNoMmvdConstraintFlag (m_noMmvdConstraintFlag);
  cinfo->setNoSmvdConstraintFlag (m_noSmvdConstraintFlag);
  cinfo->setNoProfConstraintFlag (m_noProfConstraintFlag);
  cinfo->setNoPaletteConstraintFlag (m_noPaletteConstraintFlag);
  cinfo->setNoActConstraintFlag (m_noActConstraintFlag);
  cinfo->setNoLmcsConstraintFlag (m_noLmcsConstraintFlag);
#if JVET_S0050_GCI
  cinfo->setNoExplicitScaleListConstraintFlag(m_noExplicitScaleListConstraintFlag);
  cinfo->setNoVirtualBoundaryConstraintFlag(m_noVirtualBoundaryConstraintFlag);
#endif
#if JVET_S0058_GCI
  cinfo->setNoMttConstraintFlag(m_noMttConstraintFlag);
#endif
#if JVET_R0341_GCI
  cinfo->setNoChromaQpOffsetConstraintFlag(m_noChromaQpOffsetConstraintFlag);
  cinfo->setNoQtbttDualTreeIntraConstraintFlag(m_noQtbttDualTreeIntraConstraintFlag);
  cinfo->setNoPartitionConstraintsOverrideConstraintFlag(m_noPartitionConstraintsOverrideConstraintFlag);
  cinfo->setNoSaoConstraintFlag(m_noSaoConstraintFlag);
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#if JVET_W0066_CCSAO
  cinfo->setNoCCSaoConstraintFlag(m_noCCSaoConstraintFlag);
#endif
  cinfo->setNoAlfConstraintFlag(m_noAlfConstraintFlag);
  cinfo->setNoCCAlfConstraintFlag(m_noCCAlfConstraintFlag);
  cinfo->setNoWeightedPredictionConstraintFlag(m_noWeightedPredictionConstraintFlag);
  cinfo->setNoRefWraparoundConstraintFlag(m_noRefWraparoundConstraintFlag);
  cinfo->setNoTemporalMvpConstraintFlag(m_noTemporalMvpConstraintFlag);
  cinfo->setNoSbtmvpConstraintFlag(m_noSbtmvpConstraintFlag);
  cinfo->setNoAmvrConstraintFlag(m_noAmvrConstraintFlag);
  cinfo->setNoBdofConstraintFlag(m_noBdofConstraintFlag);
  cinfo->setNoDmvrConstraintFlag(m_noDmvrConstraintFlag);
  cinfo->setNoCclmConstraintFlag(m_noCclmConstraintFlag);
  cinfo->setNoMtsConstraintFlag(m_noMtsConstraintFlag);
  cinfo->setNoSbtConstraintFlag(m_noSbtConstraintFlag);
  cinfo->setNoAffineMotionConstraintFlag(m_noAffineMotionConstraintFlag);
  cinfo->setNoBcwConstraintFlag(m_noBcwConstraintFlag);
  cinfo->setNoIbcConstraintFlag(m_noIbcConstraintFlag);
Vadim Seregin's avatar
Vadim Seregin committed
#if ENABLE_DIMD
  cinfo->setNoDimdConstraintFlag(m_noDimdConstraintFlag);
#endif
Keming Cao's avatar
Keming Cao committed
#if JVET_W0123_TIMD_FUSION
  cinfo->setNoTimdConstraintFlag(m_noTimdConstraintFlag);
#endif
fan wang's avatar
fan wang committed
#if JVET_AB0155_SGPM
  cinfo->setNoSgpmConstraintFlag(m_noSgpmConstraintFlag);
#endif
#if JVET_AD0082_TMRL_CONFIG
  cinfo->setNoTmrlConstraintFlag(m_noTmrlConstraintFlag);
#endif
#if JVET_AG0058_EIP
  cinfo->setNoEipConstraintFlag(m_noEipConstraintFlag);
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if ENABLE_OBMC
  cinfo->setNoObmcConstraintFlag(m_noObmcConstraintFlag);
#endif
  cinfo->setNoCiipConstraintFlag(m_noCiipConstraintFlag);
Han Gao's avatar
Han Gao committed
  cinfo->setNoGeoConstraintFlag(m_noGeoConstraintFlag);
  cinfo->setNoLadfConstraintFlag(m_noLadfConstraintFlag);
  cinfo->setNoTransformSkipConstraintFlag(m_noTransformSkipConstraintFlag);
  cinfo->setNoBDPCMConstraintFlag(m_noBDPCMConstraintFlag);
  cinfo->setNoJointCbCrConstraintFlag(m_noJointCbCrConstraintFlag);
  cinfo->setNoQpDeltaConstraintFlag(m_noQpDeltaConstraintFlag);
  cinfo->setNoDepQuantConstraintFlag(m_noDepQuantConstraintFlag);
  cinfo->setNoSignDataHidingConstraintFlag(m_noSignDataHidingConstraintFlag);
  cinfo->setNoTrailConstraintFlag(m_noTrailConstraintFlag);
  cinfo->setNoStsaConstraintFlag(m_noStsaConstraintFlag);
  cinfo->setNoRaslConstraintFlag(m_noRaslConstraintFlag);
  cinfo->setNoRadlConstraintFlag(m_noRadlConstraintFlag);
  cinfo->setNoIdrConstraintFlag(m_noIdrConstraintFlag);
  cinfo->setNoCraConstraintFlag(m_noCraConstraintFlag);
  cinfo->setNoGdrConstraintFlag(m_noGdrConstraintFlag);
  cinfo->setNoApsConstraintFlag(m_noApsConstraintFlag);
  profileTierLevel->setLevelIdc                    (m_level);
  profileTierLevel->setTierFlag                    (m_levelTier);
  profileTierLevel->setProfileIdc                  (m_profile);
#if JVET_S0138_GCI_PTL
  profileTierLevel->setFrameOnlyConstraintFlag     (m_frameOnlyConstraintFlag);
  profileTierLevel->setMultiLayerEnabledFlag       (m_multiLayerEnabledFlag);
#endif
  profileTierLevel->setNumSubProfile(m_numSubProfile);
  for (int k = 0; k < m_numSubProfile; k++)
  {
    profileTierLevel->setSubProfileIdc(k, m_subProfile[k]);
  }
  /* XXX: should Main be marked as compatible with still picture? */
  /* XXX: may be a good idea to refactor the above into a function
   * that chooses the actual compatibility based upon options */
  sps.setVPSId( m_vps->getVPSId() );
Seungwook Hong's avatar
Seungwook Hong committed
#if JVET_Z0118_GDR
Seungwook Hong's avatar
Seungwook Hong committed
  if (getGdrEnabled())
Seungwook Hong's avatar
Seungwook Hong committed
  {
    sps.setGDREnabledFlag(true);
  }
  else
  {
    sps.setGDREnabledFlag(false);
  }
#else
  sps.setGDREnabledFlag(false);
#endif

#if JVET_AA0146_WRAP_AROUND_FIX
  sps.setMaxPicWidthInLumaSamples( m_sourceWidth );
  sps.setMaxPicHeightInLumaSamples( m_sourceHeight );
#else
  sps.setMaxPicWidthInLumaSamples( m_iSourceWidth );
  sps.setMaxPicHeightInLumaSamples( m_iSourceHeight );

#if JVET_AI0136_ADAPTIVE_DUAL_TREE
  sps.setUseInterSliceSeparateTree ( m_interSliceSeparateTreeEnabled );
  if (getFrameRate() < 50 && (m_sourceWidth * m_sourceHeight) <= (832 * 480))
  {
    sps.setUseInterSliceSeparateTree ( false );
  }
  if(m_iQP < 27 || m_iQP>32)
  {
    sps.setUseInterSliceSeparateTree ( false );
  }
#endif

  if (m_resChangeInClvsEnabled)
#if JVET_AA0146_WRAP_AROUND_FIX
    int maxPicWidth = std::max(m_sourceWidth, (int)((double)m_sourceWidth / m_scalingRatioHor + 0.5));
    int maxPicHeight = std::max(m_sourceHeight, (int)((double)m_sourceHeight / m_scalingRatioVer + 0.5));
#else
    int maxPicWidth = std::max(m_iSourceWidth, (int)((double)m_iSourceWidth / m_scalingRatioHor + 0.5));
    int maxPicHeight = std::max(m_iSourceHeight, (int)((double)m_iSourceHeight / m_scalingRatioVer + 0.5));
#endif
#if JVET_AC0096
#if JVET_AG0116
    if (m_rprFunctionalityTestingEnabledFlag || m_gopBasedRPREnabledFlag)
#else
    if (m_rprFunctionalityTestingEnabledFlag)
    {
      maxPicWidth = std::max(maxPicWidth, (int)((double)m_sourceWidth / m_scalingRatioHor2 + 0.5));
      maxPicHeight = std::max(maxPicHeight, (int)((double)m_sourceHeight / m_scalingRatioVer2 + 0.5));
      maxPicWidth = std::max(maxPicWidth, (int)((double)m_sourceWidth / m_scalingRatioHor3 + 0.5));
      maxPicHeight = std::max(maxPicHeight, (int)((double)m_sourceHeight / m_scalingRatioVer3 + 0.5));
    }
    const int minCuSize = std::max(8, 1 << m_log2MinCUSize);
    if (maxPicWidth % minCuSize)
Taoran Lu's avatar
Taoran Lu committed
    {
      maxPicWidth += ((maxPicWidth / minCuSize) + 1) * minCuSize - maxPicWidth;
Taoran Lu's avatar
Taoran Lu committed
    }
    if (maxPicHeight % minCuSize)
Taoran Lu's avatar
Taoran Lu committed
    {
      maxPicHeight += ((maxPicHeight / minCuSize) + 1) * minCuSize - maxPicHeight;
Taoran Lu's avatar
Taoran Lu committed
    }
    sps.setMaxPicWidthInLumaSamples( maxPicWidth );
    sps.setMaxPicHeightInLumaSamples( maxPicHeight );
  }
  sps.setMaxCUWidth             ( m_maxCUWidth        );
  sps.setMaxCUHeight            ( m_maxCUHeight       );
  sps.setLog2MinCodingBlockSize ( m_log2MinCUSize );
  sps.setCTUSize                             ( m_CTUSize );
  sps.setSplitConsOverrideEnabledFlag        ( m_useSplitConsOverride );
  // convert the Intra Chroma minQT setting from chroma unit to luma unit
  m_uiMinQT[2] <<= getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, m_chromaFormatIDC);
  sps.setMinQTSizes                          ( m_uiMinQT );
Remy Foray's avatar
Remy Foray committed
  sps.setMaxMTTHierarchyDepth                ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma );
  sps.setMaxBTSize( m_uiMaxBT[1], m_uiMaxBT[0], m_uiMaxBT[2] );
  sps.setMaxTTSize( m_uiMaxTT[1], m_uiMaxTT[0], m_uiMaxTT[2] );
Kashyap Kammachi Sreedhar's avatar
Kashyap Kammachi Sreedhar committed
  sps.setIDRRefParamListPresent              ( m_idrRefParamList );
  sps.setUseDualITree                        ( m_dualITree );
Vadim Seregin's avatar
Vadim Seregin committed
#if SIGN_PREDICTION
  sps.setNumPredSigns                        ( m_numPredSign );
#if JVET_Y0141_SIGN_PRED_IMPROVE
  sps.setLog2SignPredArea                    (m_log2SignPredArea);
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#endif
#if JVET_AH0103_LOW_DELAY_LFNST_NSPT
  sps.setUseIntraLFNSTISlice                 ( m_intraLFNSTISlice );
  sps.setUseIntraLFNSTPBSlice                ( m_intraLFNSTPBSlice );
  sps.setUseInterLFNST                       ( m_interLFNST );
#else
  sps.setUseLFNST                            ( m_LFNST );
  sps.setSbTMVPEnabledFlag(m_sbTmvpEnableFlag);
  sps.setAMVREnabledFlag                ( m_ImvMode != IMV_OFF );
  sps.setBDOFEnabledFlag                    ( m_BIO );
#if JVET_W0090_ARMC_TM
#if JVET_AG0276_NLIC
  sps.setUseAltLM                           ( m_altLM );
  sps.setUseAffAltLM                        ( m_affAltLM );
#endif
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
  sps.setUseMergeOppositeLic                ( m_mergeOppositeLic );
  sps.setUseTMMergeOppositeLic              ( m_mergeTMOppositeLic );
  sps.setUseAffMergeOppositeLic             ( m_mergeAffOppositeLic );
#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION 
  sps.setUseFastSubTmvp                     ((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 0 : 832 * 480));
#endif
#if JVET_AA0093_REFINED_MOTION_FOR_ARMC
  sps.setUseArmcRefinedMotion               ( m_armcRefinedMotion );
Ling Li's avatar
Ling Li committed
  sps.setMaxNumMergeCand(getMaxNumMergeCand());
#if JVET_AG0276_LIC_FLAG_SIGNALING
  sps.setMaxNumOppositeLicMergeCand( getMaxNumOppositeLicMergeCand() );
#endif
Han Huang's avatar
Han Huang committed
#if JVET_X0049_ADAPT_DMVR
  sps.setMaxNumBMMergeCand(getMaxNumBMMergeCand());
#endif
Ling Li's avatar
Ling Li committed
  sps.setMaxNumAffineMergeCand(getMaxNumAffineMergeCand());
#if JVET_AG0276_LIC_FLAG_SIGNALING
  sps.setMaxNumAffineOppositeLicMergeCand( getMaxNumAffineOppositeLicMergeCand() );
  if (getIntraPeriod() < 0 && getBaseQP() > 32 )
  {
    sps.setUseMergeOppositeLic(false);
    sps.setUseTMMergeOppositeLic(false);
    sps.setUseAffMergeOppositeLic(false);
  }
#endif
Ling Li's avatar
Ling Li committed
  sps.setMaxNumIBCMergeCand(getMaxNumIBCMergeCand());
  sps.setMaxNumGeoCand(getMaxNumGeoCand());
#if JVET_AG0164_AFFINE_GPM
  sps.setMaxNumGpmAffCand      (((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 1280 * 720 : 0)) ? getMaxNumGpmAffCand() : 0);
#endif
#if JVET_Z0127_SPS_MHP_MAX_MRG_CAND
  sps.setMaxNumMHPCand(getMaxNumMHPCand());
#endif
  sps.setUseAffine             ( m_Affine );
  sps.setUseAffineType         ( m_AffineType );
#if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
  sps.setUseAffineTM           ( m_useAffineTM );
#if JVET_AG0276_NLIC
  sps.setUseAffAltLMTM         ( m_useAffAltLMTM );
  if (getIntraPeriod() > 0)
  {
    if ((getSourceWidth() * getSourceHeight()) > (832 * 480) && ((getSourceWidth() * getSourceHeight()) < (3840 * 2160)))
    {
      sps.setUseAffAltLMTM(false);
    }
    if (getBaseQP() > 32)
    {
      sps.setUseAltLM(false);
      sps.setUseAffAltLM(false);
      sps.setUseAffAltLMTM(false);
    }
    else if (getBaseQP() < 27)
    {
      sps.setUseAltLM(false);
      sps.setUseAffAltLM(true);
      sps.setUseAffAltLMTM(true);
    }
  }
  else
  {
    sps.setUseAffAltLM(false);
    sps.setUseAffAltLMTM(false);
    if (getBaseQP() < 27)
    {
      sps.setUseAltLM(false);
    }
  }
#endif
#if JVET_AH0119_SUBBLOCK_TM
  sps.setUseSbTmvpTM(m_useSbTmvpTM);
  if (getBaseQP() < 27)
  {
    sps.setUseSbTmvpTM(false);
    sps.setUseAffineTM(false);
  }
#endif
#if JVET_AG0135_AFFINE_CIIP
  sps.setUseCiipAffine         (((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 832 * 480 : 0)) ? m_useCiipAffine : false);
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if AFFINE_MMVD
  sps.setUseAffineMmvdMode     ( m_AffineMmvdMode );
#endif
#if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR
Vadim Seregin's avatar
Vadim Seregin committed
  sps.setUseDMVDMode           ( m_DMVDMode );
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
  sps.setTMToolsEnableFlag     ( m_tmToolsEnableFlag );
#if TM_AMVP
  sps.setUseTMAmvpMode         ( m_tmAmvpMode );
#endif
#if TM_MRG
  sps.setUseTMMrgMode          ( m_tmMrgMode );
#endif
#if JVET_W0097_GPM_MMVD_TM && TM_MRG
  sps.setUseGPMTMMode          ( m_tmGPMMode );
#endif
#if JVET_Z0061_TM_OBMC && ENABLE_OBMC
  sps.setUseOBMCTMMode         ( m_tmOBMCMode );
#endif
#if JVET_Y0134_TMVP_NAMVP_CAND_REORDERING && JVET_W0090_ARMC_TM
  sps.setUseTmvpNmvpReordering ( m_useTmvpNmvpReorder );
#endif
#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
  sps.setUseTMMMVD             ( m_useTMMMVD );
#endif
#endif
#if JVET_Z0056_GPM_SPLIT_MODE_REORDERING
  sps.setUseAltGPMSplitModeCode( m_altGPMSplitModeCode );
Vadim Seregin's avatar
Vadim Seregin committed
#endif
  sps.setUseLMChroma           ( m_LMChroma ? true : false );
  sps.setHorCollocatedChromaFlag( m_horCollocatedChromaFlag );
  sps.setVerCollocatedChromaFlag( m_verCollocatedChromaFlag );
  sps.setUseMTS                ( m_IntraMTS || m_InterMTS || m_ImplicitMTS );
  sps.setUseIntraMTS           ( m_IntraMTS );
  sps.setUseInterMTS           ( m_InterMTS );
  sps.setUseSMVD                ( m_SMVD );
  sps.setUseBcw                ( m_bcw );
Vadim Seregin's avatar
Vadim Seregin committed
#if INTER_LIC
  sps.setLicEnabledFlag        ( m_lic );
#if JVET_AG0276_LIC_SLOPE_ADJUST
  sps.setLicSlopeAdjustEnabledFlag( m_licSlopeAdjust );
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
  sps.setLadfEnabled           ( m_LadfEnabled );
    sps.setLadfNumIntervals    ( m_LadfNumIntervals );
    for ( int k = 0; k < m_LadfNumIntervals; k++ )
    {
      sps.setLadfQpOffset( m_LadfQpOffset[k], k );
      sps.setLadfIntervalLowerBound( m_LadfIntervalLowerBound[k], k );
    }
    CHECK( m_LadfIntervalLowerBound[0] != 0, "abnormal value set to LadfIntervalLowerBound[0]" );
  }
#endif
#if JVET_AA0133_INTER_MTS_OPT
  sps.setInterMTSMaxSize(m_interMTSMaxSize);
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if ENABLE_DIMD
  sps.setUseDimd            ( m_dimd );
#endif
Keming Cao's avatar
Keming Cao committed
#if JVET_W0123_TIMD_FUSION
  sps.setUseTimd            ( m_timd );
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
  sps.setUseCiipTimd        ( m_ciipTimd );
#endif
fan wang's avatar
fan wang committed
#if JVET_AB0155_SGPM
  sps.setUseSgpm            ( m_sgpm );
#endif
#if JVET_AD0082_TMRL_CONFIG
  sps.setUseTmrl            ( m_tmrl );
#endif
#if JVET_AE0174_NONINTER_TM_TOOLS_CONTROL
  sps.setTMnoninterToolsEnableFlag            ( m_tmNoninterToolsEnableFlag );
#endif
#if JVET_AG0058_EIP
  sps.setUseEip             ( m_eip );
#endif
#if JVET_AD0085_MPM_SORTING
  sps.setUseMpmSorting      ( m_mpmSorting );
#endif
#if JVET_AH0136_CHROMA_REORDERING
  sps.setUseChromaReordering (m_chromaReordering);
#endif
#if JVET_AC0147_CCCM_NO_SUBSAMPLING
  sps.setUseCccm            ( m_cccm );
#endif
#if JVET_AD0188_CCP_MERGE
  sps.setUseCcpMerge        ( m_ccpMerge );
#endif
#if JVET_AG0154_DECODER_DERIVED_CCP_FUSION
  sps.setUseDdCcpFusion     ( m_ddCcpFusion );
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if ENABLE_OBMC
  sps.setUseOBMC            ( m_OBMC );
#endif
  sps.setUseCiip            ( m_ciip );
#if JVET_X0141_CIIP_TIMD_TM && TM_MRG
  if(sps.getUseCiip())
  {
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
   if(m_tmCIIPMode == 2)
   {
#endif
   if(getIntraPeriod() < 0)
   {
      sps.setUseCiipTmMrg (false);
   }
   else
   {
      sps.setUseCiipTmMrg (true);
   }
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
   }
   else
   {
      sps.setUseCiipTmMrg  (m_tmCIIPMode == 1);
   }
#endif
#if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING
  sps.setUseGeoBlend           ( true );
#endif
Seungsoo Jeong's avatar
Seungsoo Jeong committed
  sps.setUseMMVD               ( m_MMVD );
  sps.setFpelMmvdEnabledFlag   (( m_MMVD ) ? m_allowDisFracMMVD : false);
#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED || JVET_AD0140_MVD_PREDICTION
  sps.setUseMvdPred            (m_mvdPred);
#if JVET_AC0104_IBC_BVD_PREDICTION
  sps.setUseBvdPred            (m_bvdPred);
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
  sps.setUseBvpCluster         (m_bvpCluster);
#endif
#if JVET_Z0054_BLK_REF_PIC_REORDER
  sps.setUseARL                (m_useARL);
  sps.setBdofControlPresentFlag(m_BIO);
  sps.setDmvrControlPresentFlag(m_DMVR);
  sps.setProfControlPresentFlag(m_PROF);
  sps.setAffineAmvrEnabledFlag              ( m_AffineAmvr );
  sps.setUseDMVR                            ( m_DMVR );
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
  sps.setUseAffineParaRefinement            (m_affineParaRefinement);
#endif
  sps.setUseColorTrans(m_useColorTrans);
#if !JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
Yu Han's avatar
Yu Han committed
  sps.setIBCFlag                            ( m_IBCMode);
#else
  sps.setIBCFlag                            ( m_IBCMode & 0x01);
  sps.setIBCFlagInterSlice                  ( m_IBCMode & 0x02);
  sps.setUseRRIbc                           ( m_rribc );
  sps.setUseTMIbc                           ( m_tmibc );
  sps.setUseIbcMerge                        ( m_ibcMerge );
  sps.setIBCFracFlag                        ( m_IBCFracMode);
#endif
#if JVET_AA0061_IBC_MBVD
  sps.setUseIbcMbvd                         ( m_ibcMbvd );
#if JVET_AE0169_IBC_MBVD_LIST_DERIVATION
  sps.setUseIbcMbvdAdSearch                 ( m_ibcMbvdAdSearch );
#endif
#endif
#if JVET_AC0112_IBC_CIIP
  sps.setUseIbcCiip                         ( m_ibcCiip );
#endif
#if JVET_AC0112_IBC_GPM
  sps.setUseIbcGpm                          ( m_ibcGpm );
#endif
#if JVET_AC0112_IBC_LIC
  sps.setUseIbcLic                          ( m_ibcLic );
#if JVET_AE0159_FIBC
  sps.setUseIbcFilter                       ( m_ibcFilter );
#endif
#if JVET_AE0094_IBC_NONADJACENT_SPATIAL_CANDIDATES
  sps.setUseIbcNonAdjCand                   ( m_ibcNonAdjCand );
#endif
#if JVET_AG0136_INTRA_TMP_LIC
  sps.setItmpLicExtension                   ( m_itmpLicExtension );
  sps.setItmpLicMode                        ( m_itmpLicMode );
  sps.setWrapAroundEnabledFlag                      ( m_wrapAround );
#if JVET_AH0135_TEMPORAL_PARTITIONING
  sps.setEnableMaxMttIncrease               ( m_enableMaxMttIncrease );
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if MULTI_HYP_PRED
  sps.setMaxNumAddHyps(m_maxNumAddHyps);
  sps.setNumAddHypWeights(m_numAddHypWeights);
  sps.setMaxNumAddHypRefFrames(m_maxNumAddHypRefFrames);
Vadim Seregin's avatar
Vadim Seregin committed
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#if JVET_V0130_INTRA_TMP
  sps.setUseIntraTMP(m_intraTMP);
  sps.setIntraTMPMaxSize(m_intraTmpMaxSize);
#if JVET_AE0100_BVGCCCM
  sps.setUseBvgCccm(m_bvgCccm);
#endif
#if JVET_AC0071_DBV
  sps.setUseIntraDBV(m_intraDBV);
#endif
#if JVET_AE0059_INTER_CCCM
  sps.setUseInterCccm(m_interCccm);
#endif
#if JVET_AF0073_INTER_CCP_MERGE
  sps.setUseInterCcpMerge(m_interCcpMerge);
#if JVET_AH0066_JVET_AH0202_CCP_MERGE_LUMACBF0
  sps.setUseInterCcpMergeZeroLumaCbf(m_interCcpMergeZeroLumaCbf);
#endif
Vadim Seregin's avatar
Vadim Seregin committed
#endif
  // ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here
  sps.setUseISP                             ( m_ISP );
  sps.setUseLmcs                            ( m_lmcsEnabled );
  sps.setUseMRL                ( m_MRL );
  sps.setUseMIP                ( m_MIP );
  CHECK(m_log2MinCUSize > std::min(6, floorLog2(sps.getMaxCUWidth())), "log2_min_luma_coding_block_size_minus2 shall be in the range of 0 to min (4, log2_ctu_size - 2)");
  CHECK(m_uiMaxMTTHierarchyDepth > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_inter_slice shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");
  CHECK(m_uiMaxMTTHierarchyDepthI > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_intra_slice_luma shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");
  CHECK(m_uiMaxMTTHierarchyDepthIChroma > 2 * (floorLog2(sps.getCTUSize()) - sps.getLog2MinCodingBlockSize()), "sps_max_mtt_hierarchy_depth_intra_slice_chroma shall be in the range 0 to 2*(ctbLog2SizeY - log2MinCUSize)");
  sps.setTransformSkipEnabledFlag(m_useTransformSkip);
  sps.setLog2MaxTransformSkipBlockSize(m_log2MaxTransformSkipBlockSize);
  sps.setSPSTemporalMVPEnabledFlag((getTMVPModeId() == 2 || getTMVPModeId() == 1));

  sps.setLog2MaxTbSize   ( m_log2MaxTbSize );

  for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
  {
    sps.setBitDepth      (ChannelType(channelType), m_bitDepth[channelType] );
    sps.setQpBDOffset  (ChannelType(channelType), (6 * (m_bitDepth[channelType] - 8)));
LI JINGYA's avatar
LI JINGYA committed
    sps.setInternalMinusInputBitDepth(ChannelType(channelType), max(0, (m_bitDepth[channelType] - m_inputBitDepth[channelType])));
Hendry's avatar
Hendry committed
  sps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
  sps.setEntryPointsPresentFlag( m_entryPointPresentFlag );
  sps.setUseWP( m_useWeightedPred );
  sps.setUseWPBiPred( m_useWeightedBiPred );

  sps.setSAOEnabledFlag( m_bUseSAO );
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#if JVET_W0066_CCSAO
  sps.setCCSAOEnabledFlag( m_CCSAO );
#endif
#if JVET_AG0158_ALF_LUMA_COEFF_PRECISION
  sps.setAlfPrecisionFlag( m_alfPrecision );
#endif
#if JVET_AH0057_CCALF_COEFF_PRECISION
  sps.setCCALFPrecisionFlag( m_ccalfPrecision );
Xiaoyu Xiu's avatar
Xiaoyu Xiu committed
#endif
  sps.setJointCbCrEnabledFlag( m_JointCbCrMode );
  sps.setMaxTLayers( m_maxTempLayer );
  sps.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );

  for (int i = 0; i < std::min(sps.getMaxTLayers(), (uint32_t) MAX_TLAYER); i++ )
  {
    sps.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
    sps.setNumReorderPics(m_numReorderPics[i], i);
  }

  sps.setScalingListFlag ( (m_useScalingListId == SCALING_LIST_OFF) ? 0 : 1 );
  if (sps.getUseColorTrans() && sps.getScalingListFlag())
  {
    sps.setScalingMatrixForAlternativeColourSpaceDisabledFlag( m_disableScalingMatrixForAlternativeColourSpace );
Loading
Loading full blame...