Skip to content
Snippets Groups Projects
Slice.cpp 85.6 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-2019, 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     Slice.cpp
        \brief    slice header and SPS class
    */
    
    #include "CommonDef.h"
    #include "Unit.h"
    #include "Slice.h"
    #include "Picture.h"
    #include "dtrace_next.h"
    
    
    #include "UnitTools.h"
    
    
    //! \ingroup CommonLib
    //! \{
    
    Slice::Slice()
    : m_iPPSId                        ( -1 )
    , m_PicOutputFlag                 ( true )
    , m_iPOC                          ( 0 )
    , m_iLastIDR                      ( 0 )
    , m_iAssociatedIRAP               ( 0 )
    , m_iAssociatedIRAPType           ( NAL_UNIT_INVALID )
    , m_pRPS                          ( 0 )
    , m_localRPS                      ( )
    , m_rpsIdx                        ( 0 )
    , m_RefPicListModification        ( )
    , m_eNalUnitType                  ( NAL_UNIT_CODED_SLICE_IDR_W_RADL )
    , m_eSliceType                    ( I_SLICE )
    , m_iSliceQp                      ( 0 )
    #if HEVC_DEPENDENT_SLICES
    , m_dependentSliceSegmentFlag     ( false )
    #endif
    , m_ChromaQpAdjEnabled            ( false )
    , m_deblockingFilterDisable       ( false )
    , m_deblockingFilterOverrideFlag  ( false )
    , m_deblockingFilterBetaOffsetDiv2( 0 )
    , m_deblockingFilterTcOffsetDiv2  ( 0 )
    , m_pendingRasInit                ( false )
    , m_depQuantEnabledFlag           ( false )
    #if HEVC_USE_SIGN_HIDING
    , m_signDataHidingEnabledFlag     ( false )
    #endif
    , m_bCheckLDC                     ( false )
    
    , m_iSliceQpDelta                 ( 0 )
    , m_iDepth                        ( 0 )
    #if HEVC_VPS
    , m_pcVPS                         ( NULL )
    #endif
    , m_pcSPS                         ( NULL )
    , m_pcPPS                         ( NULL )
    , m_pcPic                         ( NULL )
    , m_colFromL0Flag                 ( true )
    , m_noOutputPriorPicsFlag         ( false )
    , m_noRaslOutputFlag              ( false )
    
    , m_handleCraAsCvsStartFlag            ( false )
    
    , m_maxNumAffineMergeCand         ( 0 )
    
    , m_disFracMMVD                   ( false )
    
    , m_uiTLayer                      ( 0 )
    , m_bTLayerSwitchingFlag          ( false )
    , m_sliceMode                     ( NO_SLICES )
    , m_sliceArgument                 ( 0 )
    , m_sliceCurStartCtuTsAddr        ( 0 )
    , m_sliceCurEndCtuTsAddr          ( 0 )
    , m_independentSliceIdx           ( 0 )
    #if HEVC_DEPENDENT_SLICES
    , m_sliceSegmentIdx               ( 0 )
    , m_sliceSegmentMode              ( NO_SLICES )
    , m_sliceSegmentArgument          ( 0 )
    , m_sliceSegmentCurStartCtuTsAddr ( 0 )
    , m_sliceSegmentCurEndCtuTsAddr   ( 0 )
    #endif
    , m_nextSlice                     ( false )
    #if HEVC_DEPENDENT_SLICES
    , m_nextSliceSegment              ( false )
    #endif
    , m_sliceBits                     ( 0 )
    #if HEVC_DEPENDENT_SLICES
    , m_sliceSegmentBits              ( 0 )
    #endif
    , m_bFinalized                    ( false )
    , m_bTestWeightPred               ( false )
    , m_bTestWeightBiPred             ( false )
    , m_substreamSizes                ( )
    , m_cabacInitFlag                 ( false )
    , m_bLMvdL1Zero                   ( false )
    
    #if !JVET_M0101_HLS
    
    , m_temporalLayerNonReferenceFlag ( false )
    
    , m_LFCrossSliceBoundaryFlag      ( false )
    , m_enableTMVPFlag                ( true )
    , m_encCABACTableIdx              (I_SLICE)
    , m_iProcessingStartTime          ( 0 )
    , m_dProcessingTime               ( 0 )
    
    , m_splitConsOverrideFlag         ( false )
    , m_uiMinQTSize                   ( 0 )
    , m_uiMaxBTDepth                  ( 0 )
    , m_uiMaxTTSize                   ( 0 )
    , m_uiMinQTSizeIChroma            ( 0 )
    , m_uiMaxBTDepthIChroma           ( 0 )
    , m_uiMaxBTSizeIChroma            ( 0 )
    , m_uiMaxTTSizeIChroma            ( 0 )
    
    {
      for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
      {
        m_aiNumRefIdx[i] = 0;
      }
    
      for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
      {
        m_lambdas            [component] = 0.0;
        m_iSliceChromaQpDelta[component] = 0;
      }
    
      initEqualRef();
    
      for ( int idx = 0; idx < MAX_NUM_REF; idx++ )
      {
        m_list1IdxToList0Idx[idx] = -1;
      }
    
      for(int iNumCount = 0; iNumCount < MAX_NUM_REF; iNumCount++)
      {
        for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
        {
          m_apcRefPicList [i][iNumCount] = NULL;
          m_aiRefPOCList  [i][iNumCount] = 0;
        }
      }
    
      resetWpScaling();
      initWpAcDcParam();
    
      for(int ch=0; ch < MAX_NUM_CHANNEL_TYPE; ch++)
      {
        m_saoEnabledFlag[ch] = false;
      }
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_sliceReshapeInfo.setUseSliceReshaper(false);
      m_sliceReshapeInfo.setSliceReshapeModelPresentFlag(false);
      m_sliceReshapeInfo.setSliceReshapeChromaAdj(0);
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_sliceReshapeInfo.reshaperModelMinBinIdx = 0;
      m_sliceReshapeInfo.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1;
      memset(m_sliceReshapeInfo.reshaperModelBinCWDelta, 0, PIC_CODE_CW_BINS * sizeof(int));
    
    }
    
    Slice::~Slice()
    {
    }
    
    
    void Slice::initSlice()
    {
      for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
      {
        m_aiNumRefIdx[i]      = 0;
      }
      m_colFromL0Flag = true;
    
      m_colRefIdx = 0;
      initEqualRef();
    
      m_bCheckLDC = false;
    
    
      m_symRefIdx[0] = -1;
      m_symRefIdx[1] = -1;
    
    
      for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
      {
        m_iSliceChromaQpDelta[component] = 0;
      }
    
      m_maxNumMergeCand = MRG_MAX_NUM_CANDS;
    
      m_maxNumAffineMergeCand = AFFINE_MRG_MAX_NUM_CANDS;
    
      m_disFracMMVD          = false;
    
      m_substreamSizes.clear();
      m_cabacInitFlag        = false;
      m_enableTMVPFlag       = true;
    }
    
    void Slice::setDefaultClpRng( const SPS& sps )
    {
      m_clpRngs.comp[COMPONENT_Y].min = m_clpRngs.comp[COMPONENT_Cb].min  = m_clpRngs.comp[COMPONENT_Cr].min = 0;
      m_clpRngs.comp[COMPONENT_Y].max                                     = (1<< sps.getBitDepth(CHANNEL_TYPE_LUMA))-1;
      m_clpRngs.comp[COMPONENT_Y].bd  = sps.getBitDepth(CHANNEL_TYPE_LUMA);
      m_clpRngs.comp[COMPONENT_Y].n   = 0;
      m_clpRngs.comp[COMPONENT_Cb].max = m_clpRngs.comp[COMPONENT_Cr].max = (1<< sps.getBitDepth(CHANNEL_TYPE_CHROMA))-1;
      m_clpRngs.comp[COMPONENT_Cb].bd  = m_clpRngs.comp[COMPONENT_Cr].bd  = sps.getBitDepth(CHANNEL_TYPE_CHROMA);
      m_clpRngs.comp[COMPONENT_Cb].n   = m_clpRngs.comp[COMPONENT_Cr].n   = 0;
      m_clpRngs.used = m_clpRngs.chroma = false;
    }
    
    
    bool Slice::getRapPicFlag() const
    {
      return getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
    
    #if !JVET_M0101_HLS
    
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
    
    #endif
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA;
    
    }
    
    
    void  Slice::sortPicList        (PicList& rcListPic)
    {
      Picture*    pcPicExtract;
      Picture*    pcPicInsert;
    
      PicList::iterator    iterPicExtract;
      PicList::iterator    iterPicExtract_1;
      PicList::iterator    iterPicInsert;
    
      for (int i = 1; i < (int)(rcListPic.size()); i++)
      {
        iterPicExtract = rcListPic.begin();
        for (int j = 0; j < i; j++)
        {
          iterPicExtract++;
        }
        pcPicExtract = *(iterPicExtract);
    
        iterPicInsert = rcListPic.begin();
        while (iterPicInsert != iterPicExtract)
        {
          pcPicInsert = *(iterPicInsert);
          if (pcPicInsert->getPOC() >= pcPicExtract->getPOC())
          {
            break;
          }
    
          iterPicInsert++;
        }
    
        iterPicExtract_1 = iterPicExtract;    iterPicExtract_1++;
    
        //  swap iterPicExtract and iterPicInsert, iterPicExtract = curr. / iterPicInsert = insertion position
        rcListPic.insert( iterPicInsert, iterPicExtract, iterPicExtract_1 );
        rcListPic.erase( iterPicExtract );
      }
    }
    
    Picture* Slice::xGetRefPic (PicList& rcListPic, int poc)
    {
      PicList::iterator  iterPic = rcListPic.begin();
      Picture*           pcPic   = *(iterPic);
    
      while ( iterPic != rcListPic.end() )
      {
        if(pcPic->getPOC() == poc)
        {
          break;
        }
        iterPic++;
        pcPic = *(iterPic);
      }
      return  pcPic;
    }
    
    
    Picture* Slice::xGetLongTermRefPic( PicList& rcListPic, int poc, bool pocHasMsb)
    {
      PicList::iterator  iterPic = rcListPic.begin();
      Picture*           pcPic   = *(iterPic);
      Picture*           pcStPic = pcPic;
    
      int pocCycle = 1 << getSPS()->getBitsForPOC();
      if (!pocHasMsb)
      {
        poc = poc & (pocCycle - 1);
      }
    
      while ( iterPic != rcListPic.end() )
      {
        pcPic = *(iterPic);
        if (pcPic && pcPic->getPOC()!=this->getPOC() && pcPic->referenced)
        {
          int picPoc = pcPic->getPOC();
          if (!pocHasMsb)
          {
            picPoc = picPoc & (pocCycle - 1);
          }
    
          if (poc == picPoc)
          {
            if(pcPic->longTerm)
            {
              return pcPic;
            }
            else
            {
              pcStPic = pcPic;
            }
            break;
          }
        }
    
        iterPic++;
      }
    
      return pcStPic;
    }
    
    void Slice::setRefPOCList       ()
    {
      for (int iDir = 0; iDir < NUM_REF_PIC_LIST_01; iDir++)
      {
        for (int iNumRefIdx = 0; iNumRefIdx < m_aiNumRefIdx[iDir]; iNumRefIdx++)
        {
          m_aiRefPOCList[iDir][iNumRefIdx] = m_apcRefPicList[iDir][iNumRefIdx]->getPOC();
        }
      }
    
    }
    
    void Slice::setList1IdxToList0Idx()
    {
      int idxL0, idxL1;
      for ( idxL1 = 0; idxL1 < getNumRefIdx( REF_PIC_LIST_1 ); idxL1++ )
      {
        m_list1IdxToList0Idx[idxL1] = -1;
        for ( idxL0 = 0; idxL0 < getNumRefIdx( REF_PIC_LIST_0 ); idxL0++ )
        {
          if ( m_apcRefPicList[REF_PIC_LIST_0][idxL0]->getPOC() == m_apcRefPicList[REF_PIC_LIST_1][idxL1]->getPOC() )
          {
            m_list1IdxToList0Idx[idxL1] = idxL0;
            break;
          }
        }
      }
    }
    
    void Slice::setRefPicList( PicList& rcListPic, bool checkNumPocTotalCurr, bool bCopyL0toL1ErrorCase )
    {
      if ( m_eSliceType == I_SLICE)
      {
        ::memset( m_apcRefPicList, 0, sizeof (m_apcRefPicList));
        ::memset( m_aiNumRefIdx,   0, sizeof ( m_aiNumRefIdx ));
    
        if (!checkNumPocTotalCurr)
        {
          return;
        }
      }
    
      Picture*  pcRefPic= NULL;
      static const uint32_t MAX_NUM_NEGATIVE_PICTURES=16;
      Picture*  RefPicSetStCurr0[MAX_NUM_NEGATIVE_PICTURES];
      Picture*  RefPicSetStCurr1[MAX_NUM_NEGATIVE_PICTURES];
      Picture*  RefPicSetLtCurr[MAX_NUM_NEGATIVE_PICTURES];
      uint32_t NumPicStCurr0 = 0;
      uint32_t NumPicStCurr1 = 0;
      uint32_t NumPicLtCurr = 0;
      int i;
    
      for(i=0; i < m_pRPS->getNumberOfNegativePictures(); i++)
      {
        if(m_pRPS->getUsed(i))
        {
          pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pRPS->getDeltaPOC(i));
          pcRefPic->longTerm = false;
          pcRefPic->extendPicBorder();
          RefPicSetStCurr0[NumPicStCurr0] = pcRefPic;
          NumPicStCurr0++;
        }
      }
    
      for(; i < m_pRPS->getNumberOfNegativePictures()+m_pRPS->getNumberOfPositivePictures(); i++)
      {
        if(m_pRPS->getUsed(i))
        {
          pcRefPic = xGetRefPic(rcListPic, getPOC()+m_pRPS->getDeltaPOC(i));
          pcRefPic->longTerm = false;
          pcRefPic->extendPicBorder();
          RefPicSetStCurr1[NumPicStCurr1] = pcRefPic;
          NumPicStCurr1++;
        }
      }
    
      for(i = m_pRPS->getNumberOfNegativePictures()+m_pRPS->getNumberOfPositivePictures()+m_pRPS->getNumberOfLongtermPictures()-1; i > m_pRPS->getNumberOfNegativePictures()+m_pRPS->getNumberOfPositivePictures()-1 ; i--)
      {
        if(m_pRPS->getUsed(i))
        {
          pcRefPic = xGetLongTermRefPic(rcListPic, m_pRPS->getPOC(i), m_pRPS->getCheckLTMSBPresent(i));
          pcRefPic->longTerm = true;
          pcRefPic->extendPicBorder();
          RefPicSetLtCurr[NumPicLtCurr] = pcRefPic;
          NumPicLtCurr++;
        }
        if(pcRefPic==NULL)
        {
          pcRefPic = xGetLongTermRefPic(rcListPic, m_pRPS->getPOC(i), m_pRPS->getCheckLTMSBPresent(i));
        }
      }
      // ref_pic_list_init
      Picture*  rpsCurrList0[MAX_NUM_REF+1];
      Picture*  rpsCurrList1[MAX_NUM_REF+1];
      int numPicTotalCurr = NumPicStCurr0 + NumPicStCurr1 + NumPicLtCurr;
    
      if (checkNumPocTotalCurr)
      {
        // The variable NumPocTotalCurr is derived as specified in subclause 7.4.7.2. It is a requirement of bitstream conformance that the following applies to the value of NumPocTotalCurr:
        // - If the current picture is a BLA or CRA picture, the value of NumPocTotalCurr shall be equal to 0.
        // - Otherwise, when the current picture contains a P or B slice, the value of NumPocTotalCurr shall not be equal to 0.
        if (getRapPicFlag())
        {
    
            CHECK(numPicTotalCurr != 0, "Invalid state");
    
        }
    
        if (m_eSliceType == I_SLICE)
        {
          return;
        }
    
        CHECK(numPicTotalCurr == 0, "Invalid state");
        // general tier and level limit:
        CHECK(numPicTotalCurr > 8, "Invalid state");
      }
    
      int cIdx = 0;
      for ( i=0; i<NumPicStCurr0; i++, cIdx++)
      {
        rpsCurrList0[cIdx] = RefPicSetStCurr0[i];
      }
      for ( i=0; i<NumPicStCurr1; i++, cIdx++)
      {
        rpsCurrList0[cIdx] = RefPicSetStCurr1[i];
      }
      for ( i=0; i<NumPicLtCurr;  i++, cIdx++)
      {
        rpsCurrList0[cIdx] = RefPicSetLtCurr[i];
      }
      CHECK(cIdx != numPicTotalCurr, "Invalid state");
    
      if (m_eSliceType==B_SLICE)
      {
        cIdx = 0;
        for ( i=0; i<NumPicStCurr1; i++, cIdx++)
        {
          rpsCurrList1[cIdx] = RefPicSetStCurr1[i];
        }
        for ( i=0; i<NumPicStCurr0; i++, cIdx++)
        {
          rpsCurrList1[cIdx] = RefPicSetStCurr0[i];
        }
        for ( i=0; i<NumPicLtCurr;  i++, cIdx++)
        {
          rpsCurrList1[cIdx] = RefPicSetLtCurr[i];
        }
        CHECK(cIdx != numPicTotalCurr, "Invalid state");
      }
    
      ::memset(m_bIsUsedAsLongTerm, 0, sizeof(m_bIsUsedAsLongTerm));
    
      for (int rIdx = 0; rIdx < m_aiNumRefIdx[REF_PIC_LIST_0]; rIdx ++)
      {
        cIdx = m_RefPicListModification.getRefPicListModificationFlagL0() ? m_RefPicListModification.getRefPicSetIdxL0(rIdx) : rIdx % numPicTotalCurr;
        CHECK(cIdx < 0 || cIdx >= numPicTotalCurr, "Invalid state");
        m_apcRefPicList[REF_PIC_LIST_0][rIdx] = rpsCurrList0[ cIdx ];
        m_bIsUsedAsLongTerm[REF_PIC_LIST_0][rIdx] = ( cIdx >= NumPicStCurr0 + NumPicStCurr1 );
      }
      if ( m_eSliceType != B_SLICE )
      {
        m_aiNumRefIdx[REF_PIC_LIST_1] = 0;
        ::memset( m_apcRefPicList[REF_PIC_LIST_1], 0, sizeof(m_apcRefPicList[REF_PIC_LIST_1]));
      }
      else
      {
        for (int rIdx = 0; rIdx < m_aiNumRefIdx[REF_PIC_LIST_1]; rIdx ++)
        {
          cIdx = m_RefPicListModification.getRefPicListModificationFlagL1() ? m_RefPicListModification.getRefPicSetIdxL1(rIdx) : rIdx % numPicTotalCurr;
          CHECK(cIdx < 0 || cIdx >= numPicTotalCurr, "Invalid state");
          m_apcRefPicList[REF_PIC_LIST_1][rIdx] = rpsCurrList1[ cIdx ];
          m_bIsUsedAsLongTerm[REF_PIC_LIST_1][rIdx] = ( cIdx >= NumPicStCurr0 + NumPicStCurr1 );
        }
      }
        // For generalized B
      // note: maybe not existed case (always L0 is copied to L1 if L1 is empty)
      if( bCopyL0toL1ErrorCase && isInterB() && getNumRefIdx(REF_PIC_LIST_1) == 0)
      {
        int iNumRefIdx = getNumRefIdx(REF_PIC_LIST_0);
        setNumRefIdx( REF_PIC_LIST_1, iNumRefIdx );
    
        for (int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++)
        {
          m_apcRefPicList[REF_PIC_LIST_1][iRefIdx] = m_apcRefPicList[REF_PIC_LIST_0] [iRefIdx];
        }
      }
    }
    
    
    int Slice::getNumRpsCurrTempList() const
    {
      int numRpsCurrTempList = 0;
    
      if (m_eSliceType == I_SLICE)
      {
        return 0;
      }
      for(uint32_t i=0; i < m_pRPS->getNumberOfNegativePictures()+ m_pRPS->getNumberOfPositivePictures() + m_pRPS->getNumberOfLongtermPictures(); i++)
      {
        if(m_pRPS->getUsed(i))
        {
          numRpsCurrTempList++;
        }
      }
    
    }
    
    void Slice::initEqualRef()
    {
      for (int iDir = 0; iDir < NUM_REF_PIC_LIST_01; iDir++)
      {
        for (int iRefIdx1 = 0; iRefIdx1 < MAX_NUM_REF; iRefIdx1++)
        {
          for (int iRefIdx2 = iRefIdx1; iRefIdx2 < MAX_NUM_REF; iRefIdx2++)
          {
            m_abEqualRef[iDir][iRefIdx1][iRefIdx2] = m_abEqualRef[iDir][iRefIdx2][iRefIdx1] = (iRefIdx1 == iRefIdx2? true : false);
          }
        }
      }
    }
    
    void Slice::checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic)
    {
      int i;
      Slice* curSlice = pic->slices[curSliceSegmentIdx];
      int currColRefPOC =  curSlice->getRefPOC( RefPicList(1 - curSlice->getColFromL0Flag()), curSlice->getColRefIdx());
    
      for(i=curSliceSegmentIdx-1; i>=0; i--)
      {
        const Slice* preSlice = pic->slices[i];
        if(preSlice->getSliceType() != I_SLICE)
        {
          const int preColRefPOC  = preSlice->getRefPOC( RefPicList(1 - preSlice->getColFromL0Flag()), preSlice->getColRefIdx());
          if(currColRefPOC != preColRefPOC)
          {
            THROW("Collocated_ref_idx shall always be the same for all slices of a coded picture!");
          }
          else
          {
            break;
          }
        }
      }
    }
    
    void Slice::checkCRA(const ReferencePictureSet *pReferencePictureSet, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic)
    {
      for(int i = 0; i < pReferencePictureSet->getNumberOfNegativePictures()+pReferencePictureSet->getNumberOfPositivePictures(); i++)
      {
        if(pocCRA < MAX_UINT && getPOC() > pocCRA)
        {
          CHECK(getPOC()+pReferencePictureSet->getDeltaPOC(i) < pocCRA, "Invalid state");
        }
      }
      for(int i = pReferencePictureSet->getNumberOfNegativePictures()+pReferencePictureSet->getNumberOfPositivePictures(); i < pReferencePictureSet->getNumberOfPictures(); i++)
      {
        if(pocCRA < MAX_UINT && getPOC() > pocCRA)
        {
          if (!pReferencePictureSet->getCheckLTMSBPresent(i))
          {
            CHECK(xGetLongTermRefPic(rcListPic, pReferencePictureSet->getPOC(i), false)->getPOC() < pocCRA, "Invalid state");
          }
          else
          {
            CHECK(pReferencePictureSet->getPOC(i) < pocCRA, "Invalid state");
          }
        }
      }
      if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP ) // IDR picture found
      {
        pocCRA = getPOC();
        associatedIRAPType = getNalUnitType();
      }
      else if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) // CRA picture found
      {
        pocCRA = getPOC();
        associatedIRAPType = getNalUnitType();
      }
    
    #if !JVET_M0101_HLS
    
      else if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
             || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
             || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP ) // BLA picture found
      {
        pocCRA = getPOC();
        associatedIRAPType = getNalUnitType();
      }
    
    }
    
    /** Function for marking the reference pictures when an IDR/CRA/CRANT/BLA/BLANT is encountered.
     * \param pocCRA POC of the CRA/CRANT/BLA/BLANT picture
     * \param bRefreshPending flag indicating if a deferred decoding refresh is pending
     * \param rcListPic reference to the reference picture list
     * This function marks the reference pictures as "unused for reference" in the following conditions.
     * If the nal_unit_type is IDR/BLA/BLANT, all pictures in the reference picture list
     * are marked as "unused for reference"
     *    If the nal_unit_type is BLA/BLANT, set the pocCRA to the temporal reference of the current picture.
     * Otherwise
     *    If the bRefreshPending flag is true (a deferred decoding refresh is pending) and the current
     *    temporal reference is greater than the temporal reference of the latest CRA/CRANT/BLA/BLANT picture (pocCRA),
     *    mark all reference pictures except the latest CRA/CRANT/BLA/BLANT picture as "unused for reference" and set
     *    the bRefreshPending flag to false.
     *    If the nal_unit_type is CRA/CRANT, set the bRefreshPending flag to true and pocCRA to the temporal
     *    reference of the current picture.
     * Note that the current picture is already placed in the reference list and its marking is not changed.
     * If the current picture has a nal_ref_idc that is not 0, it will remain marked as "used for reference".
     */
    void Slice::decodingRefreshMarking(int& pocCRA, bool& bRefreshPending, PicList& rcListPic, const bool bEfficientFieldIRAPEnabled)
    {
      Picture* rpcPic;
      int      pocCurr = getPOC();
    
    
    #if !JVET_M0101_HLS
    
      if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP )  // IDR or BLA picture
    
    #else
      if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
        || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP)  // IDR picture
    #endif
    
      {
        // mark all pictures as not used for reference
        PicList::iterator        iterPic       = rcListPic.begin();
        while (iterPic != rcListPic.end())
        {
          rpcPic = *(iterPic);
          if (rpcPic->getPOC() != pocCurr)
          {
            rpcPic->referenced = false;
    
            rpcPic->getHashMap()->clearAll();
    
    #if !JVET_M0101_HLS
    
        if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
          || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP )
        {
          pocCRA = pocCurr;
        }
    
        if (bEfficientFieldIRAPEnabled)
        {
          bRefreshPending = true;
        }
      }
      else // CRA or No DR
      {
        if(bEfficientFieldIRAPEnabled && (getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL))
        {
          if (bRefreshPending==true && pocCurr > m_iLastIDR) // IDR reference marking pending
          {
            PicList::iterator        iterPic       = rcListPic.begin();
            while (iterPic != rcListPic.end())
            {
              rpcPic = *(iterPic);
              if (rpcPic->getPOC() != pocCurr && rpcPic->getPOC() != m_iLastIDR)
              {
                rpcPic->referenced = false;
    
                rpcPic->getHashMap()->clearAll();
    
              }
              iterPic++;
            }
            bRefreshPending = false;
          }
        }
        else
        {
          if (bRefreshPending==true && pocCurr > pocCRA) // CRA reference marking pending
          {
            PicList::iterator iterPic = rcListPic.begin();
            while (iterPic != rcListPic.end())
            {
              rpcPic = *(iterPic);
              if (rpcPic->getPOC() != pocCurr && rpcPic->getPOC() != pocCRA)
              {
                rpcPic->referenced = false;
    
                rpcPic->getHashMap()->clearAll();
    
              }
              iterPic++;
            }
            bRefreshPending = false;
          }
        }
        if ( getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) // CRA picture found
        {
          bRefreshPending = true;
          pocCRA = pocCurr;
        }
      }
    }
    
    void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
    {
      CHECK(!pSrc, "Source is NULL");
    
      int i, j, k;
    
      m_iPOC                 = pSrc->m_iPOC;
      m_eNalUnitType         = pSrc->m_eNalUnitType;
      m_eSliceType           = pSrc->m_eSliceType;
      m_iSliceQp             = pSrc->m_iSliceQp;
      m_iSliceQpBase         = pSrc->m_iSliceQpBase;
      m_ChromaQpAdjEnabled              = pSrc->m_ChromaQpAdjEnabled;
      m_deblockingFilterDisable         = pSrc->m_deblockingFilterDisable;
      m_deblockingFilterOverrideFlag    = pSrc->m_deblockingFilterOverrideFlag;
      m_deblockingFilterBetaOffsetDiv2  = pSrc->m_deblockingFilterBetaOffsetDiv2;
      m_deblockingFilterTcOffsetDiv2    = pSrc->m_deblockingFilterTcOffsetDiv2;
    
      for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
      {
        m_aiNumRefIdx[i]     = pSrc->m_aiNumRefIdx[i];
      }
    
      for (i = 0; i < MAX_NUM_REF; i++)
      {
        m_list1IdxToList0Idx[i] = pSrc->m_list1IdxToList0Idx[i];
      }
    
      m_bCheckLDC             = pSrc->m_bCheckLDC;
      m_iSliceQpDelta        = pSrc->m_iSliceQpDelta;
    
      m_symRefIdx[0] = pSrc->m_symRefIdx[0];
      m_symRefIdx[1] = pSrc->m_symRefIdx[1];
    
    
      for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
      {
        m_iSliceChromaQpDelta[component] = pSrc->m_iSliceChromaQpDelta[component];
      }
      for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
      {
        for (j = 0; j < MAX_NUM_REF; j++)
        {
          m_apcRefPicList[i][j]  = pSrc->m_apcRefPicList[i][j];
          m_aiRefPOCList[i][j]   = pSrc->m_aiRefPOCList[i][j];
          m_bIsUsedAsLongTerm[i][j] = pSrc->m_bIsUsedAsLongTerm[i][j];
        }
        m_bIsUsedAsLongTerm[i][MAX_NUM_REF] = pSrc->m_bIsUsedAsLongTerm[i][MAX_NUM_REF];
      }
      if( cpyAlmostAll ) m_iDepth = pSrc->m_iDepth;
    
      // access channel
      if( cpyAlmostAll ) m_pRPS   = pSrc->m_pRPS;
      m_iLastIDR             = pSrc->m_iLastIDR;
    
      if( cpyAlmostAll ) m_pcPic  = pSrc->m_pcPic;
    
      m_colFromL0Flag        = pSrc->m_colFromL0Flag;
      m_colRefIdx            = pSrc->m_colRefIdx;
    
      if( cpyAlmostAll ) setLambdas(pSrc->getLambdas());
    
      for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
      {
        for (j = 0; j < MAX_NUM_REF; j++)
        {
          for (k =0; k < MAX_NUM_REF; k++)
          {
            m_abEqualRef[i][j][k] = pSrc->m_abEqualRef[i][j][k];
          }
        }
      }
    
      m_uiTLayer                      = pSrc->m_uiTLayer;
      m_bTLayerSwitchingFlag          = pSrc->m_bTLayerSwitchingFlag;
    
      m_sliceMode                     = pSrc->m_sliceMode;
      m_sliceArgument                 = pSrc->m_sliceArgument;
      m_sliceCurStartCtuTsAddr        = pSrc->m_sliceCurStartCtuTsAddr;
      m_sliceCurEndCtuTsAddr          = pSrc->m_sliceCurEndCtuTsAddr;
      m_independentSliceIdx           = pSrc->m_independentSliceIdx;
    #if HEVC_DEPENDENT_SLICES
      m_sliceSegmentIdx               = pSrc->m_sliceSegmentIdx;
      m_sliceSegmentMode              = pSrc->m_sliceSegmentMode;
      m_sliceSegmentArgument          = pSrc->m_sliceSegmentArgument;
      m_sliceSegmentCurStartCtuTsAddr = pSrc->m_sliceSegmentCurStartCtuTsAddr;
      m_sliceSegmentCurEndCtuTsAddr   = pSrc->m_sliceSegmentCurEndCtuTsAddr;
    #endif
      m_nextSlice                     = pSrc->m_nextSlice;
    #if HEVC_DEPENDENT_SLICES
      m_nextSliceSegment              = pSrc->m_nextSliceSegment;
    #endif
      m_clpRngs                       = pSrc->m_clpRngs;
      m_pendingRasInit                = pSrc->m_pendingRasInit;
    
      for ( uint32_t e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
      {
        for ( uint32_t n=0 ; n<MAX_NUM_REF ; n++ )
        {
          memcpy(m_weightPredTable[e][n], pSrc->m_weightPredTable[e][n], sizeof(WPScalingParam)*MAX_NUM_COMPONENT );
        }
      }
    
      for( uint32_t ch = 0 ; ch < MAX_NUM_CHANNEL_TYPE; ch++)
      {
        m_saoEnabledFlag[ch] = pSrc->m_saoEnabledFlag[ch];
      }
    
      m_cabacInitFlag                 = pSrc->m_cabacInitFlag;
    
      m_bLMvdL1Zero                   = pSrc->m_bLMvdL1Zero;
      m_LFCrossSliceBoundaryFlag      = pSrc->m_LFCrossSliceBoundaryFlag;
      m_enableTMVPFlag                = pSrc->m_enableTMVPFlag;
      m_maxNumMergeCand               = pSrc->m_maxNumMergeCand;
    
      m_maxNumAffineMergeCand         = pSrc->m_maxNumAffineMergeCand;
    
      m_disFracMMVD                   = pSrc->m_disFracMMVD;
    
      if( cpyAlmostAll ) m_encCABACTableIdx  = pSrc->m_encCABACTableIdx;
    
      m_splitConsOverrideFlag         = pSrc->m_splitConsOverrideFlag;
      m_uiMinQTSize                   = pSrc->m_uiMinQTSize;
      m_uiMaxBTDepth                  = pSrc->m_uiMaxBTDepth;
      m_uiMaxTTSize                   = pSrc->m_uiMaxTTSize;
      m_uiMinQTSizeIChroma            = pSrc->m_uiMinQTSizeIChroma;
      m_uiMaxBTDepthIChroma           = pSrc->m_uiMaxBTDepthIChroma;
      m_uiMaxBTSizeIChroma            = pSrc->m_uiMaxBTSizeIChroma;
      m_uiMaxTTSizeIChroma            = pSrc->m_uiMaxTTSizeIChroma;
    
    
      m_depQuantEnabledFlag           = pSrc->m_depQuantEnabledFlag;
      m_signDataHidingEnabledFlag     = pSrc->m_signDataHidingEnabledFlag;
    
      m_sliceReshapeInfo              = pSrc->m_sliceReshapeInfo;
    
    }
    
    
    /** Function for checking if this is a switching-point
    */
    bool Slice::isTemporalLayerSwitchingPoint(PicList& rcListPic) const
    {
      // loop through all pictures in the reference picture buffer
      PicList::iterator iterPic = rcListPic.begin();
      while ( iterPic != rcListPic.end())
      {
        const Picture* pcPic = *(iterPic++);
        if( pcPic->referenced && pcPic->poc != getPOC())
        {
          if( pcPic->layer >= getTLayer())
          {
            return false;
          }
        }
      }
      return true;
    }
    
    /** Function for checking if this is a STSA candidate
     */
    bool Slice::isStepwiseTemporalLayerSwitchingPointCandidate(PicList& rcListPic) const
    {
      PicList::iterator iterPic = rcListPic.begin();
      while ( iterPic != rcListPic.end())
      {
        const Picture* pcPic = *(iterPic++);
        if( pcPic->referenced &&  pcPic->usedByCurr && pcPic->poc != getPOC())
        {
          if( pcPic->layer >= getTLayer())
          {
            return false;
          }
        }
      }
      return true;
    }
    
    
    void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const
    {
      int nalUnitType = this->getNalUnitType();
    
      // When a picture is a leading picture, it shall be a RADL or RASL picture.
      if(this->getAssociatedIRAPPOC() > this->getPOC())
      {
        // Do not check IRAP pictures since they may get a POC lower than their associated IRAP
    
    #if !JVET_M0101_HLS
    
        if(nalUnitType < NAL_UNIT_CODED_SLICE_BLA_W_LP ||
           nalUnitType > NAL_UNIT_RESERVED_IRAP_VCL23)
    
    #else
        if (nalUnitType < NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
            nalUnitType > NAL_UNIT_RESERVED_IRAP_VCL13)
    #endif
    
    #if !JVET_M0101_HLS
    
          CHECK( nalUnitType != NAL_UNIT_CODED_SLICE_RASL_N &&
                 nalUnitType != NAL_UNIT_CODED_SLICE_RASL_R &&
                 nalUnitType != NAL_UNIT_CODED_SLICE_RADL_N &&
                 nalUnitType != NAL_UNIT_CODED_SLICE_RADL_R, "Invalid NAL unit type");
    
    #else
          CHECK(nalUnitType != NAL_UNIT_CODED_SLICE_RASL &&
                nalUnitType != NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
    #endif
    
        }
      }
    
      // When a picture is a trailing picture, it shall not be a RADL or RASL picture.
      if(this->getAssociatedIRAPPOC() < this->getPOC())
      {
    
    #if !JVET_M0101_HLS
    
        CHECK( nalUnitType == NAL_UNIT_CODED_SLICE_RASL_N ||
               nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R ||
               nalUnitType == NAL_UNIT_CODED_SLICE_RADL_N ||
               nalUnitType == NAL_UNIT_CODED_SLICE_RADL_R, "Invalid NAL unit type" );
    
    #else
        CHECK(nalUnitType == NAL_UNIT_CODED_SLICE_RASL ||
              nalUnitType == NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
    #endif
    
    #if !JVET_M0101_HLS
    
      // No RASL pictures shall be present in the bitstream that are associated
      // with a BLA picture having nal_unit_type equal to BLA_W_RADL or BLA_N_LP.
      if(nalUnitType == NAL_UNIT_CODED_SLICE_RASL_N ||
         nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R)
      {
        CHECK (this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL ||
               this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_BLA_N_LP, "Invalid NAL unit type");
      }
    
    
      // No RASL pictures shall be present in the bitstream that are associated with
      // an IDR picture.
    
    #if !JVET_M0101_HLS
    
      if(nalUnitType == NAL_UNIT_CODED_SLICE_RASL_N ||
         nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R)
    
    #else
      if (nalUnitType == NAL_UNIT_CODED_SLICE_RASL)
    #endif
    
      {
        CHECK( this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP   ||
               this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL, "Invalid NAL unit type");
      }
    
      // No RADL pictures shall be present in the bitstream that are associated with
      // a BLA picture having nal_unit_type equal to BLA_N_LP or that are associated
      // with an IDR picture having nal_unit_type equal to IDR_N_LP.
    
    #if !JVET_M0101_HLS
    
      if(nalUnitType == NAL_UNIT_CODED_SLICE_RADL_N ||
         nalUnitType == NAL_UNIT_CODED_SLICE_RADL_R)
    
    #else
      if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
    #endif
    
    #if !JVET_M0101_HLS
    
        CHECK (this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_BLA_N_LP   ||
               this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP, "Invalid NAL unit type");
    
    #else
        CHECK (this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP, "Invalid NAL unit type");
    #endif
    
      }
    
      // loop through all pictures in the reference picture buffer
      PicList::iterator iterPic = rcListPic.begin();
      while ( iterPic != rcListPic.end())