diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 7a9b4c995635d9830a587d1d28a5338212626ba7..1d878b747d9432f3845c09f6a4cddb861e0d6cd9 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1143,49 +1143,85 @@ Defines the depth of the TU tree for inter CUs. \Option{MaxMTTHierarchyDepth} & %\ShortOption{\None} & \Default{3} & -Defines the maximum depth of the multi-type tree for inter slices. +Defines the initial maximum depth of the multi-type tree for inter slices. \\ \Option{MaxMTTHierarchyDepthI} & %\ShortOption{\None} & \Default{3} & -Defines the maximum depth of the multi-type tree for intra slices. +Defines the initial maximum depth of the multi-type tree for intra slices. \\ \Option{MaxMTTHierarchyDepthISliceC} & %\ShortOption{\None} & \Default{3} & -Defines the maximum depth of the multi-type tree in dual tree for chroma components. +Defines the initial maximum depth of the multi-type tree in dual tree for chroma components. \\ \Option{MaxMTTHierarchyDepthISliceL} & %\ShortOption{\None} & \Default{3} & -Defines the maximum depth of the multi-type tree in dual tree for luma component. +Defines the initial maximum depth of the multi-type tree in dual tree for luma component. \\ \Option{MinQTChromaISlice} & %\ShortOption{\None} & \Default{4} & -Defines the minimum size of the quad tree in dual tree for chroma components. +Defines the initial minimum size of the quad tree in dual tree for chroma components. \\ \Option{MinQTISlice} & %\ShortOption{\None} & \Default{8} & -Defines the minimum size of the quad tree for intra slices. +Defines the initial minimum size of the quad tree for intra slices. \\ \Option{MinQTLumaISlice} & %\ShortOption{\None} & \Default{8} & -Defines the minimum size of the quad tree in dual tree for luma component. +Defines the initial minimum size of the quad tree in dual tree for luma component. \\ \Option{MinQTNonISlice} & %\ShortOption{\None} & \Default{8} & -Defines the minimum size of the quad tree for inter slices. +Defines the initial minimum size of the quad tree for inter slices. +\\ + +\Option{MaxBTLumaISlice} & +%\ShortOption{\None} & +\Default{32} & +Defines the initial maximum size of the binary tree in dual tree for luma component. +\\ + +\Option{MaxBTChromaISlice} & +%\ShortOption{\None} & +\Default{64} & +Defines the initial maximum size of the binary tree in dual tree for chroma components. +\\ + +\Option{MaxBTNonISlice} & +%\ShortOption{\None} & +\Default{128} & +Defines the initial maximum size of the binary tree for inter slices. +\\ + +\Option{MaxTTLumaISlice} & +%\ShortOption{\None} & +\Default{32} & +Defines the initial maximum size of the tenary tree in dual tree for luma component. +\\ + +\Option{MaxTTChromaISlice} & +%\ShortOption{\None} & +\Default{32} & +Defines the initial maximum size of the tenary tree in dual tree for chroma components. +\\ + +\Option{MaxTTNonISlice} & +%\ShortOption{\None} & +\Default{64} & +Defines the initial maximum size of the tenary tree for inter slices. \\ \end{OptionTableNoShorthand} diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 4f182afe7567b7d042a8c278c6bcc49c590d3f63..7306093e91a3088be6258f2a06415d8732b41960 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -415,6 +415,10 @@ void EncApp::xInitLibCfg() m_cEncLib.setUseSplitConsOverride ( m_SplitConsOverrideEnabledFlag ); m_cEncLib.setMinQTSizes ( m_uiMinQT ); m_cEncLib.setMaxMTTHierarchyDepth ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma ); +#if JVET_Q0330_BLOCK_PARTITION + m_cEncLib.setMaxBTSizes ( m_uiMaxBT ); + m_cEncLib.setMaxTTSizes ( m_uiMaxTT ); +#endif m_cEncLib.setDualITree ( m_dualTree ); m_cEncLib.setLFNST ( m_LFNST ); m_cEncLib.setUseFastLFNST ( m_useFastLFNST ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 499f048baac932dba4d247dc733cc5f4ca584ae6..6d2008e1c7b5748b7e183bc9071d1cebbff4fa46 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -900,6 +900,14 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("MaxMTTHierarchyDepthI", m_uiMaxMTTHierarchyDepthI, 3u, "MaxMTTHierarchyDepthI") ("MaxMTTHierarchyDepthISliceL", m_uiMaxMTTHierarchyDepthI, 3u, "MaxMTTHierarchyDepthISliceL") ("MaxMTTHierarchyDepthISliceC", m_uiMaxMTTHierarchyDepthIChroma, 3u, "MaxMTTHierarchyDepthISliceC") +#if JVET_Q0330_BLOCK_PARTITION + ("MaxBTLumaISlice", m_uiMaxBT[0], 32u, "MaxBTLumaISlice") + ("MaxBTChromaISlice", m_uiMaxBT[2], 64u, "MaxBTChromaISlice") + ("MaxBTNonISlice", m_uiMaxBT[1], 128u, "MaxBTNonISlice") + ("MaxTTLumaISlice", m_uiMaxTT[0], 32u, "MaxTTLumaISlice") + ("MaxTTChromaISlice", m_uiMaxTT[2], 32u, "MaxTTChromaISlice") + ("MaxTTNonISlice", m_uiMaxTT[1], 64u, "MaxTTNonISlice") +#endif ("DualITree", m_dualTree, false, "Use separate QTBT trees for intra slice luma and chroma channel types") ( "LFNST", m_LFNST, false, "Enable LFNST (0:off, 1:on) [default: off]" ) ( "FastLFNST", m_useFastLFNST, false, "Fast methods for LFNST" ) @@ -2594,6 +2602,20 @@ bool EncAppCfg::xCheckParameter() xConfirmPara( (m_uiMaxCUHeight >> m_uiMaxCUDepth) < 4, "Minimum partition height size should be larger than or equal to 8"); xConfirmPara( m_uiMaxCUWidth < 16, "Maximum partition width size should be larger than or equal to 16"); xConfirmPara( m_uiMaxCUHeight < 16, "Maximum partition height size should be larger than or equal to 16"); +#if JVET_Q0330_BLOCK_PARTITION + xConfirmPara( m_uiMaxBT[0] < m_uiMinQT[0], "Maximum BT size for luma block in I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxBT[0] > m_uiCTUSize, "Maximum BT size for luma block in I slice should be smaller than or equal to CTUSize"); + xConfirmPara( m_uiMaxBT[1] < m_uiMinQT[1], "Maximum BT size for luma block in non I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxBT[1] > m_uiCTUSize, "Maximum BT size for luma block in non I slice should be smaller than or equal to CTUSize"); + xConfirmPara( m_uiMaxBT[2] < m_uiMinQT[2], "Maximum BT size for chroma block in I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxBT[2] > m_uiCTUSize, "Maximum BT size for chroma block in I slice should be smaller than or equal to CTUSize"); + xConfirmPara( m_uiMaxTT[0] < m_uiMinQT[0], "Maximum TT size for luma block in I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxTT[0] > m_uiCTUSize, "Maximum TT size for luma block in I slice should be smaller than or equal to CTUSize"); + xConfirmPara( m_uiMaxTT[1] < m_uiMinQT[1], "Maximum TT size for luma block in non I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxTT[1] > m_uiCTUSize, "Maximum TT size for luma block in non I slice should be smaller than or equal to CTUSize"); + xConfirmPara( m_uiMaxTT[2] < m_uiMinQT[2], "Maximum TT size for chroma block in I slice should be larger than minimum QT size"); + xConfirmPara( m_uiMaxTT[2] > m_uiCTUSize, "Maximum TT size for chroma block in I slice should be smaller than or equal to CTUSize"); +#endif xConfirmPara( (m_iSourceWidth % (std::max(8, int(m_uiMaxCUWidth >> (m_uiMaxCUDepth - 1))))) != 0, "Resulting coded frame width must be a multiple of Max(8, the minimum CU size)"); xConfirmPara( (m_iSourceHeight % (std::max(8, int(m_uiMaxCUHeight >> (m_uiMaxCUDepth - 1))))) != 0, "Resulting coded frame height must be a multiple of Max(8, the minimum CU size)"); xConfirmPara( m_log2MaxTbSize > 6, "Log2MaxTbSize must be 6 or smaller." ); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 175ab51327a2ae9abd5bc28bbd9b11af64d34fad..5f830bf650dd5eb888f7f3337239249f6e3bcedb 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -299,6 +299,10 @@ protected: unsigned m_uiMaxMTTHierarchyDepth; unsigned m_uiMaxMTTHierarchyDepthI; unsigned m_uiMaxMTTHierarchyDepthIChroma; +#if JVET_Q0330_BLOCK_PARTITION + unsigned m_uiMaxBT[3]; + unsigned m_uiMaxTT[3]; +#endif bool m_dualTree; bool m_LFNST; bool m_useFastLFNST; diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 4f1864b5f21ee9cd9fb760c1feed4ece53561611..90d7f066b4c1c39e2e4496f8f8db3653e0dc778a 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -381,19 +381,24 @@ static const int DMVR_NUM_ITERATION = 2; //QTBT high level parameters //for I slice luma CTB configuration para. static const int MAX_BT_DEPTH = 4; ///< <=7 +#if !JVET_Q0330_BLOCK_PARTITION static const int MAX_BT_SIZE = 32; ///< [1<<MIN_QT_SIZE, 1<<CTU_LOG2] static const int MAX_TT_SIZE = 32; ///< [1<<MIN_QT_SIZE, 1<<CTU_LOG2] static const int MAX_TT_SIZE_C = 32; ///< [1<<MIN_QT_SIZE, 1<<CTU_LOG2] +#endif //for P/B slice CTU config. para. static const int MAX_BT_DEPTH_INTER = 4; ///< <=7 +#if !JVET_Q0330_BLOCK_PARTITION static const int MAX_BT_SIZE_INTER = 128; ///< for initialization, [1<<MIN_BT_SIZE_INTER, 1<<CTU_LOG2] - +#endif //for I slice chroma CTB configuration para. (in luma samples) static const int MAX_BT_DEPTH_C = 0; ///< <=7 +#if !JVET_Q0330_BLOCK_PARTITION static const int MAX_BT_SIZE_C = 64; ///< [1<<MIN_QT_SIZE_C, 1<<CTU_LOG2], in luma samples static const int MAX_TT_SIZE_INTER = 64; ///< for initialization, [1<<MIN_CU_LOG2, 64] +#endif static const int MIN_DUALTREE_CHROMA_WIDTH = 4; static const int MIN_DUALTREE_CHROMA_SIZE = 16; static const SplitSeries SPLIT_BITS = 5; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index c1fc4bd09a1be0aabeb02029217e23890176f570..6d39c007b2074161b30e8202528c3e3a60e408c0 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1915,8 +1915,13 @@ SPS::SPS() , m_CTUSize(0) , m_minQT{ 0, 0, 0 } , m_maxMTTHierarchyDepth{ MAX_BT_DEPTH, MAX_BT_DEPTH_INTER, MAX_BT_DEPTH_C } +#if JVET_Q0330_BLOCK_PARTITION +, m_maxBTSize{ 0, 0, 0 } +, m_maxTTSize{ 0, 0, 0 } +#else , m_maxBTSize{ MAX_BT_SIZE, MAX_BT_SIZE_INTER, MAX_BT_SIZE_C } , m_maxTTSize{ MAX_TT_SIZE, MAX_TT_SIZE_INTER, MAX_TT_SIZE_C } +#endif , m_uiMaxCUWidth ( 32) , m_uiMaxCUHeight ( 32) , m_uiMaxCodingDepth ( 3) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index bd2ecba44893536a6ea105816f4e538729a560b9..b8fc2a85410d787e74bb265dcf9274caf79fa364 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_Q0330_BLOCK_PARTITION 1 // JVET-Q0330: fix the block partitioning at picture boundary + #define JVET_Q0417_CONSTRAINT_SPS_VB_PRESENT_FLAG 1 // JVET_Q0417: a constraint on the value of sps_virtual_boundaries_present_flag based on res_change_in_clvs_allowed_flag #define JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT 1 // JVET-Q0179: Scaling window size constraint for constraining worst case memory bandwidth diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp index 65803b7063ac660785fe203b667e3df49efbf825..70e9059ed9fde44ed5f27c58ca6d0dcf1589a173 100644 --- a/source/Lib/CommonLib/UnitPartitioner.cpp +++ b/source/Lib/CommonLib/UnitPartitioner.cpp @@ -411,6 +411,9 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca if (areaC && areaC->width == 4) canBv = false; #else if (chType == CHANNEL_TYPE_CHROMA && areaC.width == 4) canBv = false; +#endif +#if JVET_Q0330_BLOCK_PARTITION + if( !canBh && !canBv && !canQt ) canQt = true; #endif return; } @@ -554,7 +557,11 @@ PartSplit QTBTPartitioner::getImplicitSplit( const CodingStructure &cs ) const CompArea& area = currArea().Y(); const unsigned maxBtSize = cs.pcv->getMaxBtSize( *cs.slice, chType ); +#if JVET_Q0330_BLOCK_PARTITION + const bool isBtAllowed = area.width <= maxBtSize && area.height <= maxBtSize && currMtDepth < (cs.pcv->getMaxBtDepth(*cs.slice, chType) + currImplicitBtDepth); +#else const bool isBtAllowed = area.width <= maxBtSize && area.height <= maxBtSize; +#endif const unsigned minQtSize = cs.pcv->getMinQtSize( *cs.slice, chType ); const bool isQtAllowed = area.width > minQtSize && area.height > minQtSize && currBtDepth == 0; @@ -562,11 +569,19 @@ PartSplit QTBTPartitioner::getImplicitSplit( const CodingStructure &cs ) { split = CU_QUAD_SPLIT; } +#if JVET_Q0330_BLOCK_PARTITION + else if( !isBlInPic && isBtAllowed && area.width <= MAX_TB_SIZEY ) +#else else if( !isBlInPic && isBtAllowed ) +#endif { split = CU_HORZ_SPLIT; } +#if JVET_Q0330_BLOCK_PARTITION + else if( !isTrInPic && isBtAllowed && area.height <= MAX_TB_SIZEY ) +#else else if( !isTrInPic && isBtAllowed ) +#endif { split = CU_VERT_SPLIT; } @@ -578,10 +593,17 @@ PartSplit QTBTPartitioner::getImplicitSplit( const CodingStructure &cs ) { split = CU_QUAD_SPLIT; } +#if JVET_Q0330_BLOCK_PARTITION + if( (!isBlInPic || !isTrInPic) && split == CU_DONT_SPLIT ) + { + split = CU_QUAD_SPLIT; + } +#else if ((!isBlInPic || !isTrInPic) && (currArea().Y().width > MAX_TB_SIZEY || currArea().Y().height > MAX_TB_SIZEY)) { split = CU_QUAD_SPLIT; } +#endif } m_partStack.back().checkdIfImplicit = true; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index d340491c911b88a3c8248e247dfbe817aa15b432..f3eda13cdaf1b101d8b5051f66b226fae030a5d8 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -289,6 +289,10 @@ protected: uint32_t m_subPicId[MAX_NUM_SUB_PICS]; bool m_useSplitConsOverride; unsigned m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma +#if JVET_Q0330_BLOCK_PARTITION + unsigned m_uiMaxBT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma + unsigned m_uiMaxTT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma +#endif unsigned m_uiMaxMTTHierarchyDepth; unsigned m_uiMaxMTTHierarchyDepthI; unsigned m_uiMaxMTTHierarchyDepthIChroma; @@ -944,6 +948,10 @@ public: void setCTUSize ( unsigned u ) { m_CTUSize = u; } void setMinQTSizes ( unsigned* minQT) { m_uiMinQT[0] = minQT[0]; m_uiMinQT[1] = minQT[1]; m_uiMinQT[2] = minQT[2]; } +#if JVET_Q0330_BLOCK_PARTITION + void setMaxBTSizes ( unsigned* maxBT) { m_uiMaxBT[0] = maxBT[0]; m_uiMaxBT[1] = maxBT[1]; m_uiMaxBT[2] = maxBT[2]; } + void setMaxTTSizes ( unsigned* maxTT) { m_uiMaxTT[0] = maxTT[0]; m_uiMaxTT[1] = maxTT[1]; m_uiMaxTT[2] = maxTT[2]; } +#endif void setMaxMTTHierarchyDepth ( unsigned uiMaxMTTHierarchyDepth, unsigned uiMaxMTTHierarchyDepthI, unsigned uiMaxMTTHierarchyDepthIChroma ) { m_uiMaxMTTHierarchyDepth = uiMaxMTTHierarchyDepth; m_uiMaxMTTHierarchyDepthI = uiMaxMTTHierarchyDepthI; m_uiMaxMTTHierarchyDepthIChroma = uiMaxMTTHierarchyDepthIChroma; } unsigned getMaxMTTHierarchyDepth () const { return m_uiMaxMTTHierarchyDepth; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 2ae0fdb16ae1a7009238e705fc6388316b39e84e..8a743fe3b98c628bd5873fb7a1390f13909883cb 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2364,6 +2364,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 ) { +#if JVET_Q0330_BLOCK_PARTITION + const int MAX_BT_SIZE_INTER = 128; +#endif picHeader->setSplitConsOverrideFlag(true); double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] ); if( dBlkSize < AMAXBT_TH32 || pcPic->cs->sps->getCTUSize()==32 ) diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index ba649e28cdd8009097f1871105b2c333c716c97f..85f8d600ac658dff9e3547194aa18e34fb8daee3 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1092,6 +1092,10 @@ void EncLib::xInitSPS( SPS& sps, VPS& vps ) sps.setSplitConsOverrideEnabledFlag ( m_useSplitConsOverride ); sps.setMinQTSizes ( m_uiMinQT ); sps.setMaxMTTHierarchyDepth ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma ); +#if JVET_Q0330_BLOCK_PARTITION + sps.setMaxBTSize( m_uiMaxBT[1], m_uiMaxBT[0], m_uiMaxBT[2] ); + sps.setMaxTTSize( m_uiMaxTT[1], m_uiMaxTT[0], m_uiMaxTT[2] ); +#else unsigned maxBtSize[3], maxTtSize[3]; memcpy(maxBtSize, m_uiMinQT, sizeof(maxBtSize)); memcpy(maxTtSize, m_uiMinQT, sizeof(maxTtSize)); @@ -1112,6 +1116,7 @@ void EncLib::xInitSPS( SPS& sps, VPS& vps ) } sps.setMaxBTSize ( maxBtSize[1], maxBtSize[0], maxBtSize[2] ); sps.setMaxTTSize ( maxTtSize[1], maxTtSize[0], maxTtSize[2] ); +#endif sps.setIDRRefParamListPresent ( m_idrRefParamList ); sps.setUseDualITree ( m_dualITree ); sps.setUseLFNST ( m_LFNST );