Skip to content
Snippets Groups Projects
UnitPartitioner.cpp 34.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • static const int g_zScanToY[1 << ( g_maxRtGridSize << 1 )] =
    {
       0,  0,  1,  1,  0,  0,  1,  1,
       2,  2,  3,  3,  2,  2,  3,  3,
       0,  0,  1,  1,  0,  0,  1,  1,
       2,  2,  3,  3,  2,  2,  3,  3,
       4,  4,  5,  5,  4,  4,  5,  5,
       6,  6,  7,  7,  6,  5,  7,  7,
       4,  4,  5,  5,  4,  4,  5,  5,
       6,  6,  7,  7,  6,  5,  7,  7,
    };
    static const int g_rsScanToZ[1 << ( g_maxRtGridSize << 1 )] =
    {
       0,  1,  4,  5, 16, 17, 20, 21,
       2,  3,  6,  7, 18, 19, 22, 23,
       8,  9, 12, 13, 24, 25, 28, 29,
      10, 11, 14, 15, 26, 27, 30, 31,
      32, 33, 36, 37, 48, 49, 52, 53,
      34, 35, 38, 39, 50, 51, 54, 55,
      40, 41, 44, 45, 56, 57, 60, 61,
      42, 43, 46, 47, 58, 59, 62, 63,
    };
    
    Partitioning PartitionerImpl::getMaxTuTiling( const UnitArea &cuArea, const CodingStructure &cs )
    {
      static_assert( MAX_LOG2_DIFF_CU_TR_SIZE <= g_maxRtGridSize, "Z-scan tables are only provided for MAX_LOG2_DIFF_CU_TR_SIZE for up to 3 (8x8 tiling)!" );
    
      const CompArea area = cuArea.Y().valid() ? cuArea.Y() : cuArea.Cb();
    
    #if MAX_TB_SIZE_SIGNALLING
      const int maxTrSize = cs.sps->getMaxTbSize() >> ( isLuma( area.compID ) ? 0 : 1 );
    #else
      const int maxTrSize = MAX_TB_SIZEY >> ( isLuma( area.compID ) ? 0 : 1 );
    #endif
    
      const int numTilesH = std::max<int>( 1, area.width  / maxTrSize );
      const int numTilesV = std::max<int>( 1, area.height / maxTrSize );
      const int numTiles  = numTilesH * numTilesV;
    
      CHECK( numTiles > MAX_CU_TILING_PARTITIONS, "CU partitioning requires more partitions than available" );
    
      Partitioning ret;
      ret.resize( numTiles, cuArea );
    
      for( int i = 0; i < numTiles; i++ )
      {
        const int rsy = i / numTilesH;
        const int rsx = i % numTilesH;
    
        const int x = g_zScanToX[g_rsScanToZ[( rsy << g_maxRtGridSize ) + rsx]];
        const int y = g_zScanToY[g_rsScanToZ[( rsy << g_maxRtGridSize ) + rsx]];
    
        UnitArea& tile = ret[i];
    
        for( CompArea &comp : tile.blocks )
        {
          if( !comp.valid() ) continue;
    
          comp.width  /= numTilesH;
          comp.height /= numTilesV;
    
          comp.x += comp.width  * x;
          comp.y += comp.height * y;
        }
      }
    
      return ret;
    }
    
    
    Partitioning PartitionerImpl::getSbtTuTiling( const UnitArea& cuArea, const CodingStructure &cs, const PartSplit splitType )
    {
      Partitioning ret;
      int numTiles = 2;
      int widthFactor, heightFactor, xOffsetFactor, yOffsetFactor; // y = (x * factor) >> 2;
      assert( splitType >= SBT_VER_HALF_POS0_SPLIT && splitType <= SBT_HOR_QUAD_POS1_SPLIT );
    
      ret.resize( numTiles, cuArea );
      for( int i = 0; i < numTiles; i++ )
      {
        if( splitType >= SBT_VER_QUAD_POS0_SPLIT )
        {
          if( splitType == SBT_HOR_QUAD_POS0_SPLIT || splitType == SBT_HOR_QUAD_POS1_SPLIT )
          {
            widthFactor = 4;
            xOffsetFactor = 0;
            heightFactor = ( ( i == 0 && splitType == SBT_HOR_QUAD_POS0_SPLIT ) || ( i == 1 && splitType == SBT_HOR_QUAD_POS1_SPLIT ) ) ? 1 : 3;
            yOffsetFactor = ( i == 0 ) ? 0 : ( splitType == SBT_HOR_QUAD_POS0_SPLIT ? 1 : 3 );
          }
          else
          {
            widthFactor = ( ( i == 0 && splitType == SBT_VER_QUAD_POS0_SPLIT ) || ( i == 1 && splitType == SBT_VER_QUAD_POS1_SPLIT ) ) ? 1 : 3;
            xOffsetFactor = ( i == 0 ) ? 0 : ( splitType == SBT_VER_QUAD_POS0_SPLIT ? 1 : 3 );
            heightFactor = 4;
            yOffsetFactor = 0;
          }
        }
        else
        {
          if( splitType == SBT_HOR_HALF_POS0_SPLIT || splitType == SBT_HOR_HALF_POS1_SPLIT )
          {
            widthFactor = 4;
            xOffsetFactor = 0;
            heightFactor = 2;
            yOffsetFactor = ( i == 0 ) ? 0 : 2;
          }
          else
          {
            widthFactor = 2;
            xOffsetFactor = ( i == 0 ) ? 0 : 2;
            heightFactor = 4;
            yOffsetFactor = 0;
          }
        }
    
        UnitArea& tile = ret[i];
        for( CompArea &comp : tile.blocks )
        {
          if( !comp.valid() ) continue;
          comp.x += ( comp.width  * xOffsetFactor ) >> 2;
          comp.y += ( comp.height * yOffsetFactor ) >> 2;
          comp.width = ( comp.width  * widthFactor ) >> 2;
          comp.height = ( comp.height * heightFactor ) >> 2;
        }
      }
    
      return ret;
    }