在VTM中允许对使用帧间预测的CU进行子块变换( sub-block transform,SBT)。在SBT模式下,只需要对残差块的一个子部分进行变换处理。当这个帧间预测块的cu_cbf=1时,需要传输一个标志位cu_sbt_flag表示是对整个残差进行处理还是只对其进行部分处理。对前一种情况需要解析其帧间MTS信息决定其使用的变换类型。对于后一种情况对需要处理的部分使用自适应变换对于其他部分残差置零。
当一个帧间预测CU使用SBT模式时,需要在码流中传输SBT类型和SBT的位置信息。如下图所示,SBT有两种类型和两种位置。
对SBT-V(或SBT-H),TU的宽(或高)等于CU宽(或高)的1/2或1/4,也就是按2:2划分或1:3/3:1划分。2:2划分类似于二叉树(BT)划分,1:3/3:1划分类似于不对称二叉树(ABT)划分。在ABT划分中只有较小的那个区域包含非零残差。如果CU的某个维度是8则不允许在该维度上使用1:3/3:1划分。对于一个CU至多有8种SBT模式。
enum SbtIdx
{
SBT_OFF_DCT = 0,
SBT_VER_HALF = 1,
SBT_HOR_HALF = 2,
SBT_VER_QUAD = 3,
SBT_HOR_QUAD = 4,
NUMBER_SBT_IDX,
SBT_OFF_MTS, //note: must be after all SBT modes, only used in fast algorithm to discern the best mode is inter EMT
};
enum SbtPos
{
SBT_POS0 = 0,
SBT_POS1 = 1,
NUMBER_SBT_POS
};
对亮度变换块使用SBT-V和SBT-H模式时需要根据其位置选择变换核(Position-dependent transform core selection),色度TU通常使用DCT-2变换。对于SBT每种位置下水平和垂直变化如上图所示。例如对于SBT-V位置0水平变换是DCT-8垂直变换是DST-7。当TU的某个边大于32时其水平和垂直变换都是DCT-2。因此SBT指定了TU tiling,cbf和残差块的水平垂直变换类型。
#if JVET_N0866_UNIF_TRFM_SEL_IMPL_MTS_ISP
if (isSBT)
#else
if( tu.cu->sbtInfo && compID == COMPONENT_Y )
#endif
{
uint8_t sbtIdx = tu.cu->getSbtIdx();
uint8_t sbtPos = tu.cu->getSbtPos();
if( sbtIdx == SBT_VER_HALF || sbtIdx == SBT_VER_QUAD )
{
assert( tu.lwidth() <= MTS_INTER_MAX_CU_SIZE );
if( tu.lheight() > MTS_INTER_MAX_CU_SIZE )
{//!<当TU的某个边大于32时其水平和垂直变换都是DCT-2
trTypeHor = trTypeVer = DCT2;
}
else
{
if( sbtPos == SBT_POS0 ) { trTypeHor = DCT8; trTypeVer = DST7; } //!<SBT-V,position 0
else { trTypeHor = DST7; trTypeVer = DST7; } //!<SBT-V,position 1
}
}
else
{
assert( tu.lheight() <= MTS_INTER_MAX_CU_SIZE );
if( tu.lwidth() > MTS_INTER_MAX_CU_SIZE )
{//!<当TU的某个边大于32时其水平和垂直变换都是DCT-2
trTypeHor = trTypeVer = DCT2;
}
else
{
if( sbtPos == SBT_POS0 ) { trTypeHor = DST7; trTypeVer = DCT8; } //!<SBT-H,position 0
else { trTypeHor = DST7; trTypeVer = DST7; } //!<SBT-H,position 1
}
}
return;
}
在SPS中需要一个变量maxSbtSize 表示SBT能应用的最大CU size。在VTM5中,对于HD和4K序列maxSbtSize =64,对于更小分辨率的序列maxSbtSize =32。
当CU帧间预测时使用CIIP模式或TPM模式时则不允许使用SBT模式。
参考
JVET-N1002
JVET-N0866
感兴趣的请关注微信公众号Video Coding