Skip to content
Snippets Groups Projects
EncLib.cpp 115 KiB
Newer Older
  • Learn to ignore specific revisions
  • /* 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)
    
    #endif
    #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.            destroyEncData();
      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)
      {
    
        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]);
          sps0.setLambdaVal(idx, (uint32_t)LAMBDA_DEC_SIDE[26 + pps0.getPicInitQPMinus26() + m_qpOffsetList[idx] - 4 * ((int)m_isRA)]);
          uint32_t lambda = (uint32_t)LAMBDA_DEC_SIDE[26 + pps0.getPicInitQPMinus26() + m_qpOffsetList[idx] - 4 * ((int)m_isRA)];
          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 (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 (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
    
      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
        picBg->create(sps0.getGDREnabledFlag(), sps0.getChromaFormatIdc(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()),
    
                       sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #else
    
        picBg->create( sps0.getChromaFormatIdc(), Size( pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples() ),
    
                       sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled() );
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #endif
    
        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
        picOrig->create(sps0.getGDREnabledFlag(), sps0.getChromaFormatIdc(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()),
    
          sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled());
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #else
    
        picOrig->create( sps0.getChromaFormatIdc(), Size( pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples() ),
    
                         sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + EXT_PICTURE_SIZE, false, m_layerId, getGopBasedTemporalFilterEnabled() );
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #endif
    
        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();
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTrueOrg, PelStorage* pcPicYuvFilteredOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded )
    
    {
      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