Newer
Older

Karsten Suehring
committed
if( i == 1 ) blk.x += blk.width;
}
CHECK( sub[i].lumaSize().width < MIN_TB_SIZEY, "the split causes the block to be smaller than the minimal TU size" );

Karsten Suehring
committed
}
return sub;
}
else if( splitType == CU_TRIH_SPLIT )
{
Partitioning sub;
sub.resize( 3, cuArea );
for( int i = 0; i < 3; i++ )
{
for( auto &blk : sub[i].blocks )
{
blk.height >>= 1;
if( ( i + 1 ) & 1 ) blk.height >>= 1;
if( i == 1 ) blk.y += blk.height / 2;
if( i == 2 ) blk.y += 3 * blk.height;
}
CHECK( sub[i].lumaSize().height < MIN_TB_SIZEY, "the cs split causes the block to be smaller than the minimal TU size" );

Karsten Suehring
committed
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
}
return sub;
}
else if( splitType == CU_TRIV_SPLIT )
{
Partitioning sub;
sub.resize( 3, cuArea );
for( int i = 0; i < 3; i++ )
{
for( auto &blk : sub[i].blocks )
{
blk.width >>= 1;
if( ( i + 1 ) & 1 ) blk.width >>= 1;
if( i == 1 ) blk.x += blk.width / 2;
if( i == 2 ) blk.x += 3 * blk.width;
}
CHECK( sub[i].lumaSize().width < MIN_TB_SIZEY, "the cs split causes the block to be smaller than the minimal TU size" );

Karsten Suehring
committed
}
return sub;
}
else
{
THROW( "Unknown CU sub-partitioning" );
return Partitioning();
}
}
void PartitionerImpl::getTUIntraSubPartitions( Partitioning &sub, const UnitArea &tuArea, const CodingStructure &cs, const PartSplit splitType )
{
uint32_t nPartitions;
uint32_t splitDimensionSize = CU::getISPSplitDim( tuArea.lumaSize().width, tuArea.lumaSize().height, splitType );
bool isDualTree = CS::isDualITree( cs ) || cs.treeType != TREE_D;
if( splitType == TU_1D_HORZ_SPLIT )
{
nPartitions = tuArea.lumaSize().height >> floorLog2(splitDimensionSize);
sub.resize( nPartitions );
for( uint32_t i = 0; i < nPartitions; i++ )
{
sub[i] = tuArea;
CompArea& blkY = sub[i].blocks[COMPONENT_Y];
blkY.height = splitDimensionSize;
blkY.y = i > 0 ? sub[i - 1].blocks[COMPONENT_Y].y + splitDimensionSize : blkY.y;
CHECK( sub[i].lumaSize().height < 1, "the cs split causes the block to be smaller than the minimal TU size" );
}
}
else if( splitType == TU_1D_VERT_SPLIT )
{
nPartitions = tuArea.lumaSize().width >> floorLog2(splitDimensionSize);
sub.resize( nPartitions );
for( uint32_t i = 0; i < nPartitions; i++ )
{
sub[i] = tuArea;
CompArea& blkY = sub[i].blocks[COMPONENT_Y];
blkY.width = splitDimensionSize;
blkY.x = i > 0 ? sub[i - 1].blocks[COMPONENT_Y].x + splitDimensionSize : blkY.x;
CHECK( sub[i].lumaSize().width < 1, "the split causes the block to be smaller than the minimal TU size" );
}
}
else
{
THROW( "Unknown TU sub-partitioning" );
}
//we only partition luma, so there is going to be only one chroma tu at the end (unless it is dual tree, in which case there won't be any chroma components)
uint32_t partitionsWithoutChroma =
!isChromaEnabled(cs.area.chromaFormat) ? 0 : (isDualTree ? nPartitions : nPartitions - 1);
for( uint32_t i = 0; i < partitionsWithoutChroma; i++ )
{
CompArea& blkCb = sub[i].blocks[COMPONENT_Cb];
CompArea& blkCr = sub[i].blocks[COMPONENT_Cr];
blkCb = CompArea();
blkCr = CompArea();
}
}

Karsten Suehring
committed
static const int g_maxRtGridSize = 3;
static const int g_zScanToX[1 << ( g_maxRtGridSize << 1 )] =
{
0, 1, 0, 1, 2, 3, 2, 3,
0, 1, 0, 1, 2, 3, 2, 3,
4, 5, 4, 5, 6, 7, 6, 7,
4, 5, 4, 5, 6, 7, 6, 7,
0, 1, 0, 1, 2, 3, 2, 3,
0, 1, 0, 1, 2, 3, 2, 3,
4, 5, 4, 5, 6, 7, 6, 7,
4, 5, 4, 5, 6, 7, 6, 7,
};
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, 6, 7, 7,
4, 4, 5, 5, 4, 4, 5, 5,
6, 6, 7, 7, 6, 6, 7, 7,

Karsten Suehring
committed
};
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 Size area = cuArea.lumaSize();
const int maxTrSize = (area.width>64 || area.height>64) ? 64 : cs.sps->getMaxTbSize();

Karsten Suehring
committed
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
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;
}

Karsten Suehring
committed
comp.width /= numTilesH;
comp.height /= numTilesV;
comp.x += comp.width * x;
comp.y += comp.height * y;
}
}
return ret;
}
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
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;
}