source/Lib/CommonLib/Slice.cpp
void PPS::initSubPic( const SPS &sps )
{
  if( getSubPicIdMappingInPpsFlag() )
  {
    // When signalled, the number of subpictures has to match in PPS and SPS
    CHECK( getNumSubPics() != sps.getNumSubPics(), "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
  }
  else
  {
    // When not signalled  set the numer equal for convenient access
    setNumSubPics( sps.getNumSubPics() );
  }

  CHECK( getNumSubPics() > MAX_NUM_SUB_PICS, "Number of sub-pictures in picture exceeds valid range" );
  m_subPics.resize(getNumSubPics());

  // Check that no subpicture is specified outside of the conformance cropping window
  for(int i = 0; i < sps.getNumSubPics(); i++)
  {
    CHECK( (sps.getSubPicCtuTopLeftX(i) * sps.getCTUSize()) >=
          (sps.getMaxPicWidthInLumaSamples() - sps.getConformanceWindow().getWindowRightOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
    CHECK( ((sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowLeftOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window" );
    CHECK( (sps.getSubPicCtuTopLeftY(i) * sps.getCTUSize()) >=
          (sps.getMaxPicHeightInLumaSamples()  - sps.getConformanceWindow().getWindowBottomOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
    CHECK( ((sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowTopOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
  }

  // m_ctuSize,  m_picWidthInCtu, and m_picHeightInCtu might not be initialized yet.
  if( m_ctuSize == 0 || m_picWidthInCtu == 0 || m_picHeightInCtu == 0 )
  {
    m_ctuSize = sps.getCTUSize();
    m_picWidthInCtu = (m_picWidthInLumaSamples + m_ctuSize - 1) / m_ctuSize;
    m_picHeightInCtu = (m_picHeightInLumaSamples + m_ctuSize - 1) / m_ctuSize;
  }
  for( int i=0; i< getNumSubPics(); i++ )
  {
    m_subPics[i].setSubPicIdx(i);
    if( sps.getSubPicIdMappingExplicitlySignalledFlag() )
    {
      if( m_subPicIdMappingInPpsFlag )
      {
        m_subPics[i].setSubPicID( m_subPicId[i] );
      }
      else
      {
        m_subPics[i].setSubPicID( sps.getSubPicId(i) );
      }
    }
    else
    {
      m_subPics[i].setSubPicID(i);
    }
    m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
    m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
    m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
    m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));

    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
    m_subPics[i].setFirstCTUInSubPic(firstCTU);
    uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
    m_subPics[i].setLastCTUInSubPic(lastCTU);

    uint32_t left = sps.getSubPicCtuTopLeftX(i) * m_ctuSize;
    m_subPics[i].setSubPicLeft(left);

    uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
    m_subPics[i].setSubPicRight(right);

    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);

    uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
    m_subPics[i].setSubPicTop(top);

    uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);

    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);

    m_subPics[i].setSubPicBottom(bottom);

    m_subPics[i].clearCTUAddrList();

    if( m_numSlicesInPic == 1 )
    {
      CHECK( getNumSubPics() != 1, "only one slice in picture, but number of subpic is not one" );
      m_subPics[i].addAllCtusInPicToSubPic(0, getPicWidthInCtu(), 0, getPicHeightInCtu(), getPicWidthInCtu());
      m_subPics[i].setNumSlicesInSubPic(1);
    }
    else
    {
      int numSlicesInSubPic = 0;
      int idxLastSliceInSubpic = -1;
      int idxFirstSliceAfterSubpic = m_numSlicesInPic;
      for( int j = 0; j < m_numSlicesInPic; j++ )
      {
        uint32_t ctu = m_sliceMap[j].getCtuAddrInSlice(0);
        uint32_t ctu_x = ctu % m_picWidthInCtu;
        uint32_t ctu_y = ctu / m_picWidthInCtu;
        if (ctu_x >= sps.getSubPicCtuTopLeftX(i) &&
          ctu_x < (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) &&
          ctu_y >= sps.getSubPicCtuTopLeftY(i) &&
          ctu_y < (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)))
        {
          // add ctus in a slice to the subpicture it belongs to
          m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
          numSlicesInSubPic++;
          idxLastSliceInSubpic = j;
        }
        else if (idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1)
        {
          idxFirstSliceAfterSubpic = j;
        }
      }
      CHECK( idxFirstSliceAfterSubpic < idxLastSliceInSubpic, "The signalling order of slices shall follow the coding order" );
      m_subPics[i].setNumSlicesInSubPic(numSlicesInSubPic);
    }
    m_subPics[i].setTreatedAsPicFlag(sps.getSubPicTreatedAsPicFlag(i));
    m_subPics[i].setloopFilterAcrossSubPicEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
  }
}
/**
- initialize mapping between subpicture and CTUs
*/
initialize mapping between subpicture and CTUs
initialize mapping between subpicture and CTUs
void PPS::initSubPic( const SPS &sps )
{
  if( getSubPicIdMappingInPpsFlag() )
  {
    CHECK( getNumSubPics() != sps.getNumSubPics(), "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
  }
  else
  {
    setNumSubPics( sps.getNumSubPics() );
  }
  CHECK( getNumSubPics() > MAX_NUM_SUB_PICS, "Number of sub-pictures in picture exceeds valid range" );
  m_subPics.resize(getNumSubPics());
  for(int i = 0; i < sps.getNumSubPics(); i++)
  {
    CHECK( (sps.getSubPicCtuTopLeftX(i) * sps.getCTUSize()) >=
          (sps.getMaxPicWidthInLumaSamples() - sps.getConformanceWindow().getWindowRightOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
    CHECK( ((sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowLeftOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window" );
    CHECK( (sps.getSubPicCtuTopLeftY(i) * sps.getCTUSize()) >=
          (sps.getMaxPicHeightInLumaSamples()  - sps.getConformanceWindow().getWindowBottomOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
    CHECK( ((sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowTopOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
          "No subpicture can be located completely outside of the conformance cropping window");
  }
  if( m_ctuSize == 0 || m_picWidthInCtu == 0 || m_picHeightInCtu == 0 )
  {
    m_ctuSize = sps.getCTUSize();
    m_picWidthInCtu = (m_picWidthInLumaSamples + m_ctuSize - 1) / m_ctuSize;
    m_picHeightInCtu = (m_picHeightInLumaSamples + m_ctuSize - 1) / m_ctuSize;
  }
  for( int i=0; i< getNumSubPics(); i++ )
  {
    m_subPics[i].setSubPicIdx(i);
    if( sps.getSubPicIdMappingExplicitlySignalledFlag() )
    {
      if( m_subPicIdMappingInPpsFlag )
      {
        m_subPics[i].setSubPicID( m_subPicId[i] );
      }
      else
      {
        m_subPics[i].setSubPicID( sps.getSubPicId(i) );
      }
    }
    else
    {
      m_subPics[i].setSubPicID(i);
    }
    m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
    m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
    m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
    m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));
    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
    m_subPics[i].setFirstCTUInSubPic(firstCTU);
    uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
    m_subPics[i].setLastCTUInSubPic(lastCTU);
    uint32_t left = sps.getSubPicCtuTopLeftX(i) * m_ctuSize;
    m_subPics[i].setSubPicLeft(left);
    uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
    m_subPics[i].setSubPicRight(right);
    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);
    uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
    m_subPics[i].setSubPicTop(top);
    uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);
    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);
    m_subPics[i].setSubPicBottom(bottom);
    m_subPics[i].clearCTUAddrList();
    if( m_numSlicesInPic == 1 )
    {
      CHECK( getNumSubPics() != 1, "only one slice in picture, but number of subpic is not one" );
      m_subPics[i].addAllCtusInPicToSubPic(0, getPicWidthInCtu(), 0, getPicHeightInCtu(), getPicWidthInCtu());
      m_subPics[i].setNumSlicesInSubPic(1);
    }
    else
    {
      int numSlicesInSubPic = 0;
      int idxLastSliceInSubpic = -1;
      int idxFirstSliceAfterSubpic = m_numSlicesInPic;
      for( int j = 0; j < m_numSlicesInPic; j++ )
      {
        uint32_t ctu = m_sliceMap[j].getCtuAddrInSlice(0);
        uint32_t ctu_x = ctu % m_picWidthInCtu;
        uint32_t ctu_y = ctu / m_picWidthInCtu;
        if (ctu_x >= sps.getSubPicCtuTopLeftX(i) &&
          ctu_x < (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) &&
          ctu_y >= sps.getSubPicCtuTopLeftY(i) &&
          ctu_y < (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)))
        {
          m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
          numSlicesInSubPic++;
          idxLastSliceInSubpic = j;
        }
        else if (idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1)
        {
          idxFirstSliceAfterSubpic = j;
        }
      }
      CHECK( idxFirstSliceAfterSubpic < idxLastSliceInSubpic, "The signalling order of slices shall follow the coding order" );
      m_subPics[i].setNumSlicesInSubPic(numSlicesInSubPic);
    }
    m_subPics[i].setTreatedAsPicFlag(sps.getSubPicTreatedAsPicFlag(i));
    m_subPics[i].setloopFilterAcrossSubPicEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
  }
}
void PPS :: initSubPic ( const SPS & sps ) { if ( getSubPicIdMappingInPpsFlag ( ) ) { CHECK ( getNumSubPics ( ) != sps . getNumSubPics ( ) , " " ) ; } else { setNumSubPics ( sps . getNumSubPics ( ) ) ; } CHECK ( getNumSubPics ( ) > MAX_NUM_SUB_PICS , " " ) ; m_subPics . resize ( getNumSubPics ( ) ) ; for ( int i = 0 ; i < sps . getNumSubPics ( ) ; i ++ ) { CHECK ( ( sps . getSubPicCtuTopLeftX ( i ) * sps . getCTUSize ( ) ) >= ( sps . getMaxPicWidthInLumaSamples ( ) - sps . getConformanceWindow ( ) . getWindowRightOffset ( ) * SPS :: getWinUnitX ( sps . getChromaFormatIdc ( ) ) ) , " " ) ; CHECK ( ( ( sps . getSubPicCtuTopLeftX ( i ) + sps . getSubPicWidth ( i ) ) * sps . getCTUSize ( ) ) <= ( sps . getConformanceWindow ( ) . getWindowLeftOffset ( ) * SPS :: getWinUnitX ( sps . getChromaFormatIdc ( ) ) ) , " " ) ; CHECK ( ( sps . getSubPicCtuTopLeftY ( i ) * sps . getCTUSize ( ) ) >= ( sps . getMaxPicHeightInLumaSamples ( ) - sps . getConformanceWindow ( ) . getWindowBottomOffset ( ) * SPS :: getWinUnitY ( sps . getChromaFormatIdc ( ) ) ) , " " ) ; CHECK ( ( ( sps . getSubPicCtuTopLeftY ( i ) + sps . getSubPicHeight ( i ) ) * sps . getCTUSize ( ) ) <= ( sps . getConformanceWindow ( ) . getWindowTopOffset ( ) * SPS :: getWinUnitY ( sps . getChromaFormatIdc ( ) ) ) , " " ) ; } if ( m_ctuSize == 0 || m_picWidthInCtu == 0 || m_picHeightInCtu == 0 ) { m_ctuSize = sps . getCTUSize ( ) ; m_picWidthInCtu = ( m_picWidthInLumaSamples + m_ctuSize - 1 ) / m_ctuSize ; m_picHeightInCtu = ( m_picHeightInLumaSamples + m_ctuSize - 1 ) / m_ctuSize ; } for ( int i = 0 ; i < getNumSubPics ( ) ; i ++ ) { m_subPics [ i ] . setSubPicIdx ( i ) ; if ( sps . getSubPicIdMappingExplicitlySignalledFlag ( ) ) { if ( m_subPicIdMappingInPpsFlag ) { m_subPics [ i ] . setSubPicID ( m_subPicId [ i ] ) ; } else { m_subPics [ i ] . setSubPicID ( sps . getSubPicId ( i ) ) ; } } else { m_subPics [ i ] . setSubPicID ( i ) ; } m_subPics [ i ] . setSubPicCtuTopLeftX ( sps . getSubPicCtuTopLeftX ( i ) ) ; m_subPics [ i ] . setSubPicCtuTopLeftY ( sps . getSubPicCtuTopLeftY ( i ) ) ; m_subPics [ i ] . setSubPicWidthInCTUs ( sps . getSubPicWidth ( i ) ) ; m_subPics [ i ] . setSubPicHeightInCTUs ( sps . getSubPicHeight ( i ) ) ; uint32_t firstCTU = sps . getSubPicCtuTopLeftY ( i ) * m_picWidthInCtu + sps . getSubPicCtuTopLeftX ( i ) ; m_subPics [ i ] . setFirstCTUInSubPic ( firstCTU ) ; uint32_t lastCTU = ( sps . getSubPicCtuTopLeftY ( i ) + sps . getSubPicHeight ( i ) - 1 ) * m_picWidthInCtu + sps . getSubPicCtuTopLeftX ( i ) + sps . getSubPicWidth ( i ) - 1 ; m_subPics [ i ] . setLastCTUInSubPic ( lastCTU ) ; uint32_t left = sps . getSubPicCtuTopLeftX ( i ) * m_ctuSize ; m_subPics [ i ] . setSubPicLeft ( left ) ; uint32_t right = std :: min ( m_picWidthInLumaSamples - 1 , ( sps . getSubPicCtuTopLeftX ( i ) + sps . getSubPicWidth ( i ) ) * m_ctuSize - 1 ) ; m_subPics [ i ] . setSubPicRight ( right ) ; m_subPics [ i ] . setSubPicWidthInLumaSample ( right - left + 1 ) ; uint32_t top = sps . getSubPicCtuTopLeftY ( i ) * m_ctuSize ; m_subPics [ i ] . setSubPicTop ( top ) ; uint32_t bottom = std :: min ( m_picHeightInLumaSamples - 1 , ( sps . getSubPicCtuTopLeftY ( i ) + sps . getSubPicHeight ( i ) ) * m_ctuSize - 1 ) ; m_subPics [ i ] . setSubPicHeightInLumaSample ( bottom - top + 1 ) ; m_subPics [ i ] . setSubPicBottom ( bottom ) ; m_subPics [ i ] . clearCTUAddrList ( ) ; if ( m_numSlicesInPic == 1 ) { CHECK ( getNumSubPics ( ) != 1 , " " ) ; m_subPics [ i ] . addAllCtusInPicToSubPic ( 0 , getPicWidthInCtu ( ) , 0 , getPicHeightInCtu ( ) , getPicWidthInCtu ( ) ) ; m_subPics [ i ] . setNumSlicesInSubPic ( 1 ) ; } else { int numSlicesInSubPic = 0 ; int idxLastSliceInSubpic = -1 ; int idxFirstSliceAfterSubpic = m_numSlicesInPic ; for ( int j = 0 ; j < m_numSlicesInPic ; j ++ ) { uint32_t ctu = m_sliceMap [ j ] . getCtuAddrInSlice ( 0 ) ; uint32_t ctu_x = ctu % m_picWidthInCtu ; uint32_t ctu_y = ctu / m_picWidthInCtu ; if ( ctu_x >= sps . getSubPicCtuTopLeftX ( i ) && ctu_x < ( sps . getSubPicCtuTopLeftX ( i ) + sps . getSubPicWidth ( i ) ) && ctu_y >= sps . getSubPicCtuTopLeftY ( i ) && ctu_y < ( sps . getSubPicCtuTopLeftY ( i ) + sps . getSubPicHeight ( i ) ) ) { m_subPics [ i ] . addCTUsToSubPic ( m_sliceMap [ j ] . getCtuAddrList ( ) ) ; numSlicesInSubPic ++ ; idxLastSliceInSubpic = j ; } else if ( idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1 ) { idxFirstSliceAfterSubpic = j ; } } CHECK ( idxFirstSliceAfterSubpic < idxLastSliceInSubpic , " " ) ; m_subPics [ i ] . setNumSlicesInSubPic ( numSlicesInSubPic ) ; } m_subPics [ i ] . setTreatedAsPicFlag ( sps . getSubPicTreatedAsPicFlag ( i ) ) ; m_subPics [ i ] . setloopFilterAcrossSubPicEnabledFlag ( sps . getLoopFilterAcrossSubpicEnabledFlag ( i ) ) ; } }
initialize mapping between subpicture and CTUs
initialize mapping between subpicture and CTUs
// When signalled, the number of subpictures has to match in PPS and SPS // When not signalled  set the numer equal for convenient access // Check that no subpicture is specified outside of the conformance cropping window // m_ctuSize,  m_picWidthInCtu, and m_picHeightInCtu might not be initialized yet. // add ctus in a slice to the subpicture it belongs to