Skip to content
Snippets Groups Projects
CodingStructure.cpp 52.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
      if( parent )
      {
        // allow this to be false at the top level (need for edge CTU's)
        CHECKD( !area.contains( subStruct.area ), "Trying to init sub-structure not contained in the parent" );
      }
    
      subStruct.parent    = this;
      subStruct.picture   = picture;
    
      subStruct.sps       = sps;
    
      subStruct.vps       = vps;
    
      memcpy(subStruct.alfApss, alfApss, sizeof(alfApss));
    
      subStruct.lmcsAps = lmcsAps;
    
    
      subStruct.slice     = slice;
      subStruct.baseQP    = baseQP;
      subStruct.prevQP[_chType]
                          = prevQP[_chType];
      subStruct.pcv       = pcv;
    
      subStruct.m_isTuEnc = isTuEnc;
    
    
      subStruct.motionLut = motionLut;
    
    
    #if JVET_O0119_BASE_PALETTE_444
      subStruct.prevPLT = prevPLT;
    #endif
    
    
    #if JVET_O0050_LOCAL_DUAL_TREE
      subStruct.treeType  = treeType;
      subStruct.modeType  = modeType;
    #endif
    
    
      subStruct.initStructData( currQP[_chType], isLossless );
    
      if( isTuEnc )
      {
        CHECKD( area != subStruct.area, "Trying to init sub-structure for TU-encoding of incompatible size" );
    
        for( const auto &pcu : cus )
        {
          CodingUnit &cu = subStruct.addCU( *pcu, _chType );
    
          cu = *pcu;
        }
    
        for( const auto &ppu : pus )
        {
          PredictionUnit &pu = subStruct.addPU( *ppu, _chType );
    
          pu = *ppu;
        }
    
        unsigned numComp = ::getNumberValidChannels( area.chromaFormat );
        for( unsigned i = 0; i < numComp; i++)
        {
          ::memcpy( subStruct.m_isDecomp[i], m_isDecomp[i], (unitScale[i].scale( area.blocks[i].size() ).area() * sizeof( bool ) ) );
        }
      }
    }
    
    void CodingStructure::useSubStructure( const CodingStructure& subStruct, const ChannelType chType, const UnitArea &subArea, const bool cpyPred /*= true*/, const bool cpyReco /*= true*/, const bool cpyOrgResi /*= true*/, const bool cpyResi /*= true*/ )
    {
      UnitArea clippedArea = clipArea( subArea, *picture );
    
      setDecomp( clippedArea );
    
      CPelUnitBuf subPredBuf = cpyPred ? subStruct.getPredBuf( clippedArea ) : CPelUnitBuf();
      CPelUnitBuf subResiBuf = cpyResi ? subStruct.getResiBuf( clippedArea ) : CPelUnitBuf();
      CPelUnitBuf subRecoBuf = cpyReco ? subStruct.getRecoBuf( clippedArea ) : CPelUnitBuf();
    
      if( parent )
      {
        // copy data to picture
        if( cpyPred )    getPredBuf   ( clippedArea ).copyFrom( subPredBuf );
        if( cpyResi )    getResiBuf   ( clippedArea ).copyFrom( subResiBuf );
        if( cpyReco )    getRecoBuf   ( clippedArea ).copyFrom( subRecoBuf );
        if( cpyOrgResi ) getOrgResiBuf( clippedArea ).copyFrom( subStruct.getOrgResiBuf( clippedArea ) );
      }
    
      if( cpyPred ) picture->getPredBuf( clippedArea ).copyFrom( subPredBuf );
      if( cpyResi ) picture->getResiBuf( clippedArea ).copyFrom( subResiBuf );
      if( cpyReco ) picture->getRecoBuf( clippedArea ).copyFrom( subRecoBuf );
    
    
      if (!subStruct.m_isTuEnc && ((!slice->isIntra() || slice->getSPS()->getIBCFlag()) && chType != CHANNEL_TYPE_CHROMA))
    
      {
        // copy motion buffer
        MotionBuf ownMB  = getMotionBuf          ( clippedArea );
        CMotionBuf subMB = subStruct.getMotionBuf( clippedArea );
    
        ownMB.copyFrom( subMB );
    
    
        motionLut = subStruct.motionLut;
    
    #if JVET_O0119_BASE_PALETTE_444
      prevPLT = subStruct.prevPLT;
    #endif
    
    
    #if ENABLE_WPP_PARALLELISM
    
      if( nullptr == parent )
      {
    #pragma omp critical
        {
          fracBits += subStruct.fracBits;
          dist     += subStruct.dist;
          cost     += subStruct.cost;
    
    Nan Hu's avatar
    Nan Hu committed
          costDbOffset += subStruct.costDbOffset;
    
          if( parent )
          {
            // allow this to be false at the top level
            CHECKD( !area.contains( subArea ), "Trying to use a sub-structure not contained in self" );
          }
    
          // copy the CUs over
          if( subStruct.m_isTuEnc )
          {
            // don't copy if the substruct was created for encoding of the TUs
          }
          else
          {
            for( const auto &pcu : subStruct.cus )
            {
              // add an analogue CU into own CU store
              const UnitArea &cuPatch = *pcu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
              CodingUnit &cu = addCU( cuPatch, pcu->chType );
    #else
    
    
              // copy the CU info from subPatch
              cu = *pcu;
            }
          }
    
          // copy the PUs over
          if( subStruct.m_isTuEnc )
          {
            // don't copy if the substruct was created for encoding of the TUs
          }
          else
          {
            for( const auto &ppu : subStruct.pus )
            {
              // add an analogue PU into own PU store
              const UnitArea &puPatch = *ppu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
              PredictionUnit &pu = addPU( puPatch, ppu->chType );
    
              PredictionUnit &pu = addPU( puPatch, chType );
    
    
              // copy the PU info from subPatch
              pu = *ppu;
            }
          }
          // copy the TUs over
          for( const auto &ptu : subStruct.tus )
          {
            // add an analogue TU into own TU store
            const UnitArea &tuPatch = *ptu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
            TransformUnit &tu = addTU( tuPatch, ptu->chType );
    #else
    
            TransformUnit &tu = addTU( tuPatch, chType );
    
    
            // copy the TU info from subPatch
            tu = *ptu;
          }
        }
    
        return;
      }
    #endif
    
      fracBits += subStruct.fracBits;
      dist     += subStruct.dist;
      cost     += subStruct.cost;
    
    Nan Hu's avatar
    Nan Hu committed
      costDbOffset += subStruct.costDbOffset;
    
      if( parent )
      {
        // allow this to be false at the top level
        CHECKD( !area.contains( subArea ), "Trying to use a sub-structure not contained in self" );
      }
    
      // copy the CUs over
      if( subStruct.m_isTuEnc )
      {
        // don't copy if the substruct was created for encoding of the TUs
      }
      else
      {
        for( const auto &pcu : subStruct.cus )
        {
          // add an analogue CU into own CU store
          const UnitArea &cuPatch = *pcu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
          CodingUnit &cu = addCU( cuPatch, pcu->chType );
    #else
    
    
          // copy the CU info from subPatch
          cu = *pcu;
        }
      }
    
      // copy the PUs over
      if( subStruct.m_isTuEnc )
      {
        // don't copy if the substruct was created for encoding of the TUs
      }
      else
      {
        for( const auto &ppu : subStruct.pus )
        {
          // add an analogue PU into own PU store
          const UnitArea &puPatch = *ppu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
          PredictionUnit &pu = addPU( puPatch, ppu->chType );
    
          PredictionUnit &pu = addPU( puPatch, chType );
    
    
          // copy the PU info from subPatch
          pu = *ppu;
        }
      }
      // copy the TUs over
      for( const auto &ptu : subStruct.tus )
      {
        // add an analogue TU into own TU store
        const UnitArea &tuPatch = *ptu;
    
    #if JVET_O0050_LOCAL_DUAL_TREE
        TransformUnit &tu = addTU( tuPatch, ptu->chType );
    #else
    
        TransformUnit &tu = addTU( tuPatch, chType );
    
    
        // copy the TU info from subPatch
        tu = *ptu;
      }
    }
    
    void CodingStructure::copyStructure( const CodingStructure& other, const ChannelType chType, const bool copyTUs, const bool copyRecoBuf )
    {
      fracBits = other.fracBits;
      dist     = other.dist;
      cost     = other.cost;
    
    Nan Hu's avatar
    Nan Hu committed
      costDbOffset = other.costDbOffset;
    
      CHECKD( area != other.area, "Incompatible sizes" );
    
      const UnitArea dualITreeArea = CS::getArea( *this, this->area, chType );
    
      // copy the CUs over
      for (const auto &pcu : other.cus)
      {
        if( !dualITreeArea.contains( *pcu ) )
        {
          continue;
        }
        // add an analogue CU into own CU store
        const UnitArea &cuPatch = *pcu;
    
        CodingUnit &cu = addCU(cuPatch, chType);
    
        // copy the CU info from subPatch
        cu = *pcu;
      }
    
      // copy the PUs over
      for (const auto &ppu : other.pus)
      {
        if( !dualITreeArea.contains( *ppu ) )
        {
          continue;
        }
        // add an analogue PU into own PU store
        const UnitArea &puPatch = *ppu;
    
        PredictionUnit &pu = addPU(puPatch, chType);
    
        // copy the PU info from subPatch
        pu = *ppu;
      }
    
    
    Yu Han's avatar
    Yu Han committed
      if (!other.slice->isIntra() || other.slice->getSPS()->getIBCFlag())
    
      {
        // copy motion buffer
        MotionBuf  ownMB = getMotionBuf();
        CMotionBuf subMB = other.getMotionBuf();
    
        ownMB.copyFrom( subMB );
    
    
        motionLut = other.motionLut;
    
    #if JVET_O0119_BASE_PALETTE_444
      prevPLT = other.prevPLT;
    #endif
    
    
      if( copyTUs )
      {
        // copy the TUs over
        for( const auto &ptu : other.tus )
        {
          if( !dualITreeArea.contains( *ptu ) )
          {
            continue;
          }
          // add an analogue TU into own TU store
          const UnitArea &tuPatch = *ptu;
    
          TransformUnit &tu = addTU( tuPatch, chType );
    
          // copy the TU info from subPatch
          tu = *ptu;
        }
      }
    
      if( copyRecoBuf )
      {
        CPelUnitBuf recoBuf = other.getRecoBuf( area );
    
        if( parent )
        {
          // copy data to self for neighbors
          getRecoBuf( area ).copyFrom( recoBuf );
        }
    
        // copy data to picture
        picture->getRecoBuf( area ).copyFrom( recoBuf );
    
          CPelUnitBuf predBuf = other.getPredBuf(area);
          if (parent)
          {
            getPredBuf(area).copyFrom(predBuf);
          }
          picture->getPredBuf(area).copyFrom(predBuf);
        }
    
    Tobias Hinz's avatar
    Tobias Hinz committed
    
        // required for DebugCTU
        int numCh = ::getNumberValidChannels( area.chromaFormat );
        for( int i = 0; i < numCh; i++ )
        {
          const size_t _area = unitScale[i].scaleArea( area.blocks[i].area() );
    
          memcpy( m_isDecomp[i], other.m_isDecomp[i], sizeof( *m_isDecomp[0] ) * _area );
        }
    
      }
    }
    
    void CodingStructure::initStructData( const int &QP, const bool &_isLosses, const bool &skipMotBuf )
    {
      clearPUs();
      clearTUs();
      clearCUs();
    
    
    Yu Han's avatar
    Yu Han committed
      if (!skipMotBuf && (!parent || ((!slice->isIntra() || slice->getSPS()->getIBCFlag()) && !m_isTuEnc)))
    
      {
        getMotionBuf()      .memset( 0 );
      }
    
      fracBits = 0;
      dist     = 0;
      cost     = MAX_DOUBLE;
    
    Nan Hu's avatar
    Nan Hu committed
      costDbOffset = 0;
      useDbCost = false;
    
      interHad = std::numeric_limits<Distortion>::max();
    }
    
    
    void CodingStructure::clearTUs()
    {
      int numCh = ::getNumberValidChannels( area.chromaFormat );
      for( int i = 0; i < numCh; i++ )
      {
        size_t _area = ( area.blocks[i].area() >> unitScale[i].area );
    
        memset( m_isDecomp[i], false, sizeof( *m_isDecomp[0] ) * _area );
        memset( m_tuIdx   [i],     0, sizeof( *m_tuIdx   [0] ) * _area );
      }
    
    
      numCh = getNumberValidComponents( area.chromaFormat );
    
      for( int i = 0; i < numCh; i++ )
      {
        m_offsets[i] = 0;
      }
    
      for( auto &pcu : cus )
      {
        pcu->firstTU = pcu->lastTU = nullptr;
      }
    
      m_tuCache.cache( tus );
      m_numTUs = 0;
    }
    
    void CodingStructure::clearPUs()
    {
      int numCh = ::getNumberValidChannels( area.chromaFormat );
      for( int i = 0; i < numCh; i++ )
      {
        memset( m_puIdx[i], 0, sizeof( *m_puIdx[0] ) * unitScale[i].scaleArea( area.blocks[i].area() ) );
      }
    
      m_puCache.cache( pus );
      m_numPUs = 0;
    
      for( auto &pcu : cus )
      {
        pcu->firstPU = pcu->lastPU = nullptr;
      }
    }
    
    void CodingStructure::clearCUs()
    {
      int numCh = ::getNumberValidChannels( area.chromaFormat );
      for( int i = 0; i < numCh; i++ )
      {
        memset( m_cuIdx[i], 0, sizeof( *m_cuIdx[0] ) * unitScale[i].scaleArea( area.blocks[i].area() ) );
      }
    
      m_cuCache.cache( cus );
      m_numCUs = 0;
    }
    
    MotionBuf CodingStructure::getMotionBuf( const Area& _area )
    {
      const CompArea& _luma = area.Y();
    
      CHECKD( !_luma.contains( _area ), "Trying to access motion information outside of this coding structure" );
    
      const Area miArea   = g_miScaling.scale( _area );
      const Area selfArea = g_miScaling.scale( _luma );
    
      return MotionBuf( m_motionBuf + rsAddr( miArea.pos(), selfArea.pos(), selfArea.width ), selfArea.width, miArea.size() );
    }
    
    const CMotionBuf CodingStructure::getMotionBuf( const Area& _area ) const
    {
      const CompArea& _luma = area.Y();
    
      CHECKD( !_luma.contains( _area ), "Trying to access motion information outside of this coding structure" );
    
      const Area miArea   = g_miScaling.scale( _area );
      const Area selfArea = g_miScaling.scale( _luma );
    
      return MotionBuf( m_motionBuf + rsAddr( miArea.pos(), selfArea.pos(), selfArea.width ), selfArea.width, miArea.size() );
    }
    
    MotionInfo& CodingStructure::getMotionInfo( const Position& pos )
    {
      CHECKD( !area.Y().contains( pos ), "Trying to access motion information outside of this coding structure" );
    
      //return getMotionBuf().at( g_miScaling.scale( pos - area.lumaPos() ) );
      // bypass the motion buf calling and get the value directly
      const unsigned stride = g_miScaling.scaleHor( area.lumaSize().width );
      const Position miPos  = g_miScaling.scale( pos - area.lumaPos() );
    
      return *( m_motionBuf + miPos.y * stride + miPos.x );
    }
    
    const MotionInfo& CodingStructure::getMotionInfo( const Position& pos ) const
    {
      CHECKD( !area.Y().contains( pos ), "Trying to access motion information outside of this coding structure" );
    
      //return getMotionBuf().at( g_miScaling.scale( pos - area.lumaPos() ) );
      // bypass the motion buf calling and get the value directly
      const unsigned stride = g_miScaling.scaleHor( area.lumaSize().width );
      const Position miPos  = g_miScaling.scale( pos - area.lumaPos() );
    
      return *( m_motionBuf + miPos.y * stride + miPos.x );
    }
    
    
    // data accessors
           PelBuf     CodingStructure::getPredBuf(const CompArea &blk)           { return getBuf(blk,  PIC_PREDICTION); }
    const CPelBuf     CodingStructure::getPredBuf(const CompArea &blk)     const { return getBuf(blk,  PIC_PREDICTION); }
           PelUnitBuf CodingStructure::getPredBuf(const UnitArea &unit)          { return getBuf(unit, PIC_PREDICTION); }
    const CPelUnitBuf CodingStructure::getPredBuf(const UnitArea &unit)    const { return getBuf(unit, PIC_PREDICTION); }
    
           PelBuf     CodingStructure::getResiBuf(const CompArea &blk)           { return getBuf(blk,  PIC_RESIDUAL); }
    const CPelBuf     CodingStructure::getResiBuf(const CompArea &blk)     const { return getBuf(blk,  PIC_RESIDUAL); }
           PelUnitBuf CodingStructure::getResiBuf(const UnitArea &unit)          { return getBuf(unit, PIC_RESIDUAL); }
    const CPelUnitBuf CodingStructure::getResiBuf(const UnitArea &unit)    const { return getBuf(unit, PIC_RESIDUAL); }
    
           PelBuf     CodingStructure::getRecoBuf(const CompArea &blk)           { return getBuf(blk,  PIC_RECONSTRUCTION); }
    const CPelBuf     CodingStructure::getRecoBuf(const CompArea &blk)     const { return getBuf(blk,  PIC_RECONSTRUCTION); }
           PelUnitBuf CodingStructure::getRecoBuf(const UnitArea &unit)          { return getBuf(unit, PIC_RECONSTRUCTION); }
    const CPelUnitBuf CodingStructure::getRecoBuf(const UnitArea &unit)    const { return getBuf(unit, PIC_RECONSTRUCTION); }
    
           PelBuf     CodingStructure::getOrgResiBuf(const CompArea &blk)        { return getBuf(blk,  PIC_ORG_RESI); }
    const CPelBuf     CodingStructure::getOrgResiBuf(const CompArea &blk)  const { return getBuf(blk,  PIC_ORG_RESI); }
           PelUnitBuf CodingStructure::getOrgResiBuf(const UnitArea &unit)       { return getBuf(unit, PIC_ORG_RESI); }
    const CPelUnitBuf CodingStructure::getOrgResiBuf(const UnitArea &unit) const { return getBuf(unit, PIC_ORG_RESI); }
    
           PelBuf     CodingStructure::getOrgBuf(const CompArea &blk)            { return getBuf(blk,  PIC_ORIGINAL); }
    const CPelBuf     CodingStructure::getOrgBuf(const CompArea &blk)      const { return getBuf(blk,  PIC_ORIGINAL); }
           PelUnitBuf CodingStructure::getOrgBuf(const UnitArea &unit)           { return getBuf(unit, PIC_ORIGINAL); }
    const CPelUnitBuf CodingStructure::getOrgBuf(const UnitArea &unit)     const { return getBuf(unit, PIC_ORIGINAL); }
    
           PelBuf     CodingStructure::getOrgBuf(const ComponentID &compID)      { return picture->getBuf(area.blocks[compID], PIC_ORIGINAL); }
    const CPelBuf     CodingStructure::getOrgBuf(const ComponentID &compID)const { return picture->getBuf(area.blocks[compID], PIC_ORIGINAL); }
           PelUnitBuf CodingStructure::getOrgBuf()                               { return picture->getBuf(area, PIC_ORIGINAL); }
    const CPelUnitBuf CodingStructure::getOrgBuf()                         const { return picture->getBuf(area, PIC_ORIGINAL); }
    
    PelBuf CodingStructure::getBuf( const CompArea &blk, const PictureType &type )
    {
      if (!blk.valid())
      {
        return PelBuf();
      }
    
      if (type == PIC_ORIGINAL)
      {
        return picture->getBuf(blk, type);
      }
    
      const ComponentID compID = blk.compID;
    
      PelStorage* buf = type == PIC_PREDICTION ? &m_pred : ( type == PIC_RESIDUAL ? &m_resi : ( type == PIC_RECONSTRUCTION ? &m_reco : ( type == PIC_ORG_RESI ? &m_orgr : nullptr ) ) );
    
      CHECK( !buf, "Unknown buffer requested" );
    
      CHECKD( !area.blocks[compID].contains( blk ), "Buffer not contained in self requested" );
    
      CompArea cFinal = blk;
      cFinal.relativeTo( area.blocks[compID] );
    
    #if !KEEP_PRED_AND_RESI_SIGNALS
      if( !parent && ( type == PIC_RESIDUAL || type == PIC_PREDICTION ) )
      {
        cFinal.x &= ( pcv->maxCUWidthMask  >> getComponentScaleX( blk.compID, blk.chromaFormat ) );
        cFinal.y &= ( pcv->maxCUHeightMask >> getComponentScaleY( blk.compID, blk.chromaFormat ) );
      }
    #endif
    
      return buf->getBuf( cFinal );
    }
    
    const CPelBuf CodingStructure::getBuf( const CompArea &blk, const PictureType &type ) const
    {
      if (!blk.valid())
      {
        return PelBuf();
      }
    
      if (type == PIC_ORIGINAL)
      {
        return picture->getBuf(blk, type);
      }
    
      const ComponentID compID = blk.compID;
    
      const PelStorage* buf = type == PIC_PREDICTION ? &m_pred : ( type == PIC_RESIDUAL ? &m_resi : ( type == PIC_RECONSTRUCTION ? &m_reco : ( type == PIC_ORG_RESI ? &m_orgr : nullptr ) ) );
    
      CHECK( !buf, "Unknown buffer requested" );
    
      CHECKD( !area.blocks[compID].contains( blk ), "Buffer not contained in self requested" );
    
      CompArea cFinal = blk;
      cFinal.relativeTo( area.blocks[compID] );
    
    #if !KEEP_PRED_AND_RESI_SIGNALS
      if( !parent && ( type == PIC_RESIDUAL || type == PIC_PREDICTION ) )
      {
        cFinal.x &= ( pcv->maxCUWidthMask  >> getComponentScaleX( blk.compID, blk.chromaFormat ) );
        cFinal.y &= ( pcv->maxCUHeightMask >> getComponentScaleY( blk.compID, blk.chromaFormat ) );
      }
    #endif
    
      return buf->getBuf( cFinal );
    }
    
    PelUnitBuf CodingStructure::getBuf( const UnitArea &unit, const PictureType &type )
    {
      // no parent fetching for buffers
      if( area.chromaFormat == CHROMA_400 )
      {
        return PelUnitBuf( area.chromaFormat, getBuf( unit.Y(), type ) );
      }
      else
      {
        return PelUnitBuf( area.chromaFormat, getBuf( unit.Y(), type ), getBuf( unit.Cb(), type ), getBuf( unit.Cr(), type ) );
      }
    }
    
    const CPelUnitBuf CodingStructure::getBuf( const UnitArea &unit, const PictureType &type ) const
    {
      // no parent fetching for buffers
      if( area.chromaFormat == CHROMA_400 )
      {
        return CPelUnitBuf( area.chromaFormat, getBuf( unit.Y(), type ) );
      }
      else
      {
        return CPelUnitBuf( area.chromaFormat, getBuf( unit.Y(), type ), getBuf( unit.Cb(), type ), getBuf( unit.Cr(), type ) );
      }
    }
    
    const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const CodingUnit& curCu, const ChannelType _chType ) const
    {
      const CodingUnit* cu = getCU( pos, _chType );
      // exists       same slice and tile                  cu precedes curCu in encoding order
      //                                                  (thus, is either from parent CS in RD-search or its index is lower)
    
      const bool wavefrontsEnabled = curCu.slice->getPPS()->getEntropyCodingSyncEnabledFlag();
    
      int ctuSizeBit = g_aucLog2[curCu.cs->sps->getMaxCUWidth()];
    
      int xNbY  = pos.x << getChannelTypeScaleX( _chType, curCu.chromaFormat );
    
      int xCurr = curCu.blocks[_chType].x << getChannelTypeScaleX( _chType, curCu.chromaFormat );
    
      bool addCheck = (wavefrontsEnabled && (xNbY >> ctuSizeBit) >= (xCurr >> ctuSizeBit) + 1 ) ? false : true;
      if( cu && CU::isSameSliceAndTile( *cu, curCu ) && ( cu->cs != curCu.cs || cu->idx <= curCu.idx ) && addCheck)
    
    const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const
    
      const bool wavefrontsEnabled = this->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
      int ctuSizeBit = g_aucLog2[this->sps->getMaxCUWidth()];
      int xNbY  = pos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat );
      int xCurr = curPos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat );
    
      bool addCheck = (wavefrontsEnabled && (xNbY >> ctuSizeBit) >= (xCurr >> ctuSizeBit) + 1 ) ? false : true;
      return ( cu && cu->slice->getIndependentSliceIdx() == curSliceIdx && cu->tileIdx == curTileIdx && addCheck ) ? cu : nullptr;
    
    }
    
    const PredictionUnit* CodingStructure::getPURestricted( const Position &pos, const PredictionUnit& curPu, const ChannelType _chType ) const
    {
      const PredictionUnit* pu = getPU( pos, _chType );
      // exists       same slice and tile                  pu precedes curPu in encoding order
      //                                                  (thus, is either from parent CS in RD-search or its index is lower)
    
      const bool wavefrontsEnabled = curPu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
    
      int ctuSizeBit = g_aucLog2[curPu.cs->sps->getMaxCUWidth()];
      int xNbY  = pos.x << getChannelTypeScaleX( _chType, curPu.chromaFormat );
      int xCurr = curPu.blocks[_chType].x << getChannelTypeScaleX( _chType, curPu.chromaFormat );
    
      bool addCheck = (wavefrontsEnabled && (xNbY >> ctuSizeBit) >= (xCurr >> ctuSizeBit) + 1 ) ? false : true;
      if( pu && CU::isSameSliceAndTile( *pu->cu, *curPu.cu ) && ( pu->cs != curPu.cs || pu->idx <= curPu.idx ) && addCheck )
    
      {
        return pu;
      }
      else
      {
        return nullptr;
      }
    }
    
    const TransformUnit* CodingStructure::getTURestricted( const Position &pos, const TransformUnit& curTu, const ChannelType _chType ) const
    {
      const TransformUnit* tu = getTU( pos, _chType );
      // exists       same slice and tile                  tu precedes curTu in encoding order
      //                                                  (thus, is either from parent CS in RD-search or its index is lower)
    
      const bool wavefrontsEnabled = curTu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
    
      int ctuSizeBit = g_aucLog2[curTu.cs->sps->getMaxCUWidth()];
      int xNbY  = pos.x << getChannelTypeScaleX( _chType, curTu.chromaFormat );
      int xCurr = curTu.blocks[_chType].x << getChannelTypeScaleX( _chType, curTu.chromaFormat );
    
      bool addCheck = (wavefrontsEnabled && (xNbY >> ctuSizeBit) >= (xCurr >> ctuSizeBit) + 1 ) ? false : true;
      if( tu && CU::isSameSliceAndTile( *tu->cu, *curTu.cu ) && ( tu->cs != curTu.cs || tu->idx <= curTu.idx ) && addCheck )
    
    #if !JVET_O0258_REMOVE_CHROMA_IBC_FOR_DUALTREE
    
    Yu Han's avatar
    Yu Han committed
    IbcLumaCoverage CodingStructure::getIbcLumaCoverage(const CompArea& chromaArea) const
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
    {
      const unsigned int unitAreaSubBlock = MIN_PU_SIZE * MIN_PU_SIZE;
      CompArea lumaArea = CompArea(COMPONENT_Y, chromaArea.chromaFormat, chromaArea.lumaPos(), recalcSize(chromaArea.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, chromaArea.size()));
      lumaArea = clipArea(lumaArea, picture->block(COMPONENT_Y));
      const unsigned int fullArea = lumaArea.area();
    
    Yu Han's avatar
    Yu Han committed
      unsigned int ibcArea = 0;
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      for (SizeType y = 0; y < lumaArea.height; y += MIN_PU_SIZE)
      {
        for (SizeType x = 0; x < lumaArea.width; x += MIN_PU_SIZE)
        {
          Position pos = lumaArea.offset(x, y);
    
    #if JVET_O0050_LOCAL_DUAL_TREE
          if (picture->cs->getMotionInfo(pos).isInter && picture->cs->getMotionInfo(pos).isIBCmot)
    #else
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
          if (picture->cs->getMotionInfo(pos).isInter) // need to change if inter slice allows dualtree
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
          {
    
    Yu Han's avatar
    Yu Han committed
            ibcArea += unitAreaSubBlock;
    
    Yu Han's avatar
    Yu Han committed
      IbcLumaCoverage coverage = IBC_LUMA_COVERAGE_FULL;
      if (ibcArea == 0)
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      {
    
    Yu Han's avatar
    Yu Han committed
        coverage = IBC_LUMA_COVERAGE_NONE;
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      }
    
    Yu Han's avatar
    Yu Han committed
      else if (ibcArea < fullArea)
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      {
    
    Yu Han's avatar
    Yu Han committed
        coverage = IBC_LUMA_COVERAGE_PARTIAL;
    
    Xiaozhong Xu's avatar
    Xiaozhong Xu committed
      }
    
      return coverage;
    }