Skip to content
Snippets Groups Projects
DecLib.cpp 61.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •     APS *scalinglistAPS = pSlice->getscalingListAPS();
    #endif
    
        // fix Parameter Sets, now that we have the real slice
        m_pcPic->cs->slice = pSlice;
        m_pcPic->cs->sps   = sps;
        m_pcPic->cs->pps   = pps;
    
        memcpy(m_pcPic->cs->alfApss, apss, sizeof(m_pcPic->cs->alfApss));
        m_pcPic->cs->lmcsAps = lmcsAPS;
    
    #if JVET_O0299_APS_SCALINGLIST
        m_pcPic->cs->scalinglistAps = scalinglistAPS;
    #endif
    
        m_pcPic->cs->pcv   = pps->pcv;
    
        // check that the current active PPS has not changed...
        if (m_parameterSetManager.getSPSChangedFlag(sps->getSPSId()) )
        {
          EXIT("Error - a new SPS has been decoded while processing a picture");
        }
        if (m_parameterSetManager.getPPSChangedFlag(pps->getPPSId()) )
        {
          EXIT("Error - a new PPS has been decoded while processing a picture");
        }
    
    #if JVET_O_MAX_NUM_ALF_APS_8
        for (int i = 0; i < ALF_CTB_MAX_NUM_APS; i++)
    #else
    
        for (int i = 0; i < MAX_NUM_APS; i++)
    
          APS* aps = m_parameterSetManager.getAPS(i, ALF_APS);
          if (aps && m_parameterSetManager.getAPSChangedFlag(i, ALF_APS))
    
          {
            EXIT("Error - a new APS has been decoded while processing a picture");
          }
        }
    
        if (lmcsAPS && m_parameterSetManager.getAPSChangedFlag(lmcsAPS->getAPSId(), LMCS_APS) )
        {
          EXIT("Error - a new LMCS APS has been decoded while processing a picture");
        }
    
    #if JVET_O0299_APS_SCALINGLIST
        if( scalinglistAPS && m_parameterSetManager.getAPSChangedFlag( scalinglistAPS->getAPSId(), SCALING_LIST_APS ) )
        {
          EXIT( "Error - a new SCALING LIST APS has been decoded while processing a picture" );
        }
    #endif
    
        xParsePrefixSEImessages();
    
        // Check if any new SEI has arrived
         if(!m_SEIs.empty())
         {
           // Currently only decoding Unit SEI message occurring between VCL NALUs copied
           SEIMessages& picSEI = m_pcPic->SEIs;
           SEIMessages decodingUnitInfos = extractSeisByType( picSEI, SEI::DECODING_UNIT_INFO);
           picSEI.insert(picSEI.end(), decodingUnitInfos.begin(), decodingUnitInfos.end());
           deleteSEIs(m_SEIs);
         }
      }
    
    #if JVET_O0244_DELTA_POC
      Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
      const SPS *sps = pSlice->getSPS();
      const PPS *pps = pSlice->getPPS();
    
      if( !sps->getUseWP() )
      {
        CHECK( pps->getUseWP(), "When sps_weighted_pred_flag is equal to 0, the value of pps_weighted_pred_flag shall be equal to 0." );
      }
    
      if( !sps->getUseWPBiPred() )
      {
        CHECK( pps->getWPBiPred(), "When sps_weighted_bipred_flag is equal to 0, the value of pps_weighted_bipred_flag shall be equal to 0." );
      }
    #endif
    
    
    #if JVET_O1164_PS
    #if JVET_O0640_PICTURE_SIZE_CONSTRAINT
      CHECK( ( pps->getPicWidthInLumaSamples() % ( std::max( 8, int( sps->getMaxCUWidth() >> ( sps->getMaxCodingDepth() - 1 ) ) ) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" );
      CHECK( ( pps->getPicHeightInLumaSamples() % ( std::max( 8, int( sps->getMaxCUHeight() >> ( sps->getMaxCodingDepth() - 1 ) ) ) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" );
    #endif
    
      if( sps->getCTUSize() + 2 * ( 1 << sps->getLog2MinCodingBlockSize() ) > pps->getPicWidthInLumaSamples() )
      {    
        CHECK( sps->getWrapAroundEnabledFlag(), "Wraparound shall be disabled when the value of ( CtbSizeY / MinCbSizeY + 1) is less than or equal to ( pic_width_in_luma_samples / MinCbSizeY - 1 )" );
      }
    #endif
    
    }
    
    
    void DecLib::xParsePrefixSEIsForUnknownVCLNal()
    {
      while (!m_prefixSEINALUs.empty())
      {
        // do nothing?
        msg( NOTICE, "Discarding Prefix SEI associated with unknown VCL NAL unit.\n");
        delete m_prefixSEINALUs.front();
      }
      // TODO: discard following suffix SEIs as well?
    }
    
    
    void DecLib::xParsePrefixSEImessages()
    {
      while (!m_prefixSEINALUs.empty())
      {
        InputNALUnit &nalu=*m_prefixSEINALUs.front();
    
        m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_SEIs, nalu.m_nalUnitType, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
    
        delete m_prefixSEINALUs.front();
        m_prefixSEINALUs.pop_front();
      }
    }
    
    
    bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay )
    {
      m_apcSlicePilot->initSlice(); // the slice pilot is an object to prepare for a new slice
                                    // it is not associated with picture, sps or pps structures.
    
    
    Vadim Seregin's avatar
    Vadim Seregin committed
      Picture* scaledRefPic[MAX_NUM_REF] = {};
    
      if (m_bFirstSliceInPicture)
      {
        m_uiSliceSegmentIdx = 0;
      }
      else
      {
        m_apcSlicePilot->copySliceInfo( m_pcPic->slices[m_uiSliceSegmentIdx-1] );
      }
    
    
      m_apcSlicePilot->setSliceCurStartCtuTsAddr(0);
      m_apcSlicePilot->setSliceCurEndCtuTsAddr(0);
      m_apcSlicePilot->setSliceCurStartBrickIdx(0);
      m_apcSlicePilot->setSliceCurEndBrickIdx(0);
    
      m_apcSlicePilot->setNalUnitType(nalu.m_nalUnitType);
      m_apcSlicePilot->setTLayer(nalu.m_temporalId);
    
    
    #if JVET_N0865_NONSYNTAX
      if (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR)
        CHECK(nalu.m_temporalId != 0, "Current GDR picture has TemporalId not equal to 0");
    #endif
    
    
      m_HLSReader.setBitstream( &nalu.getBitstream() );
      m_HLSReader.parseSliceHeader( m_apcSlicePilot, &m_parameterSetManager, m_prevTid0POC );
    
      // update independent slice index
      uint32_t uiIndependentSliceIdx = 0;
      if (!m_bFirstSliceInPicture)
      {
        uiIndependentSliceIdx = m_pcPic->slices[m_uiSliceSegmentIdx-1]->getIndependentSliceIdx();
          uiIndependentSliceIdx++;
      }
      m_apcSlicePilot->setIndependentSliceIdx(uiIndependentSliceIdx);
    
    
    #if K0149_BLOCK_STATISTICS
      PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
      CHECK(pps == 0, "No PPS present");
      SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
      CHECK(sps == 0, "No SPS present");
    
      writeBlockStatisticsHeader(sps);
    #endif
    
    
      DTRACE_UPDATE( g_trace_ctx, std::make_pair( "poc", m_apcSlicePilot->getPOC() ) );
    
    
      xUpdatePreviousTid0POC(m_apcSlicePilot);
    
      m_apcSlicePilot->setAssociatedIRAPPOC(m_pocCRA);
      m_apcSlicePilot->setAssociatedIRAPType(m_associatedIRAPType);
    
      //For inference of NoOutputOfPriorPicsFlag
    
    #if JVET_N0865_NONSYNTAX
      if (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
    #else
    
    #if JVET_N0865_NONSYNTAX
        if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
            (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()) || 
            (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR && m_bFirstSliceInSequence))
        {
          m_apcSlicePilot->setNoIncorrectPicOutputFlag(true);
        }
    #else
    
        if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
            (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()))
    
    #if JVET_N0865_NONSYNTAX
        if (!m_bFirstSliceInBitstream &&
            (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
            m_apcSlicePilot->getNoIncorrectPicOutputFlag())
        {
          if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
          {
            m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
          }
        }
    #else
    
        if (!m_bFirstSliceInBitstream && m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoRaslOutputFlag())
        {
          if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
          {
            m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
          }
        }
    
    #if JVET_N0865_NONSYNTAX
        if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
        {
          m_lastNoIncorrectPicOutputFlag = m_apcSlicePilot->getNoIncorrectPicOutputFlag();
        }
    #else
    
        if(m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
        {
          m_craNoRaslOutputFlag = m_apcSlicePilot->getNoRaslOutputFlag();
        }
    
    #if JVET_N0865_NONSYNTAX
      if ((m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && m_apcSlicePilot->getNoOutputPriorPicsFlag())
    #else
    
      if (m_apcSlicePilot->getRapPicFlag() && m_apcSlicePilot->getNoOutputPriorPicsFlag())
    
      {
        m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC();
        m_isNoOutputPriorPics = true;
      }
      else
      {
        m_isNoOutputPriorPics = false;
      }
    
      //For inference of PicOutputFlag
    
      if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL)
    
    #if JVET_N0865_NONSYNTAX
        if (m_lastNoIncorrectPicOutputFlag)
    #else
    
    #if JVET_N0865_NONSYNTAX
      if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
          m_lastNoIncorrectPicOutputFlag)                     //Reset POC MSB when CRA or GDR has NoIncorrectPicOutputFlag equal to 1
    #else
    
      if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_craNoRaslOutputFlag) //Reset POC MSB when CRA has NoRaslOutputFlag equal to 1
    
      {
        PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
        CHECK(pps == 0, "No PPS present");
        SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
        CHECK(sps == 0, "No SPS present");
        int iMaxPOClsb = 1 << sps->getBitsForPOC();
        m_apcSlicePilot->setPOC( m_apcSlicePilot->getPOC() & (iMaxPOClsb - 1) );
        xUpdatePreviousTid0POC(m_apcSlicePilot);
      }
    
      // Skip pictures due to random access
    
      if (isRandomAccessSkipPicture(iSkipFrame, iPOCLastDisplay))
      {
        m_prevSliceSkipped = true;
        m_skippedPOC = m_apcSlicePilot->getPOC();
        return false;
      }
      // Skip TFD pictures associated with BLA/BLANT pictures
    
      // clear previous slice skipped flag
      m_prevSliceSkipped = false;
    
      //we should only get a different poc for a new picture (with CTU address==0)
      if(m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence && (m_apcSlicePilot->getSliceCurStartCtuTsAddr() != 0))
      {
        msg( WARNING, "Warning, the first slice of a picture might have been lost!\n");
      }
    
      // leave when a new picture is found
      if(m_apcSlicePilot->getSliceCurStartCtuTsAddr() == 0 && !m_bFirstSliceInPicture)
      {
        if (m_prevPOC >= m_pocRandomAccess)
        {
          DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 0 ) );
          m_prevPOC = m_apcSlicePilot->getPOC();
          return true;
        }
        m_prevPOC = m_apcSlicePilot->getPOC();
      }
      else
      {
        DTRACE_UPDATE( g_trace_ctx, std::make_pair( "final", 1 ) );
      }
    
      //detect lost reference picture and insert copy of earlier frame.
      {
        int lostPoc;
    
    Hendry's avatar
    Hendry committed
        while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true)) > 0)
          xCreateLostPicture(lostPoc - 1);
        while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL1(), 1, true)) > 0)
          xCreateLostPicture(lostPoc - 1);
    
      }
    
        m_prevPOC = m_apcSlicePilot->getPOC();
    
      if (m_bFirstSliceInPicture)
      {
        xUpdateRasInit(m_apcSlicePilot);
      }
    
      // actual decoding starts here
      xActivateParameterSets();
    
      m_bFirstSliceInSequence = false;
      m_bFirstSliceInBitstream  = false;
    
    
      Slice* pcSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
      pcSlice->setPic( m_pcPic );
      m_pcPic->poc         = pcSlice->getPOC();
      m_pcPic->layer       = pcSlice->getTLayer();
      m_pcPic->referenced  = true;
      m_pcPic->layer       = nalu.m_temporalId;
    
      // When decoding the slice header, the stored start and end addresses were actually RS addresses, not TS addresses.
      // Now, having set up the maps, convert them to the correct form.
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      const BrickMap& tileMap = *(m_pcPic->brickMap);
    
      const uint32_t numberOfCtusInFrame = m_pcPic->cs->pcv->sizeInCtus;
    
      uint32_t startCtuIdx = 0;
      while (pcSlice->getSliceCurStartBrickIdx() != tileMap.getBrickIdxBsMap(startCtuIdx) && startCtuIdx < numberOfCtusInFrame)
      {
        startCtuIdx++;
      }
      uint32_t endCtuIdx = startCtuIdx;
      while (pcSlice->getSliceCurEndBrickIdx() != tileMap.getBrickIdxBsMap(endCtuIdx) && endCtuIdx < numberOfCtusInFrame)
      {
        endCtuIdx++;
      }
      if (endCtuIdx == numberOfCtusInFrame)
        EXIT("Cannot find the last CTU index of the current slice");
    
    
      while ( (endCtuIdx < numberOfCtusInFrame) && (pcSlice->getSliceCurEndBrickIdx() == tileMap.getBrickIdxBsMap(endCtuIdx)) )
    
      {
        endCtuIdx++;
      }
      if (pcSlice->getSliceCurEndBrickIdx() != tileMap.getBrickIdxBsMap(endCtuIdx - 1))
        EXIT("Cannot find the last CTU index of the current slice");
    
      pcSlice->setSliceCurStartCtuTsAddr(startCtuIdx);
      pcSlice->setSliceCurEndCtuTsAddr(endCtuIdx);
    
    Hendry's avatar
    Hendry committed
      pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_associatedIRAPType, m_cListPic);
      pcSlice->constructRefPicList(m_cListPic);
    
    #if JVET_O0299_APS_SCALINGLIST
      pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), *pcSlice->getLmcsAPS(), *pcSlice->getscalingListAPS(), true );
    #else
    
      pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), *pcSlice->getLmcsAPS(), true );
    
        if (!pcSlice->isIntra())
        {
          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;
            }
          }
          if (pcSlice->isInterB())
          {
            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 (pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
    
    #if JVET_O0284_CONDITION_SMVD_MVDL1ZEROFLAG
          && pcSlice->getMvdL1ZeroFlag() == false
    #endif
    
        {
          int currPOC = pcSlice->getPOC();
    
          int forwardPOC = currPOC;
    
    Daniel's avatar
    Daniel committed
          int backwardPOC = currPOC;
    
          int ref = 0;
          int refIdx0 = -1;
          int refIdx1 = -1;
    
          // search nearest forward POC in List 0
          for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
          {
            int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
    
            const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
            if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) && !isRefLongTerm )
    
            if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) )
    
            {
              forwardPOC = poc;
              refIdx0 = ref;
            }
          }
    
          // search nearest backward POC in List 1
          for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
          {
            int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
    
            const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
            if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) && !isRefLongTerm )
    
    Daniel's avatar
    Daniel committed
            if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) )
    
    Daniel's avatar
    Daniel committed
              backwardPOC = poc;
    
    Daniel's avatar
    Daniel committed
          if ( !(forwardPOC < currPOC && backwardPOC > currPOC) )
    
          {
            forwardPOC = currPOC;
    
    Daniel's avatar
    Daniel committed
            backwardPOC = currPOC;
    
            refIdx0 = -1;
            refIdx1 = -1;
    
            // search nearest backward POC in List 0
            for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
            {
              int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
    
              const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
              if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) && !isRefLongTerm )
    
    Daniel's avatar
    Daniel committed
              if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) )
    
    Daniel's avatar
    Daniel committed
                backwardPOC = poc;
    
                refIdx0 = ref;
              }
            }
    
            // search nearest forward POC in List 1
            for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
            {
              int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
    
              const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
              if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) && !isRefLongTerm )
    
              if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) )
    
    Daniel's avatar
    Daniel committed
          if ( forwardPOC < currPOC && backwardPOC > currPOC )
    
          {
            pcSlice->setBiDirPred( true, refIdx0, refIdx1 );
          }
          else
          {
            pcSlice->setBiDirPred( false, -1, -1 );
          }
        }
        else
        {
          pcSlice->setBiDirPred( false, -1, -1 );
        }
    
    
        //---------------
        pcSlice->setRefPOCList();
    
    
      Quant *quant = m_cTrQuant.getQuant();
    
    
    #if JVET_O0299_APS_SCALINGLIST
      if( pcSlice->getSPS()->getScalingListFlag() )
      {
        ScalingList scalingList;
        if( pcSlice->getscalingListPresentFlag() )
        {
          APS* scalingListAPS = pcSlice->getscalingListAPS();
          scalingList = scalingListAPS->getScalingList();
        }
        else
        {
          scalingList.setDefaultScalingList();
        }
        quant->setScalingListDec( scalingList );
        quant->setUseScalingList( true );
      }
      else
      {
        quant->setUseScalingList( false );
      }
    #else
    
      if(pcSlice->getSPS()->getScalingListFlag())
      {
        ScalingList scalingList;
        if(pcSlice->getPPS()->getScalingListPresentFlag())
        {
          scalingList = pcSlice->getPPS()->getScalingList();
        }
        else if (pcSlice->getSPS()->getScalingListPresentFlag())
        {
          scalingList = pcSlice->getSPS()->getScalingList();
        }
        else
        {
          scalingList.setDefaultScalingList();
        }
        quant->setScalingListDec(scalingList);
        quant->setUseScalingList(true);
      }
      else
      {
        quant->setUseScalingList(false);
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (pcSlice->getSPS()->getUseReshaper())
      {
    
        if (pcSlice->getLmcsEnabledFlag())
        {
          APS* lmcsAPS = pcSlice->getLmcsAPS();
          SliceReshapeInfo& sInfo = lmcsAPS->getReshaperAPSInfo();
          SliceReshapeInfo& tInfo = m_cReshaper.getSliceReshaperInfo();
          tInfo.reshaperModelMaxBinIdx = sInfo.reshaperModelMaxBinIdx;
          tInfo.reshaperModelMinBinIdx = sInfo.reshaperModelMinBinIdx;
          memcpy(tInfo.reshaperModelBinCWDelta, sInfo.reshaperModelBinCWDelta, sizeof(int)*(PIC_CODE_CW_BINS));
          tInfo.maxNbitsNeededDeltaCW = sInfo.maxNbitsNeededDeltaCW;
          tInfo.setUseSliceReshaper(pcSlice->getLmcsEnabledFlag());
          tInfo.setSliceReshapeChromaAdj(pcSlice->getLmcsChromaResidualScaleFlag());
          tInfo.setSliceReshapeModelPresentFlag(true);
        }
        else
        {
          SliceReshapeInfo& tInfo = m_cReshaper.getSliceReshaperInfo();
          tInfo.setUseSliceReshaper(false);
          tInfo.setSliceReshapeChromaAdj(false);
          tInfo.setSliceReshapeModelPresentFlag(false);
        }
        if (pcSlice->getLmcsEnabledFlag())
    
    Taoran Lu's avatar
    Taoran Lu committed
        {
          m_cReshaper.constructReshaper();
        }
        else
        {
          m_cReshaper.setReshapeFlag(false);
        }
    
    Taoran Lu's avatar
    Taoran Lu committed
        if ((pcSlice->getSliceType() == I_SLICE) && m_cReshaper.getSliceReshaperInfo().getUseSliceReshaper())
    
    Taoran Lu's avatar
    Taoran Lu committed
        {
          m_cReshaper.setCTUFlag(false);
          m_cReshaper.setRecReshaped(true);
        }
        else
        {
          if (m_cReshaper.getSliceReshaperInfo().getUseSliceReshaper())
          {
            m_cReshaper.setCTUFlag(true);
            m_cReshaper.setRecReshaped(true);
          }
          else
          {
            m_cReshaper.setCTUFlag(false);
            m_cReshaper.setRecReshaped(false);
          }
        }
    
    #if JVET_O1109_UNFIY_CRS
        m_cReshaper.setVPDULoc(-1, -1);
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
      }
      else
      {
        m_cReshaper.setCTUFlag(false);
        m_cReshaper.setRecReshaped(false);
      }
    
    Tobias Hinz's avatar
    Tobias Hinz committed
      m_cSliceDecoder.decompressSlice( pcSlice, &( nalu.getBitstream() ), ( m_pcPic->poc == getDebugPOC() ? getDebugCTU() : -1 ) );
    
    #if JVET_O1164_RPR
      pcSlice->freeScaledRefPicList( scaledRefPic );
    #endif
    
    
      return false;
    }
    
    void DecLib::xDecodeVPS( InputNALUnit& nalu )
    {
      VPS* vps = new VPS();
      m_HLSReader.setBitstream( &nalu.getBitstream() );
      m_HLSReader.parseVPS( vps );
    
    Karsten Suehring's avatar
    Karsten Suehring committed
      delete vps;
    
    void DecLib::xDecodeDPS( InputNALUnit& nalu )
    {
      DPS* dps = new DPS();
      m_HLSReader.setBitstream( &nalu.getBitstream() );
      m_HLSReader.parseDPS( dps );
      m_parameterSetManager.storeDPS( dps, nalu.getBitstream().getFifo() );
    }
    
    
    void DecLib::xDecodeSPS( InputNALUnit& nalu )
    {
      SPS* sps = new SPS();
      m_HLSReader.setBitstream( &nalu.getBitstream() );
      m_HLSReader.parseSPS( sps );
      m_parameterSetManager.storeSPS( sps, nalu.getBitstream().getFifo() );
    
      DTRACE( g_trace_ctx, D_QP_PER_CTU, "CTU Size: %dx%d", sps->getMaxCUWidth(), sps->getMaxCUHeight() );
    }
    
    void DecLib::xDecodePPS( InputNALUnit& nalu )
    {
      PPS* pps = new PPS();
      m_HLSReader.setBitstream( &nalu.getBitstream() );
    
      m_HLSReader.parsePPS( pps, &m_parameterSetManager );
    
      m_parameterSetManager.storePPS( pps, nalu.getBitstream().getFifo() );
    }
    
    
    Hendry's avatar
    Hendry committed
    void DecLib::xDecodeAPS(InputNALUnit& nalu)
    {
      APS* aps = new APS();
      m_HLSReader.setBitstream(&nalu.getBitstream());
      m_HLSReader.parseAPS(aps);
    
      aps->setTemporalId(nalu.m_temporalId);
    
    Hendry's avatar
    Hendry committed
      m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo());
    }
    
    bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
    {
      bool ret;
      // ignore all NAL units of layers > 0
    
      if (getTargetDecLayer() >= 0 && nalu.m_nuhLayerId != getTargetDecLayer()) //TBC: ignore bitstreams whose nuh_layer_id is not the target layer id
    
      {
        msg( WARNING, "Warning: found NAL unit with nuh_layer_id equal to %d. Ignoring.\n", nalu.m_nuhLayerId);
        return false;
      }
    
      switch (nalu.m_nalUnitType)
      {
        case NAL_UNIT_VPS:
          xDecodeVPS( nalu );
          return false;
    
    
        case NAL_UNIT_DPS:
          xDecodeDPS( nalu );
          return false;
    
    
        case NAL_UNIT_SPS:
          xDecodeSPS( nalu );
          return false;
    
        case NAL_UNIT_PPS:
          xDecodePPS( nalu );
          return false;
    
    Hendry's avatar
    Hendry committed
        case NAL_UNIT_APS:
          xDecodeAPS(nalu);
          return false;
    
    
        case NAL_UNIT_PREFIX_SEI:
          // Buffer up prefix SEI messages until SPS of associated VCL is known.
          m_prefixSEINALUs.push_back(new InputNALUnit(nalu));
          return false;
    
        case NAL_UNIT_SUFFIX_SEI:
          if (m_pcPic)
          {
    
            m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_pcPic->SEIs, nalu.m_nalUnitType, m_parameterSetManager.getActiveSPS(), m_HRD, m_pDecodedSEIOutputStream );
    
          }
          else
          {
            msg( NOTICE, "Note: received suffix SEI but no picture currently active.\n");
          }
          return false;
    
    
        case NAL_UNIT_CODED_SLICE_TRAIL:
        case NAL_UNIT_CODED_SLICE_STSA:
        case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
        case NAL_UNIT_CODED_SLICE_IDR_N_LP:
        case NAL_UNIT_CODED_SLICE_CRA:
    
    #if JVET_N0865_NONSYNTAX
        case NAL_UNIT_CODED_SLICE_GDR:
    #endif
    
        case NAL_UNIT_CODED_SLICE_RADL:
        case NAL_UNIT_CODED_SLICE_RASL:
    
          ret = xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay);
    #if JVET_J0090_MEMORY_BANDWITH_MEASURE
          if ( ret )
          {
            m_cacheModel.reportFrame( );
            m_cacheModel.accumulateFrame( );
            m_cacheModel.clear( );
          }
    #endif
          return ret;
    
        case NAL_UNIT_EOS:
          m_associatedIRAPType = NAL_UNIT_INVALID;
          m_pocCRA = 0;
          m_pocRandomAccess = MAX_INT;
          m_prevPOC = MAX_INT;
          m_prevSliceSkipped = false;
          m_skippedPOC = 0;
          return false;
    
        case NAL_UNIT_ACCESS_UNIT_DELIMITER:
          {
            AUDReader audReader;
            uint32_t picType;
            audReader.parseAccessUnitDelimiter(&(nalu.getBitstream()),picType);
            msg( NOTICE, "Note: found NAL_UNIT_ACCESS_UNIT_DELIMITER\n");
            return false;
          }
    
        case NAL_UNIT_EOB:
          return false;
    
    
        case NAL_UNIT_RESERVED_VCL_12:
        case NAL_UNIT_RESERVED_VCL_13:
        case NAL_UNIT_RESERVED_VCL_14:
        case NAL_UNIT_RESERVED_VCL_15:
    
          msg( NOTICE, "Note: found reserved VCL NAL unit.\n");
          xParsePrefixSEIsForUnknownVCLNal();
          return false;
    
        case NAL_UNIT_RESERVED_NVCL_5:
        case NAL_UNIT_RESERVED_NVCL_6:
        case NAL_UNIT_RESERVED_NVCL_7:
        case NAL_UNIT_RESERVED_NVCL_21:
        case NAL_UNIT_RESERVED_NVCL_22:
        case NAL_UNIT_RESERVED_NVCL_23:
    
          msg( NOTICE, "Note: found reserved NAL unit.\n");
          return false;
    
        case NAL_UNIT_UNSPECIFIED_28:
        case NAL_UNIT_UNSPECIFIED_29:
        case NAL_UNIT_UNSPECIFIED_30:
        case NAL_UNIT_UNSPECIFIED_31:
    
          msg( NOTICE, "Note: found unspecified NAL unit.\n");
          return false;
        default:
          THROW( "Invalid NAL unit type" );
          break;
      }
    
      return false;
    }
    
    
    /** Function for checking if picture should be skipped because of random access. This function checks the skipping of pictures in the case of -s option random access.
     *  All pictures prior to the random access point indicated by the counter iSkipFrame are skipped.
     *  It also checks the type of Nal unit type at the random access point.
     *  If the random access point is CRA/CRANT/BLA/BLANT, TFD pictures with POC less than the POC of the random access point are skipped.
     *  If the random access point is IDR all pictures after the random access point are decoded.
     *  If the random access point is none of the above, a warning is issues, and decoding of pictures with POC
     *  equal to or greater than the random access point POC is attempted. For non IDR/CRA/BLA random
     *  access point there is no guarantee that the decoder will not crash.
     */
    bool DecLib::isRandomAccessSkipPicture( int& iSkipFrame, int& iPOCLastDisplay )
    {
      if (iSkipFrame)
      {
        iSkipFrame--;   // decrement the counter
        return true;
      }
      else if (m_pocRandomAccess == MAX_INT) // start of random access point, m_pocRandomAccess has not been set yet.
      {
    
        if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )
    
        {
          // set the POC random access since we need to skip the reordered pictures in the case of CRA/CRANT/BLA/BLANT.
          m_pocRandomAccess = m_apcSlicePilot->getPOC();
        }
        else if ( m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP )
        {
          m_pocRandomAccess = -MAX_INT; // no need to skip the reordered pictures in IDR, they are decodable.
        }
        else
        {
          if(!m_warningMessageSkipPicture)
          {
            msg( WARNING, "\nWarning: this is not a valid random access point and the data is discarded until the first CRA picture");
            m_warningMessageSkipPicture = true;
          }
          return true;
        }
      }
      // skip the reordered pictures, if necessary
    
      else if (m_apcSlicePilot->getPOC() < m_pocRandomAccess && (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL))
    
      {
        iPOCLastDisplay++;
        return true;
      }
      // if we reach here, then the picture is not skipped.
      return false;
    }
    
    
    
    
    //! \}