Skip to content
Snippets Groups Projects
EncGOP.cpp 201 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
      //preserve current reconstruction
      m_pcDeblockingTempPicYuv->copyFrom ( reco );
    
      const bool bNoFiltering      = m_DBParam[currQualityLayer][DBFLT_PARAM_AVAILABLE] && m_DBParam[currQualityLayer][DBFLT_DISABLE_FLAG]==false /*&& pcPic->getTLayer()==0*/;
      const int  maxBetaOffsetDiv2 = bNoFiltering? Clip3(MIN_BETA_OFFSET, MAX_BETA_OFFSET, m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]+1) : MAX_BETA_OFFSET;
      const int  minBetaOffsetDiv2 = bNoFiltering? Clip3(MIN_BETA_OFFSET, MAX_BETA_OFFSET, m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]-1) : MIN_BETA_OFFSET;
      const int  maxTcOffsetDiv2   = bNoFiltering? Clip3(MIN_TC_OFFSET, MAX_TC_OFFSET, m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]+2)       : MAX_TC_OFFSET;
      const int  minTcOffsetDiv2   = bNoFiltering? Clip3(MIN_TC_OFFSET, MAX_TC_OFFSET, m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]-2)       : MIN_TC_OFFSET;
    
      uint64_t distBetaPrevious      = std::numeric_limits<uint64_t>::max();
      uint64_t distMin               = std::numeric_limits<uint64_t>::max();
      bool   bDBFilterDisabledBest = true;
      int    betaOffsetDiv2Best    = 0;
      int    tcOffsetDiv2Best      = 0;
    
      for(int betaOffsetDiv2=maxBetaOffsetDiv2; betaOffsetDiv2>=minBetaOffsetDiv2; betaOffsetDiv2--)
      {
        uint64_t distTcMin = std::numeric_limits<uint64_t>::max();
        for(int tcOffsetDiv2=maxTcOffsetDiv2; tcOffsetDiv2 >= minTcOffsetDiv2; tcOffsetDiv2--)
        {
          for (int i=0; i<numSlices; i++)
          {
            Slice* pcSlice = pcPic->slices[i];
            pcSlice->setDeblockingFilterOverrideFlag  ( true);
            pcSlice->setDeblockingFilterDisable       ( false);
            pcSlice->setDeblockingFilterBetaOffsetDiv2( betaOffsetDiv2 );
            pcSlice->setDeblockingFilterTcOffsetDiv2  ( tcOffsetDiv2 );
    
    #if JVET_Q0121_DEBLOCKING_CONTROL_PARAMETERS
            pcSlice->setDeblockingFilterCbBetaOffsetDiv2( betaOffsetDiv2 );
            pcSlice->setDeblockingFilterCbTcOffsetDiv2  ( tcOffsetDiv2 );
            pcSlice->setDeblockingFilterCrBetaOffsetDiv2( betaOffsetDiv2 );
            pcSlice->setDeblockingFilterCrTcOffsetDiv2  ( tcOffsetDiv2 );
    #endif
    
          }
    
          // restore reconstruction
          reco.copyFrom( *m_pcDeblockingTempPicYuv );
    
          const uint64_t dist = preLoopFilterPicAndCalcDist( pcPic );
    
          if(dist < distMin)
          {
            distMin = dist;
            bDBFilterDisabledBest = false;
            betaOffsetDiv2Best  = betaOffsetDiv2;
            tcOffsetDiv2Best = tcOffsetDiv2;
          }
          if(dist < distTcMin)
          {
            distTcMin = dist;
          }
          else if(tcOffsetDiv2 <-2)
          {
            break;
          }
        }
        if(betaOffsetDiv2<-1 && distTcMin >= distBetaPrevious)
        {
          break;
        }
        distBetaPrevious = distTcMin;
      }
    
      //update:
      m_DBParam[currQualityLayer][DBFLT_PARAM_AVAILABLE] = 1;
      m_DBParam[currQualityLayer][DBFLT_DISABLE_FLAG]    = bDBFilterDisabledBest;
      m_DBParam[currQualityLayer][DBFLT_BETA_OFFSETD2]   = betaOffsetDiv2Best;
      m_DBParam[currQualityLayer][DBFLT_TC_OFFSETD2]     = tcOffsetDiv2Best;
    
      // restore reconstruction
      reco.copyFrom( *m_pcDeblockingTempPicYuv );
    
      const PPS* pcPPS = pcPic->slices[0]->getPPS();
      if(bDBFilterDisabledBest)
      {
        for (int i=0; i<numSlices; i++)
        {
          Slice* pcSlice = pcPic->slices[i];
          pcSlice->setDeblockingFilterOverrideFlag( true);
          pcSlice->setDeblockingFilterDisable     ( true);
        }
      }
      else if(betaOffsetDiv2Best == pcPPS->getDeblockingFilterBetaOffsetDiv2() &&  tcOffsetDiv2Best == pcPPS->getDeblockingFilterTcOffsetDiv2())
      {
        for (int i=0; i<numSlices; i++)
        {
          Slice*      pcSlice = pcPic->slices[i];
          pcSlice->setDeblockingFilterOverrideFlag   ( false);
          pcSlice->setDeblockingFilterDisable        ( pcPPS->getPPSDeblockingFilterDisabledFlag() );
          pcSlice->setDeblockingFilterBetaOffsetDiv2 ( pcPPS->getDeblockingFilterBetaOffsetDiv2() );
          pcSlice->setDeblockingFilterTcOffsetDiv2   ( pcPPS->getDeblockingFilterTcOffsetDiv2()   );
    
    #if JVET_Q0121_DEBLOCKING_CONTROL_PARAMETERS
          pcSlice->setDeblockingFilterCbBetaOffsetDiv2 ( pcPPS->getDeblockingFilterBetaOffsetDiv2() );
          pcSlice->setDeblockingFilterCbTcOffsetDiv2   ( pcPPS->getDeblockingFilterTcOffsetDiv2()   );
          pcSlice->setDeblockingFilterCrBetaOffsetDiv2 ( pcPPS->getDeblockingFilterBetaOffsetDiv2() );
          pcSlice->setDeblockingFilterCrTcOffsetDiv2   ( pcPPS->getDeblockingFilterTcOffsetDiv2()   );
    #endif
    
        }
      }
      else
      {
        for (int i=0; i<numSlices; i++)
        {
          Slice* pcSlice = pcPic->slices[i];
          pcSlice->setDeblockingFilterOverrideFlag   ( true);
          pcSlice->setDeblockingFilterDisable        ( false );
          pcSlice->setDeblockingFilterBetaOffsetDiv2 ( betaOffsetDiv2Best);
          pcSlice->setDeblockingFilterTcOffsetDiv2   ( tcOffsetDiv2Best);
    
    #if JVET_Q0121_DEBLOCKING_CONTROL_PARAMETERS
          pcSlice->setDeblockingFilterCbBetaOffsetDiv2 ( betaOffsetDiv2Best);
          pcSlice->setDeblockingFilterCbTcOffsetDiv2   ( tcOffsetDiv2Best);
          pcSlice->setDeblockingFilterCrBetaOffsetDiv2 ( betaOffsetDiv2Best);
          pcSlice->setDeblockingFilterCrTcOffsetDiv2   ( tcOffsetDiv2Best);
    #endif
    
    
    void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicList& rcListPic, const ReferencePictureList *rpl0, const ReferencePictureList *rpl1 )
    {
      Picture* rpcPic;
      int pocCycle = 0;
    
      Picture* pic = slice->getPic();
      const VPS* vps = slice->getPic()->cs->vps;
      int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx( pic->layerId );
    
      ReferencePictureList* pLocalRPL0 = slice->getLocalRPL0();
      *pLocalRPL0 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() );
    
      uint32_t numOfSTRPL0 = 0;
      uint32_t numOfLTRPL0 = 0;
      uint32_t numOfILRPL0 = 0;
      uint32_t numOfRefPic = rpl0->getNumberOfShorttermPictures() + rpl0->getNumberOfLongtermPictures();
      uint32_t refPicIdxL0 = 0;
    
      for( int ii = 0; ii < numOfRefPic; ii++ )
      {
        // loop through all pictures in the reference picture buffer
        PicList::iterator iterPic = rcListPic.begin();
        bool isAvailable = false;
    
        pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
        while( iterPic != rcListPic.end() )
        {
          rpcPic = *( iterPic++ );
    
          if( rpcPic->layerId == pic->layerId )
          {
            if( !rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
            {
              isAvailable = true;
              break;
            }
            else if( rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
            {
              isAvailable = true;
              break;
            }
          }
        }
    
        if( isAvailable )
        {
          pLocalRPL0->setRefPicIdentifier( refPicIdxL0, rpl0->getRefPicIdentifier( ii ), rpl0->isRefPicLongterm( ii ), false, NOT_VALID );
          refPicIdxL0++;
          numOfSTRPL0 = numOfSTRPL0 + ( ( rpl0->isRefPicLongterm( ii ) ) ? 0 : 1 );
          numOfLTRPL0 += ( rpl0->isRefPicLongterm( ii ) && !rpl0->isInterLayerRefPic( ii ) ) ? 1 : 0;
          isAvailable = false;
        }
      }
    
      // inter-layer reference pictures are added to the end of the reference picture list
      if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
      {
        numOfRefPic = rpl0->getNumberOfInterLayerPictures() ? rpl0->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
    
        for( int ii = 0; ii < numOfRefPic; ii++ )
        {
          // loop through all pictures in the reference picture buffer
          PicList::iterator iterPic = rcListPic.begin();
    
          while( iterPic != rcListPic.end() )
          {
            rpcPic = *( iterPic++ );
            int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
    
            if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
            {          
              pLocalRPL0->setRefPicIdentifier( refPicIdxL0, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
              refPicIdxL0++;
              numOfILRPL0++;
              break;
            }
          }
        }
      }
    
      if( slice->getEnableDRAPSEI() )
      {
        pLocalRPL0->setNumberOfShorttermPictures( numOfSTRPL0 );
        pLocalRPL0->setNumberOfLongtermPictures( numOfLTRPL0 );
        pLocalRPL0->setNumberOfInterLayerPictures( numOfILRPL0 );
    
        if( !slice->isIRAP() && !slice->isPOCInRefPicList( pLocalRPL0, slice->getAssociatedIRAPPOC() ) )
        {
          if( slice->getUseLTforDRAP() && !slice->isPOCInRefPicList( rpl1, slice->getAssociatedIRAPPOC() ) )
          {
            // Adding associated IRAP as longterm picture
            pLocalRPL0->setRefPicIdentifier( refPicIdxL0, slice->getAssociatedIRAPPOC(), true, false, 0 );
            refPicIdxL0++;
            numOfLTRPL0++;
          }
          else
          {
            // Adding associated IRAP as shortterm picture
            pLocalRPL0->setRefPicIdentifier( refPicIdxL0, slice->getPOC() - slice->getAssociatedIRAPPOC(), false, false, 0 );
            refPicIdxL0++;
            numOfSTRPL0++;
          }
        }
      }
    
      ReferencePictureList* pLocalRPL1 = slice->getLocalRPL1();
      *pLocalRPL1 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() );
    
      uint32_t numOfSTRPL1 = 0;
      uint32_t numOfLTRPL1 = 0;
      uint32_t numOfILRPL1 = 0;
      numOfRefPic = rpl1->getNumberOfShorttermPictures() + rpl1->getNumberOfLongtermPictures();
      uint32_t refPicIdxL1 = 0;
    
      for( int ii = 0; ii < numOfRefPic; ii++ )
      {
        // loop through all pictures in the reference picture buffer
        PicList::iterator iterPic = rcListPic.begin();
        bool isAvailable = false;
        pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
        while( iterPic != rcListPic.end() )
        {
          rpcPic = *( iterPic++ );
    
          if( rpcPic->layerId == pic->layerId )
          {
            if( !rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
            {
              isAvailable = true;
              break;
            }
            else if( rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
            {
              isAvailable = true;
              break;
            }
          }      
        }
    
        if( isAvailable )
        {
          pLocalRPL1->setRefPicIdentifier( refPicIdxL1, rpl1->getRefPicIdentifier( ii ), rpl1->isRefPicLongterm( ii ), false, NOT_VALID );
          refPicIdxL1++;
          numOfSTRPL1 = numOfSTRPL1 + ( ( rpl1->isRefPicLongterm( ii ) ) ? 0 : 1 );
          numOfLTRPL1 += ( rpl1->isRefPicLongterm( ii ) && !rpl1->isInterLayerRefPic( ii ) ) ? 1 : 0;
          isAvailable = false;
        }
      }
    
      
      // inter-layer reference pictures are added to the end of the reference picture list
      if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
      {
        numOfRefPic = rpl1->getNumberOfInterLayerPictures() ? rpl1->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
    
        for( int ii = 0; ii < numOfRefPic; ii++ )
        {
          // loop through all pictures in the reference picture buffer
          PicList::iterator iterPic = rcListPic.begin();
    
          while( iterPic != rcListPic.end() )
          {
            rpcPic = *( iterPic++ );
            int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
    
            if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
            {
              pLocalRPL1->setRefPicIdentifier( refPicIdxL1, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
              refPicIdxL1++;
              numOfILRPL1++;
              break;
            }
          }
        }
      }
    
      //Copy from L1 if we have less than active ref pic
      int numOfNeedToFill = rpl0->getNumberOfActivePictures() - (numOfLTRPL0 + numOfSTRPL0);
      bool isDisallowMixedRefPic = ( slice->getSPS()->getAllActiveRplEntriesHasSameSignFlag() ) ? true : false;
      int originalL0StrpNum = numOfSTRPL0;
      int originalL0LtrpNum = numOfLTRPL0;
      int originalL0IlrpNum = numOfILRPL0;
    
      for( int ii = 0; numOfNeedToFill > 0 && ii < ( pLocalRPL1->getNumberOfLongtermPictures() + pLocalRPL1->getNumberOfShorttermPictures() + pLocalRPL1->getNumberOfInterLayerPictures() ); ii++ )
      {
        if( ii <= ( numOfLTRPL1 + numOfSTRPL1 + numOfILRPL1 - 1 ) )
        {
          //Make sure this copy is not already in L0
          bool canIncludeThis = true;
          for( int jj = 0; jj < refPicIdxL0; jj++ )
          {
            if( ( pLocalRPL1->getRefPicIdentifier( ii ) == pLocalRPL0->getRefPicIdentifier( jj ) ) && ( pLocalRPL1->isRefPicLongterm( ii ) == pLocalRPL0->isRefPicLongterm( jj ) ) && pLocalRPL1->getInterLayerRefPicIdx( ii ) == pLocalRPL0->getInterLayerRefPicIdx( jj ) )
            {
              canIncludeThis = false;
            }
    
            bool sameSign = ( pLocalRPL1->getRefPicIdentifier( ii ) > 0 ) == ( pLocalRPL0->getRefPicIdentifier( 0 ) > 0 );
    
            if( isDisallowMixedRefPic && canIncludeThis && !pLocalRPL1->isRefPicLongterm( ii ) && !sameSign )
            {
              canIncludeThis = false;
            }
          }
          if( canIncludeThis )
          {
            pLocalRPL0->setRefPicIdentifier( refPicIdxL0, pLocalRPL1->getRefPicIdentifier( ii ), pLocalRPL1->isRefPicLongterm( ii ), pLocalRPL1->isInterLayerRefPic( ii ), pLocalRPL1->getInterLayerRefPicIdx( ii ) );
            refPicIdxL0++;
            numOfSTRPL0 = numOfSTRPL0 + ( ( pLocalRPL1->isRefPicLongterm( ii ) ) ? 0 : 1 );
            numOfLTRPL0 += ( pLocalRPL1->isRefPicLongterm( ii ) && !pLocalRPL1->isInterLayerRefPic( ii ) ) ? 1 : 0;
            numOfILRPL0 += pLocalRPL1->isInterLayerRefPic( ii ) ? 1 : 0;
            numOfNeedToFill--;
          }
        }
      }
      pLocalRPL0->setNumberOfLongtermPictures( numOfLTRPL0 );
      pLocalRPL0->setNumberOfShorttermPictures( numOfSTRPL0 );
      pLocalRPL0->setNumberOfInterLayerPictures( numOfILRPL0 );
      int numPics = numOfLTRPL0 + numOfSTRPL0;
    
      pLocalRPL0->setNumberOfActivePictures( ( numPics < rpl0->getNumberOfActivePictures() ? numPics : rpl0->getNumberOfActivePictures() ) + numOfILRPL0 );
      pLocalRPL0->setLtrpInSliceHeaderFlag( rpl0->getLtrpInSliceHeaderFlag() );
      slice->setRPL0idx( -1 );
      slice->setRPL0( pLocalRPL0 );
    
      //Copy from L0 if we have less than active ref pic
      numOfNeedToFill = pLocalRPL0->getNumberOfActivePictures() - ( numOfLTRPL1 + numOfSTRPL1 );
    
      for( int ii = 0; numOfNeedToFill > 0 && ii < ( pLocalRPL0->getNumberOfLongtermPictures() + pLocalRPL0->getNumberOfShorttermPictures() + pLocalRPL0->getNumberOfInterLayerPictures() ); ii++ )
      {
        if( ii <= ( originalL0StrpNum + originalL0LtrpNum + originalL0IlrpNum - 1 ) )
        {
          //Make sure this copy is not already in L0
          bool canIncludeThis = true;
          for( int jj = 0; jj < refPicIdxL1; jj++ )
          {
            if( ( pLocalRPL0->getRefPicIdentifier( ii ) == pLocalRPL1->getRefPicIdentifier( jj ) ) && ( pLocalRPL0->isRefPicLongterm( ii ) == pLocalRPL1->isRefPicLongterm( jj ) ) && pLocalRPL0->getInterLayerRefPicIdx( ii ) == pLocalRPL1->getInterLayerRefPicIdx( jj ) )
            {
              canIncludeThis = false;
            }
    
            bool sameSign = ( pLocalRPL0->getRefPicIdentifier( ii ) > 0 ) == ( pLocalRPL1->getRefPicIdentifier( 0 ) > 0 );
    
            if( isDisallowMixedRefPic && canIncludeThis && !pLocalRPL0->isRefPicLongterm( ii ) && !sameSign )
            {
              canIncludeThis = false;
            }
          }
          if( canIncludeThis )
          {
            pLocalRPL1->setRefPicIdentifier( refPicIdxL1, pLocalRPL0->getRefPicIdentifier( ii ), pLocalRPL0->isRefPicLongterm( ii ), pLocalRPL0->isInterLayerRefPic( ii ), pLocalRPL0->getInterLayerRefPicIdx( ii ) );
            refPicIdxL1++;
            numOfSTRPL1 = numOfSTRPL1 + ( ( pLocalRPL0->isRefPicLongterm( ii ) ) ? 0 : 1 );
            numOfLTRPL1 += ( pLocalRPL0->isRefPicLongterm( ii ) && !pLocalRPL0->isInterLayerRefPic( ii ) ) ? 1 : 0;
            numOfLTRPL1 += pLocalRPL0->isInterLayerRefPic( ii ) ? 1 : 0;
            numOfNeedToFill--;
          }
        }
      }
      pLocalRPL1->setNumberOfLongtermPictures( numOfLTRPL1 );
      pLocalRPL1->setNumberOfShorttermPictures( numOfSTRPL1 );
      pLocalRPL1->setNumberOfInterLayerPictures( numOfILRPL1 );
      numPics = numOfLTRPL1 + numOfSTRPL1;
    
      pLocalRPL1->setNumberOfActivePictures( ( isDisallowMixedRefPic ? numPics : ( numPics < rpl1->getNumberOfActivePictures() ? numPics : rpl1->getNumberOfActivePictures() ) ) + numOfILRPL1 );
      pLocalRPL1->setLtrpInSliceHeaderFlag( rpl1->getLtrpInSliceHeaderFlag() );
      slice->setRPL1idx( -1 );
      slice->setRPL1( pLocalRPL1 );
    }