Skip to content
Snippets Groups Projects
EncGOP.cpp 283 KiB
Newer Older
  • Learn to ignore specific revisions
  • Vadim Seregin's avatar
    Vadim Seregin committed
    
    
    #if JVET_V0094_BILATERAL_FILTER
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    class BIFCabacEstImp : public BIFCabacEst
    {
      CABACWriter* CABACEstimator;
    public:
      BIFCabacEstImp(CABACWriter* _CABACEstimator) : CABACEstimator(_CABACEstimator) {};
      virtual ~BIFCabacEstImp() {};
    
    
    #if JVET_AG0196_CABAC_RETRAIN
      virtual uint64_t getBits( const ComponentID compID, Slice& slice, const BifParams& htdfParams )
    #else
    
      virtual uint64_t getBits(const ComponentID compID, const Slice& slice, const BifParams& htdfParams)
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      {
        CABACEstimator->initCtxModels(slice);
        CABACEstimator->resetBits();
    
        CABACEstimator->bif( compID, slice, htdfParams);
    
        return CABACEstimator->getEstFracBits();
      }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    
    
    // ====================================================================================================================
    // Public member functions
    // ====================================================================================================================
    
    void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std::list<PelUnitBuf *> &rcListPicYuvRecOut,
                             bool isField, bool isTff, const InputColourSpaceConversion snr_conversion,
                             const bool printFrameMSE,
    #if MSSIM_UNIFORM_METRICS_LOG
                             const bool printMSSSIM,
    #endif
                             bool isEncodeLtRef, const int picIdInGOP)
    
    Brian Heng's avatar
    Brian Heng committed
      PicHeader*      picHeader = NULL;
    
      Slice*      pcSlice;
      OutputBitstream  *pcBitstreamRedirect;
      pcBitstreamRedirect = new OutputBitstream;
      AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      Picture* scaledRefPic[MAX_NUM_REF] = {};
    
      xInitGOP( iPOCLast, iNumPicRcvd, isField, isEncodeLtRef );
    
    
      m_iNumPicCoded = 0;
      SEIMessages leadingSeiMessages;
      SEIMessages nestedSeiMessages;
      SEIMessages duInfoSeiMessages;
      SEIMessages trailingSeiMessages;
      std::deque<DUData> duData;
    
      EfficientFieldIRAPMapping effFieldIRAPMap;
      if (m_pcCfg->getEfficientFieldIRAPEnabled())
      {
        effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);
      }
    
    
    Haiwei Sun's avatar
    Haiwei Sun committed
      if( isField && picIdInGOP == 0 )
      {
        for( int iGOPid = 0; iGOPid < max(2, m_iGopSize); iGOPid++ )
        {
          m_pcCfg->setEncodedFlag( iGOPid, false );
        }
      }
    
      for( int iGOPid = picIdInGOP; iGOPid <= picIdInGOP; iGOPid++ )
      {
        // reset flag indicating whether pictures have been encoded
        m_pcCfg->setEncodedFlag( iGOPid, false );
    
        if (m_pcCfg->getEfficientFieldIRAPEnabled())
        {
          iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid);
        }
    
        //-- For time output for each slice
        auto beforeTime = std::chrono::steady_clock::now();
    
    #if !X0038_LAMBDA_FROM_QP_CAPABILITY
        uint32_t uiColDir = calculateCollocatedFromL1Flag(m_pcCfg, iGOPid, m_iGopSize);
    #endif
    
        /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
        int iTimeOffset;
        int pocCurr;
    
        int multipleFactor = m_pcCfg->getUseCompositeRef() ? 2 : 1;
    
    
        if(iPOCLast == 0) //case first frame or first top field
        {
          pocCurr=0;
    
          iTimeOffset = isField ? (1 - multipleFactor) : multipleFactor;
    
        }
        else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
        {
          pocCurr = 1;
    
          pocCurr = iPOCLast - iNumPicRcvd * multipleFactor + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1 : 0);
    
        if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
        {
          pocCurr++;
          iTimeOffset--;
        }
        if (pocCurr / multipleFactor >= m_pcCfg->getFramesToBeEncoded())
    
        {
          if (m_pcCfg->getEfficientFieldIRAPEnabled())
          {
            iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
          }
          continue;
        }
    
        if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
        {
          m_iLastIDR = pocCurr;
        }
    
        // start a new access unit: create an entry in the list of output access units
        AccessUnit accessUnit;
    
        accessUnit.temporalId = m_pcCfg->getGOPEntry( iGOPid ).m_temporalId;
    
        xGetBuffer( rcListPic, rcListPicYuvRecOut,
                    iNumPicRcvd, iTimeOffset, pcPic, pocCurr, isField );
    
    Brian Heng's avatar
    Brian Heng committed
        picHeader = pcPic->cs->picHeader;
    
        picHeader->setSPSId( pcPic->cs->pps->getSPSId() );
        picHeader->setPPSId( pcPic->cs->pps->getPPSId() );
    
        picHeader->setMinQTSizes(pcPic->cs->sps->getMinQTSizes());
        picHeader->setMaxMTTHierarchyDepths(pcPic->cs->sps->getMaxMTTHierarchyDepths());
        picHeader->setMaxBTSizes(pcPic->cs->sps->getMaxBTSizes());
        picHeader->setMaxTTSizes(pcPic->cs->sps->getMaxTTSizes());
    
    Brian Heng's avatar
    Brian Heng committed
        picHeader->setSplitConsOverrideFlag(false);
    
        // initial two flags to be false
        picHeader->setPicInterSliceAllowedFlag(false);
        picHeader->setPicIntraSliceAllowedFlag(false);
    
    #if ER_CHROMA_QP_WCG_PPS
    
        // th this is a hot fix for the choma qp control
        if( m_pcEncLib->getWCGChromaQPControl().isEnabled() && m_pcEncLib->getSwitchPOC() != -1 )
        {
          static int usePPS = 0; /* TODO: MT */
          if( pocCurr == m_pcEncLib->getSwitchPOC() )
          {
            usePPS = 1;
          }
          const PPS *pPPS = m_pcEncLib->getPPS(usePPS);
          // replace the pps with a more appropriated one
          pcPic->cs->pps = pPPS;
        }
    
        // create objects based on the picture size
        const int picWidth = pcPic->cs->pps->getPicWidthInLumaSamples();
        const int picHeight = pcPic->cs->pps->getPicHeightInLumaSamples();
        const int maxCUWidth = pcPic->cs->sps->getMaxCUWidth();
        const int maxCUHeight = pcPic->cs->sps->getMaxCUHeight();
        const ChromaFormat chromaFormatIDC = pcPic->cs->sps->getChromaFormatIdc();
    
        const int maxTotalCUDepth = floorLog2(maxCUWidth) - pcPic->cs->sps->getLog2MinCodingBlockSize();
    
    
        m_pcSliceEncoder->create( picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth );
    
    
    #if ENABLE_SPLIT_PARALLELISM
    
        pcPic->scheduler.init( pcPic->cs->pcv->heightInCtus, pcPic->cs->pcv->widthInCtus, 1                          , 0                             , m_pcCfg->getNumSplitThreads() );
    #endif
    
    #if JVET_Y0240_BIM
        const bool isCurrentFrameFiltered = m_pcCfg->getGopBasedTemporalFilterEnabled() || m_pcCfg->getBIM();
    #else
        const bool isCurrentFrameFiltered = m_pcCfg->getGopBasedTemporalFilterEnabled();
    #endif
        const SPS& sps = *pcPic->cs->sps;
        pcPic->createTempBuffers(pcPic->cs->pps->pcv->maxCUWidth, isCurrentFrameFiltered, m_pcEncLib->isResChangeInClvsEnabled(), false);
        pcPic->getTrueOrigBuf().copyFrom(pcPic->getOrigBuf());
        if (m_pcEncLib->isResChangeInClvsEnabled())
        {
          pcPic->M_BUFS(0, PIC_TRUE_ORIGINAL_INPUT).copyFrom(pcPic->M_BUFS(0, PIC_ORIGINAL_INPUT));
        }
        if(isCurrentFrameFiltered)
        {
          if (m_pcEncLib->isResChangeInClvsEnabled())
          {
            m_pcEncLib->getTemporalFilter().filter(pcPic->M_BUFS(0, PIC_ORIGINAL_INPUT), pocCurr);
    
            const Window& curScalingWindow = pcPic->getScalingWindow();
            const int curPicWidth = pcPic->M_BUFS(0, PIC_ORIGINAL).Y().width - SPS::getWinUnitX(sps.getChromaFormatIdc()) * (curScalingWindow.getWindowLeftOffset() + curScalingWindow.getWindowRightOffset());
            const int curPicHeight = pcPic->M_BUFS(0, PIC_ORIGINAL).Y().height - SPS::getWinUnitY(sps.getChromaFormatIdc()) * (curScalingWindow.getWindowTopOffset() + curScalingWindow.getWindowBottomOffset());
            
            const PPS* pps = m_pcEncLib->getPPS(0);
            const Window& refScalingWindow = pps->getScalingWindow();
            const int refPicWidth = pcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).Y().width - SPS::getWinUnitX(sps.getChromaFormatIdc()) * (refScalingWindow.getWindowLeftOffset() + refScalingWindow.getWindowRightOffset());
            const int refPicHeight = pcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).Y().height - SPS::getWinUnitY(sps.getChromaFormatIdc()) * (refScalingWindow.getWindowTopOffset() + refScalingWindow.getWindowBottomOffset());
            const int xScale = ((refPicWidth << SCALE_RATIO_BITS) + (curPicWidth >> 1)) / curPicWidth;
            const int yScale = ((refPicHeight << SCALE_RATIO_BITS) + (curPicHeight >> 1)) / curPicHeight;
            std::pair<int, int> scalingRatio = std::pair<int, int>(xScale, yScale);
    
            Picture::rescalePicture(scalingRatio, pcPic->M_BUFS(0, PIC_ORIGINAL_INPUT), curScalingWindow, pcPic->M_BUFS(0, PIC_ORIGINAL), pps->getScalingWindow(), chromaFormatIDC, sps.getBitDepths(), true, true,
              sps.getHorCollocatedChromaFlag(), sps.getVerCollocatedChromaFlag());
          }
          else
          {
            m_pcEncLib->getTemporalFilter().filter(pcPic->M_BUFS(0, PIC_ORIGINAL), pocCurr);
          }
          pcPic->getFilteredOrigBuf().copyFrom(pcPic->getOrigBuf());
        }
    
        pcPic->cs->createTemporaryCsData((bool)pcPic->cs->sps->getPLTMode());
    
    
        //  Slice data initialization
        pcPic->clearSliceBuffer();
        pcPic->allocateNewSlice();
        m_pcSliceEncoder->setSliceSegmentIdx(0);
    
    
        m_pcSliceEncoder->initEncSlice(pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField, isEncodeLtRef, m_pcEncLib->getLayerId() );
    
    
        DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );
        DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "final", 0 ) ) );
    
    
    #if JVET_AG0145_ADAPTIVE_CLIPPING
        getRealRange(pcPic);
    #endif
    
    #if !SHARP_LUMA_DELTA_QP
        //Set Frame/Field coding
        pcPic->fieldPic = isField;
    #endif
    
    
        pcSlice->setLastIDR(m_iLastIDR);
    
        pcSlice->setIndependentSliceIdx(0);
    
        if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
        {
          pcSlice->setSliceType(P_SLICE);
        }
        if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
        {
          pcSlice->setSliceType(I_SLICE);
        }
    
        pcSlice->setTLayer(m_pcCfg->getGOPEntry(iGOPid).m_temporalId);
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #if JVET_Z0118_GDR
    
        if (m_pcCfg->getGdrEnabled() && pocCurr >= m_pcCfg->getGdrPocStart())
    
    Seungwook Hong's avatar
    Seungwook Hong committed
        {
          pcSlice->setSliceType(B_SLICE);
        }
    
    Seungwook Hong's avatar
    Seungwook Hong committed
        else if (m_pcCfg->getGdrEnabled() && (pocCurr != 0) && (pocCurr < m_pcCfg->getGdrPocStart()))
        {
          pcSlice->setSliceType(B_SLICE);
        }
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    
        // note : first picture is GDR(I_SLICE)
        if (m_pcCfg->getGdrEnabled() && pocCurr == 0)
        {
          pcSlice->setSliceType(I_SLICE);
        }
    #endif
    
    
    #if JVET_AI0136_ADAPTIVE_DUAL_TREE
        if ( pcSlice->isIntra() )
        {
          pcSlice->setSeparateTreeEnabled( pcSlice->getSPS()->getUseDualITree()  );
        }
        else
        {
          //CHECK( !rpcSlice->getSPS()->getSpsNext().getInterSliceSeparateTreeEnabled(), "Error separate trees not enabled\n" )
          pcSlice->setSeparateTreeEnabled( pcSlice->getSPS()->getInterSliceSeparateTreeEnabled()  );
        }
        pcSlice->setProcessingIntraRegion( false );
    #endif
    
    
        // Set the nal unit type
        pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
    
        // set two flags according to slice type presented in the picture
        if (pcSlice->getSliceType() != I_SLICE)
    
          picHeader->setPicInterSliceAllowedFlag(true);
    
        if (pcSlice->getSliceType() == I_SLICE)
    
          picHeader->setPicIntraSliceAllowedFlag(true);
    
        picHeader->setGdrOrIrapPicFlag(picHeader->getGdrPicFlag() || pcSlice->isIRAP());
    
          if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)  // IRAP picture
    
            m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
            m_associatedIRAPPOC[pcPic->layerId] = pocCurr;
    
          pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
          pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);
    
        }
    
        pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled());
    
        if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
        {
          setUseLTRef(true);
          setPrepareLTRef(false);
          setNewestBgPOC(pocCurr);
          setLastLTRefPoc(pocCurr);
        }
    
        else if (m_pcCfg->getUseCompositeRef() && getLastLTRefPoc() >= 0 && getEncodedLTRef()==false && !getPicBg()->getSpliceFull() && (pocCurr - getLastLTRefPoc()) > (m_pcCfg->getFrameRate() * 2))
    
        {
          setUseLTRef(false);
          setPrepareLTRef(false);
          setEncodedLTRef(true);
          setNewestBgPOC(-1);
          setLastLTRefPoc(-1);
        }
    
    
    Hendry's avatar
    Hendry committed
        if (m_pcCfg->getUseCompositeRef() && m_picBg->getSpliceFull() && getUseLTRef())
        {
          m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, m_bgPOC);
        }
        else
        {
          m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, -1);
        }
    
          if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)  // IRAP picture
    
            m_associatedIRAPType[pcPic->layerId] = pcSlice->getNalUnitType();
            m_associatedIRAPPOC[pcPic->layerId] = pocCurr;
    
          pcSlice->setAssociatedIRAPType(m_associatedIRAPType[pcPic->layerId]);
          pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC[pcPic->layerId]);
    
        pcSlice->setEnableDRAPSEI(m_pcEncLib->getDependentRAPIndicationSEIEnabled());
    
        if (m_pcEncLib->getDependentRAPIndicationSEIEnabled())
    
        {
          // Only mark the picture as DRAP if all of the following applies:
          //  1) DRAP indication SEI messages are enabled
          //  2) The current picture is not an intra picture
          //  3) The current picture is in the DRAP period
          //  4) The current picture is a trailing picture
    
          pcSlice->setDRAP(m_pcEncLib->getDependentRAPIndicationSEIEnabled() && m_pcEncLib->getDrapPeriod() > 0 && !pcSlice->isIntra() &&
                  pocCurr % m_pcEncLib->getDrapPeriod() == 0 && pocCurr > pcSlice->getAssociatedIRAPPOC());
    
          if (pcSlice->isDRAP())
          {
            int pocCycle = 1 << (pcSlice->getSPS()->getBitsForPOC());
    
            int deltaPOC = pocCurr > pcSlice->getAssociatedIRAPPOC() ? pocCurr - pcSlice->getAssociatedIRAPPOC() : pocCurr - ( pcSlice->getAssociatedIRAPPOC() & (pocCycle -1) );
    
            CHECK(deltaPOC > (pocCycle >> 1), "Use a greater value for POC wraparound to enable a POC distance between IRAP and DRAP of " << deltaPOC << ".");
    
            m_latestDRAPPOC = pocCurr;
    
            pcSlice->setTLayer(0); // Force DRAP picture to have temporal layer 0
          }
    
          pcSlice->setLatestDRAPPOC(m_latestDRAPPOC);
    
          pcSlice->setUseLTforDRAP(false); // When set, sets the associated IRAP as long-term in RPL0 at slice level, unless the associated IRAP is already included in RPL0 or RPL1 defined in SPS
    
          PicList::iterator iterPic = rcListPic.begin();
          Picture *rpcPic;
          while (iterPic != rcListPic.end())
          {
            rpcPic = *(iterPic++);
            if ( pcSlice->isDRAP() && rpcPic->getPOC() != pocCurr )
            {
                rpcPic->precedingDRAP = true;
            }
            else if ( !pcSlice->isDRAP() && rpcPic->getPOC() == pocCurr )
            {
              rpcPic->precedingDRAP = false;
            }
          }
        }
    
    
        if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
    
            (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) )
    
          || ((m_pcEncLib->getAvoidIntraInDepLayer() || !pcSlice->isIRAP()) && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId())))
    
          xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() );
    
        pcSlice->applyReferencePictureListBasedMarking( rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1(), pcSlice->getPic()->layerId, *(pcSlice->getPPS()));
    
          && !(pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL     // Check if not a leading picture
            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL)
    
        if (pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
    
            for(int ii=0;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
    
    Hendry's avatar
    Hendry committed
              int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId;
    
              if (lTid == pcSlice->getTLayer())
              {
                const ReferencePictureList* rpl0 = pcSlice->getSPS()->getRPLList0()->getReferencePictureList(ii);
                for (int jj = 0; jj < pcSlice->getRPL0()->getNumberOfActivePictures(); jj++)
                {
    
    #if JVET_S0045_SIGN
                  int tPoc = pcSlice->getPOC() + rpl0->getRefPicIdentifier(jj);
    #else
    
                  int tPoc = pcSlice->getPOC() - rpl0->getRefPicIdentifier(jj);
    
    Hendry's avatar
    Hendry committed
                  int kk = 0;
                  for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
                  {
                    if (m_pcCfg->getRPLEntry(0, kk).m_POC == tPoc)
                    {
                      break;
                    }
                  }
                  int tTid = m_pcCfg->getRPLEntry(0, kk).m_temporalId;
                  if (tTid >= pcSlice->getTLayer())
                  {
                    isSTSA = false;
                    break;
                  }
                }
                const ReferencePictureList* rpl1 = pcSlice->getSPS()->getRPLList1()->getReferencePictureList(ii);
                for (int jj = 0; jj < pcSlice->getRPL1()->getNumberOfActivePictures(); jj++)
                {
    
    #if JVET_S0045_SIGN
                  int tPoc = pcSlice->getPOC() + rpl1->getRefPicIdentifier(jj);
    #else
    
                  int tPoc = pcSlice->getPOC() - rpl1->getRefPicIdentifier(jj);
    
    Hendry's avatar
    Hendry committed
                  int kk = 0;
                  for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++)
                  {
                    if (m_pcCfg->getRPLEntry(1, kk).m_POC == tPoc)
                    {
                      break;
                    }
                  }
                  int tTid = m_pcCfg->getRPLEntry(1, kk).m_temporalId;
                  if (tTid >= pcSlice->getTLayer())
                  {
                    isSTSA = false;
                    break;
                  }
                }
              }
    
              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA);
    
    Hendry's avatar
    Hendry committed
        if (m_pcCfg->getUseCompositeRef() && getUseLTRef() && (pocCurr > getLastLTRefPoc()))
        {
          pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : min(m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL0()->getNumberOfActivePictures()));
          pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : min(m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL1()->getNumberOfActivePictures()));
        }
        else
        {
          pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : pcSlice->getRPL0()->getNumberOfActivePictures());
          pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : pcSlice->getRPL1()->getNumberOfActivePictures());
        }
    
        if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef()) {
    
          arrangeCompositeReference(pcSlice, rcListPic, pocCurr);
        }
    
    Hendry's avatar
    Hendry committed
        pcSlice->constructRefPicList(rcListPic);
    
        // store sub-picture numbers, sizes, and locations with a picture
    
    #if JVET_S0258_SUBPIC_CONSTRAINTS
        pcSlice->getPic()->subPictures.clear();
    
        for( int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++ )
        {
          pcSlice->getPic()->subPictures.push_back( pcPic->cs->pps->getSubPic( subPicIdx ) );
        }
    #else
    
        pcSlice->getPic()->numSubpics = pcPic->cs->pps->getNumSubPics();
        pcSlice->getPic()->subpicWidthInCTUs.clear();
        pcSlice->getPic()->subpicHeightInCTUs.clear();
        pcSlice->getPic()->subpicCtuTopLeftX.clear();
        pcSlice->getPic()->subpicCtuTopLeftY.clear();
        for (int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++)
        {
          pcSlice->getPic()->subpicWidthInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicWidthInCTUs());
          pcSlice->getPic()->subpicHeightInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicHeightInCTUs());
          pcSlice->getPic()->subpicCtuTopLeftX.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX());
          pcSlice->getPic()->subpicCtuTopLeftY.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY());
    
        const VPS* vps = pcPic->cs->vps;
        int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId);
        if (vps && !vps->getIndependentLayerFlag(layerIdx) && pcPic->cs->pps->getNumSubPics() > 1)
        {
    
          CU::checkConformanceILRP(pcSlice);
    
        xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic );
    
    #if JVET_AI0136_ADAPTIVE_DUAL_TREE
        if ( !pcSlice->isIntra() )
        { 
          if ( (picWidth * picHeight) <= (1280*720) && ( pcSlice->getTLayer()>0 ) )
          {
            pcSlice->setSeparateTreeEnabled(false);
          }
          else if ( pcSlice->getTLayer()>=ID_SEP_TREE_TID_OFF ) 
          {
            pcSlice->setSeparateTreeEnabled(false);
          }
        }
    #endif
    
    
          {
            int refLayer = pcSlice->getDepth();
            if( refLayer > 9 ) refLayer = 9; // Max layer is 10
    
    
    #if JVET_X0144_MAX_MTT_DEPTH_TID
            if( m_pcCfg->getMaxMTTHierarchyDepthByTid( refLayer ) != m_pcCfg->getMaxMTTHierarchyDepth() )
            {
              picHeader->setSplitConsOverrideFlag( true );
              picHeader->setMaxMTTHierarchyDepth( P_SLICE, m_pcCfg->getMaxMTTHierarchyDepthByTid( refLayer ) );
            }
    #endif
    
    
            if( m_bInitAMaxBT && pcSlice->getPOC() > m_uiPrevISlicePOC )
            {
              ::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
              ::memset( m_uiNumBlk,  0, sizeof( m_uiNumBlk ) );
              m_bInitAMaxBT = false;
            }
    
            if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 )
            {
    
    Brian Heng's avatar
    Brian Heng committed
              picHeader->setSplitConsOverrideFlag(true);
              double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
    
              unsigned int newMaxBtSize = picHeader->getMaxBTSize(pcSlice->getSliceType(), CHANNEL_TYPE_LUMA);
              if( dBlkSize < AMAXBT_TH32 )
    
              else if( dBlkSize < AMAXBT_TH64 )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if CTU_256
              else if( dBlkSize < AMAXBT_TH128 )
              {
                newMaxBtSize = 128;
              }
              else
              {
                newMaxBtSize = 256;
              }
    #else
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
              newMaxBtSize = Clip3(picHeader->getMinQTSize(pcSlice->getSliceType()), pcPic->cs->sps->getCTUSize(), newMaxBtSize);
              picHeader->setMaxBTSize(1, newMaxBtSize);
    
    
              m_uiBlkSize[refLayer] = 0;
              m_uiNumBlk [refLayer] = 0;
            }
          }
          else
          {
            if( m_bInitAMaxBT )
            {
              ::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
              ::memset( m_uiNumBlk,  0, sizeof( m_uiNumBlk ) );
            }
    
            m_uiPrevISlicePOC = pcSlice->getPOC();
            m_bInitAMaxBT = true;
          }
    
    #if JVET_S0133_PH_SYNTAX_OVERRIDE_ENC_FIX
          bool identicalToSPS=true;
          const SPS* sps =pcSlice->getSPS();
    
          if (picHeader->getPicInterSliceAllowedFlag())
          {
    
            if (picHeader->getMinQTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMinQTSize(pcSlice->getSliceType()) ||
                picHeader->getMaxMTTHierarchyDepth(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxMTTHierarchyDepth() ||
                picHeader->getMaxBTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxBTSize() ||
    
                picHeader->getMaxTTSize(pcSlice->getSliceType()) != pcSlice->getSPS()->getMaxTTSize()
              )
            {
              identicalToSPS=false;
            }
          }
    
    
          if (identicalToSPS && picHeader->getPicIntraSliceAllowedFlag())
    
          {
            if (picHeader->getMinQTSize(I_SLICE) != sps->getMinQTSize(I_SLICE) ||
                picHeader->getMaxMTTHierarchyDepth(I_SLICE) != sps->getMaxMTTHierarchyDepthI() ||
                picHeader->getMaxBTSize(I_SLICE) != sps->getMaxBTSizeI() ||
                picHeader->getMaxTTSize(I_SLICE) != sps->getMaxTTSizeI()
            )
            {
              identicalToSPS=false;
            }
    
            if (identicalToSPS && sps->getUseDualITree())
            {
              if (picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA) ||
                  picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxMTTHierarchyDepthIChroma() ||
                  picHeader->getMaxBTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxBTSizeIChroma() ||
                  picHeader->getMaxTTSize(I_SLICE, CHANNEL_TYPE_CHROMA) != sps->getMaxTTSizeIChroma()
               )
              {
                identicalToSPS=false;
              }
            }
          }
    
          if (identicalToSPS)
          {
            picHeader->setSplitConsOverrideFlag(false);
          }
    #endif
    
        }
    
        //  Slice info. refinement
        if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
        {
          pcSlice->setSliceType ( P_SLICE );
        }
    
        xUpdateRasInit( pcSlice );
    
        if ( pcSlice->getPendingRasInit() )
        {
          // this ensures that independently encoded bitstream chunks can be combined to bit-equal
          pcSlice->setEncCABACTableIdx( pcSlice->getSliceType() );
        }
        else
        {
          pcSlice->setEncCABACTableIdx( m_pcSliceEncoder->getEncCABACTableIdx() );
        }
    
        if (pcSlice->getSliceType() == B_SLICE)
        {
    
          bool bLowDelay = true;
          int  iCurrPOC  = pcSlice->getPOC();
          int iRefIdx = 0;
    
          for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
          {
            if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
            {
              bLowDelay = false;
            }
          }
          for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
          {
            if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
            {
              bLowDelay = false;
            }
          }
    
          pcSlice->setCheckLDC(bLowDelay);
    
    #if JVET_AF0128_LIC_MERGE_TM
          bool bLowDelayB = false;
          if (pcSlice->isInterB() && bLowDelay)
          {
            int min = MAX_INT;
            for (int k = 0; k < NUM_REF_PIC_LIST_01; k++)
            {
              for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx((RefPicList)k); iRefIdx++)
              {
                if (pcSlice->getPOC() - pcSlice->getRefPic((RefPicList)k, iRefIdx)->getPOC() < min)
                {
                  min = pcSlice->getPOC() - pcSlice->getRefPic((RefPicList)k, iRefIdx)->getPOC();
                }
              }
            }
            if (min == 1)
            {
              bLowDelayB = true;
            }
          }
          pcSlice->setCheckLDB(bLowDelayB);
    #endif
    
    #if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
        if (!pcSlice->isIntra() && pcSlice->getSPS()->getUseAML())
        {
          int index = pcSlice->getSPS()->getQPOffsetsIdx(pcSlice->getSliceQp() - (pcSlice->getPPS()->getPicInitQPMinus26() + 26));
          if (index != -1)
          {
            const SPS* sps = pcSlice->getSPS();
            pcSlice->setCostForARMC(sps->getLambdaVal(index));
          }
          else
          {
            pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp(), 0), MAX_QP)]);
          }
    
          if (pcSlice->getCheckLDC())
          {
            int iCurrPOC = pcSlice->getPOC();
            int iRefIdx  = 0;
            int mindist  = MAX_INT;
            for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); iRefIdx++)
            {
              if (abs(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() - iCurrPOC) < mindist)
              {
                mindist = abs(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() - iCurrPOC);
              }
            }
            if (pcSlice->isInterB())
            {
              for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); iRefIdx++)
              {
                if (abs(pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() - iCurrPOC) < mindist)
                {
                  mindist = abs(pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() - iCurrPOC);
                }
              }
            }
            if (mindist != 1 )
            {
              pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp() - 4, 0), MAX_QP)]);
            }
          }
          else
          {
            pcSlice->setCostForARMC((uint32_t) LAMBDA_DEC_SIDE[min(max(pcSlice->getSliceQp() - 4, 0), MAX_QP)]);
          }
        }
    #endif
    
    
    
        //-------------------------------------------------------------
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if MULTI_HYP_PRED  
        pcSlice->setNumMultiHypRefPics(pcSlice->getSPS()->getMaxNumAddHypRefFrames());
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if MULTI_HYP_PRED  
        pcSlice->setNumMultiHypRefPics((int)pcSlice->getMultiHypRefPicList().size());
    #endif
    
        if (m_pcEncLib->getTMVPModeId() == 2)
        {
          if (iGOPid == 0) // first picture in SOP (i.e. forward B)
          {
    
    Brian Heng's avatar
    Brian Heng committed
            picHeader->setEnableTMVPFlag(0);
    
          }
          else
          {
            // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
    
    Brian Heng's avatar
    Brian Heng committed
            picHeader->setEnableTMVPFlag(1);
    
        else if (m_pcEncLib->getTMVPModeId() == 1)
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setEnableTMVPFlag(1);
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setEnableTMVPFlag(0);
    
        // disable TMVP when current picture is the only ref picture
    
    #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
        if (pcSlice->isIRAP() && pcSlice->getUseIBC())
    #else
    
    Yu Han's avatar
    Yu Han committed
        if (pcSlice->isIRAP() && pcSlice->getSPS()->getIBCFlag())
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setEnableTMVPFlag(0);
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
        int poc1stCol = -1;
        int list1stCol = 0;
        int list2ndCol = 0;
    #endif
        if (pcSlice->getSliceType() != I_SLICE && picHeader->getEnableTMVPFlag())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          const bool isResamplingPossible = pcSlice->getSPS()->getRprEnabledFlag();
    
    
          for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); refIdx++)
    
            CHECK(pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L0 reference picture");
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            if ((!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
    #else
            if (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS()))
    #endif
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
              poc1stCol = pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->getPOC();
              list1stCol = 0;
    #endif
    
          if (pcSlice->getSliceType() == B_SLICE)
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            list2ndCol = 1;
            if (colRefIdxL0 < 0)
    
              for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); refIdx++)
              {
                CHECK(pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L1 reference picture");
                if ((!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
                {
                  poc1stCol = pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->getPOC();
                  list1stCol = 1;
                  colRefIdxL0 = refIdx;
                  break;
                }
              }
            }
    #endif
            for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1); refIdx++)
            {
              CHECK(pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L1 reference picture");
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
              int poc2ndCol = pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->getPOC();
              if ((poc1stCol != poc2ndCol) && (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
    #else
              if (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_1, refIdx)->isRefScaled(pcSlice->getPPS()))
    #endif
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
                list2ndCol = 1;
    #endif
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
          else
          {
            for (int refIdx = 0; refIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0); refIdx++)
            {
              int poc2ndCol = pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->getPOC();
              CHECK(pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->unscaledPic == nullptr, "unscaledPic is not set for L0 reference picture");
              if ((poc1stCol != poc2ndCol) && (!isResamplingPossible || !pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pcSlice->getPPS())) /*&& (pcSlice->getRefPic(REF_PIC_LIST_0, refIdx)->slices[0]->getSliceType() != I_SLICE)*/)
              {
                colRefIdxL1 = refIdx;
                break;
              }
            }
          }
    #endif
          if (colRefIdxL0 >= 0 && colRefIdxL1 >= 0)
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            const Picture *refPicL0 = pcSlice->getRefPic(RefPicList(list1stCol), colRefIdxL0);
            if (!refPicL0->slices.size())
    
            const Picture *refPicL1 = pcSlice->getRefPic(RefPicList(list2ndCol), colRefIdxL1);
            if (!refPicL1->slices.size())
            {
              refPicL1 = refPicL1->unscaledPic;
            }
            picHeader->setPicColFromL0Flag(1 - list1stCol);
            pcSlice->setColFromL0Flag(1 - list1stCol);
            pcSlice->setColRefIdx(colRefIdxL0);
            picHeader->setColRefIdx(colRefIdxL0);
            picHeader->setPicColFromL0Flag2nd(1 - list2ndCol);
            pcSlice->setColFromL0Flag2nd(1 - list2ndCol);
            pcSlice->setColRefIdx2nd(colRefIdxL1);
            picHeader->setColRefIdx2nd(colRefIdxL1);
    
            int poc1st = refPicL0->getPOC();
            int poc2nd = refPicL1->getPOC();
            int pocCur = pcSlice->getPOC();
            if ((abs(poc1st - pocCur) == abs(poc2nd - pocCur)) && (refPicL0->slices[0]->getSliceQp() < refPicL1->slices[0]->getSliceQp()))
            {
              picHeader->setPicColFromL0Flag2nd(1 - list1stCol);
              pcSlice->setColFromL0Flag2nd(1 - list1stCol);
              pcSlice->setColRefIdx2nd(colRefIdxL0);
              picHeader->setColRefIdx2nd(colRefIdxL0);
              picHeader->setPicColFromL0Flag(1 - list2ndCol);
              pcSlice->setColFromL0Flag(1 - list2ndCol);
              pcSlice->setColRefIdx(colRefIdxL1);
              picHeader->setColRefIdx(colRefIdxL1);
            }
    #else
            const Picture *refPicL0 = pcSlice->getRefPic(REF_PIC_LIST_0, colRefIdxL0);
            if (!refPicL0->slices.size())
            {
              refPicL0 = refPicL0->unscaledPic;
            }
    
            const Picture *refPicL1 = pcSlice->getRefPic(REF_PIC_LIST_1, colRefIdxL1);
            if (!refPicL1->slices.size())
    
            CHECK(!refPicL0->slices.size(), "Wrong L0 reference picture");
            CHECK(!refPicL1->slices.size(), "Wrong L1 reference picture");
    
            const uint32_t uiColFromL0 = refPicL0->slices[0]->getSliceQp() > refPicL1->slices[0]->getSliceQp();
    
            picHeader->setPicColFromL0Flag(uiColFromL0);
            pcSlice->setColFromL0Flag(uiColFromL0);
            pcSlice->setColRefIdx(uiColFromL0 ? colRefIdxL0 : colRefIdxL1);
            picHeader->setColRefIdx(uiColFromL0 ? colRefIdxL0 : colRefIdxL1);
    #endif
    
    #if !JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
          else if (colRefIdxL0 < 0 && colRefIdxL1 >= 0)
    
            picHeader->setPicColFromL0Flag(false);
            pcSlice->setColFromL0Flag(false);
            pcSlice->setColRefIdx(colRefIdxL1);
            picHeader->setColRefIdx(colRefIdxL1);
    
    #endif
          else if (colRefIdxL0 >= 0 && colRefIdxL1 < 0)
          {
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            picHeader->setPicColFromL0Flag(1 - list1stCol);
            pcSlice->setColFromL0Flag(1 - list1stCol);
            pcSlice->setColRefIdx(colRefIdxL0);
            picHeader->setColRefIdx(colRefIdxL0);
            picHeader->setPicColFromL0Flag2nd(1 - list2ndCol);
            pcSlice->setColFromL0Flag2nd(1 - list2ndCol);
            pcSlice->setColRefIdx2nd(0);
            picHeader->setColRefIdx2nd(0);
    #else
            picHeader->setPicColFromL0Flag(true);
            pcSlice->setColFromL0Flag(true);
            pcSlice->setColRefIdx(colRefIdxL0);
            picHeader->setColRefIdx(colRefIdxL0);
    #endif
    
            picHeader->setEnableTMVPFlag(0);
    
    #if JVET_AH0069_CMVP
          if (picHeader->getEnableTMVPFlag())
          {
            pcSlice->setRefRefIdxList();
          }
    #endif
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
    #if JVET_Y0134_TMVP_NAMVP_CAND_REORDERING
          if (picHeader->getEnableTMVPFlag())
          {
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            for (int colFrameIdx = 0; colFrameIdx < (pcSlice->isInterB() ? 2 : 1); colFrameIdx++)
            {
              const Picture* const pColPic = pcSlice->getRefPic(RefPicList(colFrameIdx == 0 ? 1 - pcSlice->getColFromL0Flag() : 1 - pcSlice->getColFromL0Flag2nd()), colFrameIdx == 0 ? pcSlice->getColRefIdx() : pcSlice->getColRefIdx2nd());
    #else
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
            const Picture* const pColPic = pcSlice->getRefPic(RefPicList(pcSlice->isInterB() ? 1 - pcSlice->getColFromL0Flag() : 0), pcSlice->getColRefIdx());
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
            if (pColPic)
            {
              const int currPOC = pcSlice->getPOC();
              const int colPOC = pColPic->getPOC();
    
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
              pcSlice->resizeImBuf(pColPic->numSlices, colFrameIdx);
    #else
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
              pcSlice->resizeImBuf(pColPic->numSlices);
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
              Slice *pColSlice = nullptr;
              for (int sliceIdx = 0; sliceIdx < pColPic->numSlices; sliceIdx++)
              {
                pColSlice = pColPic->slices[sliceIdx];
                if (pColSlice->isIntra())
                {
                  continue;
                }