diff --git a/CMakeLists.txt b/CMakeLists.txt index f341203e4ab01c05be786b6484571d5b59568ee6..2d59e741e2bc1a55a25bcd53674cbf8ad515f974 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,6 @@ endif() set( EXTENSION_360_VIDEO OFF CACHE BOOL "If EXTENSION_360_VIDEO is on, 360Lib will be added" ) set( SET_ENABLE_TRACING OFF CACHE BOOL "Set ENABLE_TRACING as a compiler flag" ) set( ENABLE_TRACING OFF CACHE BOOL "If SET_ENABLE_TRACING is on, it will be set to this value" ) -set( ENABLE_VTM OFF CACHE BOOL "If ENABLE_VTM is on, the software will be compiled as VTM" ) if( CMAKE_COMPILER_IS_GNUCC ) set( BUILD_STATIC OFF CACHE BOOL "Build static executables" ) diff --git a/Makefile b/Makefile index 49169a7be2f6c4fe207cef1f66aee1a4c538fd7c..b1d03c555c91bc07e2c55fbdd1ac97abcc5a91aa 100644 --- a/Makefile +++ b/Makefile @@ -63,10 +63,6 @@ ifneq ($(verbose),) CMAKE_OPTIONS += -DCMAKE_VERBOSE_MAKEFILE=ON endif -ifneq ($(enable-vtm),) -CMAKE_OPTIONS += -DENABLE_VTM=ON -endif - ifneq ($(enable-tracing),) CONFIG_OPTIONS += -DSET_ENABLE_TRACING=ON -DENABLE_TRACING=$(enable-tracing) endif diff --git a/source/App/DecoderAnalyserApp/CMakeLists.txt b/source/App/DecoderAnalyserApp/CMakeLists.txt index f6b036a19763aecf1ab71d00aedb92244ac68634..ad272ca1f34efd94444f2a9c1a750c7d4c0fecc3 100644 --- a/source/App/DecoderAnalyserApp/CMakeLists.txt +++ b/source/App/DecoderAnalyserApp/CMakeLists.txt @@ -27,10 +27,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions( ${EXE_NAME} PUBLIC RExt__DECODER_DEBUG_BIT_STATISTICS=1 ) target_compile_definitions( ${EXE_NAME} PUBLIC RExt__DECODER_DEBUG_TOOL_STATISTICS=1 ) -if( ENABLE_VTM ) - target_compile_definitions( ${EXE_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( SET_ENABLE_TRACING ) if( ENABLE_TRACING ) target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_TRACING=1 ) diff --git a/source/App/DecoderApp/CMakeLists.txt b/source/App/DecoderApp/CMakeLists.txt index 0e36d288f490cc9d795b254e54f9fdaf90bb0cd5..4e71c5c1e139ad10e15b9a973624f2fa2ea70274 100644 --- a/source/App/DecoderApp/CMakeLists.txt +++ b/source/App/DecoderApp/CMakeLists.txt @@ -25,11 +25,6 @@ endif() add_executable( ${EXE_NAME} ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -if( ENABLE_VTM ) - target_compile_definitions( ${EXE_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - - if( SET_ENABLE_TRACING ) if( ENABLE_TRACING ) target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_TRACING=1 ) diff --git a/source/App/DecoderApp/decmain.cpp b/source/App/DecoderApp/decmain.cpp index 7a876635bbb711ed53b00b51d1cd92b67e220cbb..70470d42a109ef4fba8e93427e2e3a9d958662a0 100644 --- a/source/App/DecoderApp/decmain.cpp +++ b/source/App/DecoderApp/decmain.cpp @@ -54,7 +54,7 @@ int main(int argc, char* argv[]) // print information fprintf( stdout, "\n" ); - fprintf( stdout, "VVCSoftware: BMS Decoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); + fprintf( stdout, "VVCSoftware: VTM Decoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); fprintf( stdout, NVM_ONOS ); fprintf( stdout, NVM_COMPILEDBY ); fprintf( stdout, NVM_BITS ); diff --git a/source/App/EncoderApp/CMakeLists.txt b/source/App/EncoderApp/CMakeLists.txt index d4b240ea68159a975c0529dcdb8eb158408a0649..2299bcf8f1987839181ad36b53cba3e95c844042 100644 --- a/source/App/EncoderApp/CMakeLists.txt +++ b/source/App/EncoderApp/CMakeLists.txt @@ -27,10 +27,6 @@ endif() add_executable( ${EXE_NAME} ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -if( ENABLE_VTM ) - target_compile_definitions( ${EXE_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( SET_ENABLE_TRACING ) if( ENABLE_TRACING ) target_compile_definitions( ${EXE_NAME} PUBLIC ENABLE_TRACING=1 ) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index dba92e5f4c7e66e372a9df3d748621a55ef5913a..ab7fcde8ec6df67dad3d9bf65d03174e30a64e04 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -213,6 +213,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setRDpenalty ( m_rdPenalty ); m_cEncLib.setQTBT ( m_QTBT ); m_cEncLib.setCTUSize ( m_uiCTUSize ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + m_cEncLib.setUseSplitConsOverride ( m_SplitConsOverrideEnabledFlag ); +#endif m_cEncLib.setMinQTSizes ( m_uiMinQT ); m_cEncLib.setMaxBTDepth ( m_uiMaxBTDepth, m_uiMaxBTDepthI, m_uiMaxBTDepthIChroma ); m_cEncLib.setDualITree ( m_dualTree ); @@ -246,6 +249,18 @@ void EncApp::xInitLibCfg() m_cEncLib.setUseGBi ( m_GBi ); m_cEncLib.setUseGBiFast ( m_GBiFast ); #endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + m_cEncLib.setUseLadf ( m_LadfEnabed ); + if ( m_LadfEnabed ) + { + m_cEncLib.setLadfNumIntervals ( m_LadfNumIntervals); + for ( int k = 0; k < m_LadfNumIntervals; k++ ) + { + m_cEncLib.setLadfQpOffset( m_LadfQpOffset[k], k ); + m_cEncLib.setLadfIntervalLowerBound(m_LadfIntervalLowerBound[k], k); + } + } +#endif // ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here m_cEncLib.setMaxCUWidth ( m_QTBT ? m_uiCTUSize : m_uiMaxCUWidth ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 9b4797641ad5af99e5b98a390417a44405ab8c87..fc12314b2aeedd2f4357acd99e0cba4fe8f0f06d 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -699,6 +699,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<bool> cfg_timeCodeSeiHoursFlag (0, 1, 0, MAX_TIMECODE_SEI_SETS); SMultiValueInput<int> cfg_timeCodeSeiTimeOffsetLength (0, 31, 0, MAX_TIMECODE_SEI_SETS); SMultiValueInput<int> cfg_timeCodeSeiTimeOffsetValue (std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), 0, MAX_TIMECODE_SEI_SETS); +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + const int defaultLadfQpOffset[3] = { 1, 0, 1 }; + const int defaultLadfIntervalLowerBound[2] = { 350, 833 }; + SMultiValueInput<int> cfg_LadfQpOffset ( -MAX_QP, MAX_QP, 2, MAX_LADF_INTERVALS, defaultLadfQpOffset, 3 ); + SMultiValueInput<int> cfg_LadfIntervalLowerBound ( 0, std::numeric_limits<int>::max(), 1, MAX_LADF_INTERVALS - 1, defaultLadfIntervalLowerBound, 2 ); +#endif int warnUnknowParameter = 0; #if ENABLE_TRACING @@ -796,6 +802,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("QTBT", m_QTBT, false, "Enable QTBT (0:off, 1:on) [default: off]") ("MTT", m_MTT, 0u, "Multi type tree type (0: off, 1:QTBT + triple split) [default: 0]") ("CTUSize", m_uiCTUSize, 128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]") +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + ("EnablePartitionConstraintsOverride", m_SplitConsOverrideEnabledFlag, true, "Enable partition constraints override") +#endif ("MinQTISlice", m_uiMinQT[0], 8u, "MinQTISlice") ("MinQTLumaISlice", m_uiMinQT[0], 8u, "MinQTLumaISlice") ("MinQTChromaISlice", m_uiMinQT[2], 4u, "MinQTChromaISlice") @@ -850,6 +859,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #if JVET_L0646_GBI ("GBi", m_GBi, false, "Enable Generalized Bi-prediction(GBi)") ("GBiFast", m_GBiFast, false, "Fast methods for Generalized Bi-prediction(GBi)\n") +#endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + ("LADF", m_LadfEnabed, false, "Luma adaptive deblocking filter QP Offset(L0414)") + ("LadfNumIntervals", m_LadfNumIntervals, 3, "LADF number of intervals (2-5, inclusive)") + ("LadfQpOffset", cfg_LadfQpOffset, cfg_LadfQpOffset, "LADF QP offset") + ("LadfIntervalLowerBound", cfg_LadfIntervalLowerBound, cfg_LadfIntervalLowerBound, "LADF lower bound for 2nd lowest interval") #endif // ADD_NEW_TOOL : (encoder app) add parsing parameters here @@ -1686,6 +1701,19 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) } #endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + if ( m_LadfEnabed ) + { + CHECK( m_LadfNumIntervals != cfg_LadfQpOffset.values.size(), "size of LadfQpOffset must be equal to LadfNumIntervals"); + CHECK( m_LadfNumIntervals - 1 != cfg_LadfIntervalLowerBound.values.size(), "size of LadfIntervalLowerBound must be equal to LadfNumIntervals - 1"); + m_LadfQpOffset = cfg_LadfQpOffset.values; + for (int k = 1; k < m_LadfNumIntervals; k++) + { + m_LadfIntervalLowerBound[k] = cfg_LadfIntervalLowerBound.values[k - 1]; + } + } +#endif + // reading external dQP description from file if ( !m_dQPFileName.empty() ) { @@ -1835,7 +1863,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_uiLog2DiffMaxMinCodingBlockSize = m_uiMaxCodingDepth; m_uiMaxCUWidth = m_uiMaxCUHeight = m_uiCTUSize; m_uiMaxCUDepth = m_uiMaxCodingDepth; +#if !JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT m_uiLog2DiffMaxMinCodingBlockSize = m_uiMaxCUDepth - 1; +#endif } // check validity of input parameters @@ -1993,6 +2023,9 @@ bool EncAppCfg::xCheckParameter() #endif +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + xConfirmPara( m_useAMaxBT && !m_SplitConsOverrideEnabledFlag, "AMaxBt can only be used with PartitionConstriantsOverride enabled" ); +#endif xConfirmPara( m_useAMaxBT && !m_QTBT, "AMaxBT can only be used with QTBT!" ); @@ -3131,6 +3164,9 @@ void EncAppCfg::xPrintParameter() #if JVET_L0646_GBI msg( VERBOSE, "GBi:%d ", m_GBi ); msg( VERBOSE, "GBiFast:%d ", m_GBiFast ); +#endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + msg( VERBOSE, "LADF:%d ", m_LadfEnabed ); #endif } // ADD_NEW_TOOL (add some output indicating the usage of tools) diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 42a6aaf618e2ad76b16a8f7e6de2e896216eba4e..712a0e1276075c1389a703d31eba94034b292c90 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -198,6 +198,9 @@ protected: // coding unit (CU) definition bool m_QTBT; unsigned m_uiCTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_SplitConsOverrideEnabledFlag; +#endif unsigned m_uiMinQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_uiMaxBTDepth; unsigned m_uiMaxBTDepthI; @@ -227,6 +230,12 @@ protected: #if JVET_L0646_GBI bool m_GBi; bool m_GBiFast; +#endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + bool m_LadfEnabed; + int m_LadfNumIntervals; + std::vector<int> m_LadfQpOffset; + int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS]; #endif // ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here diff --git a/source/App/EncoderApp/encmain.cpp b/source/App/EncoderApp/encmain.cpp index ddc89e4ee542cee5bc8a2db83d3a75ac0d0fdeba..1c691efd98864d5959bed04dbc7691199c778bed 100644 --- a/source/App/EncoderApp/encmain.cpp +++ b/source/App/EncoderApp/encmain.cpp @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) { // print information fprintf( stdout, "\n" ); - fprintf( stdout, "VVCSoftware: BMS Encoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); + fprintf( stdout, "VVCSoftware: VTM Encoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); fprintf( stdout, NVM_ONOS ); fprintf( stdout, NVM_COMPILEDBY ); fprintf( stdout, NVM_BITS ); diff --git a/source/App/SEIRemovalApp/seiremovalmain.cpp b/source/App/SEIRemovalApp/seiremovalmain.cpp index 54827f5ac7b37743d6bb0aa9f85019b052da7603..a536e8a802b93a323581593fd987909bd85b620c 100644 --- a/source/App/SEIRemovalApp/seiremovalmain.cpp +++ b/source/App/SEIRemovalApp/seiremovalmain.cpp @@ -54,7 +54,7 @@ int main(int argc, char* argv[]) // print information fprintf( stdout, "\n" ); - fprintf( stdout, "VVCSoftware: BMS Decoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); + fprintf( stdout, "VVCSoftware: VTM Decoder Version %s ", NEXT_SOFTWARE_VERSION /*NV_VERSION*/ ); fprintf( stdout, NVM_ONOS ); fprintf( stdout, NVM_COMPILEDBY ); fprintf( stdout, NVM_BITS ); diff --git a/source/Lib/CommonAnalyserLib/CMakeLists.txt b/source/Lib/CommonAnalyserLib/CMakeLists.txt index e0cdf5fa1e65f7bf849ba5296d9a0cd897260f68..e8b16075b0e043e46ac705aba60774cb22366242 100644 --- a/source/Lib/CommonAnalyserLib/CMakeLists.txt +++ b/source/Lib/CommonAnalyserLib/CMakeLists.txt @@ -48,10 +48,6 @@ set( INC_FILES ${BASE_INC_FILES} ${X86_INC_FILES} ${MD5_INC_FILES} ) add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) target_compile_definitions( ${LIB_NAME} PUBLIC RExt__DECODER_DEBUG_TOOL_STATISTICS=1 ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif() diff --git a/source/Lib/CommonLib/CMakeLists.txt b/source/Lib/CommonLib/CMakeLists.txt index 7a91672c034457ed88f3bf059fed4a539d1e7a7e..54bba996e1a60d13fcbe63b4bba30c4f8100c58e 100644 --- a/source/Lib/CommonLib/CMakeLists.txt +++ b/source/Lib/CommonLib/CMakeLists.txt @@ -47,10 +47,6 @@ set( INC_FILES ${BASE_INC_FILES} ${X86_INC_FILES} ${MD5_INC_FILES} ) # library add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif() diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 41d8be8c326c47a95fdbd4bf4792a44a5f2bd618..4f4bf797c30b0472c3cfd9c76fa8077bd6e82f83 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -258,6 +258,9 @@ static const int MAX_TU_SIZE = 128; static const int MAX_LOG2_TU_SIZE_PLUS_ONE = 8; ///< log2(MAX_TU_SIZE) + 1 static const int MAX_NUM_PARTS_IN_CTU = ( ( MAX_CU_SIZE * MAX_CU_SIZE ) >> ( MIN_CU_LOG2 << 1 ) ); static const int MAX_TR_SIZE = MAX_CU_SIZE; +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS +static const int MAX_TU_SIZE_FOR_PROFILE = 64; +#endif #if ENABLE_BMS static const int MAX_LOG2_DIFF_CU_TR_SIZE = 2; static const int MAX_CU_TILING_PARTITIONS = 1 << ( MAX_LOG2_DIFF_CU_TR_SIZE << 1 ); @@ -291,6 +294,16 @@ static const int AFFINE_MAX_NUM_V2 = 2; ///< max static const int AFFINE_MAX_NUM_COMB = 12; ///< max number of combined motion candidates static const int AFFINE_MIN_BLOCK_SIZE = 4; ///< Minimum affine MC block size + +#if JVET_L0054_MMVD +static const int MMVD_REFINE_STEP = 8; ///< max number of distance step +static const int MMVD_MAX_REFINE_NUM = (MMVD_REFINE_STEP * 4); ///< max number of candidate from a base candidate +static const int MMVD_BASE_MV_NUM = 2; ///< max number of base candidate +static const int MMVD_ADD_NUM = (MMVD_MAX_REFINE_NUM * MMVD_BASE_MV_NUM);///< total number of mmvd candidate +static const int MMVD_MRG_MAX_RD_NUM = MRG_MAX_NUM_CANDS; +static const int MMVD_MRG_MAX_RD_BUF_NUM = (MMVD_MRG_MAX_RD_NUM + 1);///< increase buffer size by 1 +#endif + #if JVET_L0274 static const int MAX_NUM_REG_BINS_4x4SUBBLOCK = 32; ///< max number of context-coded bins (incl. gt2 bins) per 4x4 subblock static const int MAX_NUM_GT2_BINS_4x4SUBBLOCK = 4; ///< max number of gt2 bins per 4x4 subblock @@ -308,6 +321,10 @@ static const int GBI_NUM = 5; ///< the static const int GBI_DEFAULT = ((uint8_t)(GBI_NUM >> 1)); ///< Default weighting index representing for w=0.5 static const int GBI_SIZE_CONSTRAINT = 256; ///< disabling GBi if cu size is smaller than 256 #endif +#if JVET_L0266_HMVP +static const int MAX_NUM_HMVP_CANDS = 6; ///< maximum number of HMVP candidates to be stored and used in merge list +static const int MAX_NUM_HMVP_AVMPCANDS = 4; ///< maximum number of HMVP candidates to be used in AMVP list +#endif #if W0038_DB_OPT static const int MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS = 8 ; @@ -361,7 +378,11 @@ static const double AMAXBT_TH64 = 30.0; static const int MAX_DELTA_QP = 7; ///< maximum supported delta QP value static const int MAX_TESTED_QPs = ( 1 + 1 + ( MAX_DELTA_QP << 1 ) ); ///< dqp=0 +- max_delta_qp + lossless mode +#if JVET_L0285_8BIT_TRANSFORM_CORE +static const int COM16_C806_TRANS_PREC = 0; +#else static const int COM16_C806_TRANS_PREC = 2; +#endif static const int NUM_MERGE_IDX_EXT_CTX = 5; static const unsigned E0104_ALF_MAX_TEMPLAYERID = 5; // define to zero to switch of code @@ -370,6 +391,10 @@ static const unsigned C806_ALF_TEMPPRED_NUM = 6; static const int NTAPS_LUMA = 8; ///< Number of taps for luma static const int NTAPS_CHROMA = 4; ///< Number of taps for chroma +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET +static const int MAX_LADF_INTERVALS = 5; /// max number of luma adaptive deblocking filter qp offset intervals +#endif + #if JVET_L0256_BIO static const int NTAPS_BILINEAR = 2; ///< Number of taps for bilinear filter #endif diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index 9f41baa2f13ebd3fb2c9912b3ec24a1ba834bde7..bbdc6f2ed935169ad7e1581664170a3c3d7bbd88 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -365,6 +365,9 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) CHECK( candIdx >= numValidMergeCand, "Merge candidate does not exist" ); pu.mergeFlag = true; +#if JVET_L0054_MMVD + pu.mmvdMergeFlag = false; +#endif pu.interDir = interDirNeighbours[candIdx]; pu.mergeIdx = candIdx; pu.mergeType = mrgTypeNeighbours[candIdx]; @@ -384,3 +387,209 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) #endif } +#if JVET_L0054_MMVD +void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) +{ + const Slice &slice = *pu.cs->slice; + const int mvShift = VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; + const int refMvdCands[8] = { 1 << mvShift , 2 << mvShift , 4 << mvShift , 8 << mvShift , 16 << mvShift , 32 << mvShift, 64 << mvShift , 128 << mvShift }; + int fPosGroup = 0; + int fPosBaseIdx = 0; + int fPosStep = 0; + int tempIdx = 0; + int fPosPosition = 0; + Mv tempMv[2]; + + tempIdx = candIdx; + fPosGroup = tempIdx / (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); + tempIdx = tempIdx - fPosGroup * (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); + fPosBaseIdx = tempIdx / MMVD_MAX_REFINE_NUM; + tempIdx = tempIdx - fPosBaseIdx * (MMVD_MAX_REFINE_NUM); + fPosStep = tempIdx / 4; + fPosPosition = tempIdx - fPosStep * (4); + + const int offset = refMvdCands[fPosStep]; +#if !REMOVE_MV_ADAPT_PREC + const int highPrecList0 = mmvdBaseMv[fPosBaseIdx][0].mv.highPrec; + const int highPrecList1 = mmvdBaseMv[fPosBaseIdx][1].mv.highPrec; +#endif + const int refList0 = mmvdBaseMv[fPosBaseIdx][0].refIdx; + const int refList1 = mmvdBaseMv[fPosBaseIdx][1].refIdx; + + if ((refList0 != -1) && (refList1 != -1)) + { + const int poc0 = slice.getRefPOC(REF_PIC_LIST_0, refList0); + const int poc1 = slice.getRefPOC(REF_PIC_LIST_1, refList1); + const int currPoc = slice.getPOC(); + int refSign = 1; + + if ((poc0 - currPoc) * (currPoc - poc1) > 0) + { + refSign = -1; + } +#if REMOVE_MV_ADAPT_PREC + if (fPosPosition == 0) + { + tempMv[0] = Mv(offset, 0); + tempMv[1] = Mv(offset * refSign, 0); + } + else if (fPosPosition == 1) + { + tempMv[0] = Mv(-offset, 0); + tempMv[1] = Mv(-offset * refSign, 0); + } + else if (fPosPosition == 2) + { + tempMv[0] = Mv(0, offset); + tempMv[1] = Mv(0, offset * refSign); + } + else + { + tempMv[0] = Mv(0, -offset); + tempMv[1] = Mv(0, -offset * refSign); + } +#else + if (fPosPosition == 0) + { + tempMv[0] = Mv(offset, 0, highPrecList0); + tempMv[1] = Mv(offset * refSign, 0, highPrecList1); + } + else if (fPosPosition == 1) + { + tempMv[0] = Mv(-offset, 0, highPrecList0); + tempMv[1] = Mv(-offset * refSign, 0, highPrecList1); + } + else if (fPosPosition == 2) + { + tempMv[0] = Mv(0, offset, highPrecList0); + tempMv[1] = Mv(0, offset * refSign, highPrecList1); + } + else + { + tempMv[0] = Mv(0, -offset, highPrecList0); + tempMv[1] = Mv(0, -offset * refSign, highPrecList1); + } +#endif + if (abs(poc1 - currPoc) > abs(poc0 - currPoc)) + { + const int scale = PU::getDistScaleFactor(currPoc, poc0, currPoc, poc1); + if (scale != 4096) + { + tempMv[0] = tempMv[0].scaleMv(scale); + } + } + else if (abs(poc1 - currPoc) < abs(poc0 - currPoc)) + { + const int scale = PU::getDistScaleFactor(currPoc, poc1, currPoc, poc0); + if (scale != 4096) + { + tempMv[1] = tempMv[1].scaleMv(scale); + } + } + + pu.interDir = 3; + pu.mv[REF_PIC_LIST_0] = mmvdBaseMv[fPosBaseIdx][0].mv + tempMv[0]; + pu.refIdx[REF_PIC_LIST_0] = refList0; + pu.mv[REF_PIC_LIST_1] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1]; + pu.refIdx[REF_PIC_LIST_1] = refList1; + } + else if (refList0 != -1) + { +#if REMOVE_MV_ADAPT_PREC + if (fPosPosition == 0) + { + tempMv[0] = Mv(offset, 0); + } + else if (fPosPosition == 1) + { + tempMv[0] = Mv(-offset, 0); + } + else if (fPosPosition == 2) + { + tempMv[0] = Mv(0, offset); + } + else + { + tempMv[0] = Mv(0, -offset); + } +#else + if (fPosPosition == 0) + { + tempMv[0] = Mv(offset, 0, highPrecList0); + } + else if (fPosPosition == 1) + { + tempMv[0] = Mv(-offset, 0, highPrecList0); + } + else if (fPosPosition == 2) + { + tempMv[0] = Mv(0, offset, highPrecList0); + } + else + { + tempMv[0] = Mv(0, -offset, highPrecList0); + } +#endif + pu.interDir = 1; + pu.mv[REF_PIC_LIST_0] = mmvdBaseMv[fPosBaseIdx][0].mv + tempMv[0]; + pu.refIdx[REF_PIC_LIST_0] = refList0; + pu.mv[REF_PIC_LIST_1] = Mv(0, 0); + pu.refIdx[REF_PIC_LIST_1] = -1; + } + else if (refList1 != -1) + { +#if REMOVE_MV_ADAPT_PREC + if (fPosPosition == 0) + { + tempMv[1] = Mv(offset, 0); + } + else if (fPosPosition == 1) + { + tempMv[1] = Mv(-offset, 0); + } + else if (fPosPosition == 2) + { + tempMv[1] = Mv(0, offset); + } + else + { + tempMv[1] = Mv(0, -offset); + } +#else + if (fPosPosition == 0) + { + tempMv[1] = Mv(offset, 0, highPrecList1); + } + else if (fPosPosition == 1) + { + tempMv[1] = Mv(-offset, 0, highPrecList1); + } + else if (fPosPosition == 2) + { + tempMv[1] = Mv(0, offset, highPrecList1); + } + else + { + tempMv[1] = Mv(0, -offset, highPrecList1); + } +#endif + pu.interDir = 2; + pu.mv[REF_PIC_LIST_0] = Mv(0, 0); + pu.refIdx[REF_PIC_LIST_0] = -1; + pu.mv[REF_PIC_LIST_1] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1]; + pu.refIdx[REF_PIC_LIST_1] = refList1; + } + + pu.mmvdMergeFlag = true; + pu.mmvdMergeIdx = candIdx; + pu.mergeFlag = true; + pu.mergeIdx = candIdx; + pu.mergeType = MRG_TYPE_DEFAULT_N; + pu.mvd[REF_PIC_LIST_0] = Mv(); + pu.mvd[REF_PIC_LIST_1] = Mv(); + pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; + pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID; + pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID; + pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID; +} +#endif \ No newline at end of file diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index 58c8d8e5898b9222b1fa7529b6654b597c06ffed..f98d40a0190883c0de652daa87671730f511eef7 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -309,6 +309,10 @@ public: MotionBuf subPuMvpMiBuf; MotionBuf subPuMvpExtMiBuf; +#if JVET_L0054_MMVD + MvField mmvdBaseMv[MMVD_BASE_MV_NUM][2]; + void setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx); +#endif void setMergeInfo( PredictionUnit& pu, int candIdx ); }; diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 434e66e89c9de59b81126a4def2fbfdc28370c46..36f6118eaf38ddb98d48e980b40da6665321ee1c 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -313,7 +313,28 @@ const CtxSet ContextSetCfg::MergeIdx = ContextSetCfg::addCtxSet { CNU, CNU, CNU, CNU, CNU,}, #endif }); +#if JVET_L0054_MMVD +const CtxSet ContextSetCfg::MmvdFlag = ContextSetCfg::addCtxSet +({ + { 151, }, + { CNU, }, + { CNU, }, + }); +const CtxSet ContextSetCfg::MmvdMergeIdx = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + }); + +const CtxSet ContextSetCfg::MmvdStepMvpIdx = ContextSetCfg::addCtxSet +({ + { 184, }, + { CNU, }, + { CNU, }, + }); +#endif const CtxSet ContextSetCfg::PartSize = ContextSetCfg::addCtxSet ({ { 154, 139, 154, 154,}, diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h index 3e4679c06bd64c00f0f7611e8ca52e739902a135..3e08409e3475ef600e486ccfed9c35e40144ed1b 100644 --- a/source/Lib/CommonLib/Contexts.h +++ b/source/Lib/CommonLib/Contexts.h @@ -166,6 +166,11 @@ public: static const CtxSet DeltaQP; static const CtxSet InterDir; static const CtxSet RefPic; +#if JVET_L0054_MMVD + static const CtxSet MmvdFlag; + static const CtxSet MmvdMergeIdx; + static const CtxSet MmvdStepMvpIdx; +#endif static const CtxSet AffineFlag; static const CtxSet AffineType; static const CtxSet Mvd; diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp index f4b7522fcca5fa803b7c52569a6fd313297f1966..71f3397ba4c77f123ecb72901da7a6860ff204e1 100644 --- a/source/Lib/CommonLib/LoopFilter.cpp +++ b/source/Lib/CommonLib/LoopFilter.cpp @@ -560,6 +560,36 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De return ( ( abs( mvQ0.getHor() - mvP0.getHor() ) >= nThreshold ) || ( abs( mvQ0.getVer() - mvP0.getVer() ) >= nThreshold ) ) ? 1 : 0; } +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET +void LoopFilter::deriveLADFShift( const Pel* src, const int stride, int& shift, const DeblockEdgeDir edgeDir, const SPS sps ) +{ + uint32_t lumaLevel = 0; + shift = sps.getSpsNext().getLadfQpOffset(0); + + if (edgeDir == EDGE_VER) + { + lumaLevel = (src[0] + src[3*stride] + src[-1] + src[3*stride - 1]) >> 2; + } + else // (edgeDir == EDGE_HOR) + { + lumaLevel = (src[0] + src[3] + src[-stride] + src[-stride + 3]) >> 2; + } + + for ( int k = 1; k < sps.getSpsNext().getLadfNumIntervals(); k++ ) + { + const int th = sps.getSpsNext().getLadfIntervalLowerBound( k ); + if ( lumaLevel > th ) + { + shift = sps.getSpsNext().getLadfQpOffset( k ); + } + else + { + break; + } + } +} +#endif + void LoopFilter::xEdgeFilterLuma(const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge) { const CompArea& lumaArea = cu.block(COMPONENT_Y); @@ -645,6 +675,14 @@ void LoopFilter::xEdgeFilterLuma(const CodingUnit& cu, const DeblockEdgeDir edge iQP = (cuP.qp + cuQ.qp + 1) >> 1; +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + if ( sps.getSpsNext().getLadfEnabled() ) + { + int iShift = 0; + deriveLADFShift( piTmpSrc + iSrcStep * (iIdx*pelsInPart), iStride, iShift, edgeDir, sps ); + iQP += iShift; + } +#endif const int iIndexTC = Clip3(0, MAX_QP + DEFAULT_INTRA_TC_OFFSET, int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs - 1) + (tcOffsetDiv2 << 1))); const int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1)); diff --git a/source/Lib/CommonLib/LoopFilter.h b/source/Lib/CommonLib/LoopFilter.h index efe3a2c154163cfaf08c1d0e72fc8320ea61b24f..2a7cb9c028aa5ce1574fef9a338359e708ccb73b 100644 --- a/source/Lib/CommonLib/LoopFilter.h +++ b/source/Lib/CommonLib/LoopFilter.h @@ -62,7 +62,7 @@ private: private: /// CU-level deblocking function void xDeblockCU ( CodingUnit& cu, const DeblockEdgeDir edgeDir ); - + // set / get functions void xSetLoopfilterParam ( const CodingUnit& cu ); @@ -79,6 +79,9 @@ private: void xEdgeFilterLuma ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge ); void xEdgeFilterChroma ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge ); +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + void deriveLADFShift( const Pel* src, const int stride, int& shift, const DeblockEdgeDir edgeDir, const SPS sps ); +#endif inline void xPelFilterLuma ( Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const int iThrCut, const bool bFilterSecondP, const bool bFilterSecondQ, const ClpRng& clpRng ) const; inline void xPelFilterChroma ( Pel* piSrc, const int iOffset, const int tc, const bool bPartPNoFilter, const bool bPartQNoFilter, const ClpRng& clpRng ) const; diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h index 26fcb5a712797ddf09b3b2b262617542e8c8269d..c883e5f77ba05521e7bb7b2fcbcaab6dab093c75 100644 --- a/source/Lib/CommonLib/MotionInfo.h +++ b/source/Lib/CommonLib/MotionInfo.h @@ -162,7 +162,7 @@ public: } Mv* pAffineMv = &(m_mvAffine[0][0][0][0]); - for (int ui = 0; ui < 2 * 2 * 33 * 3; ++ui, ++pMv) + for (int ui = 0; ui < 2 * 2 * 33 * 3; ++ui, ++pAffineMv) { pAffineMv->set(0, 0); } @@ -208,5 +208,11 @@ public: } }; #endif - +#if JVET_L0266_HMVP +struct LutMotionCand +{ + MotionInfo* motionCand; + int currCnt; +}; +#endif #endif // __MOTIONINFO__ diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index 8a2ac97f5aa77a099147081b89a9110d5130b39a..0f74964b245ae6255ae2f88cab9b68c496c300e2 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -317,7 +317,11 @@ uint32_t deriveWeightIdxBits(uint8_t gbiIdx) // Note: align this with TEncSbac:: // initialize ROM variables void initROM() { +#if JVET_L0285_8BIT_TRANSFORM_CORE + int c; +#else int i, c; +#endif #if RExt__HIGH_BIT_DEPTH_SUPPORT { @@ -367,6 +371,7 @@ void initROM() g_aucLog2 [i] = c; } +#if !JVET_L0285_8BIT_TRANSFORM_CORE c = 2; //for the 2x2 transforms if QTBT is on const double PI = 3.14159265358979323846; @@ -410,6 +415,8 @@ void initROM() } c <<= 1; } +#endif + gp_sizeIdxInfo = new SizeIndexInfoLog2(); gp_sizeIdxInfo->init(MAX_CU_SIZE); @@ -611,7 +618,7 @@ const uint8_t g_aucTrSetHorz35[35] = //EMT threshold const uint32_t g_EmtSigNumThr = 2; - +#if !JVET_L0285_8BIT_TRANSFORM_CORE //EMT transform coeficient variable TMatrixCoeff g_aiTr2 [NUM_TRANS_TYPE][ 2][ 2]; TMatrixCoeff g_aiTr4 [NUM_TRANS_TYPE][ 4][ 4]; @@ -619,6 +626,7 @@ TMatrixCoeff g_aiTr8 [NUM_TRANS_TYPE][ 8][ 8]; TMatrixCoeff g_aiTr16 [NUM_TRANS_TYPE][ 16][ 16]; TMatrixCoeff g_aiTr32 [NUM_TRANS_TYPE][ 32][ 32]; TMatrixCoeff g_aiTr64 [NUM_TRANS_TYPE][ 64][ 64]; +#endif //-------------------------------------------------------------------------------------------------- //coefficients diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h index afbb242da407759e18c6aeeb871eb063a13e4678..ce3a6554ad7c93d5befd599a71527d1126e47e9e 100644 --- a/source/Lib/CommonLib/Rom.h +++ b/source/Lib/CommonLib/Rom.h @@ -128,13 +128,31 @@ extern const uint8_t g_aucTrSetHorz35[35]; extern const uint32_t g_EmtSigNumThr; +#if JVET_L0285_8BIT_TRANSFORM_CORE +extern const TMatrixCoeff g_trCoreDCT2P2 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 2][ 2]; +extern const TMatrixCoeff g_trCoreDCT2P4 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 4][ 4]; +extern const TMatrixCoeff g_trCoreDCT2P8 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 8][ 8]; +extern const TMatrixCoeff g_trCoreDCT2P16 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 16][ 16]; +extern const TMatrixCoeff g_trCoreDCT2P32 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 32][ 32]; +extern const TMatrixCoeff g_trCoreDCT2P64 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 64][ 64]; + +extern const TMatrixCoeff g_trCoreDCT8P4 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 4][ 4]; +extern const TMatrixCoeff g_trCoreDCT8P8 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 8][ 8]; +extern const TMatrixCoeff g_trCoreDCT8P16 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 16][ 16]; +extern const TMatrixCoeff g_trCoreDCT8P32 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 32][ 32]; + +extern const TMatrixCoeff g_trCoreDST7P4 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 4][ 4]; +extern const TMatrixCoeff g_trCoreDST7P8 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 8][ 8]; +extern const TMatrixCoeff g_trCoreDST7P16 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 16][ 16]; +extern const TMatrixCoeff g_trCoreDST7P32 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 32][ 32]; +#else extern TMatrixCoeff g_aiTr2 [NUM_TRANS_TYPE][ 2][ 2]; extern TMatrixCoeff g_aiTr4 [NUM_TRANS_TYPE][ 4][ 4]; extern TMatrixCoeff g_aiTr8 [NUM_TRANS_TYPE][ 8][ 8]; extern TMatrixCoeff g_aiTr16 [NUM_TRANS_TYPE][ 16][ 16]; extern TMatrixCoeff g_aiTr32 [NUM_TRANS_TYPE][ 32][ 32]; extern TMatrixCoeff g_aiTr64 [NUM_TRANS_TYPE][ 64][ 64]; - +#endif // ==================================================================================================================== // Decision tree templates diff --git a/source/Lib/CommonLib/RomTr.cpp b/source/Lib/CommonLib/RomTr.cpp index 4f2b3c3d869ec079129fe1b1b117f7d8d9abaaef..3cd8cd0826c1ef1ed660f67d388d0a80a4c9b55c 100644 --- a/source/Lib/CommonLib/RomTr.cpp +++ b/source/Lib/CommonLib/RomTr.cpp @@ -37,5 +37,396 @@ #include "Rom.h" +#if JVET_L0285_8BIT_TRANSFORM_CORE + +// DCT-2 +#define DEFINE_DCT2_P2_MATRIX(a) \ +{ \ + {a, a}, \ + {a, -a} \ +} + +#define DEFINE_DCT2_P4_MATRIX(a,b,c) \ +{ \ + { a, a, a, a}, \ + { b, c, -c, -b}, \ + { a, -a, -a, a}, \ + { c, -b, b, -c} \ +} + +#define DEFINE_DCT2_P8_MATRIX(a,b,c,d,e,f,g) \ +{ \ + { a, a, a, a, a, a, a, a}, \ + { d, e, f, g, -g, -f, -e, -d}, \ + { b, c, -c, -b, -b, -c, c, b}, \ + { e, -g, -d, -f, f, d, g, -e}, \ + { a, -a, -a, a, a, -a, -a, a}, \ + { f, -d, g, e, -e, -g, d, -f}, \ + { c, -b, b, -c, -c, b, -b, c}, \ + { g, -f, e, -d, d, -e, f, -g} \ +} + +#define DEFINE_DCT2_P16_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \ +{ \ + { a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a}, \ + { h, i, j, k, l, m, n, o, -o, -n, -m, -l, -k, -j, -i, -h}, \ + { d, e, f, g, -g, -f, -e, -d, -d, -e, -f, -g, g, f, e, d}, \ + { i, l, o, -m, -j, -h, -k, -n, n, k, h, j, m, -o, -l, -i}, \ + { b, c, -c, -b, -b, -c, c, b, b, c, -c, -b, -b, -c, c, b}, \ + { j, o, -k, -i, -n, l, h, m, -m, -h, -l, n, i, k, -o, -j}, \ + { e, -g, -d, -f, f, d, g, -e, -e, g, d, f, -f, -d, -g, e}, \ + { k, -m, -i, o, h, n, -j, -l, l, j, -n, -h, -o, i, m, -k}, \ + { a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a}, \ + { l, -j, -n, h, -o, -i, m, k, -k, -m, i, o, -h, n, j, -l}, \ + { f, -d, g, e, -e, -g, d, -f, -f, d, -g, -e, e, g, -d, f}, \ + { m, -h, l, n, -i, k, o, -j, j, -o, -k, i, -n, -l, h, -m}, \ + { c, -b, b, -c, -c, b, -b, c, c, -b, b, -c, -c, b, -b, c}, \ + { n, -k, h, -j, m, o, -l, i, -i, l, -o, -m, j, -h, k, -n}, \ + { g, -f, e, -d, d, -e, f, -g, -g, f, -e, d, -d, e, -f, g}, \ + { o, -n, m, -l, k, -j, i, -h, h, -i, j, -k, l, -m, n, -o} \ +} + +#define DEFINE_DCT2_P32_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E) \ +{ \ + { a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a}, \ + { p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, -E, -D, -C, -B, -A, -z, -y, -x, -w, -v, -u, -t, -s, -r, -q, -p}, \ + { h, i, j, k, l, m, n, o, -o, -n, -m, -l, -k, -j, -i, -h, -h, -i, -j, -k, -l, -m, -n, -o, o, n, m, l, k, j, i, h}, \ + { q, t, w, z, C, -E, -B, -y, -v, -s, -p, -r, -u, -x, -A, -D, D, A, x, u, r, p, s, v, y, B, E, -C, -z, -w, -t, -q}, \ + { d, e, f, g, -g, -f, -e, -d, -d, -e, -f, -g, g, f, e, d, d, e, f, g, -g, -f, -e, -d, -d, -e, -f, -g, g, f, e, d}, \ + { r, w, B, -D, -y, -t, -p, -u, -z, -E, A, v, q, s, x, C, -C, -x, -s, -q, -v, -A, E, z, u, p, t, y, D, -B, -w, -r}, \ + { i, l, o, -m, -j, -h, -k, -n, n, k, h, j, m, -o, -l, -i, -i, -l, -o, m, j, h, k, n, -n, -k, -h, -j, -m, o, l, i}, \ + { s, z, -D, -w, -p, -v, -C, A, t, r, y, -E, -x, -q, -u, -B, B, u, q, x, E, -y, -r, -t, -A, C, v, p, w, D, -z, -s}, \ + { b, c, -c, -b, -b, -c, c, b, b, c, -c, -b, -b, -c, c, b, b, c, -c, -b, -b, -c, c, b, b, c, -c, -b, -b, -c, c, b}, \ + { t, C, -y, -p, -x, D, u, s, B, -z, -q, -w, E, v, r, A, -A, -r, -v, -E, w, q, z, -B, -s, -u, -D, x, p, y, -C, -t}, \ + { j, o, -k, -i, -n, l, h, m, -m, -h, -l, n, i, k, -o, -j, -j, -o, k, i, n, -l, -h, -m, m, h, l, -n, -i, -k, o, j}, \ + { u, -E, -t, -v, D, s, w, -C, -r, -x, B, q, y, -A, -p, -z, z, p, A, -y, -q, -B, x, r, C, -w, -s, -D, v, t, E, -u}, \ + { e, -g, -d, -f, f, d, g, -e, -e, g, d, f, -f, -d, -g, e, e, -g, -d, -f, f, d, g, -e, -e, g, d, f, -f, -d, -g, e}, \ + { v, -B, -p, -C, u, w, -A, -q, -D, t, x, -z, -r, -E, s, y, -y, -s, E, r, z, -x, -t, D, q, A, -w, -u, C, p, B, -v}, \ + { k, -m, -i, o, h, n, -j, -l, l, j, -n, -h, -o, i, m, -k, -k, m, i, -o, -h, -n, j, l, -l, -j, n, h, o, -i, -m, k}, \ + { w, -y, -u, A, s, -C, -q, E, p, D, -r, -B, t, z, -v, -x, x, v, -z, -t, B, r, -D, -p, -E, q, C, -s, -A, u, y, -w}, \ + { a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a, a, -a, -a, a}, \ + { x, -v, -z, t, B, -r, -D, p, -E, -q, C, s, -A, -u, y, w, -w, -y, u, A, -s, -C, q, E, -p, D, r, -B, -t, z, v, -x}, \ + { l, -j, -n, h, -o, -i, m, k, -k, -m, i, o, -h, n, j, -l, -l, j, n, -h, o, i, -m, -k, k, m, -i, -o, h, -n, -j, l}, \ + { y, -s, -E, r, -z, -x, t, D, -q, A, w, -u, -C, p, -B, -v, v, B, -p, C, u, -w, -A, q, -D, -t, x, z, -r, E, s, -y}, \ + { f, -d, g, e, -e, -g, d, -f, -f, d, -g, -e, e, g, -d, f, f, -d, g, e, -e, -g, d, -f, -f, d, -g, -e, e, g, -d, f}, \ + { z, -p, A, y, -q, B, x, -r, C, w, -s, D, v, -t, E, u, -u, -E, t, -v, -D, s, -w, -C, r, -x, -B, q, -y, -A, p, -z}, \ + { m, -h, l, n, -i, k, o, -j, j, -o, -k, i, -n, -l, h, -m, -m, h, -l, -n, i, -k, -o, j, -j, o, k, -i, n, l, -h, m}, \ + { A, -r, v, -E, -w, q, -z, -B, s, -u, D, x, -p, y, C, -t, t, -C, -y, p, -x, -D, u, -s, B, z, -q, w, E, -v, r, -A}, \ + { c, -b, b, -c, -c, b, -b, c, c, -b, b, -c, -c, b, -b, c, c, -b, b, -c, -c, b, -b, c, c, -b, b, -c, -c, b, -b, c}, \ + { B, -u, q, -x, E, y, -r, t, -A, -C, v, -p, w, -D, -z, s, -s, z, D, -w, p, -v, C, A, -t, r, -y, -E, x, -q, u, -B}, \ + { n, -k, h, -j, m, o, -l, i, -i, l, -o, -m, j, -h, k, -n, -n, k, -h, j, -m, -o, l, -i, i, -l, o, m, -j, h, -k, n}, \ + { C, -x, s, -q, v, -A, -E, z, -u, p, -t, y, -D, -B, w, -r, r, -w, B, D, -y, t, -p, u, -z, E, A, -v, q, -s, x, -C}, \ + { g, -f, e, -d, d, -e, f, -g, -g, f, -e, d, -d, e, -f, g, g, -f, e, -d, d, -e, f, -g, -g, f, -e, d, -d, e, -f, g}, \ + { D, -A, x, -u, r, -p, s, -v, y, -B, E, C, -z, w, -t, q, -q, t, -w, z, -C, -E, B, -y, v, -s, p, -r, u, -x, A, -D}, \ + { o, -n, m, -l, k, -j, i, -h, h, -i, j, -k, l, -m, n, -o, -o, n, -m, l, -k, j, -i, h, -h, i, -j, k, -l, m, -n, o}, \ + { E, -D, C, -B, A, -z, y, -x, w, -v, u, -t, s, -r, q, -p, p, -q, r, -s, t, -u, v, -w, x, -y, z, -A, B, -C, D, -E} \ +} + + +#define DEFINE_DCT2_P64_MATRIX(aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck) \ +{ \ + { aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa, aa }, \ + { bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, -ck, -cj, -ci, -ch, -cg, -cf, -ce, -cd, -cc, -cb, -ca, -bz, -by, -bx, -bw, -bv, -bu, -bt, -bs, -br, -bq, -bp, -bo, -bn, -bm, -bl, -bk, -bj, -bi, -bh, -bg, -bf }, \ + { ap, aq, ar, as, at, au, av, aw, ax, ay, az, ba, bb, bc, bd, be, -be, -bd, -bc, -bb, -ba, -az, -ay, -ax, -aw, -av, -au, -at, -as, -ar, -aq, -ap, -ap, -aq, -ar, -as, -at, -au, -av, -aw, -ax, -ay, -az, -ba, -bb, -bc, -bd, -be, be, bd, bc, bb, ba, az, ay, ax, aw, av, au, at, as, ar, aq, ap }, \ + { bg, bj, bm, bp, bs, bv, by, cb, ce, ch, ck, -ci, -cf, -cc, -bz, -bw, -bt, -bq, -bn, -bk, -bh, -bf, -bi, -bl, -bo, -br, -bu, -bx, -ca, -cd, -cg, -cj, cj, cg, cd, ca, bx, bu, br, bo, bl, bi, bf, bh, bk, bn, bq, bt, bw, bz, cc, cf, ci, -ck, -ch, -ce, -cb, -by, -bv, -bs, -bp, -bm, -bj, -bg }, \ + { ah, ai, aj, ak, al, am, an, ao, -ao, -an, -am, -al, -ak, -aj, -ai, -ah, -ah, -ai, -aj, -ak, -al, -am, -an, -ao, ao, an, am, al, ak, aj, ai, ah, ah, ai, aj, ak, al, am, an, ao, -ao, -an, -am, -al, -ak, -aj, -ai, -ah, -ah, -ai, -aj, -ak, -al, -am, -an, -ao, ao, an, am, al, ak, aj, ai, ah }, \ + { bh, bm, br, bw, cb, cg, -ck, -cf, -ca, -bv, -bq, -bl, -bg, -bi, -bn, -bs, -bx, -cc, -ch, cj, ce, bz, bu, bp, bk, bf, bj, bo, bt, by, cd, ci, -ci, -cd, -by, -bt, -bo, -bj, -bf, -bk, -bp, -bu, -bz, -ce, -cj, ch, cc, bx, bs, bn, bi, bg, bl, bq, bv, ca, cf, ck, -cg, -cb, -bw, -br, -bm, -bh }, \ + { aq, at, aw, az, bc, -be, -bb, -ay, -av, -as, -ap, -ar, -au, -ax, -ba, -bd, bd, ba, ax, au, ar, ap, as, av, ay, bb, be, -bc, -az, -aw, -at, -aq, -aq, -at, -aw, -az, -bc, be, bb, ay, av, as, ap, ar, au, ax, ba, bd, -bd, -ba, -ax, -au, -ar, -ap, -as, -av, -ay, -bb, -be, bc, az, aw, at, aq }, \ + { bi, bp, bw, cd, ck, -ce, -bx, -bq, -bj, -bh, -bo, -bv, -cc, -cj, cf, by, br, bk, bg, bn, bu, cb, ci, -cg, -bz, -bs, -bl, -bf, -bm, -bt, -ca, -ch, ch, ca, bt, bm, bf, bl, bs, bz, cg, -ci, -cb, -bu, -bn, -bg, -bk, -br, -by, -cf, cj, cc, bv, bo, bh, bj, bq, bx, ce, -ck, -cd, -bw, -bp, -bi }, \ + { ad, ae, af, ag, -ag, -af, -ae, -ad, -ad, -ae, -af, -ag, ag, af, ae, ad, ad, ae, af, ag, -ag, -af, -ae, -ad, -ad, -ae, -af, -ag, ag, af, ae, ad, ad, ae, af, ag, -ag, -af, -ae, -ad, -ad, -ae, -af, -ag, ag, af, ae, ad, ad, ae, af, ag, -ag, -af, -ae, -ad, -ad, -ae, -af, -ag, ag, af, ae, ad }, \ + { bj, bs, cb, ck, -cc, -bt, -bk, -bi, -br, -ca, -cj, cd, bu, bl, bh, bq, bz, ci, -ce, -bv, -bm, -bg, -bp, -by, -ch, cf, bw, bn, bf, bo, bx, cg, -cg, -bx, -bo, -bf, -bn, -bw, -cf, ch, by, bp, bg, bm, bv, ce, -ci, -bz, -bq, -bh, -bl, -bu, -cd, cj, ca, br, bi, bk, bt, cc, -ck, -cb, -bs, -bj }, \ + { ar, aw, bb, -bd, -ay, -at, -ap, -au, -az, -be, ba, av, aq, as, ax, bc, -bc, -ax, -as, -aq, -av, -ba, be, az, au, ap, at, ay, bd, -bb, -aw, -ar, -ar, -aw, -bb, bd, ay, at, ap, au, az, be, -ba, -av, -aq, -as, -ax, -bc, bc, ax, as, aq, av, ba, -be, -az, -au, -ap, -at, -ay, -bd, bb, aw, ar }, \ + { bk, bv, cg, -ce, -bt, -bi, -bm, -bx, -ci, cc, br, bg, bo, bz, ck, -ca, -bp, -bf, -bq, -cb, cj, by, bn, bh, bs, cd, -ch, -bw, -bl, -bj, -bu, -cf, cf, bu, bj, bl, bw, ch, -cd, -bs, -bh, -bn, -by, -cj, cb, bq, bf, bp, ca, -ck, -bz, -bo, -bg, -br, -cc, ci, bx, bm, bi, bt, ce, -cg, -bv, -bk }, \ + { ai, al, ao, -am, -aj, -ah, -ak, -an, an, ak, ah, aj, am, -ao, -al, -ai, -ai, -al, -ao, am, aj, ah, ak, an, -an, -ak, -ah, -aj, -am, ao, al, ai, ai, al, ao, -am, -aj, -ah, -ak, -an, an, ak, ah, aj, am, -ao, -al, -ai, -ai, -al, -ao, am, aj, ah, ak, an, -an, -ak, -ah, -aj, -am, ao, al, ai }, \ + { bl, by, -ck, -bx, -bk, -bm, -bz, cj, bw, bj, bn, ca, -ci, -bv, -bi, -bo, -cb, ch, bu, bh, bp, cc, -cg, -bt, -bg, -bq, -cd, cf, bs, bf, br, ce, -ce, -br, -bf, -bs, -cf, cd, bq, bg, bt, cg, -cc, -bp, -bh, -bu, -ch, cb, bo, bi, bv, ci, -ca, -bn, -bj, -bw, -cj, bz, bm, bk, bx, ck, -by, -bl }, \ + { as, az, -bd, -aw, -ap, -av, -bc, ba, at, ar, ay, -be, -ax, -aq, -au, -bb, bb, au, aq, ax, be, -ay, -ar, -at, -ba, bc, av, ap, aw, bd, -az, -as, -as, -az, bd, aw, ap, av, bc, -ba, -at, -ar, -ay, be, ax, aq, au, bb, -bb, -au, -aq, -ax, -be, ay, ar, at, ba, -bc, -av, -ap, -aw, -bd, az, as }, \ + { bm, cb, -cf, -bq, -bi, -bx, cj, bu, bf, bt, ci, -by, -bj, -bp, -ce, cc, bn, bl, ca, -cg, -br, -bh, -bw, ck, bv, bg, bs, ch, -bz, -bk, -bo, -cd, cd, bo, bk, bz, -ch, -bs, -bg, -bv, -ck, bw, bh, br, cg, -ca, -bl, -bn, -cc, ce, bp, bj, by, -ci, -bt, -bf, -bu, -cj, bx, bi, bq, cf, -cb, -bm }, \ + { ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab, ab, ac, -ac, -ab, -ab, -ac, ac, ab }, \ + { bn, ce, -ca, -bj, -br, -ci, bw, bf, bv, -cj, -bs, -bi, -bz, cf, bo, bm, cd, -cb, -bk, -bq, -ch, bx, bg, bu, -ck, -bt, -bh, -by, cg, bp, bl, cc, -cc, -bl, -bp, -cg, by, bh, bt, ck, -bu, -bg, -bx, ch, bq, bk, cb, -cd, -bm, -bo, -cf, bz, bi, bs, cj, -bv, -bf, -bw, ci, br, bj, ca, -ce, -bn }, \ + { at, bc, -ay, -ap, -ax, bd, au, as, bb, -az, -aq, -aw, be, av, ar, ba, -ba, -ar, -av, -be, aw, aq, az, -bb, -as, -au, -bd, ax, ap, ay, -bc, -at, -at, -bc, ay, ap, ax, -bd, -au, -as, -bb, az, aq, aw, -be, -av, -ar, -ba, ba, ar, av, be, -aw, -aq, -az, bb, as, au, bd, -ax, -ap, -ay, bc, at }, \ + { bo, ch, -bv, -bh, -ca, cc, bj, bt, -cj, -bq, -bm, -cf, bx, bf, by, -ce, -bl, -br, -ck, bs, bk, cd, -bz, -bg, -bw, cg, bn, bp, ci, -bu, -bi, -cb, cb, bi, bu, -ci, -bp, -bn, -cg, bw, bg, bz, -cd, -bk, -bs, ck, br, bl, ce, -by, -bf, -bx, cf, bm, bq, cj, -bt, -bj, -cc, ca, bh, bv, -ch, -bo }, \ + { aj, ao, -ak, -ai, -an, al, ah, am, -am, -ah, -al, an, ai, ak, -ao, -aj, -aj, -ao, ak, ai, an, -al, -ah, -am, am, ah, al, -an, -ai, -ak, ao, aj, aj, ao, -ak, -ai, -an, al, ah, am, -am, -ah, -al, an, ai, ak, -ao, -aj, -aj, -ao, ak, ai, an, -al, -ah, -am, am, ah, al, -an, -ai, -ak, ao, aj }, \ + { bp, ck, -bq, -bo, -cj, br, bn, ci, -bs, -bm, -ch, bt, bl, cg, -bu, -bk, -cf, bv, bj, ce, -bw, -bi, -cd, bx, bh, cc, -by, -bg, -cb, bz, bf, ca, -ca, -bf, -bz, cb, bg, by, -cc, -bh, -bx, cd, bi, bw, -ce, -bj, -bv, cf, bk, bu, -cg, -bl, -bt, ch, bm, bs, -ci, -bn, -br, cj, bo, bq, -ck, -bp }, \ + { au, -be, -at, -av, bd, as, aw, -bc, -ar, -ax, bb, aq, ay, -ba, -ap, -az, az, ap, ba, -ay, -aq, -bb, ax, ar, bc, -aw, -as, -bd, av, at, be, -au, -au, be, at, av, -bd, -as, -aw, bc, ar, ax, -bb, -aq, -ay, ba, ap, az, -az, -ap, -ba, ay, aq, bb, -ax, -ar, -bc, aw, as, bd, -av, -at, -be, au }, \ + { bq, -ci, -bl, -bv, cd, bg, ca, -by, -bi, -cf, bt, bn, ck, -bo, -bs, cg, bj, bx, -cb, -bf, -cc, bw, bk, ch, -br, -bp, cj, bm, bu, -ce, -bh, -bz, bz, bh, ce, -bu, -bm, -cj, bp, br, -ch, -bk, -bw, cc, bf, cb, -bx, -bj, -cg, bs, bo, -ck, -bn, -bt, cf, bi, by, -ca, -bg, -cd, bv, bl, ci, -bq }, \ + { ae, -ag, -ad, -af, af, ad, ag, -ae, -ae, ag, ad, af, -af, -ad, -ag, ae, ae, -ag, -ad, -af, af, ad, ag, -ae, -ae, ag, ad, af, -af, -ad, -ag, ae, ae, -ag, -ad, -af, af, ad, ag, -ae, -ae, ag, ad, af, -af, -ad, -ag, ae, ae, -ag, -ad, -af, af, ad, ag, -ae, -ae, ag, ad, af, -af, -ad, -ag, ae }, \ + { br, -cf, -bg, -cc, bu, bo, -ci, -bj, -bz, bx, bl, ck, -bm, -bw, ca, bi, ch, -bp, -bt, cd, bf, ce, -bs, -bq, cg, bh, cb, -bv, -bn, cj, bk, by, -by, -bk, -cj, bn, bv, -cb, -bh, -cg, bq, bs, -ce, -bf, -cd, bt, bp, -ch, -bi, -ca, bw, bm, -ck, -bl, -bx, bz, bj, ci, -bo, -bu, cc, bg, cf, -br }, \ + { av, -bb, -ap, -bc, au, aw, -ba, -aq, -bd, at, ax, -az, -ar, -be, as, ay, -ay, -as, be, ar, az, -ax, -at, bd, aq, ba, -aw, -au, bc, ap, bb, -av, -av, bb, ap, bc, -au, -aw, ba, aq, bd, -at, -ax, az, ar, be, -as, -ay, ay, as, -be, -ar, -az, ax, at, -bd, -aq, -ba, aw, au, -bc, -ap, -bb, av }, \ + { bs, -cc, -bi, -cj, bl, bz, -bv, -bp, cf, bf, cg, -bo, -bw, by, bm, -ci, -bh, -cd, br, bt, -cb, -bj, -ck, bk, ca, -bu, -bq, ce, bg, ch, -bn, -bx, bx, bn, -ch, -bg, -ce, bq, bu, -ca, -bk, ck, bj, cb, -bt, -br, cd, bh, ci, -bm, -by, bw, bo, -cg, -bf, -cf, bp, bv, -bz, -bl, cj, bi, cc, -bs }, \ + { ak, -am, -ai, ao, ah, an, -aj, -al, al, aj, -an, -ah, -ao, ai, am, -ak, -ak, am, ai, -ao, -ah, -an, aj, al, -al, -aj, an, ah, ao, -ai, -am, ak, ak, -am, -ai, ao, ah, an, -aj, -al, al, aj, -an, -ah, -ao, ai, am, -ak, -ak, am, ai, -ao, -ah, -an, aj, al, -al, -aj, an, ah, ao, -ai, -am, ak }, \ + { bt, -bz, -bn, cf, bh, ck, -bi, -ce, bo, by, -bu, -bs, ca, bm, -cg, -bg, -cj, bj, cd, -bp, -bx, bv, br, -cb, -bl, ch, bf, ci, -bk, -cc, bq, bw, -bw, -bq, cc, bk, -ci, -bf, -ch, bl, cb, -br, -bv, bx, bp, -cd, -bj, cj, bg, cg, -bm, -ca, bs, bu, -by, -bo, ce, bi, -ck, -bh, -cf, bn, bz, -bt }, \ + { aw, -ay, -au, ba, as, -bc, -aq, be, ap, bd, -ar, -bb, at, az, -av, -ax, ax, av, -az, -at, bb, ar, -bd, -ap, -be, aq, bc, -as, -ba, au, ay, -aw, -aw, ay, au, -ba, -as, bc, aq, -be, -ap, -bd, ar, bb, -at, -az, av, ax, -ax, -av, az, at, -bb, -ar, bd, ap, be, -aq, -bc, as, ba, -au, -ay, aw }, \ + { bu, -bw, -bs, by, bq, -ca, -bo, cc, bm, -ce, -bk, cg, bi, -ci, -bg, ck, bf, cj, -bh, -ch, bj, cf, -bl, -cd, bn, cb, -bp, -bz, br, bx, -bt, -bv, bv, bt, -bx, -br, bz, bp, -cb, -bn, cd, bl, -cf, -bj, ch, bh, -cj, -bf, -ck, bg, ci, -bi, -cg, bk, ce, -bm, -cc, bo, ca, -bq, -by, bs, bw, -bu }, \ + { aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa, aa, -aa, -aa, aa }, \ + { bv, -bt, -bx, br, bz, -bp, -cb, bn, cd, -bl, -cf, bj, ch, -bh, -cj, bf, -ck, -bg, ci, bi, -cg, -bk, ce, bm, -cc, -bo, ca, bq, -by, -bs, bw, bu, -bu, -bw, bs, by, -bq, -ca, bo, cc, -bm, -ce, bk, cg, -bi, -ci, bg, ck, -bf, cj, bh, -ch, -bj, cf, bl, -cd, -bn, cb, bp, -bz, -br, bx, bt, -bv }, \ + { ax, -av, -az, at, bb, -ar, -bd, ap, -be, -aq, bc, as, -ba, -au, ay, aw, -aw, -ay, au, ba, -as, -bc, aq, be, -ap, bd, ar, -bb, -at, az, av, -ax, -ax, av, az, -at, -bb, ar, bd, -ap, be, aq, -bc, -as, ba, au, -ay, -aw, aw, ay, -au, -ba, as, bc, -aq, -be, ap, -bd, -ar, bb, at, -az, -av, ax }, \ + { bw, -bq, -cc, bk, ci, -bf, ch, bl, -cb, -br, bv, bx, -bp, -cd, bj, cj, -bg, cg, bm, -ca, -bs, bu, by, -bo, -ce, bi, ck, -bh, cf, bn, -bz, -bt, bt, bz, -bn, -cf, bh, -ck, -bi, ce, bo, -by, -bu, bs, ca, -bm, -cg, bg, -cj, -bj, cd, bp, -bx, -bv, br, cb, -bl, -ch, bf, -ci, -bk, cc, bq, -bw }, \ + { al, -aj, -an, ah, -ao, -ai, am, ak, -ak, -am, ai, ao, -ah, an, aj, -al, -al, aj, an, -ah, ao, ai, -am, -ak, ak, am, -ai, -ao, ah, -an, -aj, al, al, -aj, -an, ah, -ao, -ai, am, ak, -ak, -am, ai, ao, -ah, an, aj, -al, -al, aj, an, -ah, ao, ai, -am, -ak, ak, am, -ai, -ao, ah, -an, -aj, al }, \ + { bx, -bn, -ch, bg, -ce, -bq, bu, ca, -bk, -ck, bj, -cb, -bt, br, cd, -bh, ci, bm, -by, -bw, bo, cg, -bf, cf, bp, -bv, -bz, bl, cj, -bi, cc, bs, -bs, -cc, bi, -cj, -bl, bz, bv, -bp, -cf, bf, -cg, -bo, bw, by, -bm, -ci, bh, -cd, -br, bt, cb, -bj, ck, bk, -ca, -bu, bq, ce, -bg, ch, bn, -bx }, \ + { ay, -as, -be, ar, -az, -ax, at, bd, -aq, ba, aw, -au, -bc, ap, -bb, -av, av, bb, -ap, bc, au, -aw, -ba, aq, -bd, -at, ax, az, -ar, be, as, -ay, -ay, as, be, -ar, az, ax, -at, -bd, aq, -ba, -aw, au, bc, -ap, bb, av, -av, -bb, ap, -bc, -au, aw, ba, -aq, bd, at, -ax, -az, ar, -be, -as, ay }, \ + { by, -bk, cj, bn, -bv, -cb, bh, -cg, -bq, bs, ce, -bf, cd, bt, -bp, -ch, bi, -ca, -bw, bm, ck, -bl, bx, bz, -bj, ci, bo, -bu, -cc, bg, -cf, -br, br, cf, -bg, cc, bu, -bo, -ci, bj, -bz, -bx, bl, -ck, -bm, bw, ca, -bi, ch, bp, -bt, -cd, bf, -ce, -bs, bq, cg, -bh, cb, bv, -bn, -cj, bk, -by }, \ + { af, -ad, ag, ae, -ae, -ag, ad, -af, -af, ad, -ag, -ae, ae, ag, -ad, af, af, -ad, ag, ae, -ae, -ag, ad, -af, -af, ad, -ag, -ae, ae, ag, -ad, af, af, -ad, ag, ae, -ae, -ag, ad, -af, -af, ad, -ag, -ae, ae, ag, -ad, af, af, -ad, ag, ae, -ae, -ag, ad, -af, -af, ad, -ag, -ae, ae, ag, -ad, af }, \ + { bz, -bh, ce, bu, -bm, cj, bp, -br, -ch, bk, -bw, -cc, bf, -cb, -bx, bj, -cg, -bs, bo, ck, -bn, bt, cf, -bi, by, ca, -bg, cd, bv, -bl, ci, bq, -bq, -ci, bl, -bv, -cd, bg, -ca, -by, bi, -cf, -bt, bn, -ck, -bo, bs, cg, -bj, bx, cb, -bf, cc, bw, -bk, ch, br, -bp, -cj, bm, -bu, -ce, bh, -bz }, \ + { az, -ap, ba, ay, -aq, bb, ax, -ar, bc, aw, -as, bd, av, -at, be, au, -au, -be, at, -av, -bd, as, -aw, -bc, ar, -ax, -bb, aq, -ay, -ba, ap, -az, -az, ap, -ba, -ay, aq, -bb, -ax, ar, -bc, -aw, as, -bd, -av, at, -be, -au, au, be, -at, av, bd, -as, aw, bc, -ar, ax, bb, -aq, ay, ba, -ap, az }, \ + { ca, -bf, bz, cb, -bg, by, cc, -bh, bx, cd, -bi, bw, ce, -bj, bv, cf, -bk, bu, cg, -bl, bt, ch, -bm, bs, ci, -bn, br, cj, -bo, bq, ck, -bp, bp, -ck, -bq, bo, -cj, -br, bn, -ci, -bs, bm, -ch, -bt, bl, -cg, -bu, bk, -cf, -bv, bj, -ce, -bw, bi, -cd, -bx, bh, -cc, -by, bg, -cb, -bz, bf, -ca }, \ + { am, -ah, al, an, -ai, ak, ao, -aj, aj, -ao, -ak, ai, -an, -al, ah, -am, -am, ah, -al, -an, ai, -ak, -ao, aj, -aj, ao, ak, -ai, an, al, -ah, am, am, -ah, al, an, -ai, ak, ao, -aj, aj, -ao, -ak, ai, -an, -al, ah, -am, -am, ah, -al, -an, ai, -ak, -ao, aj, -aj, ao, ak, -ai, an, al, -ah, am }, \ + { cb, -bi, bu, ci, -bp, bn, -cg, -bw, bg, -bz, -cd, bk, -bs, -ck, br, -bl, ce, by, -bf, bx, cf, -bm, bq, -cj, -bt, bj, -cc, -ca, bh, -bv, -ch, bo, -bo, ch, bv, -bh, ca, cc, -bj, bt, cj, -bq, bm, -cf, -bx, bf, -by, -ce, bl, -br, ck, bs, -bk, cd, bz, -bg, bw, cg, -bn, bp, -ci, -bu, bi, -cb }, \ + { ba, -ar, av, -be, -aw, aq, -az, -bb, as, -au, bd, ax, -ap, ay, bc, -at, at, -bc, -ay, ap, -ax, -bd, au, -as, bb, az, -aq, aw, be, -av, ar, -ba, -ba, ar, -av, be, aw, -aq, az, bb, -as, au, -bd, -ax, ap, -ay, -bc, at, -at, bc, ay, -ap, ax, bd, -au, as, -bb, -az, aq, -aw, -be, av, -ar, ba }, \ + { cc, -bl, bp, -cg, -by, bh, -bt, ck, bu, -bg, bx, ch, -bq, bk, -cb, -cd, bm, -bo, cf, bz, -bi, bs, -cj, -bv, bf, -bw, -ci, br, -bj, ca, ce, -bn, bn, -ce, -ca, bj, -br, ci, bw, -bf, bv, cj, -bs, bi, -bz, -cf, bo, -bm, cd, cb, -bk, bq, -ch, -bx, bg, -bu, -ck, bt, -bh, by, cg, -bp, bl, -cc }, \ + { ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac, ac, -ab, ab, -ac, -ac, ab, -ab, ac }, \ + { cd, -bo, bk, -bz, -ch, bs, -bg, bv, -ck, -bw, bh, -br, cg, ca, -bl, bn, -cc, -ce, bp, -bj, by, ci, -bt, bf, -bu, cj, bx, -bi, bq, -cf, -cb, bm, -bm, cb, cf, -bq, bi, -bx, -cj, bu, -bf, bt, -ci, -by, bj, -bp, ce, cc, -bn, bl, -ca, -cg, br, -bh, bw, ck, -bv, bg, -bs, ch, bz, -bk, bo, -cd }, \ + { bb, -au, aq, -ax, be, ay, -ar, at, -ba, -bc, av, -ap, aw, -bd, -az, as, -as, az, bd, -aw, ap, -av, bc, ba, -at, ar, -ay, -be, ax, -aq, au, -bb, -bb, au, -aq, ax, -be, -ay, ar, -at, ba, bc, -av, ap, -aw, bd, az, -as, as, -az, -bd, aw, -ap, av, -bc, -ba, at, -ar, ay, be, -ax, aq, -au, bb }, \ + { ce, -br, bf, -bs, cf, cd, -bq, bg, -bt, cg, cc, -bp, bh, -bu, ch, cb, -bo, bi, -bv, ci, ca, -bn, bj, -bw, cj, bz, -bm, bk, -bx, ck, by, -bl, bl, -by, -ck, bx, -bk, bm, -bz, -cj, bw, -bj, bn, -ca, -ci, bv, -bi, bo, -cb, -ch, bu, -bh, bp, -cc, -cg, bt, -bg, bq, -cd, -cf, bs, -bf, br, -ce }, \ + { an, -ak, ah, -aj, am, ao, -al, ai, -ai, al, -ao, -am, aj, -ah, ak, -an, -an, ak, -ah, aj, -am, -ao, al, -ai, ai, -al, ao, am, -aj, ah, -ak, an, an, -ak, ah, -aj, am, ao, -al, ai, -ai, al, -ao, -am, aj, -ah, ak, -an, -an, ak, -ah, aj, -am, -ao, al, -ai, ai, -al, ao, am, -aj, ah, -ak, an }, \ + { cf, -bu, bj, -bl, bw, -ch, -cd, bs, -bh, bn, -by, cj, cb, -bq, bf, -bp, ca, ck, -bz, bo, -bg, br, -cc, -ci, bx, -bm, bi, -bt, ce, cg, -bv, bk, -bk, bv, -cg, -ce, bt, -bi, bm, -bx, ci, cc, -br, bg, -bo, bz, -ck, -ca, bp, -bf, bq, -cb, -cj, by, -bn, bh, -bs, cd, ch, -bw, bl, -bj, bu, -cf }, \ + { bc, -ax, as, -aq, av, -ba, -be, az, -au, ap, -at, ay, -bd, -bb, aw, -ar, ar, -aw, bb, bd, -ay, at, -ap, au, -az, be, ba, -av, aq, -as, ax, -bc, -bc, ax, -as, aq, -av, ba, be, -az, au, -ap, at, -ay, bd, bb, -aw, ar, -ar, aw, -bb, -bd, ay, -at, ap, -au, az, -be, -ba, av, -aq, as, -ax, bc }, \ + { cg, -bx, bo, -bf, bn, -bw, cf, ch, -by, bp, -bg, bm, -bv, ce, ci, -bz, bq, -bh, bl, -bu, cd, cj, -ca, br, -bi, bk, -bt, cc, ck, -cb, bs, -bj, bj, -bs, cb, -ck, -cc, bt, -bk, bi, -br, ca, -cj, -cd, bu, -bl, bh, -bq, bz, -ci, -ce, bv, -bm, bg, -bp, by, -ch, -cf, bw, -bn, bf, -bo, bx, -cg }, \ + { ag, -af, ae, -ad, ad, -ae, af, -ag, -ag, af, -ae, ad, -ad, ae, -af, ag, ag, -af, ae, -ad, ad, -ae, af, -ag, -ag, af, -ae, ad, -ad, ae, -af, ag, ag, -af, ae, -ad, ad, -ae, af, -ag, -ag, af, -ae, ad, -ad, ae, -af, ag, ag, -af, ae, -ad, ad, -ae, af, -ag, -ag, af, -ae, ad, -ad, ae, -af, ag }, \ + { ch, -ca, bt, -bm, bf, -bl, bs, -bz, cg, ci, -cb, bu, -bn, bg, -bk, br, -by, cf, cj, -cc, bv, -bo, bh, -bj, bq, -bx, ce, ck, -cd, bw, -bp, bi, -bi, bp, -bw, cd, -ck, -ce, bx, -bq, bj, -bh, bo, -bv, cc, -cj, -cf, by, -br, bk, -bg, bn, -bu, cb, -ci, -cg, bz, -bs, bl, -bf, bm, -bt, ca, -ch }, \ + { bd, -ba, ax, -au, ar, -ap, as, -av, ay, -bb, be, bc, -az, aw, -at, aq, -aq, at, -aw, az, -bc, -be, bb, -ay, av, -as, ap, -ar, au, -ax, ba, -bd, -bd, ba, -ax, au, -ar, ap, -as, av, -ay, bb, -be, -bc, az, -aw, at, -aq, aq, -at, aw, -az, bc, be, -bb, ay, -av, as, -ap, ar, -au, ax, -ba, bd }, \ + { ci, -cd, by, -bt, bo, -bj, bf, -bk, bp, -bu, bz, -ce, cj, ch, -cc, bx, -bs, bn, -bi, bg, -bl, bq, -bv, ca, -cf, ck, cg, -cb, bw, -br, bm, -bh, bh, -bm, br, -bw, cb, -cg, -ck, cf, -ca, bv, -bq, bl, -bg, bi, -bn, bs, -bx, cc, -ch, -cj, ce, -bz, bu, -bp, bk, -bf, bj, -bo, bt, -by, cd, -ci }, \ + { ao, -an, am, -al, ak, -aj, ai, -ah, ah, -ai, aj, -ak, al, -am, an, -ao, -ao, an, -am, al, -ak, aj, -ai, ah, -ah, ai, -aj, ak, -al, am, -an, ao, ao, -an, am, -al, ak, -aj, ai, -ah, ah, -ai, aj, -ak, al, -am, an, -ao, -ao, an, -am, al, -ak, aj, -ai, ah, -ah, ai, -aj, ak, -al, am, -an, ao }, \ + { cj, -cg, cd, -ca, bx, -bu, br, -bo, bl, -bi, bf, -bh, bk, -bn, bq, -bt, bw, -bz, cc, -cf, ci, ck, -ch, ce, -cb, by, -bv, bs, -bp, bm, -bj, bg, -bg, bj, -bm, bp, -bs, bv, -by, cb, -ce, ch, -ck, -ci, cf, -cc, bz, -bw, bt, -bq, bn, -bk, bh, -bf, bi, -bl, bo, -br, bu, -bx, ca, -cd, cg, -cj }, \ + { be, -bd, bc, -bb, ba, -az, ay, -ax, aw, -av, au, -at, as, -ar, aq, -ap, ap, -aq, ar, -as, at, -au, av, -aw, ax, -ay, az, -ba, bb, -bc, bd, -be, -be, bd, -bc, bb, -ba, az, -ay, ax, -aw, av, -au, at, -as, ar, -aq, ap, -ap, aq, -ar, as, -at, au, -av, aw, -ax, ay, -az, ba, -bb, bc, -bd, be }, \ + { ck, -cj, ci, -ch, cg, -cf, ce, -cd, cc, -cb, ca, -bz, by, -bx, bw, -bv, bu, -bt, bs, -br, bq, -bp, bo, -bn, bm, -bl, bk, -bj, bi, -bh, bg, -bf, bf, -bg, bh, -bi, bj, -bk, bl, -bm, bn, -bo, bp, -bq, br, -bs, bt, -bu, bv, -bw, bx, -by, bz, -ca, cb, -cc, cd, -ce, cf, -cg, ch, -ci, cj, -ck }, \ + } + +// DCT-8 +#define DEFINE_DCT8_P4_MATRIX(a,b,c,d) \ +{ \ + { a, b, c, d,}, \ + { b, 0, -b, -b,}, \ + { c, -b, -d, a,}, \ + { d, -b, a, -c,}, \ +} + +#define DEFINE_DCT8_P8_MATRIX(a,b,c,d,e,f,g,h) \ +{ \ + { a, b, c, d, e, f, g, h,}, \ + { b, e, h, -g, -d, -a, -c, -f,}, \ + { c, h, -e, -a, -f, g, b, d,}, \ + { d, -g, -a, -h, c, e, -f, -b,}, \ + { e, -d, -f, c, g, -b, -h, a,}, \ + { f, -a, g, e, -b, h, d, -c,}, \ + { g, -c, b, -f, -h, d, -a, e,}, \ + { h, -f, d, -b, a, -c, e, -g,}, \ +} + +#define DEFINE_DCT8_P16_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ +{ \ + { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p,}, \ + { b, e, h, k, n, 0, -n, -k, -h, -e, -b, -b, -e, -h, -k, -n,}, \ + { c, h, m, -p, -k, -f, -a, -e, -j, -o, n, i, d, b, g, l,}, \ + { d, k, -p, -i, -b, -f, -m, n, g, a, h, o, -l, -e, -c, -j,}, \ + { e, n, -k, -b, -h, 0, h, b, k, -n, -e, -e, -n, k, b, h,}, \ + { f, 0, -f, -f, 0, f, f, 0, -f, -f, 0, f, f, 0, -f, -f,}, \ + { g, -n, -a, -m, h, f, -o, -b, -l, i, e, -p, -c, -k, j, d,}, \ + { h, -k, -e, n, b, 0, -b, -n, e, k, -h, -h, k, e, -n, -b,}, \ + { i, -h, -j, g, k, -f, -l, e, m, -d, -n, c, o, -b, -p, a,}, \ + { j, -e, -o, a, -n, -f, i, k, -d, -p, b, -m, -g, h, l, -c,}, \ + { k, -b, n, h, -e, 0, e, -h, -n, b, -k, -k, b, -n, -h, e,}, \ + { l, -b, i, o, -e, f, -p, -h, c, -m, -k, a, -j, -n, d, -g,}, \ + { m, -e, d, -l, -n, f, -c, k, o, -g, b, -j, -p, h, -a, i,}, \ + { n, -h, b, -e, k, 0, -k, e, -b, h, -n, -n, h, -b, e, -k,}, \ + { o, -k, g, -c, b, -f, j, -n, -p, l, -h, d, -a, e, -i, m,}, \ + { p, -n, l, -j, h, -f, d, -b, a, -c, e, -g, i, -k, m, -o,}, \ +} + +#define DEFINE_DCT8_P32_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F) \ +{ \ + { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F,}, \ + { b, e, h, k, n, q, t, w, z, C, F, -E, -B, -y, -v, -s, -p, -m, -j, -g, -d, -a, -c, -f, -i, -l, -o, -r, -u, -x, -A, -D,}, \ + { c, h, m, r, w, B, 0, -B, -w, -r, -m, -h, -c, -c, -h, -m, -r, -w, -B, 0, B, w, r, m, h, c, c, h, m, r, w, B,}, \ + { d, k, r, y, F, -A, -t, -m, -f, -b, -i, -p, -w, -D, C, v, o, h, a, g, n, u, B, -E, -x, -q, -j, -c, -e, -l, -s, -z,}, \ + { e, n, w, F, -y, -p, -g, -c, -l, -u, -D, A, r, i, a, j, s, B, -C, -t, -k, -b, -h, -q, -z, E, v, m, d, f, o, x,}, \ + { f, q, B, -A, -p, -e, -g, -r, -C, z, o, d, h, s, D, -y, -n, -c, -i, -t, -E, x, m, b, j, u, F, -w, -l, -a, -k, -v,}, \ + { g, t, 0, -t, -g, -g, -t, 0, t, g, g, t, 0, -t, -g, -g, -t, 0, t, g, g, t, 0, -t, -g, -g, -t, 0, t, g, g, t,}, \ + { h, w, -B, -m, -c, -r, 0, r, c, m, B, -w, -h, -h, -w, B, m, c, r, 0, -r, -c, -m, -B, w, h, h, w, -B, -m, -c, -r,}, \ + { i, z, -w, -f, -l, -C, t, c, o, F, -q, -a, -r, E, n, d, u, -B, -k, -g, -x, y, h, j, A, -v, -e, -m, -D, s, b, p,}, \ + { j, C, -r, -b, -u, z, g, m, F, -o, -e, -x, w, d, p, -E, -l, -h, -A, t, a, s, -B, -i, -k, -D, q, c, v, -y, -f, -n,}, \ + { k, F, -m, -i, -D, o, g, B, -q, -e, -z, s, c, x, -u, -a, -v, w, b, t, -y, -d, -r, A, f, p, -C, -h, -n, E, j, l,}, \ + { l, -E, -h, -p, A, d, t, -w, -a, -x, s, e, B, -o, -i, -F, k, m, -D, -g, -q, z, c, u, -v, -b, -y, r, f, C, -n, -j,}, \ + { m, -B, -c, -w, r, h, 0, -h, -r, w, c, B, -m, -m, B, c, w, -r, -h, 0, h, r, -w, -c, -B, m, m, -B, -c, -w, r, h,}, \ + { n, -y, -c, -D, i, s, -t, -h, E, d, x, -o, -m, z, b, C, -j, -r, u, g, -F, -e, -w, p, l, -A, -a, -B, k, q, -v, -f,}, \ + { o, -v, -h, C, a, D, -g, -w, n, p, -u, -i, B, b, E, -f, -x, m, q, -t, -j, A, c, F, -e, -y, l, r, -s, -k, z, d,}, \ + { p, -s, -m, v, j, -y, -g, B, d, -E, -a, -F, c, C, -f, -z, i, w, -l, -t, o, q, -r, -n, u, k, -x, -h, A, e, -D, -b,}, \ + { q, -p, -r, o, s, -n, -t, m, u, -l, -v, k, w, -j, -x, i, y, -h, -z, g, A, -f, -B, e, C, -d, -D, c, E, -b, -F, a,}, \ + { r, -m, -w, h, B, -c, 0, c, -B, -h, w, m, -r, -r, m, w, -h, -B, c, 0, -c, B, h, -w, -m, r, r, -m, -w, h, B, -c,}, \ + { s, -j, -B, a, -C, -i, t, r, -k, -A, b, -D, -h, u, q, -l, -z, c, -E, -g, v, p, -m, -y, d, -F, -f, w, o, -n, -x, e,}, \ + { t, -g, 0, g, -t, -t, g, 0, -g, t, t, -g, 0, g, -t, -t, g, 0, -g, t, t, -g, 0, g, -t, -t, g, 0, -g, t, t, -g,}, \ + { u, -d, B, n, -k, -E, g, -r, -x, a, -y, -q, h, -F, -j, o, A, -c, v, t, -e, C, m, -l, -D, f, -s, -w, b, -z, -p, i,}, \ + { v, -a, w, u, -b, x, t, -c, y, s, -d, z, r, -e, A, q, -f, B, p, -g, C, o, -h, D, n, -i, E, m, -j, F, l, -k,}, \ + { w, -c, r, B, -h, m, 0, -m, h, -B, -r, c, -w, -w, c, -r, -B, h, -m, 0, m, -h, B, r, -c, w, w, -c, r, B, -h, m,}, \ + { x, -f, m, -E, -q, b, -t, -B, j, -i, A, u, -c, p, F, -n, e, -w, -y, g, -l, D, r, -a, s, C, -k, h, -z, -v, d, -o,}, \ + { y, -i, h, -x, -z, j, -g, w, A, -k, f, -v, -B, l, -e, u, C, -m, d, -t, -D, n, -c, s, E, -o, b, -r, -F, p, -a, q,}, \ + { z, -l, c, -q, E, u, -g, h, -v, -D, p, -b, m, -A, -y, k, -d, r, -F, -t, f, -i, w, C, -o, a, -n, B, x, -j, e, -s,}, \ + { A, -o, c, -j, v, F, -t, h, -e, q, -C, -y, m, -a, l, -x, -D, r, -f, g, -s, E, w, -k, b, -n, z, B, -p, d, -i, u,}, \ + { B, -r, h, -c, m, -w, 0, w, -m, c, -h, r, -B, -B, r, -h, c, -m, w, 0, -w, m, -c, h, -r, B, B, -r, h, -c, m, -w,}, \ + { C, -u, m, -e, d, -l, t, -B, -D, v, -n, f, -c, k, -s, A, E, -w, o, -g, b, -j, r, -z, -F, x, -p, h, -a, i, -q, y,}, \ + { D, -x, r, -l, f, -a, g, -m, s, -y, E, C, -w, q, -k, e, -b, h, -n, t, -z, F, B, -v, p, -j, d, -c, i, -o, u, -A,}, \ + { E, -A, w, -s, o, -k, g, -c, b, -f, j, -n, r, -v, z, -D, -F, B, -x, t, -p, l, -h, d, -a, e, -i, m, -q, u, -y, C,}, \ + { F, -D, B, -z, x, -v, t, -r, p, -n, l, -j, h, -f, d, -b, a, -c, e, -g, i, -k, m, -o, q, -s, u, -w, y, -A, C, -E,}, \ +} + + +// DST-7 +#define DEFINE_DST7_P4_MATRIX(a,b,c,d) \ +{ \ + { a, b, c, d }, \ + { c, c, 0, -c }, \ + { d, -a, -c, b }, \ + { b, -d, c, -a }, \ +} + +#define DEFINE_DST7_P8_MATRIX(a,b,c,d,e,f,g,h) \ +{ \ + { a, b, c, d, e, f, g, h,}, \ + { c, f, h, e, b, -a, -d, -g,}, \ + { e, g, b, -c, -h, -d, a, f,}, \ + { g, c, -d, -f, a, h, b, -e,}, \ + { h, -a, -g, b, f, -c, -e, d,}, \ + { f, -e, -a, g, -d, -b, h, -c,}, \ + { d, -h, e, -a, -c, g, -f, b,}, \ + { b, -d, f, -h, g, -e, c, -a,}, \ +} + +#define DEFINE_DST7_P16_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ +{ \ + { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p,}, \ + { c, f, i, l, o, o, l, i, f, c, 0, -c, -f, -i, -l, -o,}, \ + { e, j, o, m, h, c, -b, -g, -l, -p, -k, -f, -a, d, i, n,}, \ + { g, n, l, e, -b, -i, -p, -j, -c, d, k, o, h, a, -f, -m,}, \ + { i, o, f, -c, -l, -l, -c, f, o, i, 0, -i, -o, -f, c, l,}, \ + { k, k, 0, -k, -k, 0, k, k, 0, -k, -k, 0, k, k, 0, -k,}, \ + { m, g, -f, -n, -a, l, h, -e, -o, -b, k, i, -d, -p, -c, j,}, \ + { o, c, -l, -f, i, i, -f, -l, c, o, 0, -o, -c, l, f, -i,}, \ + { p, -a, -o, b, n, -c, -m, d, l, -e, -k, f, j, -g, -i, h,}, \ + { n, -e, -i, j, d, -o, a, m, -f, -h, k, c, -p, b, l, -g,}, \ + { l, -i, -c, o, -f, -f, o, -c, -i, l, 0, -l, i, c, -o, f,}, \ + { j, -m, c, g, -p, f, d, -n, i, a, -k, l, -b, -h, o, -e,}, \ + { h, -p, i, -a, -g, o, -j, b, f, -n, k, -c, -e, m, -l, d,}, \ + { f, -l, o, -i, c, c, -i, o, -l, f, 0, -f, l, -o, i, -c,}, \ + { d, -h, l, -p, m, -i, e, -a, -c, g, -k, o, -n, j, -f, b,}, \ + { b, -d, f, -h, j, -l, n, -p, o, -m, k, -i, g, -e, c, -a,}, \ +} + +#define DEFINE_DST7_P32_MATRIX(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F) \ +{ \ + { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F,}, \ + { c, f, i, l, o, r, u, x, A, D, F, C, z, w, t, q, n, k, h, e, b, -a, -d, -g, -j, -m, -p, -s, -v, -y, -B, -E,}, \ + { e, j, o, t, y, D, D, y, t, o, j, e, 0, -e, -j, -o, -t, -y, -D, -D, -y, -t, -o, -j, -e, 0, e, j, o, t, y, D,}, \ + { g, n, u, B, D, w, p, i, b, -e, -l, -s, -z, -F, -y, -r, -k, -d, c, j, q, x, E, A, t, m, f, -a, -h, -o, -v, -C,}, \ + { i, r, A, C, t, k, b, -g, -p, -y, -E, -v, -m, -d, e, n, w, F, x, o, f, -c, -l, -u, -D, -z, -q, -h, a, j, s, B,}, \ + { k, v, F, u, j, -a, -l, -w, -E, -t, -i, b, m, x, D, s, h, -c, -n, -y, -C, -r, -g, d, o, z, B, q, f, -e, -p, -A,}, \ + { m, z, z, m, 0, -m, -z, -z, -m, 0, m, z, z, m, 0, -m, -z, -z, -m, 0, m, z, z, m, 0, -m, -z, -z, -m, 0, m, z,}, \ + { o, D, t, e, -j, -y, -y, -j, e, t, D, o, 0, -o, -D, -t, -e, j, y, y, j, -e, -t, -D, -o, 0, o, D, t, e, -j, -y,}, \ + { q, E, n, -c, -t, -B, -k, f, w, y, h, -i, -z, -v, -e, l, C, s, b, -o, -F, -p, a, r, D, m, -d, -u, -A, -j, g, x,}, \ + { s, A, h, -k, -D, -p, c, v, x, e, -n, -F, -m, f, y, u, b, -q, -C, -j, i, B, r, -a, -t, -z, -g, l, E, o, -d, -w,}, \ + { u, w, b, -s, -y, -d, q, A, f, -o, -C, -h, m, E, j, -k, -F, -l, i, D, n, -g, -B, -p, e, z, r, -c, -x, -t, a, v,}, \ + { w, s, -d, -A, -o, h, E, k, -l, -D, -g, p, z, c, -t, -v, a, x, r, -e, -B, -n, i, F, j, -m, -C, -f, q, y, b, -u,}, \ + { y, o, -j, -D, -e, t, t, -e, -D, -j, o, y, 0, -y, -o, j, D, e, -t, -t, e, D, j, -o, -y, 0, y, o, -j, -D, -e, t,}, \ + { A, k, -p, -v, e, F, f, -u, -q, j, B, a, -z, -l, o, w, -d, -E, -g, t, r, -i, -C, -b, y, m, -n, -x, c, D, h, -s,}, \ + { C, g, -v, -n, o, u, -h, -B, a, D, f, -w, -m, p, t, -i, -A, b, E, e, -x, -l, q, s, -j, -z, c, F, d, -y, -k, r,}, \ + { E, c, -B, -f, y, i, -v, -l, s, o, -p, -r, m, u, -j, -x, g, A, -d, -D, a, F, b, -C, -e, z, h, -w, -k, t, n, -q,}, \ + { F, -a, -E, b, D, -c, -C, d, B, -e, -A, f, z, -g, -y, h, x, -i, -w, j, v, -k, -u, l, t, -m, -s, n, r, -o, -q, p,}, \ + { D, -e, -y, j, t, -o, -o, t, j, -y, -e, D, 0, -D, e, y, -j, -t, o, o, -t, -j, y, e, -D, 0, D, -e, -y, j, t, -o,}, \ + { B, -i, -s, r, j, -A, -a, C, -h, -t, q, k, -z, -b, D, -g, -u, p, l, -y, -c, E, -f, -v, o, m, -x, -d, F, -e, -w, n,}, \ + { z, -m, -m, z, 0, -z, m, m, -z, 0, z, -m, -m, z, 0, -z, m, m, -z, 0, z, -m, -m, z, 0, -z, m, m, -z, 0, z, -m,}, \ + { x, -q, -g, E, -j, -n, A, -c, -u, t, d, -B, m, k, -D, f, r, -w, -a, y, -p, -h, F, -i, -o, z, -b, -v, s, e, -C, l,}, \ + { v, -u, -a, w, -t, -b, x, -s, -c, y, -r, -d, z, -q, -e, A, -p, -f, B, -o, -g, C, -n, -h, D, -m, -i, E, -l, -j, F, -k,}, \ + { t, -y, e, o, -D, j, j, -D, o, e, -y, t, 0, -t, y, -e, -o, D, -j, -j, D, -o, -e, y, -t, 0, t, -y, e, o, -D, j,}, \ + { r, -C, k, g, -y, v, -d, -n, F, -o, -c, u, -z, h, j, -B, s, -a, -q, D, -l, -f, x, -w, e, m, -E, p, b, -t, A, -i,}, \ + { p, -F, q, -a, -o, E, -r, b, n, -D, s, -c, -m, C, -t, d, l, -B, u, -e, -k, A, -v, f, j, -z, w, -g, -i, y, -x, h,}, \ + { n, -B, w, -i, -e, s, -F, r, -d, -j, x, -A, m, a, -o, C, -v, h, f, -t, E, -q, c, k, -y, z, -l, -b, p, -D, u, -g,}, \ + { l, -x, C, -q, e, g, -s, E, -v, j, b, -n, z, -A, o, -c, -i, u, -F, t, -h, -d, p, -B, y, -m, a, k, -w, D, -r, f,}, \ + { j, -t, D, -y, o, -e, -e, o, -y, D, -t, j, 0, -j, t, -D, y, -o, e, e, -o, y, -D, t, -j, 0, j, -t, D, -y, o, -e,}, \ + { h, -p, x, -F, y, -q, i, -a, -g, o, -w, E, -z, r, -j, b, f, -n, v, -D, A, -s, k, -c, -e, m, -u, C, -B, t, -l, d,}, \ + { f, -l, r, -x, D, -C, w, -q, k, -e, -a, g, -m, s, -y, E, -B, v, -p, j, -d, -b, h, -n, t, -z, F, -A, u, -o, i, -c,}, \ + { d, -h, l, -p, t, -x, B, -F, C, -y, u, -q, m, -i, e, -a, -c, g, -k, o, -s, w, -A, E, -D, z, -v, r, -n, j, -f, b,}, \ + { b, -d, f, -h, j, -l, n, -p, r, -t, v, -x, z, -B, D, -F, E, -C, A, -y, w, -u, s, -q, o, -m, k, -i, g, -e, c, -a,}, \ +} + +//-------------------------------------------------------------------------------------------------- +// DCT-2 +const TMatrixCoeff g_trCoreDCT2P2[TRANSFORM_NUMBER_OF_DIRECTIONS][2][2] = +{ + DEFINE_DCT2_P2_MATRIX(64), + DEFINE_DCT2_P2_MATRIX(64) +}; + +const TMatrixCoeff g_trCoreDCT2P4[TRANSFORM_NUMBER_OF_DIRECTIONS][4][4] = +{ + DEFINE_DCT2_P4_MATRIX(64, 83, 36), + DEFINE_DCT2_P4_MATRIX(64, 83, 36) +}; + +const TMatrixCoeff g_trCoreDCT2P8[TRANSFORM_NUMBER_OF_DIRECTIONS][8][8] = +{ + DEFINE_DCT2_P8_MATRIX(64, 83, 36, 89, 75, 50, 18), + DEFINE_DCT2_P8_MATRIX(64, 83, 36, 89, 75, 50, 18) +}; + +const TMatrixCoeff g_trCoreDCT2P16[TRANSFORM_NUMBER_OF_DIRECTIONS][16][16] = +{ + DEFINE_DCT2_P16_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9), + DEFINE_DCT2_P16_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9) +}; + +const TMatrixCoeff g_trCoreDCT2P32[TRANSFORM_NUMBER_OF_DIRECTIONS][32][32] = +{ + DEFINE_DCT2_P32_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9, 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4), + DEFINE_DCT2_P32_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9, 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4) +}; + +const TMatrixCoeff g_trCoreDCT2P64[TRANSFORM_NUMBER_OF_DIRECTIONS][64][64] = +{ + DEFINE_DCT2_P64_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9, 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4, 91, 90, 90, 90, 88, 87, 86, 84, 83, 81, 79, 77, 73, 71, 69, 65, 62, 59, 56, 52, 48, 44, 41, 37, 33, 28, 24, 20, 15, 11, 7, 2), + DEFINE_DCT2_P64_MATRIX(64, 83, 36, 89, 75, 50, 18, 90, 87, 80, 70, 57, 43, 25, 9, 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4, 91, 90, 90, 90, 88, 87, 86, 84, 83, 81, 79, 77, 73, 71, 69, 65, 62, 59, 56, 52, 48, 44, 41, 37, 33, 28, 24, 20, 15, 11, 7, 2) +}; + +// DCT-8 +const TMatrixCoeff g_trCoreDCT8P4[TRANSFORM_NUMBER_OF_DIRECTIONS][4][4] = +{ + DEFINE_DCT8_P4_MATRIX(84, 74, 55, 29), + DEFINE_DCT8_P4_MATRIX(84, 74, 55, 29) +}; +const TMatrixCoeff g_trCoreDCT8P8[TRANSFORM_NUMBER_OF_DIRECTIONS][8][8] = +{ + DEFINE_DCT8_P8_MATRIX(86, 85, 78, 71, 60, 46, 32, 17), + DEFINE_DCT8_P8_MATRIX(86, 85, 78, 71, 60, 46, 32, 17) +}; +const TMatrixCoeff g_trCoreDCT8P16[TRANSFORM_NUMBER_OF_DIRECTIONS][16][16] = +{ + DEFINE_DCT8_P16_MATRIX(90, 89, 87, 83, 81, 77, 72, 66, 62, 56, 49, 41, 33, 25, 17, 9), + DEFINE_DCT8_P16_MATRIX(90, 89, 87, 83, 81, 77, 72, 66, 62, 56, 49, 41, 33, 25, 17, 9) +}; +const TMatrixCoeff g_trCoreDCT8P32[TRANSFORM_NUMBER_OF_DIRECTIONS][32][32] = +{ + DEFINE_DCT8_P32_MATRIX(90, 90, 89, 88, 88, 86, 85, 84, 82, 80, 78, 77, 74, 72, 68, 66, 63, 60, 56, 53, 50, 45, 42, 38, 34, 30, 26, 21, 17, 13, 9, 4), + DEFINE_DCT8_P32_MATRIX(90, 90, 89, 88, 88, 86, 85, 84, 82, 80, 78, 77, 74, 72, 68, 66, 63, 60, 56, 53, 50, 45, 42, 38, 34, 30, 26, 21, 17, 13, 9, 4) +}; + +// DST-7 +const TMatrixCoeff g_trCoreDST7P4[TRANSFORM_NUMBER_OF_DIRECTIONS][4][4] = +{ + DEFINE_DST7_P4_MATRIX(29, 55, 74, 84), + DEFINE_DST7_P4_MATRIX(29, 55, 74, 84) +}; +const TMatrixCoeff g_trCoreDST7P8[TRANSFORM_NUMBER_OF_DIRECTIONS][8][8] = +{ + DEFINE_DST7_P8_MATRIX(17, 32, 46, 60, 71, 78, 85, 86), + DEFINE_DST7_P8_MATRIX(17, 32, 46, 60, 71, 78, 85, 86) +}; +const TMatrixCoeff g_trCoreDST7P16[TRANSFORM_NUMBER_OF_DIRECTIONS][16][16] = +{ + DEFINE_DST7_P16_MATRIX(9, 17, 25, 33, 41, 49, 56, 62, 66, 72, 77, 81, 83, 87, 89, 90), + DEFINE_DST7_P16_MATRIX(9, 17, 25, 33, 41, 49, 56, 62, 66, 72, 77, 81, 83, 87, 89, 90) +}; +const TMatrixCoeff g_trCoreDST7P32[TRANSFORM_NUMBER_OF_DIRECTIONS][32][32] = +{ + DEFINE_DST7_P32_MATRIX(4, 9, 13, 17, 21, 26, 30, 34, 38, 42, 45, 50, 53, 56, 60, 63, 66, 68, 72, 74, 77, 78, 80, 82, 84, 85, 86, 88, 88, 89, 90, 90), + DEFINE_DST7_P32_MATRIX(4, 9, 13, 17, 21, 26, 30, 34, 38, 42, 45, 50, 53, 56, 60, 63, 66, 68, 72, 74, 77, 78, 80, 82, 84, 85, 86, 88, 88, 89, 90, 90) +}; +#endif // JVET_L0285_8BIT_TRANSFORM_CORE //-------------------------------------------------------------------------------------------------- diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 4bd5fc727de62598db47986f29f9af51f2f8b66d..61e3c8fd94c8b40ed4dd23ce7710a32ca06e2c92 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -41,6 +41,9 @@ #include "Picture.h" #include "dtrace_next.h" +#if JVET_L0266_HMVP +#include "UnitTools.h" +#endif //! \ingroup CommonLib //! \{ @@ -124,7 +127,20 @@ Slice::Slice() , m_encCABACTableIdx (I_SLICE) , m_iProcessingStartTime ( 0 ) , m_dProcessingTime ( 0 ) +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT +, m_splitConsOverrideFlag ( false ) +, m_uiMinQTSize ( 0 ) +, m_uiMaxBTDepth ( 0 ) +, m_uiMaxTTSize ( 0 ) +, m_uiMinQTSizeIChroma ( 0 ) +, m_uiMaxBTDepthIChroma ( 0 ) +, m_uiMaxBTSizeIChroma ( 0 ) +, m_uiMaxTTSizeIChroma ( 0 ) +#endif , m_uiMaxBTSize ( 0 ) +#if JVET_L0266_HMVP +, m_MotionCandLut (NULL) +#endif { for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++) { @@ -161,11 +177,16 @@ Slice::Slice() m_saoEnabledFlag[ch] = false; } +#if JVET_L0266_HMVP + initMotionLUTs(); +#endif } Slice::~Slice() { - +#if JVET_L0266_HMVP + destroyMotionLUTs(); +#endif } @@ -197,6 +218,9 @@ void Slice::initSlice() m_enableTMVPFlag = true; m_subPuMvpSubBlkSizeSliceEnable = false; m_subPuMvpSubBlkLog2Size = 2; +#if JVET_L0266_HMVP + resetMotionLUTs(); +#endif } void Slice::setDefaultClpRng( const SPS& sps ) @@ -815,6 +839,16 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) m_subPuMvpSubBlkLog2Size = pSrc->m_subPuMvpSubBlkLog2Size; m_maxNumMergeCand = pSrc->m_maxNumMergeCand; if( cpyAlmostAll ) m_encCABACTableIdx = pSrc->m_encCABACTableIdx; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + m_splitConsOverrideFlag = pSrc->m_splitConsOverrideFlag; + m_uiMinQTSize = pSrc->m_uiMinQTSize; + m_uiMaxBTDepth = pSrc->m_uiMaxBTDepth; + m_uiMaxTTSize = pSrc->m_uiMaxTTSize; + m_uiMinQTSizeIChroma = pSrc->m_uiMinQTSizeIChroma; + m_uiMaxBTDepthIChroma = pSrc->m_uiMaxBTDepthIChroma; + m_uiMaxBTSizeIChroma = pSrc->m_uiMaxBTSizeIChroma; + m_uiMaxTTSizeIChroma = pSrc->m_uiMaxTTSizeIChroma; +#endif m_uiMaxBTSize = pSrc->m_uiMaxBTSize; } @@ -1550,8 +1584,76 @@ void Slice::stopProcessingTimer() m_dProcessingTime += (double)(clock()-m_iProcessingStartTime) / CLOCKS_PER_SEC; m_iProcessingStartTime = 0; } +#if JVET_L0266_HMVP +void Slice::initMotionLUTs() +{ + m_MotionCandLut = new LutMotionCand; + m_MotionCandLut->currCnt = 0; + m_MotionCandLut->motionCand = nullptr; + m_MotionCandLut->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS]; +} +void Slice::destroyMotionLUTs() +{ + delete[] m_MotionCandLut->motionCand; + m_MotionCandLut->motionCand = nullptr; + delete[] m_MotionCandLut; + m_MotionCandLut = NULL; +} +void Slice::resetMotionLUTs() +{ + m_MotionCandLut->currCnt = 0; +} + +MotionInfo Slice::getMotionInfoFromLUTs(int MotCandIdx) const +{ + return m_MotionCandLut->motionCand[MotCandIdx]; +} + +void Slice::addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi) +{ + int currCnt = lutMC->currCnt ; + + bool pruned = false; + int sameCandIdx = -1; + for (int idx = 0; idx < currCnt; idx++) + { + if (lutMC->motionCand[idx] == newMi) + { + sameCandIdx = idx; + pruned = true; + break; + } + } + if (pruned || lutMC->currCnt == MAX_NUM_HMVP_CANDS) + { + int startIdx = pruned ? sameCandIdx : 0; + memmove(&lutMC->motionCand[startIdx], &lutMC->motionCand[startIdx+1], sizeof(MotionInfo)*(currCnt - sameCandIdx - 1)); + memcpy(&lutMC->motionCand[lutMC->currCnt-1], &newMi, sizeof(MotionInfo)); + } + else + { + memcpy(&lutMC->motionCand[lutMC->currCnt++], &newMi, sizeof(MotionInfo)); + } +} + +void Slice::updateMotionLUTs(LutMotionCand* lutMC, CodingUnit & cu) +{ + PredictionUnit *selectedPU = cu.firstPU; + if (cu.affine) { return; } + + MotionInfo newMi = selectedPU->getMotionInfo(); + addMotionInfoToLUTs(lutMC, newMi); +} + +void Slice::copyMotionLUTs(LutMotionCand* Src, LutMotionCand* Dst) +{ + memcpy(Dst->motionCand, Src->motionCand, sizeof(MotionInfo)*(std::min(Src->currCnt, MAX_NUM_HMVP_CANDS))); + Dst->currCnt = Src->currCnt; +} +#endif + unsigned Slice::getMinPictureDistance() const { int minPicDist = MAX_INT; @@ -1646,12 +1748,25 @@ SPSNext::SPSNext( SPS& sps ) #if ENABLE_WPP_PARALLELISM , m_NextDQP ( false ) #endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + , m_LadfEnabled ( false ) + , m_LadfNumIntervals ( 0 ) + , m_LadfQpOffset { 0 } + , m_LadfIntervalLowerBound { 0 } +#endif // default values for additional parameters , m_CTUSize ( 0 ) +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , m_minQT { 0, 0, 0 } +#else , m_minQT { 0, 0 } +#endif , m_maxBTDepth { MAX_BT_DEPTH, MAX_BT_DEPTH_INTER, MAX_BT_DEPTH_C } , m_maxBTSize { MAX_BT_SIZE, MAX_BT_SIZE_INTER, MAX_BT_SIZE_C } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , m_maxTTSize { MAX_TT_SIZE, MAX_TT_SIZE_INTER, MAX_TT_SIZE_C } +#endif , m_subPuLog2Size ( 0 ) , m_subPuMrgMode ( 0 ) , m_ImvMode ( IMV_OFF ) @@ -2448,6 +2563,11 @@ uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType uint32_t PreCalcValues::getMaxBtDepth( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxBTDepth() : slice.getMaxBTDepthIChroma(); + else +#endif return maxBtDepth[getValIdx( slice, chType )]; } @@ -2458,7 +2578,14 @@ uint32_t PreCalcValues::getMinBtSize( const Slice &slice, const ChannelType chTy uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (slice.getSplitConsOverrideFlag()) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxBTSize() : slice.getMaxBTSizeIChroma(); + else + return maxBtSize[getValIdx(slice, chType)]; +#else return ( !slice.isIRAP() || isLuma( chType ) || ISingleTree ) ? slice.getMaxBTSize() : MAX_BT_SIZE_C; +#endif } uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chType ) const @@ -2468,10 +2595,20 @@ uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chTy uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxTTSize() : slice.getMaxTTSizeIChroma(); + else +#endif return maxTtSize[getValIdx( slice, chType )]; } uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMinQTSize() : slice.getMinQTSizeIChroma(); + else +#endif return minQtSize[getValIdx( slice, chType )]; } diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index f122ab69dbb603ea6f662f32fd5e5f6d84c4a72f..8cbcfee8795e65767309db01ed782f10b68b45ef 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -49,7 +49,10 @@ //! \ingroup CommonLib //! \{ - +#if JVET_L0266_HMVP +#include "CommonLib/MotionInfo.h" +struct MotionInfo; +#endif struct Picture; @@ -820,6 +823,12 @@ private: #if ENABLE_WPP_PARALLELISM bool m_NextDQP; #endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + bool m_LadfEnabled; + int m_LadfNumIntervals; + int m_LadfQpOffset[MAX_LADF_INTERVALS]; + int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS]; +#endif public: const static int NumReservedFlags = 32 - 27; /* current number of tool enabling flags */ @@ -828,9 +837,15 @@ private: //===== additional parameters ===== // qtbt unsigned m_CTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned m_partitionOverrideEnalbed; // enable partition constraints override function +#endif unsigned m_minQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_maxBTDepth[3]; unsigned m_maxBTSize[3]; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned m_maxTTSize[3]; +#endif unsigned m_dualITree; // sub-pu merging unsigned m_subPuLog2Size; @@ -889,11 +904,25 @@ public: #if JVET_L0646_GBI void setUseGBi ( bool b ) { m_GBi = b; } bool getUseGBi () const { return m_GBi; } +#endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + void setLadfEnabled ( bool b ) { m_LadfEnabled = b; } + bool getLadfEnabled () const { return m_LadfEnabled; } + void setLadfNumIntervals ( int i ) { m_LadfNumIntervals = i; } + int getLadfNumIntervals () const { return m_LadfNumIntervals; } + void setLadfQpOffset ( int value, int idx ) { m_LadfQpOffset[ idx ] = value; } + int getLadfQpOffset ( int idx ) const { return m_LadfQpOffset[ idx ]; } + void setLadfIntervalLowerBound( int value, int idx ) { m_LadfIntervalLowerBound[ idx ] = value; } + int getLadfIntervalLowerBound( int idx ) const { return m_LadfIntervalLowerBound[ idx ]; } #endif //===== additional parameters ===== // qtbt void setCTUSize ( unsigned ctuSize ) { m_CTUSize = ctuSize; } unsigned getCTUSize () const { return m_CTUSize; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setSplitConsOverrideEnabledFlag(bool b) { m_partitionOverrideEnalbed = b; } + bool getSplitConsOverrideEnabledFlag() const { return m_partitionOverrideEnalbed; } +#endif void setMinQTSizes ( unsigned* minQT ) { m_minQT[0] = minQT[0]; m_minQT[1] = minQT[1]; m_minQT[2] = minQT[2]; } unsigned getMinQTSize ( SliceType slicetype, ChannelType chType = CHANNEL_TYPE_LUMA ) @@ -910,6 +939,14 @@ public: unsigned getMaxBTSize () const { return m_maxBTSize[1]; } unsigned getMaxBTSizeI () const { return m_maxBTSize[0]; } unsigned getMaxBTSizeIChroma () const { return m_maxBTSize[2]; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setMaxTTSize (unsigned maxTTSize, + unsigned maxTTSizeI, + unsigned maxTTSizeC) { m_maxTTSize[1] = maxTTSize; m_maxTTSize[0] = maxTTSizeI; m_maxTTSize[2] = maxTTSizeC; } + unsigned getMaxTTSize() const { return m_maxTTSize[1]; } + unsigned getMaxTTSizeI() const { return m_maxTTSize[0]; } + unsigned getMaxTTSizeIChroma() const { return m_maxTTSize[2]; } +#endif void setUseDualITree ( bool b ) { m_dualITree = b; } bool getUseDualITree () const { return m_dualITree; } @@ -1557,9 +1594,23 @@ private: clock_t m_iProcessingStartTime; double m_dProcessingTime; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_splitConsOverrideFlag; + uint32_t m_uiMinQTSize; + uint32_t m_uiMaxBTDepth; + uint32_t m_uiMaxTTSize; + + uint32_t m_uiMinQTSizeIChroma; + uint32_t m_uiMaxBTDepthIChroma; + uint32_t m_uiMaxBTSizeIChroma; + uint32_t m_uiMaxTTSizeIChroma; +#endif uint32_t m_uiMaxBTSize; AlfSliceParam m_alfSliceParam; +#if JVET_L0266_HMVP + LutMotionCand* m_MotionCandLut; +#endif public: Slice(); @@ -1667,6 +1718,25 @@ public: void setLambdas( const double lambdas[MAX_NUM_COMPONENT] ) { for (int component = 0; component < MAX_NUM_COMPONENT; component++) m_lambdas[component] = lambdas[component]; } const double* getLambdas() const { return m_lambdas; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setSplitConsOverrideFlag(bool b) { m_splitConsOverrideFlag = b; } + bool getSplitConsOverrideFlag() const { return m_splitConsOverrideFlag; } + void setMinQTSize(int i) { m_uiMinQTSize = i; } + uint32_t getMinQTSize() const { return m_uiMinQTSize; } + void setMaxBTDepth(int i) { m_uiMaxBTDepth = i; } + uint32_t getMaxBTDepth() const { return m_uiMaxBTDepth; } + void setMaxTTSize(int i) { m_uiMaxTTSize = i; } + uint32_t getMaxTTSize() const { return m_uiMaxTTSize; } + + void setMinQTSizeIChroma(int i) { m_uiMinQTSizeIChroma = i; } + uint32_t getMinQTSizeIChroma() const { return m_uiMinQTSizeIChroma; } + void setMaxBTDepthIChroma(int i) { m_uiMaxBTDepthIChroma = i; } + uint32_t getMaxBTDepthIChroma() const { return m_uiMaxBTDepthIChroma; } + void setMaxBTSizeIChroma(int i) { m_uiMaxBTSizeIChroma = i; } + uint32_t getMaxBTSizeIChroma() const { return m_uiMaxBTSizeIChroma; } + void setMaxTTSizeIChroma(int i) { m_uiMaxTTSizeIChroma = i; } + uint32_t getMaxTTSizeIChroma() const { return m_uiMaxTTSizeIChroma; } +#endif void setMaxBTSize(int i) { m_uiMaxBTSize = i; } uint32_t getMaxBTSize() const { return m_uiMaxBTSize; } @@ -1817,6 +1887,20 @@ public: void setAlfSliceParam( AlfSliceParam& alfSliceParam ) { m_alfSliceParam = alfSliceParam; } AlfSliceParam& getAlfSliceParam() { return m_alfSliceParam; } +#if JVET_L0266_HMVP + void initMotionLUTs (); + void destroyMotionLUTs (); + void resetMotionLUTs(); + int getAvailableLUTMrgNum() const { return m_MotionCandLut->currCnt; } + MotionInfo getMotionInfoFromLUTs(int MotCandIdx) const; + LutMotionCand* getMotionLUTs() { return m_MotionCandLut; } + + + void addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi); + + void updateMotionLUTs(LutMotionCand* lutMC, CodingUnit & cu); + void copyMotionLUTs(LutMotionCand* Src, LutMotionCand* Dst); +#endif protected: Picture* xGetRefPic (PicList& rcListPic, int poc); @@ -2064,7 +2148,11 @@ public: , minBtSize { MIN_BT_SIZE, MIN_BT_SIZE_INTER, MIN_BT_SIZE_C } , maxBtSize { sps.getSpsNext().getMaxBTSizeI(), sps.getSpsNext().getMaxBTSize(), sps.getSpsNext().getMaxBTSizeIChroma() } , minTtSize { MIN_TT_SIZE, MIN_TT_SIZE_INTER, MIN_TT_SIZE_C } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , maxTtSize { sps.getSpsNext().getMaxTTSizeI(), sps.getSpsNext().getMaxTTSize(), sps.getSpsNext().getMaxTTSizeIChroma() } +#else , maxTtSize { MAX_TT_SIZE, MAX_TT_SIZE_INTER, MAX_TT_SIZE_C } +#endif , minQtSize { sps.getSpsNext().getMinQTSize( I_SLICE, CHANNEL_TYPE_LUMA ), sps.getSpsNext().getMinQTSize( B_SLICE, CHANNEL_TYPE_LUMA ), sps.getSpsNext().getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA ) } {} diff --git a/source/Lib/CommonLib/TrQuant_EMT.cpp b/source/Lib/CommonLib/TrQuant_EMT.cpp index 99ec664b4e91f3e92debc46a093ed08e92cca477..c7100ab6a2d6a5bd37455539ab37589da261b23c 100644 --- a/source/Lib/CommonLib/TrQuant_EMT.cpp +++ b/source/Lib/CommonLib/TrQuant_EMT.cpp @@ -54,7 +54,11 @@ void fastForwardDCT2_B2(const TCoeff *src, TCoeff *dst, int shift, int line, int int E, O; TCoeff add = (shift > 0) ? (1 << (shift - 1)) : 0; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P2[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr2[DCT2][0]; +#endif TCoeff *pCoef = dst; const int reducedLine = line - iSkipLine; @@ -88,7 +92,11 @@ void fastInverseDCT2_B2(const TCoeff *src, TCoeff *dst, int shift, int line, int int E, O; int add = 1 << (shift - 1); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P2[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr2[DCT2][0]; +#endif const int reducedLine = line - iSkipLine; for (j = 0; j<reducedLine; j++) @@ -134,7 +142,11 @@ void fastForwardDCT2_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int TCoeff E[2], O[2]; TCoeff add = (shift > 0) ? (1 << (shift - 1)) : 0; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P4[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr4[DCT2][0]; +#endif TCoeff *pCoef = dst; const int reducedLine = line - iSkipLine; @@ -179,7 +191,11 @@ void fastInverseDCT2_B4( const TCoeff *src, TCoeff *dst, int shift, int line, in int E[2], O[2]; int add = 1 << ( shift - 1 ); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P4[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr4[DCT2][0]; +#endif const int reducedLine = line - iSkipLine; for( j = 0; j < reducedLine; j++ ) @@ -291,7 +307,11 @@ void fastForwardDCT2_B8( const TCoeff *src, TCoeff *dst, int shift, int line, in TCoeff EE[2], EO[2]; TCoeff add = ( shift > 0 ) ? ( 1 << ( shift - 1 ) ) : 0; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P8[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr8[DCT2][0]; +#endif TCoeff *pCoef = dst; const int reducedLine = line - iSkipLine; @@ -348,7 +368,11 @@ void fastInverseDCT2_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int int EE[2], EO[2]; int add = 1 << (shift - 1); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P8[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr8[DCT2][0]; +#endif const int reducedLine = line - iSkipLine; for( j = 0; j < reducedLine; j++ ) @@ -399,7 +423,11 @@ void fastForwardDCT2_B16(const TCoeff *src, TCoeff *dst, int shift, int line, in TCoeff EEE[2], EEO[2]; TCoeff add = ( shift > 0 ) ? ( 1 << ( shift - 1 ) ) : 0; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P16[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr16[DCT2][0]; +#endif TCoeff *pCoef = dst; const int reducedLine = line - iSkipLine; @@ -470,7 +498,11 @@ void fastInverseDCT2_B16( const TCoeff *src, TCoeff *dst, int shift, int line, i int EEE[2], EEO[2]; int add = 1 << ( shift - 1 ); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P16[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr16[DCT2][0]; +#endif const int reducedLine = line - iSkipLine; @@ -533,7 +565,11 @@ void fastForwardDCT2_B32( const TCoeff *src, TCoeff *dst, int shift, int line, i TCoeff EEEE[ 2], EEEO[ 2]; TCoeff add = ( shift > 0 ) ? ( 1 << ( shift - 1 ) ) : 0; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P32[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr32[DCT2][0]; +#endif TCoeff *pCoef = dst; const int reducedLine = line - iSkipLine; @@ -615,7 +651,11 @@ void fastInverseDCT2_B32(const TCoeff *src, TCoeff *dst, int shift, int line, in int EEEE[2], EEEO[2]; int add = 1 << (shift - 1); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P32[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr32[DCT2][0]; +#endif const int reducedLine = line - iSkipLine; for (j = 0; j<reducedLine; j++) @@ -676,7 +716,11 @@ void fastForwardDCT2_B64(const TCoeff *src, TCoeff *dst, int shift, int line, in int rnd_factor = 1 << (shift - 1); const int uiTrSize = 64; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P64[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr64[DCT2][0]; +#endif int j, k; TCoeff E[32], O[32]; @@ -781,7 +825,11 @@ void fastInverseDCT2_B64(const TCoeff *src, TCoeff *dst, int shift, int line, in { int rnd_factor = 1 << (shift - 1); const int uiTrSize = 64; +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT2P64[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr64[DCT2][0]; +#endif int j, k; TCoeff E[32], O[32]; @@ -869,7 +917,9 @@ void fastForwardDST7_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int int i; TCoeff rnd_factor = (shift > 0) ? (1 << (shift - 1)) : 0; -#if HEVC_USE_4x4_DSTVII +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDST7P4[TRANSFORM_FORWARD][0]; +#elif HEVC_USE_4x4_DSTVII const TMatrixCoeff *iT = use ? g_aiTr4[DST7][0] : g_as_DST_MAT_4[TRANSFORM_FORWARD][0]; #else const TMatrixCoeff *iT = g_aiTr4[DST7][0]; @@ -911,7 +961,9 @@ void fastInverseDST7_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int TCoeff c[4]; TCoeff rnd_factor = (shift > 0) ? (1 << (shift - 1)) : 0; -#if HEVC_USE_4x4_DSTVII +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDST7P4[TRANSFORM_INVERSE][0]; +#elif HEVC_USE_4x4_DSTVII const TMatrixCoeff *iT = use ? g_aiTr4[DST7][0] : g_as_DST_MAT_4[TRANSFORM_INVERSE][0]; #else const TMatrixCoeff *iT = g_aiTr4[DST7][0]; @@ -944,34 +996,58 @@ void fastInverseDST7_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int void fastForwardDST7_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDST7P8[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr8[DST7][0] ); +#endif } void fastInverseDST7_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDST7P8[TRANSFORM_INVERSE][0]); +#else _fastInverseMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr8[DST7][0] ); +#endif } void fastForwardDST7_B16(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDST7P16[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr16[DST7][0] ); +#endif } void fastInverseDST7_B16(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDST7P16[TRANSFORM_INVERSE][0]); +#else _fastInverseMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr16[DST7][0] ); +#endif } void fastForwardDST7_B32(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDST7P32[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr32[DST7][0] ); +#endif } void fastInverseDST7_B32(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDST7P32[TRANSFORM_INVERSE][0] ); +#else _fastInverseMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr32[DST7][0] ); +#endif } @@ -980,7 +1056,11 @@ void fastForwardDCT8_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int { int i; int rnd_factor = 1 << (shift - 1); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT8P4[TRANSFORM_FORWARD][0]; +#else const TMatrixCoeff *iT = g_aiTr4[DCT8][0]; +#endif int c[4]; TCoeff *pCoeff = dst; @@ -1017,7 +1097,11 @@ void fastInverseDCT8_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int int i; int rnd_factor = 1 << (shift - 1); +#if JVET_L0285_8BIT_TRANSFORM_CORE + const TMatrixCoeff *iT = g_trCoreDCT8P4[TRANSFORM_INVERSE][0]; +#else const TMatrixCoeff *iT = g_aiTr4[DCT8][0]; +#endif int c[4]; const int reducedLine = line - iSkipLine; @@ -1046,33 +1130,57 @@ void fastInverseDCT8_B4(const TCoeff *src, TCoeff *dst, int shift, int line, int void fastForwardDCT8_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDCT8P8[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr8[DCT8][0] ); +#endif } void fastInverseDCT8_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDCT8P8[TRANSFORM_INVERSE][0] ); +#else _fastInverseMM< 8 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr8[DCT8][0] ); +#endif } void fastForwardDCT8_B16(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDCT8P16[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr16[DCT8][0] ); +#endif } void fastInverseDCT8_B16(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDCT8P16[TRANSFORM_INVERSE][0] ); +#else _fastInverseMM< 16 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr16[DCT8][0] ); +#endif } void fastForwardDCT8_B32(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastForwardMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_trCoreDCT8P32[TRANSFORM_FORWARD][0] ); +#else _fastForwardMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, g_aiTr32[DCT8][0] ); +#endif } void fastInverseDCT8_B32(const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum) { +#if JVET_L0285_8BIT_TRANSFORM_CORE + _fastInverseMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_trCoreDCT8P32[TRANSFORM_INVERSE][0] ); +#else _fastInverseMM< 32 >( src, dst, shift, line, iSkipLine, iSkipLine2, outputMinimum, outputMaximum, g_aiTr32[DCT8][0] ); +#endif } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index e6ad40144ce200256e7f02b07bc582741f44c798..bacad9ccba0fb6d93fb027be3b6750e9937c5840 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,13 @@ #include <assert.h> #include <cassert> +#define JVET_L0285_8BIT_TRANSFORM_CORE 1 // Primary transform using 8-bit cores + +#define JVET_L0081_VPDU_SPLIT_CONSTRAINTS 1 // VPDU constraints for binary and ternary partitions + +#define JVET_L0104_NO_4x4BI_INTER_CU 1 // Prohibit 4x4 bi-prediction for inter CU +#define JVET_L0266_HMVP 1 //History-based MVP + #define JVET_L0553_FIX_INITQP 1 #define JVET_L0147_ALF_SUBSAMPLED_LAPLACIAN 1 // Subsampled Laplacian calculation @@ -57,6 +64,7 @@ #define JVET_L0191_LM_WO_LMS 1 // NO LMS regression. min/max are used instead #define JVET_L0090_PAIR_AVG 1 // Add pairwise average candidates, replace HEVC combined candidates +#define JVET_L0054_MMVD 1 #define JVET_L0392_ALF_INIT_STATE 1 @@ -127,6 +135,7 @@ #define NUM_SPLIT_THREADS_IF_MSVC 4 #endif +#define JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT 1 // ==================================================================================================================== @@ -287,6 +296,7 @@ #define QP_SWITCHING_FOR_PARALLEL 1 ///< Replace floating point QP with a source-file frame number. After switching POC, increase base QP instead of frame level QP. +#define LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET 1 /// JVET-L0414 (CE11.2.2) with explicit signalling of num interval, threshold and qpOffset // ==================================================================================================================== // Derived macros // ==================================================================================================================== diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index 6152c93f57b58f37865eb29ad338f314b8b6babd..e81e2170b05dc2fff3268b1370cf4ae7a49cde36 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -253,6 +253,9 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other ) mtDepth = other.mtDepth; splitSeries = other.splitSeries; skip = other.skip; +#if JVET_L0054_MMVD + mmvdSkip = other.mmvdSkip; +#endif affine = other.affine; affineType = other.affineType; transQuantBypass = other.transQuantBypass; @@ -268,6 +271,8 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other ) imvNumCand = other.imvNumCand; #if JVET_L0646_GBI GBiIdx = other.GBiIdx; + for (int i = 0; i<2; i++) + refIdxBi[i] = other.refIdxBi[i]; #endif return *this; } @@ -282,6 +287,9 @@ void CodingUnit::initData() mtDepth = 0; splitSeries = 0; skip = false; +#if JVET_L0054_MMVD + mmvdSkip = false; +#endif affine = false; affineType = 0; transQuantBypass = false; @@ -297,6 +305,8 @@ void CodingUnit::initData() imvNumCand = 0; #if JVET_L0646_GBI GBiIdx = GBI_DEFAULT; + for (int i = 0; i < 2; i++) + refIdxBi[i] = -1; #endif } @@ -317,6 +327,10 @@ void PredictionUnit::initData() // inter data mergeFlag = false; mergeIdx = MAX_UCHAR; +#if JVET_L0054_MMVD + mmvdMergeFlag = false; + mmvdMergeIdx = MAX_UINT; +#endif interDir = MAX_UCHAR; mergeType = MRG_TYPE_DEFAULT_N; for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) @@ -347,6 +361,10 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) { mergeFlag = predData.mergeFlag; mergeIdx = predData.mergeIdx; +#if JVET_L0054_MMVD + mmvdMergeFlag = predData.mmvdMergeFlag; + mmvdMergeIdx = predData.mmvdMergeIdx; +#endif interDir = predData.interDir; mergeType = predData.mergeType; for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) @@ -374,6 +392,10 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) mergeFlag = other.mergeFlag; mergeIdx = other.mergeIdx; +#if JVET_L0054_MMVD + mmvdMergeFlag = other.mmvdMergeFlag; + mmvdMergeIdx = other.mmvdMergeIdx; +#endif interDir = other.interDir; mergeType = other.mergeType; for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 93924a20065a649ddfe4e80adaf1b4553766616c..083a2e36eefe2257e9b01c77f96670b4ff5ed906 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -295,6 +295,9 @@ struct CodingUnit : public UnitArea int8_t qp; SplitSeries splitSeries; bool skip; +#if JVET_L0054_MMVD + bool mmvdSkip; +#endif bool affine; int affineType; bool transQuantBypass; @@ -349,6 +352,10 @@ struct InterPredictionData { bool mergeFlag; uint8_t mergeIdx; +#if JVET_L0054_MMVD + bool mmvdMergeFlag; + uint32_t mmvdMergeIdx; +#endif uint8_t interDir; uint8_t mvpIdx [NUM_REF_PIC_LIST_01]; uint8_t mvpNum [NUM_REF_PIC_LIST_01]; diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp index 17c68fe15488eebb418c3a6e6295f74024db6601..949f5975a936ab30f20d7035d0db6d4d5beb4528 100644 --- a/source/Lib/CommonLib/UnitPartitioner.cpp +++ b/source/Lib/CommonLib/UnitPartitioner.cpp @@ -412,17 +412,29 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs { case CU_HORZ_SPLIT: if( area.height <= minBtSize || area.height > maxBtSize ) return false; +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + if( area.width > MAX_TU_SIZE_FOR_PROFILE && area.height <= MAX_TU_SIZE_FOR_PROFILE ) return false; +#endif break; case CU_VERT_SPLIT: if( area.width <= minBtSize || area.width > maxBtSize ) return false; +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + if( area.width <= MAX_TU_SIZE_FOR_PROFILE && area.height > MAX_TU_SIZE_FOR_PROFILE ) return false; +#endif break; case CU_TRIH_SPLIT: if( ( cs.sps->getSpsNext().getMTTMode() & 1 ) != 1 ) return false; if( area.height <= 2 * minTtSize || area.height > maxTtSize || area.width > maxTtSize) return false; +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + if( area.width > MAX_TU_SIZE_FOR_PROFILE || area.height > MAX_TU_SIZE_FOR_PROFILE ) return false; +#endif break; case CU_TRIV_SPLIT: if( ( cs.sps->getSpsNext().getMTTMode() & 1 ) != 1 ) return false; if( area.width <= 2 * minTtSize || area.width > maxTtSize || area.height > maxTtSize) return false; +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + if( area.width > MAX_TU_SIZE_FOR_PROFILE || area.height > MAX_TU_SIZE_FOR_PROFILE ) return false; +#endif break; default: break; diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 065e4fe39742efeb66e7cff63714dc3909d5d84f..7f6f5034df91c1c89892ce7ed3f479e9233b6708 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -494,8 +494,95 @@ uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chT return uiIntraMode; } +#if JVET_L0266_HMVP +bool PU::xCheckSimilarMotion(const int mergeCandIndex, const int prevCnt, const MergeCtx mergeCandList, bool hasPruned[MRG_MAX_NUM_CANDS]) +{ + for (uint32_t ui = 0; ui < prevCnt; ui++) + { + if (hasPruned[ui]) + { + continue; + } + if (mergeCandList.interDirNeighbours[ui] == mergeCandList.interDirNeighbours[mergeCandIndex]) + { + if (mergeCandList.interDirNeighbours[ui] == 3) + { + int offset0 = (ui * 2); + int offset1 = (mergeCandIndex * 2); + if (mergeCandList.mvFieldNeighbours[offset0].refIdx == mergeCandList.mvFieldNeighbours[offset1].refIdx && + mergeCandList.mvFieldNeighbours[offset0 + 1].refIdx == mergeCandList.mvFieldNeighbours[offset1 + 1].refIdx && + mergeCandList.mvFieldNeighbours[offset0].mv == mergeCandList.mvFieldNeighbours[offset1].mv && + mergeCandList.mvFieldNeighbours[offset0 + 1].mv == mergeCandList.mvFieldNeighbours[offset1 + 1].mv + ) + { + hasPruned[ui] = true; + return true; + } + } + else + { + int offset0 = (ui * 2) + mergeCandList.interDirNeighbours[ui] - 1; + int offset1 = (mergeCandIndex * 2) + mergeCandList.interDirNeighbours[ui] - 1; + if (mergeCandList.mvFieldNeighbours[offset0].refIdx == mergeCandList.mvFieldNeighbours[offset1].refIdx && + mergeCandList.mvFieldNeighbours[offset0].mv == mergeCandList.mvFieldNeighbours[offset1].mv + ) + { + hasPruned[ui] = true; + return true; + } + } + } + } -void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx ) + return false; +} +#if JVET_L0090_PAIR_AVG +bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos) +#else +bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos) +#endif +{ + MotionInfo miNeighbor; + bool hasPruned[MRG_MAX_NUM_CANDS]; + memset(hasPruned, 0, MRG_MAX_NUM_CANDS * sizeof(bool)); + if (isAvailableSubPu) + { + hasPruned[subPuMvpPos] = true; + } + int num_avai_candInLUT = slice.getAvailableLUTMrgNum(); + for (int mrgIdx = 1; mrgIdx <= num_avai_candInLUT; mrgIdx++) + { + miNeighbor = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx); + mrgCtx.interDirNeighbours[cnt] = miNeighbor.interDir; + mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miNeighbor.mv[0], miNeighbor.refIdx[0]); + if (slice.isInterB()) + { + mrgCtx.mvFieldNeighbours[(cnt << 1) + 1].setMvField(miNeighbor.mv[1], miNeighbor.refIdx[1]); + } + if (!xCheckSimilarMotion(cnt, prevCnt, mrgCtx, hasPruned)) + { +#if !JVET_L0090_PAIR_AVG + isCandInter[cnt] = true; +#endif + if (mrgCandIdx == cnt && canFastExit) + { + return true; + } + cnt ++; + if (cnt == maxNumMergeCandMin1) + { + break; + } + } + } + return false; +} +#endif +void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, +#if JVET_L0054_MMVD + int mmvdList, +#endif + const int& mrgCandIdx ) { const CodingStructure &cs = *pu.cs; const Slice &slice = *pu.cs->slice; @@ -723,7 +810,11 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co bool bMrgIdxMatchATMVPCan = ( mrgCandIdx == cnt ); bool tmpLICFlag = false; - isAvailableSubPu = cs.sps->getSpsNext().getUseATMVP() && getInterMergeSubPuMvpCand( pu, mrgCtx, tmpLICFlag, cnt + isAvailableSubPu = cs.sps->getSpsNext().getUseATMVP() && + getInterMergeSubPuMvpCand( pu, mrgCtx, tmpLICFlag, cnt +#if JVET_L0054_MMVD + , mmvdList +#endif ); if( isAvailableSubPu ) @@ -923,7 +1014,21 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co { return; } - +#if JVET_L0266_HMVP + int maxNumMergeCandMin1 = maxNumMergeCand - 1; + if (cnt != maxNumMergeCandMin1) + { +#if JVET_L0090_PAIR_AVG + bool bFound = addMergeHMVPCand(slice, mrgCtx, canFastExit, mrgCandIdx, maxNumMergeCandMin1, cnt, cnt, isAvailableSubPu, subPuMvpPos); +#else + bool bFound = addMergeHMVPCand(slice, mrgCtx, isCandInter, canFastExit, mrgCandIdx, maxNumMergeCandMin1, cnt, cnt, isAvailableSubPu, subPuMvpPos); +#endif + if (bFound) + { + return; + } + } +#endif #if JVET_L0090_PAIR_AVG // pairwise-average candidates { @@ -1015,8 +1120,11 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co uint32_t uiArrayAddr = cnt; #if !JVET_L0090_PAIR_AVG +#if JVET_L0266_HMVP + uint32_t uiCutoff = std::min( uiArrayAddr, 3u ); +#else uint32_t uiCutoff = std::min( uiArrayAddr, 4u ); - +#endif if (slice.isInterB()) { static const uint32_t NUM_PRIORITY_LIST = 12; @@ -1117,7 +1225,78 @@ static int xGetDistScaleFactor(const int &iCurrPOC, const int &iCurrRefPOC, cons return iScale; } } +#if JVET_L0054_MMVD +int PU::getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int &colPOC, const int &colRefPOC) +{ + return xGetDistScaleFactor(currPOC, currRefPOC, colPOC, colRefPOC); +} + +void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx) +{ + int refIdxList0, refIdxList1; + int k; + int currBaseNum = 0; + const uint16_t maxNumMergeCand = mrgCtx.numValidMergeCand; + +#if !REMOVE_MV_ADAPT_PREC + if (pu.cu->slice->getSPS()->getSpsNext().getUseHighPrecMv()) + { + for (k = 0; k < maxNumMergeCand; k++) + { + if (mrgCtx.mrgTypeNeighbours[k] == MRG_TYPE_DEFAULT_N) + { + if ((mrgCtx.mvFieldNeighbours[(k << 1)].mv.highPrec == false) && (mrgCtx.mvFieldNeighbours[(k << 1)].refIdx >= 0)) + { + mrgCtx.mvFieldNeighbours[(k << 1)].mv.setHighPrec(); + } + if ((mrgCtx.mvFieldNeighbours[(k << 1) + 1].mv.highPrec == false) && (mrgCtx.mvFieldNeighbours[(k << 1) + 1].refIdx >= 0)) + { + mrgCtx.mvFieldNeighbours[(k << 1) + 1].mv.setHighPrec(); + } + } + } + } +#endif + for (k = 0; k < maxNumMergeCand; k++) + { + if (mrgCtx.mrgTypeNeighbours[k] == MRG_TYPE_DEFAULT_N) + { + refIdxList0 = mrgCtx.mvFieldNeighbours[(k << 1)].refIdx; + refIdxList1 = mrgCtx.mvFieldNeighbours[(k << 1) + 1].refIdx; + + if ((refIdxList0 >= 0) && (refIdxList1 >= 0)) + { + mrgCtx.mmvdBaseMv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[(k << 1)]; + mrgCtx.mmvdBaseMv[currBaseNum][1] = mrgCtx.mvFieldNeighbours[(k << 1) + 1]; + } + else if (refIdxList0 >= 0) + { + mrgCtx.mmvdBaseMv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[(k << 1)]; + mrgCtx.mmvdBaseMv[currBaseNum][1] = MvField(Mv(0, 0), -1); + } + else if (refIdxList1 >= 0) + { + mrgCtx.mmvdBaseMv[currBaseNum][0] = MvField(Mv(0, 0), -1); + mrgCtx.mmvdBaseMv[currBaseNum][1] = mrgCtx.mvFieldNeighbours[(k << 1) + 1]; + } + currBaseNum++; + + if (currBaseNum == MMVD_BASE_MV_NUM) + break; + } + } + + if (currBaseNum < MMVD_BASE_MV_NUM) + { + for (k = currBaseNum; k < MMVD_BASE_MV_NUM; k++) + { + mrgCtx.mmvdBaseMv[k][0] = MvField(Mv(0, 0), 0); + mrgCtx.mmvdBaseMv[k][0] = MvField(Mv(0, 0), 0); + } + } +} +#endif bool PU::getColocatedMVP(const PredictionUnit &pu, const RefPicList &eRefPicList, const Position &_pos, Mv& rcMv, const int &refIdx ) { // don't perform MV compression when generally disabled or subPuMvp is used @@ -1391,9 +1570,37 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in if ((C0Avail && getColocatedMVP(pu, eRefPicList, posC0, cColMv, refIdx_Col)) || getColocatedMVP(pu, eRefPicList, posC1, cColMv, refIdx_Col)) { +#if JVET_L0266_HMVP + if (pu.cu->imv != 0) + { + unsigned imvShift = pu.cu->imv << 1; + roundMV(cColMv, imvShift); + } + int i = 0; + for (i = 0; i < pInfo->numCand; i++) + { + if (cColMv == pInfo->mvCand[i]) + { + break; + } + } + if (i == pInfo->numCand) + { + pInfo->mvCand[pInfo->numCand++] = cColMv; + } +#else pInfo->mvCand[pInfo->numCand++] = cColMv; +#endif } } +#if JVET_L0266_HMVP + if (pInfo->numCand < AMVP_MAX_NUM_CANDS) + { + const int currRefPOC = cs.slice->getRefPic(eRefPicList, refIdx)->getPOC(); + const RefPicList eRefPicList2nd = (eRefPicList == REF_PIC_LIST_0) ? REF_PIC_LIST_1 : REF_PIC_LIST_0; + addAMVPHMVPCand(pu, eRefPicList, eRefPicList2nd, currRefPOC, *pInfo, pu.cu->imv); + } +#endif if (pInfo->numCand > AMVP_MAX_NUM_CANDS) { pInfo->numCand = AMVP_MAX_NUM_CANDS; @@ -1952,9 +2159,67 @@ bool PU::addMVPCandWithScaling( const PredictionUnit &pu, const RefPicList &eRef return false; } +#if JVET_L0266_HMVP +void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList, const RefPicList eRefPicList2nd, const int currRefPOC, AMVPInfo &info, uint8_t imv) +{ + const Slice &slice = *(*pu.cs).slice; + + MotionInfo neibMi; + int i = 0; + unsigned imvShift = imv << 1; + + int num_avai_candInLUT = slice.getAvailableLUTMrgNum(); + int num_allowedCand = std::min(MAX_NUM_HMVP_AVMPCANDS, num_avai_candInLUT); + + for (int mrgIdx = 1; mrgIdx <= num_allowedCand; mrgIdx++) + { + if (info.numCand >= AMVP_MAX_NUM_CANDS) + { + return; + } + neibMi = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx); + + for (int predictorSource = 0; predictorSource < 2; predictorSource++) + { + const RefPicList eRefPicListIndex = (predictorSource == 0) ? eRefPicList : eRefPicList2nd; + const int neibRefIdx = neibMi.refIdx[eRefPicListIndex]; + + if (neibRefIdx >= 0 && currRefPOC == slice.getRefPOC(eRefPicListIndex, neibRefIdx)) + { + Mv pmv = neibMi.mv[eRefPicListIndex]; + if (imv != 0) + { + roundMV(pmv, imvShift); + } + for (i = 0; i < info.numCand; i++) + { + if (pmv == info.mvCand[i]) + { + break; + } + } + if (i == info.numCand) + { + info.mvCand[info.numCand++] = pmv; + if (info.numCand >= AMVP_MAX_NUM_CANDS) + { + return; + } + } + } + } + } +} +#endif bool PU::isBipredRestriction(const PredictionUnit &pu) { const SPSNext &spsNext = pu.cs->sps->getSpsNext(); +#if JVET_L0104_NO_4x4BI_INTER_CU + if(pu.cu->lumaSize().width == 4 && pu.cu->lumaSize().height ==4 ) + { + return true; + } +#endif if( !pu.cs->pcv->only2Nx2N && !spsNext.getUseSubPuMvp() && pu.cu->lumaSize().width == 8 && ( pu.lumaSize().width < 8 || pu.lumaSize().height < 8 ) ) { return true; @@ -2281,6 +2546,9 @@ void clipColBlkMv(int& mvX, int& mvY, const PredictionUnit& pu) #endif bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, bool& LICFlag, const int count +#if JVET_L0054_MMVD + , int mmvdList +#endif ) { const Slice &slice = *pu.cs->slice; @@ -2406,7 +2674,10 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b { return false; } - +#if JVET_L0054_MMVD + if (mmvdList != 1) + { +#endif #if JVET_L0257_ATMVP_COLBLK_CLIP int xOff = (puWidth >> 1) + tempX; int yOff = (puHeight >> 1) + tempY; @@ -2481,7 +2752,9 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b mb.subBuf(g_miScaling.scale(Position{ x, y } -pu.lumaPos()), g_miScaling.scale(Size(puWidth, puHeight))).fill(mi); } } - +#if JVET_L0054_MMVD + } +#endif return true; } @@ -2611,7 +2884,11 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP { // this function is never called for merge THROW("unexpected"); - PU::getInterMergeCandidates ( pu, mrgCtx ); + PU::getInterMergeCandidates ( pu, mrgCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); PU::restrictBiPredMergeCands( pu, mrgCtx ); mrgCtx.setMergeInfo( pu, pu.mergeIdx ); @@ -2704,7 +2981,11 @@ void CU::resetMVDandMV2Int( CodingUnit& cu, InterPrediction *interPred ) } else { - PU::getInterMergeCandidates ( pu, mrgCtx ); + PU::getInterMergeCandidates ( pu, mrgCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); PU::restrictBiPredMergeCands( pu, mrgCtx ); mrgCtx.setMergeInfo( pu, pu.mergeIdx ); diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 3247170c6f357a977fdc39d16be213adee1a28ee..de3d187675a6ce4a4d0cebc863ac108869bfbac1 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -109,8 +109,15 @@ namespace PU int getIntraMPMs(const PredictionUnit &pu, unsigned *mpm, const ChannelType &channelType = CHANNEL_TYPE_LUMA); void getIntraChromaCandModes (const PredictionUnit &pu, unsigned modeList[NUM_CHROMA_MODE]); uint32_t getFinalIntraMode (const PredictionUnit &pu, const ChannelType &chType); - - void getInterMergeCandidates (const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1 ); + void getInterMergeCandidates (const PredictionUnit &pu, MergeCtx& mrgCtx, +#if JVET_L0054_MMVD + int mmvdList, +#endif + const int& mrgCandIdx = -1 ); +#if JVET_L0054_MMVD + void getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); + int getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int &colPOC, const int &colRefPOC); +#endif bool isDiffMER (const PredictionUnit &pu, const PredictionUnit &pu2); bool getColocatedMVP (const PredictionUnit &pu, const RefPicList &eRefPicList, const Position &pos, Mv& rcMv, const int &refIdx); void fillMvpCand ( PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AMVPInfo &amvpInfo ); @@ -118,6 +125,15 @@ namespace PU bool addMVPCandUnscaled (const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AMVPInfo &amvpInfo, bool affine = false); bool addMVPCandWithScaling (const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AMVPInfo &amvpInfo, bool affine = false); void xInheritedAffineMv ( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] ); +#if JVET_L0266_HMVP + bool xCheckSimilarMotion(const int mergeCandIndex, const int prevCnt, const MergeCtx mergeCandList, bool hasPruned[MRG_MAX_NUM_CANDS]); +#if JVET_L0090_PAIR_AVG + bool addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos); +#else + bool addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos); +#endif + void addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList, const RefPicList eRefPicList2nd, const int currRefPOC, AMVPInfo &info, uint8_t imv); +#endif bool isBipredRestriction (const PredictionUnit &pu); void spanMotionInfo ( PredictionUnit &pu, const MergeCtx &mrgCtx = MergeCtx() ); void applyImv ( PredictionUnit &pu, MergeCtx &mrgCtx, InterPrediction *interPred = NULL ); @@ -135,6 +151,9 @@ namespace PU #endif ); bool getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx &mrgCtx, bool& LICFlag, const int count +#if JVET_L0054_MMVD + , int mmvdList +#endif ); bool getInterMergeSubPuRecurCand(const PredictionUnit &pu, MergeCtx &mrgCtx, const int count); bool isBiPredFromDifferentDir (const PredictionUnit &pu); @@ -178,7 +197,11 @@ namespace TU uint32_t getCtuAddr (const Position& pos, const PreCalcValues &pcv); template<typename T, size_t N> +#if JVET_L0054_MMVD +uint32_t updateCandList(T uiMode, double uiCost, static_vector<T, N>& candModeList, static_vector<double, N>& candCostList, size_t uiFastCandNum = N, int* iserttPos = nullptr) +#else uint32_t updateCandList( T uiMode, double uiCost, static_vector<T, N>& candModeList, static_vector<double, N>& candCostList, size_t uiFastCandNum = N ) +#endif { CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" ); CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" ); @@ -201,15 +224,32 @@ uint32_t updateCandList( T uiMode, double uiCost, static_vector<T, N>& candModeL } candModeList[currSize - shift] = uiMode; candCostList[currSize - shift] = uiCost; +#if JVET_L0054_MMVD + if (iserttPos != nullptr) + { + *iserttPos = int(currSize - shift); + } +#endif return 1; } else if( currSize < uiFastCandNum ) { candModeList.insert( candModeList.end() - shift, uiMode ); candCostList.insert( candCostList.end() - shift, uiCost ); +#if JVET_L0054_MMVD + if (iserttPos != nullptr) + { + *iserttPos = int(candModeList.size() - shift - 1); + } +#endif return 1; } - +#if JVET_L0054_MMVD + if (iserttPos != nullptr) + { + *iserttPos = -1; + } +#endif return 0; } diff --git a/source/Lib/DecoderAnalyserLib/CMakeLists.txt b/source/Lib/DecoderAnalyserLib/CMakeLists.txt index 9b0017617cd6af649ccf69129f8205355165e636..4fbd3463e03b7c3a6b7e3eef48f11f6b4a417a30 100644 --- a/source/Lib/DecoderAnalyserLib/CMakeLists.txt +++ b/source/Lib/DecoderAnalyserLib/CMakeLists.txt @@ -17,10 +17,6 @@ add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) target_compile_definitions( ${LIB_NAME} PUBLIC RExt__DECODER_DEBUG_BIT_STATISTICS=1 ) target_compile_definitions( ${LIB_NAME} PUBLIC RExt__DECODER_DEBUG_TOOL_STATISTICS=1 ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif() diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 70aae0890cdc0a0bd6a842586cf89ef874d7ad75..b58966e8de83e770f99d1db2bf36c9c2bbb01419 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -757,6 +757,11 @@ void CABACReader::cu_skip_flag( CodingUnit& cu ) if( skip ) { +#if JVET_L0054_MMVD + unsigned mmvdSkip = m_BinDecoder.decodeBin(Ctx::MmvdFlag(0)); + cu.mmvdSkip = mmvdSkip; + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_cu_skip_flag() ctx=%d mmvd_skip=%d\n", 0, mmvdSkip ? 1 : 0); +#endif cu.skip = true; cu.rootCbf = false; cu.predMode = MODE_INTER; @@ -1155,6 +1160,13 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) if( pu.mergeFlag ) { affine_flag ( *pu.cu ); +#if JVET_L0054_MMVD + if (pu.mmvdMergeFlag) + { + mmvd_merge_idx(pu); + } + else +#endif merge_data ( pu ); } else @@ -1236,6 +1248,12 @@ void CABACReader::affine_flag( CodingUnit& cu ) { return; } +#if JVET_L0054_MMVD + if (cu.firstPU->mergeFlag && (cu.firstPU->mmvdMergeFlag || cu.mmvdSkip)) + { + return; + } +#endif CHECK( !cu.cs->pcv->rectCUs && cu.lumaSize().width != cu.lumaSize().height, "CU width and height are not equal for QTBT off." ); @@ -1265,6 +1283,13 @@ void CABACReader::merge_flag( PredictionUnit& pu ) pu.mergeFlag = ( m_BinDecoder.decodeBin( Ctx::MergeFlag() ) ); DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", pu.mergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height ); +#if JVET_L0054_MMVD + if (pu.mergeFlag) + { + pu.mmvdMergeFlag = (m_BinDecoder.decodeBin(Ctx::MmvdFlag(0))); + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.mmvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height); + } +#endif } @@ -1274,7 +1299,13 @@ void CABACReader::merge_data( PredictionUnit& pu ) { return; } - +#if JVET_L0054_MMVD + if (pu.cu->mmvdSkip) + { + mmvd_merge_idx(pu); + } + else +#endif merge_idx( pu ); } @@ -1319,6 +1350,76 @@ void CABACReader::merge_idx( PredictionUnit& pu ) DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx ); } +#if JVET_L0054_MMVD +void CABACReader::mmvd_merge_idx(PredictionUnit& pu) +{ + RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET(STATS__CABAC_BITS__MERGE_INDEX); + int var0, var1, var2; + int dir0 = 0; + int var = 0; + int mvpIdx = 0; + + pu.mmvdMergeIdx = 0; + + mvpIdx = (var + dir0)*(MMVD_MAX_REFINE_NUM*MMVD_BASE_MV_NUM); + + int numCandminus1_base = MMVD_BASE_MV_NUM - 1; + var0 = 0; + if (numCandminus1_base > 0) + { + if (m_BinDecoder.decodeBin(Ctx::MmvdMergeIdx())) + { + var0++; + for (; var0 < numCandminus1_base; var0++) + { + if (!m_BinDecoder.decodeBinEP()) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", var0); + int numCandminus1_step = MMVD_REFINE_STEP - 1; + var1 = 0; + if (numCandminus1_step > 0) + { + if (m_BinDecoder.decodeBin(Ctx::MmvdStepMvpIdx())) + { + var1++; + for (; var1 < numCandminus1_step; var1++) + { + if (!m_BinDecoder.decodeBinEP()) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", var1); + var2 = 0; + if (m_BinDecoder.decodeBinEP()) + { + var2 += 2; + if (m_BinDecoder.decodeBinEP()) + { + var2 += 1; + } + } + else + { + var2 += 0; + if (m_BinDecoder.decodeBinEP()) + { + var2 += 1; + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2); + mvpIdx += (var0 * MMVD_MAX_REFINE_NUM + var1 * 4 + var2); + pu.mmvdMergeIdx = mvpIdx; + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx); +} +#endif void CABACReader::inter_pred_idc( PredictionUnit& pu ) { @@ -1329,7 +1430,11 @@ void CABACReader::inter_pred_idc( PredictionUnit& pu ) pu.interDir = 1; return; } +#if JVET_L0104_NO_4x4BI_INTER_CU + if( !(PU::isBipredRestriction(pu)) && ( pu.cu->partSize == SIZE_2Nx2N || pu.cs->sps->getSpsNext().getUseSubPuMvp() || pu.cu->lumaSize().width != 8 ) ) +#else if( pu.cu->partSize == SIZE_2Nx2N || pu.cs->sps->getSpsNext().getUseSubPuMvp() || pu.cu->lumaSize().width != 8 ) +#endif { unsigned ctxId = DeriveCtx::CtxInterDir(pu); if( m_BinDecoder.decodeBin( Ctx::InterDir(ctxId) ) ) diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index fd194650c2275ac547e9cff453b7c7f04d167b64..fa5236476e45f3ebea59d0f230602df17a3a83bd 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -97,6 +97,9 @@ public: void merge_data ( PredictionUnit& pu ); void affine_flag ( CodingUnit& cu ); void merge_idx ( PredictionUnit& pu ); +#if JVET_L0054_MMVD + void mmvd_merge_idx(PredictionUnit& pu); +#endif void imv_mode ( CodingUnit& cu, MergeCtx& mrgCtx ); void inter_pred_idc ( PredictionUnit& pu ); void ref_idx ( PredictionUnit& pu, RefPicList eRefList ); diff --git a/source/Lib/DecoderLib/CMakeLists.txt b/source/Lib/DecoderLib/CMakeLists.txt index 62413e9004538890a6c4506006be8d78ea6c6959..23a3659a11518bf298d19a5155b0df1830d55398 100644 --- a/source/Lib/DecoderLib/CMakeLists.txt +++ b/source/Lib/DecoderLib/CMakeLists.txt @@ -16,10 +16,6 @@ endif() add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) target_compile_definitions( ${LIB_NAME} PUBLIC ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif() diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 8fb1c75ba89f278c1a621440ce9e8fd16f45bade..591c6de39ada9fee244f0213ff2e977bdc3af505 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -316,6 +316,9 @@ void DecCu::xReconInter(CodingUnit &cu) { // inter prediction m_pcInterPred->motionCompensation( cu ); +#if JVET_L0266_HMVP + cu.slice->updateMotionLUTs(cu.slice->getMotionLUTs(), cu); +#endif DTRACE ( g_trace_ctx, D_TMP, "pred " ); DTRACE_CRC( g_trace_ctx, D_TMP, *cu.cs, cu.cs->getPredBuf( cu ), &cu.Y() ); @@ -414,6 +417,63 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) if( pu.mergeFlag ) { +#if JVET_L0054_MMVD + if (pu.mmvdMergeFlag || pu.cu->mmvdSkip) + { + if (pu.cs->sps->getSpsNext().getUseSubPuMvp()) + { + Size bufSize = g_miScaling.scale(pu.lumaSize()); + mrgCtx.subPuMvpMiBuf = MotionBuf(m_SubPuMiBuf, bufSize); + } + + if (cu.cs->pps->getLog2ParallelMergeLevelMinus2() && cu.partSize != SIZE_2Nx2N && cu.lumaSize().width <= 8) + { + if (!mrgCtx.hasMergedCandList) + { + // temporarily set size to 2Nx2N + PartSize tmpPS = SIZE_2Nx2N; + PredictionUnit tmpPU = pu; + static_cast<UnitArea&> (tmpPU) = cu; + std::swap(tmpPS, cu.partSize); +#if JVET_L0054_MMVD + int fPosBaseIdx = pu.mmvdMergeIdx / MMVD_MAX_REFINE_NUM; + PU::getInterMergeCandidates(tmpPU, mrgCtx, 1, fPosBaseIdx + 1); +#else + PU::getInterMergeCandidates(tmpPU, mrgCtx, 255); +#endif + PU::getInterMMVDMergeCandidates(tmpPU, mrgCtx, + pu.mmvdMergeIdx + ); + std::swap(tmpPS, cu.partSize); + mrgCtx.hasMergedCandList = true; + } + } + else + { +#if JVET_L0054_MMVD + int fPosBaseIdx = pu.mmvdMergeIdx / MMVD_MAX_REFINE_NUM; + PU::getInterMergeCandidates(pu, mrgCtx, 1, fPosBaseIdx + 1); +#else + PU::getInterMergeCandidates(pu, mrgCtx, 255); +#endif + PU::getInterMMVDMergeCandidates(pu, mrgCtx, + pu.mmvdMergeIdx + ); + } + mrgCtx.setMmvdMergeCandiInfo(pu, pu.mmvdMergeIdx); + + if (pu.interDir == 3 /* PRED_BI */ && PU::isBipredRestriction(pu)) + { + pu.mv[REF_PIC_LIST_1] = Mv(0, 0); + pu.refIdx[REF_PIC_LIST_1] = -1; + pu.interDir = 1; + } + + PU::spanMotionInfo(pu, mrgCtx); + } + else + { +#endif { if( pu.cu->affine ) { @@ -461,14 +521,22 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) PredictionUnit tmpPU = pu; static_cast<UnitArea&> ( tmpPU ) = cu; std::swap( tmpPS, cu.partSize ); +#if JVET_L0054_MMVD + PU::getInterMergeCandidates(tmpPU, mrgCtx, 0, pu.mergeIdx); +#else PU::getInterMergeCandidates( tmpPU, mrgCtx, pu.mergeIdx ); +#endif std::swap( tmpPS, cu.partSize ); mrgCtx.hasMergedCandList = true; } } else { +#if JVET_L0054_MMVD + PU::getInterMergeCandidates(pu, mrgCtx, 0, pu.mergeIdx); +#else PU::getInterMergeCandidates( pu, mrgCtx, pu.mergeIdx ); +#endif } mrgCtx.setMergeInfo( pu, pu.mergeIdx ); @@ -486,6 +554,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) PU::spanMotionInfo( pu, mrgCtx ); } } +#if JVET_L0054_MMVD + } +#endif } else { diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 5802f9b3490eb7ec1662a7e6c755391fbc50ab01..908bd0020d4c585116b5414f000b47b2aff9f038 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -827,23 +827,67 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) unsigned minQT [3] = { 0, 0, 0 }; unsigned maxBTD[3] = { 0, 0, 0 }; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned maxBTSize[3] = { 0, 0, 0 }; + unsigned maxTTSize[3] = { 0, 0, 0 }; +#endif READ_FLAG( symbol, "qtbt_dual_intra_tree" ); spsNext.setUseDualITree( symbol ); READ_UVLC( symbol, "log2_CTU_size_minus2" ); spsNext.setCTUSize( 1 << ( symbol + MIN_CU_LOG2 ) ); spsNext.getSPS().setMaxCodingDepth( symbol ); // overwrite original value spsNext.getSPS().setMaxCUWidth ( spsNext.getCTUSize() ); // overwrite original value spsNext.getSPS().setMaxCUHeight ( spsNext.getCTUSize() ); // overwrite original value +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_FLAG( symbol, "sps_override_partition_constraints_enable_flag"); spsNext.setSplitConsOverrideEnabledFlag( symbol ); + READ_UVLC( symbol, "sps_log2_diff_min_qt_min_cb_intra_slice"); minQT[0] = 1 << (symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); + READ_UVLC( symbol, "sps_log2_diff_min_qt_min_cb_inter_slice"); minQT[1] = 1 << (symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); + READ_UVLC( symbol, "sps_max_mtt_hierarchy_depth_inter_slices"); maxBTD[1] = symbol; + READ_UVLC( symbol, "sps_max_mtt_hierarchy_depth_intra_slices"); maxBTD[0] = symbol; +#else READ_UVLC( symbol, "log2_minQT_ISlice_minus2" ); minQT [0] = 1 << ( symbol + MIN_CU_LOG2 ); READ_UVLC( symbol, "log2_minQT_PBSlice_minus2" ); minQT [1] = 1 << ( symbol + MIN_CU_LOG2 ); READ_UVLC( symbol, "max_bt_depth" ); maxBTD[0] = symbol; READ_UVLC( symbol, "max_bt_depth_i_slice" ); maxBTD[1] = symbol; +#endif + +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + maxTTSize[0] = maxBTSize[0] = minQT[0]; + if (maxBTD[0] != 0) + { + READ_UVLC(symbol, "sps_log2_diff_max_bt_min_qt_intra_slice"); maxBTSize[0] <<= symbol; + READ_UVLC(symbol, "sps_log2_diff_max_tt_min_qt_intra_slice"); maxTTSize[0] <<= symbol; + } + maxTTSize[1] = maxBTSize[1] = minQT[1]; + if (maxBTD[1] != 0) + { + READ_UVLC(symbol, "sps_log2_diff_max_bt_min_qt_inter_slice"); maxBTSize[1] <<= symbol; + READ_UVLC(symbol, "sps_log2_diff_max_tt_min_qt_inter_slice"); maxTTSize[1] <<= symbol; + } +#endif if( spsNext.getUseDualITree() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_UVLC( symbol, "sps_log2_diff_min_qt_min_cb_intra_slice_chroma" ); minQT [2] = 1 << ( symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); + READ_UVLC( symbol, "sps_max_mtt_hierarchy_depth_intra_slices_chroma"); maxBTD[2] = symbol; + maxTTSize[2] = maxBTSize[2] = minQT[2]; + if (maxBTD[2] != 0) + { + READ_UVLC(symbol, "sps_log2_diff_max_bt_min_qt_intra_slice_chroma"); maxBTSize[2] <<= symbol; + READ_UVLC(symbol, "sps_log2_diff_max_tt_min_qt_intra_slice_chroma"); maxTTSize[2] <<= symbol; + } +#else READ_UVLC( symbol, "log2_minQT_ISliceChroma_minus2" ); minQT [2] = 1 << ( symbol + MIN_CU_LOG2 ); READ_UVLC( symbol, "max_bt_depth_i_slice_chroma" ); maxBTD[2] = symbol; +#endif } spsNext.setMinQTSizes( minQT ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + spsNext.setMaxBTDepth( maxBTD[1], maxBTD[0], maxBTD[2] ); + spsNext.setMaxBTSize( maxBTSize[1], maxBTSize[0], maxBTSize[2] ); + spsNext.setMaxTTSize( maxTTSize[1], maxTTSize[0], maxTTSize[2] ); +#else spsNext.setMaxBTDepth( maxBTD[0], maxBTD[1], maxBTD[2] ); +#endif } if( spsNext.getUseSubPuMvp() ) @@ -869,6 +913,21 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) } +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + READ_FLAG( symbol, "sps_ladf_enabled_flag" ); spsNext.setLadfEnabled( symbol != 0 ); + if ( spsNext.getLadfEnabled() ) + { + int signedSymbol = 0; + READ_CODE( 2, symbol, "sps_num_ladf_intervals_minus2"); spsNext.setLadfNumIntervals( symbol + 2 ); + READ_SVLC(signedSymbol, "sps_ladf_lowest_interval_qp_offset" ); spsNext.setLadfQpOffset( signedSymbol, 0 ); + for ( int k = 1; k < spsNext.getLadfNumIntervals(); k++ ) + { + READ_SVLC(signedSymbol, "sps_ladf_qp_offset" ); spsNext.setLadfQpOffset( signedSymbol, k ); + READ_UVLC( symbol, "sps_ladf_delta_threshold_minus1"); + spsNext.setLadfIntervalLowerBound(symbol + spsNext.getLadfIntervalLowerBound(k - 1) + 1, k); + } + } +#endif // ADD_NEW_TOOL : (sps extension parser) read tool enabling flags and associated parameters here } @@ -960,8 +1019,13 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_UVLC( uiCode, "log2_min_luma_coding_block_size_minus2"); + int log2MinCUSize = uiCode + 2; +#else READ_UVLC( uiCode, "log2_min_luma_coding_block_size_minus3" ); int log2MinCUSize = uiCode + 3; +#endif pcSPS->setLog2MinCodingBlockSize(log2MinCUSize); READ_UVLC( uiCode, "log2_diff_max_min_luma_coding_block_size" ); pcSPS->setLog2DiffMaxMinCodingBlockSize(uiCode); @@ -1664,6 +1728,42 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para #endif if( sps->getSpsNext().getUseQTBT() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (sps->getSpsNext().getSplitConsOverrideEnabledFlag()) + { + READ_FLAG(uiCode, "partition_constrainst_override_flag"); pcSlice->setSplitConsOverrideFlag(uiCode ? true : false); + if (pcSlice->getSplitConsOverrideFlag()) + { + READ_UVLC(uiCode, "log2_diff_min_qt_min_cb"); pcSlice->setMinQTSize(1 << (uiCode + sps->getLog2MinCodingBlockSize())); + READ_UVLC(uiCode, "max_mtt_hierarchy_depth"); pcSlice->setMaxBTDepth(uiCode); + if (pcSlice->getMaxBTDepth() != 0) + { + READ_UVLC(uiCode, "log2_diff_max_bt_min_qt"); pcSlice->setMaxBTSize(pcSlice->getMinQTSize() << uiCode); + READ_UVLC(uiCode, "log2_diff_max_tt_min_qt"); pcSlice->setMaxTTSize(pcSlice->getMinQTSize() << uiCode); + } + else + { + pcSlice->setMaxBTSize(pcSlice->getMinQTSize()); + pcSlice->setMaxTTSize(pcSlice->getMinQTSize()); + } + if (pcSlice->isIntra() && sps->getSpsNext().getUseDualITree()) + { + READ_UVLC(uiCode, "log2_diff_min_qt_min_cb_chroma"); pcSlice->setMinQTSizeIChroma(1 << (uiCode + sps->getLog2MinCodingBlockSize())); + READ_UVLC(uiCode, "max_mtt_hierarchy_depth_chroma"); pcSlice->setMaxBTDepthIChroma(uiCode); + if (pcSlice->getMaxBTDepthIChroma() != 0) + { + READ_UVLC(uiCode, "log2_diff_max_bt_min_qt_chroma"); pcSlice->setMaxBTSizeIChroma(pcSlice->getMinQTSizeIChroma() << uiCode); + READ_UVLC(uiCode, "log2_diff_max_tt_min_qt_chroma"); pcSlice->setMaxTTSizeIChroma(pcSlice->getMinQTSizeIChroma() << uiCode); + } + else + { + pcSlice->setMaxBTSizeIChroma(pcSlice->getMinQTSizeIChroma()); + pcSlice->setMaxTTSizeIChroma(pcSlice->getMinQTSizeIChroma()); + } + } + } + } +#else if (!pcSlice->isIntra()) { READ_UVLC(uiCode, "max_binary_tree_unit_size"); @@ -1674,6 +1774,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { pcSlice->setMaxBTSize(MAX_BT_SIZE); } +#endif } if (!pcSlice->isIntra()) { diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 6eb95048a8d34be9fdb4d2bd1d56368420e34b0e..7636c2b34f332af8b0c695fa3854eb66ccde4002 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -666,6 +666,13 @@ void CABACWriter::cu_skip_flag( const CodingUnit& cu ) m_BinEncoder.encodeBin( ( cu.skip ), Ctx::SkipFlag( ctxId ) ); DTRACE( g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0 ); +#if JVET_L0054_MMVD + if (cu.skip) + { + m_BinEncoder.encodeBin(cu.mmvdSkip, Ctx::MmvdFlag(0)); + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_cu_skip_flag() ctx=%d mmvd_skip=%d\n", 0, cu.mmvdSkip ? 1 : 0); + } +#endif } @@ -1114,6 +1121,13 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu ) if( pu.mergeFlag ) { affine_flag ( *pu.cu ); +#if JVET_L0054_MMVD + if (pu.mmvdMergeFlag) + { + mmvd_merge_idx(pu); + } + else +#endif merge_idx ( pu ); } else @@ -1180,7 +1194,12 @@ void CABACWriter::affine_flag( const CodingUnit& cu ) } CHECK( !cu.cs->pcv->rectCUs && cu.lumaSize().width != cu.lumaSize().height, "CU width and height are not equal for QTBT off." ); - +#if JVET_L0054_MMVD + if (cu.firstPU->mergeFlag && (cu.firstPU->mmvdMergeFlag || cu.mmvdSkip)) + { + return; + } +#endif unsigned ctxId = DeriveCtx::CtxAffineFlag( cu ); m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) ); DTRACE( g_trace_ctx, D_COMMON, " (%d) affine_flag() affine=%d\n", DTRACE_GET_COUNTER(g_trace_ctx, D_COMMON), cu.affine ? 1 : 0 ); @@ -1202,6 +1221,13 @@ void CABACWriter::merge_flag( const PredictionUnit& pu ) m_BinEncoder.encodeBin( pu.mergeFlag, Ctx::MergeFlag() ); DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", pu.mergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height ); +#if JVET_L0054_MMVD + if (pu.mergeFlag) + { + m_BinEncoder.encodeBin(pu.mmvdMergeFlag, Ctx::MmvdFlag(0)); + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.mmvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height); + } +#endif } void CABACWriter::imv_mode( const CodingUnit& cu ) @@ -1277,14 +1303,76 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) } DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx ); } +#if JVET_L0054_MMVD +void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu) +{ + int var0, var1, var2; + int mvpIdx = pu.mmvdMergeIdx; + var0 = mvpIdx / MMVD_MAX_REFINE_NUM; + var1 = (mvpIdx - (var0 * MMVD_MAX_REFINE_NUM)) / 4; + var2 = mvpIdx - (var0 * MMVD_MAX_REFINE_NUM) - var1 * 4; + int numCandminus1_base = MMVD_BASE_MV_NUM - 1; + if (numCandminus1_base > 0) + { + if (var0 == 0) + { + m_BinEncoder.encodeBin(0, Ctx::MmvdMergeIdx()); + } + else + { + m_BinEncoder.encodeBin(1, Ctx::MmvdMergeIdx()); + for (unsigned idx = 1; idx < numCandminus1_base; idx++) + { + m_BinEncoder.encodeBinEP(var0 == idx ? 0 : 1); + if (var0 == idx) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", var0); + + int numCandminus1_step = MMVD_REFINE_STEP - 1; + if (numCandminus1_step > 0) + { + if (var1 == 0) + { + m_BinEncoder.encodeBin(0, Ctx::MmvdStepMvpIdx()); + } + else + { + m_BinEncoder.encodeBin(1, Ctx::MmvdStepMvpIdx()); + for (unsigned idx = 1; idx < numCandminus1_step; idx++) + { + m_BinEncoder.encodeBinEP(var1 == idx ? 0 : 1); + if (var1 == idx) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", var1); + + m_BinEncoder.encodeBinsEP(var2, 2); + + DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2); + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx); +} +#endif void CABACWriter::inter_pred_idc( const PredictionUnit& pu ) { if( !pu.cs->slice->isInterB() ) { return; } +#if JVET_L0104_NO_4x4BI_INTER_CU + if( !(PU::isBipredRestriction(pu)) && ( pu.cu->partSize == SIZE_2Nx2N || pu.cs->sps->getSpsNext().getUseSubPuMvp() || pu.cu->lumaSize().width != 8 ) ) +#else if( pu.cu->partSize == SIZE_2Nx2N || pu.cs->sps->getSpsNext().getUseSubPuMvp() || pu.cu->lumaSize().width != 8 ) +#endif { unsigned ctxId = DeriveCtx::CtxInterDir(pu); if( pu.interDir == 3 ) diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index b17bfadeef0a8c6034921de77b5838e451e51257..b597aa474d329e7271ebff05054f4df528db5fb5 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -110,6 +110,9 @@ public: void merge_flag ( const PredictionUnit& pu ); void affine_flag ( const CodingUnit& cu ); void merge_idx ( const PredictionUnit& pu ); +#if JVET_L0054_MMVD + void mmvd_merge_idx(const PredictionUnit& pu); +#endif void imv_mode ( const CodingUnit& cu ); void inter_pred_idc ( const PredictionUnit& pu ); void ref_idx ( const PredictionUnit& pu, RefPicList eRefList ); diff --git a/source/Lib/EncoderLib/CMakeLists.txt b/source/Lib/EncoderLib/CMakeLists.txt index 9e75e9fb100aea05e051b09172210d93e3b66676..89286b308f417c0aa6795129e38fa0612deba306 100644 --- a/source/Lib/EncoderLib/CMakeLists.txt +++ b/source/Lib/EncoderLib/CMakeLists.txt @@ -16,10 +16,6 @@ endif() add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) target_compile_definitions( ${LIB_NAME} PUBLIC ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif() diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index cbae17fd0545d92836ba84151d0dd0f63a4c3d32..00826ad0231d92fbcea10c1c35c75a093149368e 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -174,6 +174,9 @@ protected: bool m_useAMP; bool m_QTBT; unsigned m_CTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_useSplitConsOverride; +#endif unsigned m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma unsigned m_uiMaxBTDepth; unsigned m_uiMaxBTDepthI; @@ -210,6 +213,12 @@ protected: #if JVET_L0646_GBI bool m_GBi; bool m_GBiFast; +#endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + bool m_LadfEnabled; + int m_LadfNumIntervals; + int m_LadfQpOffset[MAX_LADF_INTERVALS]; + int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS]; #endif // ADD_NEW_TOOL : (encoder lib) add tool enabling flags and associated parameters here @@ -601,6 +610,10 @@ public: unsigned getMaxBTDepthIChroma () const { return m_uiMaxBTDepthIChroma; } bool getQTBT () const { return m_QTBT; } int getCTUSize () const { return m_CTUSize; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setUseSplitConsOverride (bool n) { m_useSplitConsOverride = n; } + bool getUseSplitConsOverride () const { return m_useSplitConsOverride; } +#endif void setDualITree ( bool b ) { m_dualITree = b; } bool getDualITree () const { return m_dualITree; } @@ -657,6 +670,18 @@ public: bool getUseGBi () const { return m_GBi; } void setUseGBiFast ( uint32_t b ) { m_GBiFast = b; } bool getUseGBiFast () const { return m_GBiFast; } +#endif + +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + void setUseLadf ( bool b ) { m_LadfEnabled = b; } + bool getUseLadf () const { return m_LadfEnabled; } + void setLadfNumIntervals ( int i ) { m_LadfNumIntervals = i; } + int getLadfNumIntervals () const { return m_LadfNumIntervals; } + void setLadfQpOffset ( int value, int idx ){ m_LadfQpOffset[ idx ] = value; } + int getLadfQpOffset ( int idx ) const { return m_LadfQpOffset[ idx ]; } + void setLadfIntervalLowerBound ( int value, int idx ){ m_LadfIntervalLowerBound[ idx ] = value; } + int getLadfIntervalLowerBound ( int idx ) const { return m_LadfIntervalLowerBound[ idx ]; } + #endif // ADD_NEW_TOOL : (encoder lib) add access functions here diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 926841c1057fb2740c447752eab355c7ab3f2bc3..59d7debcba80b1c050693610cb3d9158ec57a8fe 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -78,10 +78,21 @@ void EncCu::create( EncCfg* encCfg ) m_pTempCS = new CodingStructure** [numWidths]; m_pBestCS = new CodingStructure** [numWidths]; +#if JVET_L0266_HMVP + m_pTempMotLUTs = new LutMotionCand**[numWidths]; + m_pBestMotLUTs = new LutMotionCand**[numWidths]; + m_pSplitTempMotLUTs = new LutMotionCand**[numWidths]; +#endif + for( unsigned w = 0; w < numWidths; w++ ) { m_pTempCS[w] = new CodingStructure* [numHeights]; m_pBestCS[w] = new CodingStructure* [numHeights]; +#if JVET_L0266_HMVP + m_pTempMotLUTs[w] = new LutMotionCand*[numHeights]; + m_pBestMotLUTs[w] = new LutMotionCand*[numHeights]; + m_pSplitTempMotLUTs[w] = new LutMotionCand*[numHeights]; +#endif for( unsigned h = 0; h < numHeights; h++ ) { @@ -95,11 +106,32 @@ void EncCu::create( EncCfg* encCfg ) m_pTempCS[w][h]->create( chromaFormat, Area( 0, 0, width, height ), false ); m_pBestCS[w][h]->create( chromaFormat, Area( 0, 0, width, height ), false ); +#if JVET_L0266_HMVP + m_pTempMotLUTs[w][h] = new LutMotionCand ; + m_pBestMotLUTs[w][h] = new LutMotionCand ; + m_pSplitTempMotLUTs[w][h] = new LutMotionCand; + m_pSplitTempMotLUTs[w][h]->currCnt = 0; + m_pSplitTempMotLUTs[w][h]->motionCand = nullptr; + m_pSplitTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS]; + + m_pTempMotLUTs[w][h]->currCnt = 0; + m_pTempMotLUTs[w][h]->motionCand = nullptr; + m_pTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS]; + + m_pBestMotLUTs[w][h]->currCnt = 0; + m_pBestMotLUTs[w][h]->motionCand = nullptr; + m_pBestMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS]; +#endif } else { m_pTempCS[w][h] = nullptr; m_pBestCS[w][h] = nullptr; +#if JVET_L0266_HMVP + m_pTempMotLUTs[w][h] = nullptr; + m_pBestMotLUTs[w][h] = nullptr; + m_pSplitTempMotLUTs[w][h] = nullptr; +#endif } } } @@ -151,7 +183,11 @@ void EncCu::create( EncCfg* encCfg ) m_modeCtrl->create( *encCfg ); #endif +#if JVET_L0054_MMVD + for (unsigned ui = 0; ui < MMVD_MRG_MAX_RD_BUF_NUM; ui++) +#else for( unsigned ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ ) +#endif { m_acMergeBuffer[ui].create( chromaFormat, Area( 0, 0, uiMaxWidth, uiMaxHeight ) ); } @@ -180,15 +216,46 @@ void EncCu::destroy() delete m_pBestCS[w][h]; delete m_pTempCS[w][h]; +#if JVET_L0266_HMVP + if (m_pTempMotLUTs[w][h]) + { + delete[] m_pTempMotLUTs[w][h]->motionCand; + m_pTempMotLUTs[w][h]->motionCand = nullptr; + delete[] m_pTempMotLUTs[w][h]; + } + if (m_pBestMotLUTs[w][h]) + { + delete[] m_pBestMotLUTs[w][h]->motionCand; + m_pBestMotLUTs[w][h]->motionCand = nullptr; + delete[] m_pBestMotLUTs[w][h]; + } + + if (m_pSplitTempMotLUTs[w][h]) + { + delete[] m_pSplitTempMotLUTs[w][h]->motionCand; + m_pSplitTempMotLUTs[w][h]->motionCand = nullptr; + delete[] m_pSplitTempMotLUTs[w][h]; + } +#endif } } delete[] m_pTempCS[w]; delete[] m_pBestCS[w]; +#if JVET_L0266_HMVP + delete[] m_pBestMotLUTs[w]; + delete[] m_pTempMotLUTs[w]; + delete[] m_pSplitTempMotLUTs[w]; +#endif } delete[] m_pBestCS; m_pBestCS = nullptr; delete[] m_pTempCS; m_pTempCS = nullptr; +#if JVET_L0266_HMVP + delete[] m_pSplitTempMotLUTs; m_pSplitTempMotLUTs = nullptr; + delete[] m_pBestMotLUTs; m_pBestMotLUTs = nullptr; + delete[] m_pTempMotLUTs; m_pTempMotLUTs = nullptr; +#endif #if REUSE_CU_RESULTS m_modeCtrl->destroy(); @@ -292,6 +359,12 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign CodingStructure *tempCS = m_pTempCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )]; CodingStructure *bestCS = m_pBestCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )]; +#if JVET_L0266_HMVP + LutMotionCand *tempMotCandLUTs = m_pTempMotLUTs[gp_sizeIdxInfo->idxFrom(area.lumaSize().width)][gp_sizeIdxInfo->idxFrom(area.lumaSize().height)]; + LutMotionCand *bestMotCandLUTs = m_pBestMotLUTs[gp_sizeIdxInfo->idxFrom(area.lumaSize().width)][gp_sizeIdxInfo->idxFrom(area.lumaSize().height)]; + cs.slice->copyMotionLUTs(cs.slice->getMotionLUTs(), tempMotCandLUTs); + cs.slice->copyMotionLUTs(cs.slice->getMotionLUTs(), bestMotCandLUTs); +#endif cs.initSubStructure( *tempCS, partitioner->chType, partitioner->currArea(), false ); cs.initSubStructure( *bestCS, partitioner->chType, partitioner->currArea(), false ); @@ -299,12 +372,20 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign tempCS->baseQP = bestCS->baseQP = currQP[CH_L]; tempCS->prevQP[CH_L] = bestCS->prevQP[CH_L] = prevQP[CH_L]; - xCompressCU( tempCS, bestCS, *partitioner ); + xCompressCU( tempCS, bestCS, *partitioner +#if JVET_L0266_HMVP + , tempMotCandLUTs + , bestMotCandLUTs +#endif + ); // all signals were already copied during compression if the CTU was split - at this point only the structures are copied to the top level CS const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1 && KEEP_PRED_AND_RESI_SIGNALS; cs.useSubStructure( *bestCS, partitioner->chType, CS::getArea( *bestCS, area, partitioner->chType ), copyUnsplitCTUSignals, false, false, copyUnsplitCTUSignals ); +#if JVET_L0266_HMVP + cs.slice->copyMotionLUTs(bestMotCandLUTs, cs.slice->getMotionLUTs()); +#endif if( !cs.pcv->ISingleTree && cs.slice->isIRAP() && cs.pcv->chrFormat != CHROMA_400 ) { @@ -318,7 +399,12 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign tempCS->baseQP = bestCS->baseQP = currQP[CH_C]; tempCS->prevQP[CH_C] = bestCS->prevQP[CH_C] = prevQP[CH_C]; - xCompressCU( tempCS, bestCS, *partitioner ); + xCompressCU( tempCS, bestCS, *partitioner +#if JVET_L0266_HMVP + , tempMotCandLUTs + , bestMotCandLUTs +#endif + ); const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1 && KEEP_PRED_AND_RESI_SIGNALS; cs.useSubStructure( *bestCS, partitioner->chType, CS::getArea( *bestCS, area, partitioner->chType ), copyUnsplitCTUSignals, false, false, copyUnsplitCTUSignals ); @@ -465,8 +551,16 @@ int EncCu::updateCtuDataISlice(const CPelBuf buf) return( iSumHad ); } +#if JVET_L0266_HMVP +bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode ) +#else void EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode ) +#endif { +#if JVET_L0266_HMVP + bool bestCSUpdated = false; +#endif + if( !tempCS->cus.empty() ) { if( tempCS->cus.size() == 1 ) @@ -497,14 +591,26 @@ void EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, std::swap( tempCS, bestCS ); // store temp best CI for next CU coding m_CurrCtx->best = m_CABACEstimator->getCtx(); +#if JVET_L0266_HMVP + bestCSUpdated = true; +#endif } } // reset context states m_CABACEstimator->getCtx() = m_CurrCtx->start; +#if JVET_L0266_HMVP + return bestCSUpdated; +#endif + } -void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner ) +void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner +#if JVET_L0266_HMVP + , LutMotionCand *&tempMotCandLUTs + , LutMotionCand *&bestMotCandLUTs +#endif +) { #if ENABLE_SPLIT_PARALLELISM CHECK( m_dataId != tempCS->picture->scheduler.getDataId(), "Working in the wrong dataId!" ); @@ -557,6 +663,12 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par m_modeCtrl->finishCULevel( partitioner ); return; } +#if JVET_L0266_HMVP + if (!slice.isIntra()) + { + tempCS->slice->copyMotionLUTs(tempMotCandLUTs, tempCS->slice->getMotionLUTs()); + } +#endif DTRACE_UPDATE( g_trace_ctx, std::make_pair( "cux", uiLPelX ) ); DTRACE_UPDATE( g_trace_ctx, std::make_pair( "cuy", uiTPelY ) ); @@ -606,6 +718,10 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par else if( currTestMode.type == ETM_MERGE_SKIP ) { xCheckRDCostMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode ); +#if JVET_L0054_MMVD + CodingUnit* cu = bestCS->getCU(partitioner.chType); + cu->mmvdSkip = cu->skip == false ? false : cu->mmvdSkip; +#endif } else if( currTestMode.type == ETM_INTRA ) { @@ -618,7 +734,13 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par else if( isModeSplit( currTestMode ) ) { - xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode ); + xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode +#if JVET_L0266_HMVP + , tempMotCandLUTs + , bestMotCandLUTs + , partitioner.currArea() +#endif + ); } else { @@ -644,7 +766,12 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par // QP from last processed CU for further processing bestCS->prevQP[partitioner.chType] = bestCS->cus.back()->qp; - +#if JVET_L0266_HMVP + if (!slice.isIntra() && bestCS->cus.size() == 1 && bestCS->cus.back()->predMode == MODE_INTER && bestCS->area == *bestCS->cus.back()) + { + bestCS->slice->updateMotionLUTs(bestMotCandLUTs, (*bestCS->cus.back())); + } +#endif bestCS->picture->getRecoBuf( currCsArea ).copyFrom( bestCS->getRecoBuf( currCsArea ) ); m_modeCtrl->finishCULevel( partitioner ); @@ -892,7 +1019,13 @@ void EncCu::copyState( EncCu* other, Partitioner& partitioner, const UnitArea& c } #endif -void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode) +void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode +#if JVET_L0266_HMVP + , LutMotionCand* &tempMotCandLUTs + , LutMotionCand* &bestMotCandLUTs + , UnitArea parArea +#endif +) { const int qp = encTestMode.qp; const PPS &pps = *tempCS->pps; @@ -901,6 +1034,13 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, const int oldPrevQp = tempCS->prevQP[partitioner.chType]; const uint32_t currDepth = partitioner.currDepth; +#if JVET_L0266_HMVP + const unsigned wParIdx = gp_sizeIdxInfo->idxFrom(parArea.lwidth()); + const unsigned hParIdx = gp_sizeIdxInfo->idxFrom(parArea.lheight()); + + tempCS->slice->copyMotionLUTs(tempMotCandLUTs, m_pSplitTempMotLUTs[wParIdx][hParIdx]); +#endif + const PartSplit split = getPartSplit( encTestMode ); CHECK( split == CU_DONT_SPLIT, "No proper split provided!" ); @@ -961,8 +1101,19 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, tempCS->initSubStructure( *tempSubCS, partitioner.chType, subCUArea, false ); tempCS->initSubStructure( *bestSubCS, partitioner.chType, subCUArea, false ); +#if JVET_L0266_HMVP + LutMotionCand *tempSubMotCandLUTs = m_pTempMotLUTs[wIdx][hIdx]; + LutMotionCand *bestSubMotCandLUTs = m_pBestMotLUTs[wIdx][hIdx]; + tempCS->slice->copyMotionLUTs(tempMotCandLUTs, tempSubMotCandLUTs); + tempCS->slice->copyMotionLUTs(tempMotCandLUTs, bestSubMotCandLUTs); +#endif - xCompressCU( tempSubCS, bestSubCS, partitioner ); + xCompressCU( tempSubCS, bestSubCS, partitioner +#if JVET_L0266_HMVP + , tempSubMotCandLUTs + , bestSubMotCandLUTs +#endif + ); if( bestSubCS->cost == MAX_DOUBLE ) { @@ -970,12 +1121,25 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, tempCS->cost = MAX_DOUBLE; m_CurrCtx--; partitioner.exitCurrSplit(); +#if JVET_L0266_HMVP + bool bestCSUpdated = +#endif xCheckBestMode( tempCS, bestCS, partitioner, encTestMode ); + +#if JVET_L0266_HMVP + if (bestCSUpdated) + { + std::swap(tempMotCandLUTs, bestMotCandLUTs); + } +#endif return; } bool keepResi = KEEP_PRED_AND_RESI_SIGNALS; tempCS->useSubStructure( *bestSubCS, partitioner.chType, CS::getArea( *tempCS, subCUArea, partitioner.chType ), KEEP_PRED_AND_RESI_SIGNALS, true, keepResi, keepResi ); +#if JVET_L0266_HMVP + tempCS->slice->copyMotionLUTs(bestSubMotCandLUTs, tempMotCandLUTs); +#endif if(currDepth < pps.getMaxCuDQPDepth()) { @@ -1079,8 +1243,22 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, // RD check for sub partitioned coding structure. +#if JVET_L0266_HMVP + bool bestCSUpdated = +#endif xCheckBestMode( tempCS, bestCS, partitioner, encTestMode ); +#if JVET_L0266_HMVP + if (!slice.isIntra()) + { + if (bestCSUpdated) + { + std::swap(tempMotCandLUTs, bestMotCandLUTs); + } + tempCS->slice->copyMotionLUTs(m_pSplitTempMotLUTs[wParIdx][hParIdx], tempMotCandLUTs); + } +#endif + tempCS->releaseIntermediateData(); tempCS->prevQP[partitioner.chType] = oldPrevQp; @@ -1131,6 +1309,9 @@ void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestC cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = encTestMode.partSize; cu.predMode = MODE_INTRA; cu.transQuantBypass = encTestMode.lossless; @@ -1244,6 +1425,9 @@ void EncCu::xCheckIntraPCM(CodingStructure *&tempCS, CodingStructure *&bestCS, P cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = SIZE_2Nx2N; cu.predMode = MODE_INTRA; cu.transQuantBypass = encTestMode.lossless; @@ -1413,11 +1597,68 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& PredictionUnit pu( tempCS->area ); pu.cu = &cu; pu.cs = tempCS; - - PU::getInterMergeCandidates(pu, mergeCtx); + PU::getInterMergeCandidates(pu, mergeCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); +#if JVET_L0054_MMVD + PU::getInterMMVDMergeCandidates(pu, mergeCtx); +#endif +#if JVET_L0104_NO_4x4BI_INTER_CU + if (PU::isBipredRestriction(pu)) + { + for( uint32_t mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; ++mergeCand ) + { + if( mergeCtx.interDirNeighbours[ mergeCand ] == 3 ) + { + mergeCtx.interDirNeighbours[ mergeCand ] = 1; + mergeCtx.mvFieldNeighbours[( mergeCand << 1 ) + 1].setMvField( Mv( 0, 0 ), -1 ); +#if JVET_L0646_GBI + mergeCtx.GBiIdx[mergeCand] = GBI_DEFAULT; +#endif + } + } + } +#endif } +#if JVET_L0054_MMVD + bool candHasNoResidual[MRG_MAX_NUM_CANDS + MMVD_ADD_NUM]; + for (uint32_t ui = 0; ui < MRG_MAX_NUM_CANDS + MMVD_ADD_NUM; ui++) + { + candHasNoResidual[ui] = false; + } + + bool bestIsSkip = false; + bool bestIsMMVDSkip = true; + PelUnitBuf acMergeRealBuffer[MMVD_MRG_MAX_RD_BUF_NUM]; + PelUnitBuf * acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM]; + PelUnitBuf * singleMergeTempBuffer; + int insertPos; + unsigned uiNumMrgSATDCand = mergeCtx.numValidMergeCand + MMVD_ADD_NUM; + + static_vector<unsigned, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> RdModeList; + bool mrgTempBufSet = false; + for (unsigned i = 0; i < MRG_MAX_NUM_CANDS + MMVD_ADD_NUM; i++) + { + RdModeList.push_back(i); + } + const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); + for (unsigned i = 0; i < MMVD_MRG_MAX_RD_BUF_NUM; i++) + { + acMergeRealBuffer[i] = m_acMergeBuffer[i].getBuf(localUnitArea); + if (i < MMVD_MRG_MAX_RD_NUM) + { + acMergeTempBuffer[i] = acMergeRealBuffer + i; + } + else + { + singleMergeTempBuffer = acMergeRealBuffer + i; + } + } +#else bool candHasNoResidual[MRG_MAX_NUM_CANDS]; for (uint32_t ui = 0; ui < mergeCtx.numValidMergeCand; ui++) { @@ -1438,7 +1679,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { RdModeList.push_back( i ); } - +#endif if( m_pcEncCfg->getUseFastMerge() ) { uiNumMrgSATDCand = NUM_MRG_SATD_CAND; @@ -1447,10 +1688,15 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& if( auto blkCache = dynamic_cast< CacheBlkInfoCtrl* >( m_modeCtrl ) ) { bestIsSkip = blkCache->isSkip( tempCS->area ); +#if JVET_L0054_MMVD + bestIsMMVDSkip = blkCache->isMMVDSkip(tempCS->area); +#endif } - +#if JVET_L0054_MMVD + static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> candCostList; +#else static_vector<double, MRG_MAX_NUM_CANDS> candCostList; - +#endif // 1. Pass: get SATD-cost for selected candidates and reduce their count if( !bestIsSkip ) { @@ -1466,6 +1712,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = SIZE_2Nx2N; //cu.affine cu.predMode = MODE_INTER; @@ -1484,16 +1733,20 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& const UnitArea localUnitArea( tempCS->area.chromaFormat, Area( 0, 0, tempCS->area.Y().width, tempCS->area.Y().height) ); for( uint32_t uiMergeCand = 0; uiMergeCand < mergeCtx.numValidMergeCand; uiMergeCand++ ) { +#if !JVET_L0054_MMVD acMergeBuffer[uiMergeCand] = m_acMergeBuffer[uiMergeCand].getBuf( localUnitArea ); - +#endif mergeCtx.setMergeInfo( pu, uiMergeCand ); PU::spanMotionInfo( pu, mergeCtx ); - +#if JVET_L0054_MMVD + distParam.cur = singleMergeTempBuffer->Y(); + m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer); +#else distParam.cur = acMergeBuffer[uiMergeCand].Y(); m_pcInterSearch->motionCompensation( pu, acMergeBuffer[uiMergeCand] ); - +#endif if( mergeCtx.interDirNeighbours[uiMergeCand] == 3 && mergeCtx.mrgTypeNeighbours[uiMergeCand] == MRG_TYPE_DEFAULT_N ) { mergeCtx.mvFieldNeighbours[2*uiMergeCand].mv = pu.mv[0]; @@ -1509,11 +1762,121 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { uiBitsCand--; } +#if JVET_L0054_MMVD + uiBitsCand++; // for mmvd_flag +#endif double cost = (double)uiSad + (double)uiBitsCand * sqrtLambdaForFirstPass; - +#if JVET_L0054_MMVD + insertPos = -1; + updateCandList(uiMergeCand, cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + if (insertPos != -1) + { + if (insertPos == RdModeList.size() - 1) + { + swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); + } + else + { + for (uint32_t i = uint32_t(RdModeList.size()) - 1; i > insertPos; i--) + { + swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); + } + swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); + } + } +#else updateCandList( uiMergeCand, cost, RdModeList, candCostList, uiNumMrgSATDCand ); +#endif CHECK( std::min( uiMergeCand + 1, uiNumMrgSATDCand ) != RdModeList.size(), "" ); } +#if JVET_L0054_MMVD + cu.mmvdSkip = true; + int tempNum = 0; + tempNum = MMVD_ADD_NUM; + bool allowDirection[4] = { true, true, true, true }; + for (uint32_t mergeCand = mergeCtx.numValidMergeCand; mergeCand < mergeCtx.numValidMergeCand + tempNum; mergeCand++) + { + const int mmvdMergeCand = mergeCand - mergeCtx.numValidMergeCand; + int bitsBaseIdx = 0; + int bitsRefineStep = 0; + int bitsDirection = 2; + int bitsCand = 0; + int baseIdx; + int refineStep; + int direction; + baseIdx = mmvdMergeCand / MMVD_MAX_REFINE_NUM; + refineStep = (mmvdMergeCand - (baseIdx * MMVD_MAX_REFINE_NUM)) / 4; + direction = (mmvdMergeCand - baseIdx * MMVD_MAX_REFINE_NUM - refineStep * 4) % 4; + if (refineStep == 0) + { + allowDirection[direction] = true; + } + if (allowDirection[direction] == false) + { + continue; + } + bitsBaseIdx = baseIdx + 1; + if (baseIdx == MMVD_BASE_MV_NUM - 1) + { + bitsBaseIdx--; + } + + bitsRefineStep = refineStep + 1; + if (refineStep == MMVD_REFINE_STEP - 1) + { + bitsRefineStep--; + } + + bitsCand = bitsBaseIdx + bitsRefineStep + bitsDirection; + bitsCand++; // for mmvd_flag + +#if !JVET_L0054_MMVD + acMergeBuffer[mergeCand] = m_acMergeBuffer[mergeCand].getBuf(localUnitArea); +#endif + mergeCtx.setMmvdMergeCandiInfo(pu, mmvdMergeCand); + + PU::spanMotionInfo(pu, mergeCtx); +#if JVET_L0054_MMVD + distParam.cur = singleMergeTempBuffer->Y(); + m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer); +#else + distParam.cur = acMergeBuffer[mergeCand].Y(); + m_pcInterSearch->motionCompensation(pu, acMergeBuffer[mergeCand]); +#endif + + Distortion uiSad = distParam.distFunc(distParam); + + +#if !JVET_L0054_MMVD + uint32_t bitsCand = mergeCand + 1; + if (mergeCand == tempCS->slice->getMaxNumMergeCand() - 1) + { + bitsCand--; + } +#endif + double cost = (double)uiSad + (double)bitsCand * sqrtLambdaForFirstPass; +#if JVET_L0054_MMVD + allowDirection[direction] = cost > 1.3 * candCostList[0] ? 0 : 1; +#endif +#if JVET_L0054_MMVD + insertPos = -1; + updateCandList(mergeCand, cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + if (insertPos != -1) + { + for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + { + swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); + } + swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); + } +#else + updateCandList(mergeCand, cost, RdModeList, candCostList, uiNumMrgSATDCand); +#endif +#if !JVET_L0054_MMVD + CHECK(std::min(mergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), ""); +#endif + } +#endif // Try to limit number of candidates using SATD-costs for( uint32_t i = 1; i < uiNumMrgSATDCand; i++ ) { @@ -1528,7 +1891,18 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } else { +#if JVET_L0054_MMVD + if (bestIsMMVDSkip) + { + uiNumMrgSATDCand = mergeCtx.numValidMergeCand + MMVD_ADD_NUM; + } + else + { + uiNumMrgSATDCand = mergeCtx.numValidMergeCand; + } +#else uiNumMrgSATDCand = mergeCtx.numValidMergeCand; +#endif } } @@ -1540,7 +1914,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& for( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++ ) { uint32_t uiMergeCand = RdModeList[uiMrgHADIdx]; +#if JVET_L0054_MMVD + if (((uiNoResidualPass != 0) && candHasNoResidual[uiMrgHADIdx]) +#else if( ( (uiNoResidualPass != 0) && candHasNoResidual[uiMergeCand] ) +#endif || ( (uiNoResidualPass == 0) && bestIsSkip ) ) { continue; @@ -1555,6 +1933,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = SIZE_2Nx2N; //cu.affine cu.predMode = MODE_INTER; @@ -1563,8 +1944,20 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& cu.chromaQpAdj = cu.transQuantBypass ? 0 : m_cuChromaQpOffsetIdxPlus1; cu.qp = encTestMode.qp; PredictionUnit &pu = tempCS->addPU( cu, partitioner.chType ); - +#if JVET_L0054_MMVD + if (uiMergeCand >= mergeCtx.numValidMergeCand) + { + cu.mmvdSkip = true; + mergeCtx.setMmvdMergeCandiInfo(pu, uiMergeCand - mergeCtx.numValidMergeCand); + } + else + { + cu.mmvdSkip = false; + mergeCtx.setMergeInfo(pu, uiMergeCand); + } +#else mergeCtx.setMergeInfo( pu, uiMergeCand ); +#endif PU::spanMotionInfo( pu, mergeCtx ); if( mrgTempBufSet ) @@ -1572,18 +1965,28 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if DMVR_JVET_LOW_LATENCY_K0217 pu.mvd[0] = refinedMvdL0[uiMergeCand]; #endif +#if JVET_L0054_MMVD + tempCS->getPredBuf().copyFrom(*acMergeTempBuffer[uiMrgHADIdx]); +#else tempCS->getPredBuf().copyFrom( acMergeBuffer[ uiMergeCand ]); +#endif } else { m_pcInterSearch->motionCompensation( pu ); } - +#if JVET_L0054_MMVD + xEncodeInterResidual(tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass + , NULL + , 1 + , uiNoResidualPass == 0 ? &candHasNoResidual[uiMrgHADIdx] : NULL); +#else xEncodeInterResidual( tempCS, bestCS, partitioner, encTestMode, uiNoResidualPass , NULL , 1 , uiNoResidualPass == 0 ? &candHasNoResidual[uiMergeCand] : NULL ); +#endif if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip ) { @@ -1656,6 +2059,9 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = encTestMode.partSize; cu.affine = true; cu.predMode = MODE_INTER; @@ -1765,6 +2171,9 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = encTestMode.partSize; //cu.affine cu.predMode = MODE_INTER; @@ -1932,6 +2341,9 @@ bool EncCu::xCheckRDCostInterIMV( CodingStructure *&tempCS, CodingStructure *&be cu.tileIdx = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() ); #endif cu.skip = false; +#if JVET_L0054_MMVD + cu.mmvdSkip = false; +#endif cu.partSize = encTestMode.partSize; //cu.affine cu.predMode = MODE_INTER; diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index d8131f4532a7f5b5e278e8284af1d8cf9275b42c..91dce9f29bf40ac80bb7bb47a7342a2f7842cc41 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -95,6 +95,11 @@ private: CodingStructure ***m_pTempCS; CodingStructure ***m_pBestCS; +#if JVET_L0266_HMVP + LutMotionCand ***m_pTempMotLUTs; + LutMotionCand ***m_pBestMotLUTs; + LutMotionCand ***m_pSplitTempMotLUTs; +#endif // Access channel EncCfg* m_pcEncCfg; IntraSearch* m_pcIntraSearch; @@ -107,9 +112,11 @@ private: RateCtrl* m_pcRateCtrl; CodingStructure ***m_pImvTempCS; EncModeCtrl *m_modeCtrl; - +#if JVET_L0054_MMVD + PelStorage m_acMergeBuffer[MMVD_MRG_MAX_RD_BUF_NUM]; +#else PelStorage m_acMergeBuffer[MRG_MAX_NUM_CANDS]; - +#endif MotionInfo m_SubPuMiBuf [( MAX_CU_SIZE * MAX_CU_SIZE ) >> ( MIN_CU_LOG2 << 1 )]; unsigned int m_subMergeBlkSize[10]; unsigned int m_subMergeBlkNum[10]; @@ -167,15 +174,31 @@ public: protected: - void xCompressCU ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm ); + void xCompressCU ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm +#if JVET_L0266_HMVP + , LutMotionCand *&tempMotCandLUTs + , LutMotionCand *&bestMotCandLUTs +#endif + ); #if ENABLE_SPLIT_PARALLELISM void xCompressCUParallel ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm ); void copyState ( EncCu* other, Partitioner& pm, const UnitArea& currArea, const bool isDist ); #endif - void xCheckBestMode ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode ); +#if JVET_L0266_HMVP + bool +#else + void +#endif + xCheckBestMode ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode ); - void xCheckModeSplit ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode ); + void xCheckModeSplit ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode +#if JVET_L0266_HMVP + , LutMotionCand* &tempMotCandLUTs + , LutMotionCand* &bestMotCandLUTs + , UnitArea parArea +#endif + ); void xCheckRDCostIntra ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode ); void xCheckIntraPCM ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode ); @@ -206,6 +229,10 @@ protected: #if JVET_L0646_GBI bool xIsGBiSkip(const CodingUnit& cu) { + if (cu.slice->getSliceType() != B_SLICE) + { + return true; + } return((m_pcEncCfg->getBaseQP() > 32) && ((cu.slice->getTLayer() >= 4) || ((cu.refIdxBi[0] >= 0 && cu.refIdxBi[1] >= 0) && (abs(cu.slice->getPOC() - cu.slice->getRefPOC(REF_PIC_LIST_0, cu.refIdxBi[0])) == 1 diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 4768bd7914759c699945005c7e3e5d188004b108..c531e9d1cfe0a58e0a3cc8bddeaab9f0e2343898 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1644,6 +1644,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + pcSlice->setSplitConsOverrideFlag(true); +#endif double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] ); if( dBlkSize < AMAXBT_TH32 ) { diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index ea5b9913b8c0ef17763ed002151df0548c1aa581..5f0cdc5613c9418498a623bf9db84c66a1ce12d3 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -830,6 +830,9 @@ void EncLib::xInitSPS(SPS &sps) sps.getSpsNext().setNextToolsEnabled ( m_profile == Profile::NEXT ); sps.getSpsNext().setUseQTBT ( m_QTBT ); sps.getSpsNext().setCTUSize ( m_CTUSize ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + sps.getSpsNext().setSplitConsOverrideEnabledFlag( m_useSplitConsOverride ); +#endif sps.getSpsNext().setMinQTSizes ( m_uiMinQT ); sps.getSpsNext().setUseLargeCTU ( m_LargeCTU ); sps.getSpsNext().setMaxBTDepth ( m_uiMaxBTDepth, m_uiMaxBTDepthI, m_uiMaxBTDepthIChroma ); @@ -858,6 +861,20 @@ void EncLib::xInitSPS(SPS &sps) #if JVET_L0646_GBI sps.getSpsNext().setUseGBi ( m_GBi ); #endif +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + sps.getSpsNext().setLadfEnabled ( m_LadfEnabled ); + if ( m_LadfEnabled ) + { + sps.getSpsNext().setLadfNumIntervals ( m_LadfNumIntervals ); + for ( int k = 0; k < m_LadfNumIntervals; k++ ) + { + sps.getSpsNext().setLadfQpOffset( m_LadfQpOffset[k], k ); + sps.getSpsNext().setLadfIntervalLowerBound( m_LadfIntervalLowerBound[k], k ); + } + CHECK( m_LadfIntervalLowerBound[0] != 0, "abnormal value set to LadfIntervalLowerBound[0]" ); + } +#endif + // ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here int minCUSize = ( /*sps.getSpsNext().getUseQTBT() ? 1 << MIN_CU_LOG2 :*/ sps.getMaxCUWidth() >> sps.getLog2DiffMaxMinCodingBlockSize() ); diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index db0ef5bf6b7d7b56b9aaafd1edfb1007e80262f6..3b07db382b4b0a5ae092ce899062d2f338d13e08 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -473,6 +473,16 @@ bool CacheBlkInfoCtrl::isSkip( const UnitArea& area ) return m_codedCUInfo[idx1][idx2][idx3][idx4]->isSkip; } +#if JVET_L0054_MMVD +bool CacheBlkInfoCtrl::isMMVDSkip(const UnitArea& area) +{ + unsigned idx1, idx2, idx3, idx4; + getAreaIdx(area.Y(), *m_slice_chblk->getPPS()->pcv, idx1, idx2, idx3, idx4); + + return m_codedCUInfo[idx1][idx2][idx3][idx4]->isMMVDSkip; +} +#endif + void CacheBlkInfoCtrl::setMv( const UnitArea& area, const RefPicList refPicList, const int iRefIdx, const Mv& rMv ) { if( iRefIdx >= MAX_STORED_CU_INFO_REFS ) return; @@ -1398,9 +1408,15 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt { unsigned maxBTD = cs.pcv->getMaxBtDepth( slice, partitioner.chType ); const CodingUnit *cuBR = bestCS->cus.back(); +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + unsigned height = partitioner.currArea().lumaSize().height; +#endif if( bestCU && ( ( bestCU->btDepth == 0 && maxBTD >= ( slice.isIntra() ? 3 : 2 ) ) || ( bestCU->btDepth == 1 && cuBR && cuBR->btDepth == 1 && maxBTD >= ( slice.isIntra() ? 4 : 3 ) ) ) +#if JVET_L0081_VPDU_SPLIT_CONSTRAINTS + && ( width <= MAX_TU_SIZE_FOR_PROFILE && height <= MAX_TU_SIZE_FOR_PROFILE ) +#endif && cuECtx.get<bool>( DID_HORZ_SPLIT ) && cuECtx.get<bool>( DID_VERT_SPLIT ) ) { return false; @@ -1503,6 +1519,9 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt relatedCU.isInter = true; #if HM_CODED_CU_INFO relatedCU.isSkip |= bestCU->skip; +#if JVET_L0054_MMVD + relatedCU.isMMVDSkip |= bestCU->mmvdSkip; +#endif #else relatedCU.isSkip = bestCU->skip; #endif diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h index 987c6a6750dc5ff2fb66ab023c83c529c5324bdd..f56fceb06b1435025bced67fcf32150c1a4c7253 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.h +++ b/source/Lib/EncoderLib/EncModeCtrl.h @@ -317,7 +317,9 @@ struct CodedCUInfo bool isInter; bool isIntra; bool isSkip; - +#if JVET_L0054_MMVD + bool isMMVDSkip; +#endif bool validMv[NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS]; Mv saveMv [NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS]; @@ -368,7 +370,9 @@ public: virtual ~CacheBlkInfoCtrl() {} bool isSkip ( const UnitArea& area ); - +#if JVET_L0054_MMVD + bool isMMVDSkip(const UnitArea& area); +#endif bool getMv ( const UnitArea& area, const RefPicList refPicList, const int iRefIdx, Mv& rMv ) const; void setMv ( const UnitArea& area, const RefPicList refPicList, const int iRefIdx, const Mv& rMv ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index c9791afa2acfb7ad0632ce30a6cf5a2896ec3257..84994c21fa1caedb22671714471d3e72aae63503 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -672,7 +672,22 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() ); #endif rpcSlice->setMaxNumMergeCand ( m_pcCfg->getMaxNumMergeCand() ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + rpcSlice->setSplitConsOverrideFlag(false); + rpcSlice->setMinQTSize( rpcSlice->getSPS()->getSpsNext().getMinQTSize(eSliceType)); + rpcSlice->setMaxBTDepth( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxBTDepthI() : rpcSlice->getSPS()->getSpsNext().getMaxBTDepth() ); + rpcSlice->setMaxBTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxBTSizeI() : rpcSlice->getSPS()->getSpsNext().getMaxBTSize() ); + rpcSlice->setMaxTTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxTTSizeI() : rpcSlice->getSPS()->getSpsNext().getMaxTTSize() ); + if ( eSliceType == I_SLICE && rpcSlice->getSPS()->getSpsNext().getUseDualITree() ) + { + rpcSlice->setMinQTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMinQTSize(eSliceType, CHANNEL_TYPE_CHROMA) ); + rpcSlice->setMaxBTDepthIChroma( rpcSlice->getSPS()->getSpsNext().getMaxBTDepthIChroma() ); + rpcSlice->setMaxBTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMaxBTSizeIChroma() ); + rpcSlice->setMaxTTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMaxTTSizeIChroma() ); + } +#else rpcSlice->setMaxBTSize ( rpcSlice->isIntra() ? MAX_BT_SIZE : MAX_BT_SIZE_INTER ); +#endif } diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 8e01532c7e6012e760088d6b3fd92d1d1924d7c9..c3267fac82b983c0178909aeadf0aa5f69dfa548 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -692,16 +692,54 @@ void InterSearch::xMergeEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, int pu.UnitArea::operator=( *pu.cu ); pu.cu->partSize = SIZE_2Nx2N; - +#if JVET_L0054_MMVD + if(pu.mmvdMergeFlag) + { + PU::getInterMergeCandidates( pu, mergeCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); + PU::getInterMMVDMergeCandidates(pu, mergeCtx); + } + else + { + PU::getInterMergeCandidates(pu, mergeCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); + } +#else PU::getInterMergeCandidates( pu, mergeCtx ); - +#endif pu.UnitArea::operator=( unitArea ); pu.cu->partSize = partSize; } } else { +#if JVET_L0054_MMVD + if(pu.mmvdMergeFlag) + { + PU::getInterMergeCandidates( pu, mergeCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); + PU::getInterMMVDMergeCandidates(pu, mergeCtx); + } + else + { + PU::getInterMergeCandidates(pu, mergeCtx +#if JVET_L0054_MMVD + , 0 +#endif + ); + } +#else PU::getInterMergeCandidates( pu, mergeCtx ); +#endif } PU::restrictBiPredMergeCands( pu, mergeCtx ); @@ -4565,6 +4603,13 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa m_CABACEstimator->cu_skip_flag ( cu ); m_CABACEstimator->affine_flag( cu ); +#if JVET_L0054_MMVD + if (cu.mmvdSkip) + { + m_CABACEstimator->mmvd_merge_idx(pu); + } + else +#endif m_CABACEstimator->merge_idx ( pu ); @@ -4689,6 +4734,13 @@ uint64_t InterSearch::xGetSymbolFracBitsInter(CodingStructure &cs, Partitioner & m_CABACEstimator->cu_skip_flag ( cu ); m_CABACEstimator->affine_flag ( cu ); +#if JVET_L0054_MMVD + if (cu.mmvdSkip) + { + m_CABACEstimator->mmvd_merge_idx(*cu.firstPU); + } + else +#endif m_CABACEstimator->merge_idx ( *cu.firstPU ); fracBits += m_CABACEstimator->getEstFracBits(); } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index b84bbf562be107a7a5f5eb5825f21a02b5d41255..7ad505f512d60bc9a81a7895d096f1ceb4ddee52 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -567,22 +567,48 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) { WRITE_FLAG( spsNext.getUseDualITree(), "qtbt_dual_intra_tree" ); WRITE_UVLC( g_aucLog2[spsNext.getCTUSize()] - MIN_CU_LOG2, "log2_CTU_size_minus2" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_FLAG (spsNext.getSplitConsOverrideEnabledFlag(), "sps_override_partition_constraints_enable_flag"); + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize(I_SLICE)] - spsNext.getSPS().getLog2MinCodingBlockSize(), "sps_log2_diff_min_qt_min_cb_intra_slice"); + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize(B_SLICE)] - spsNext.getSPS().getLog2MinCodingBlockSize(), "sps_log2_diff_min_qt_min_cb_inter_slice"); + WRITE_UVLC( spsNext.getMaxBTDepth(), "sps_max_mtt_hierarchy_depth_inter_slices"); + WRITE_UVLC( spsNext.getMaxBTDepthI(), "sps_max_mtt_hierarchy_depth_intra_slices"); + if (spsNext.getMaxBTDepthI() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSizeI()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE)], "sps_log2_diff_max_bt_min_qt_intra_slice"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSizeI()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE)], "sps_log2_diff_max_tt_min_qt_intra_slice"); + } + if (spsNext.getMaxBTDepth() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSize()] - g_aucLog2[spsNext.getMinQTSize(B_SLICE)], "sps_log2_diff_max_bt_min_qt_inter_slice"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSize()] - g_aucLog2[spsNext.getMinQTSize(B_SLICE)], "sps_log2_diff_max_tt_min_qt_inter_slice"); + } +#else WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE ) ] - MIN_CU_LOG2, "log2_minQT_ISlice_minus2" ); WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( B_SLICE ) ] - MIN_CU_LOG2, "log2_minQT_PBSlice_minus2" ); WRITE_UVLC( spsNext.getMaxBTDepth(), "max_bt_depth" ); WRITE_UVLC( spsNext.getMaxBTDepthI(), "max_bt_depth_i_slice" ); +#endif if( spsNext.getUseDualITree() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA )] - spsNext.getSPS().getLog2MinCodingBlockSize(), "sps_log2_diff_min_qt_min_cb_intra_slice_chroma"); + WRITE_UVLC( spsNext.getMaxBTDepthIChroma(), "sps_max_mtt_hierarchy_depth_intra_slices_chroma"); + if (spsNext.getMaxBTDepthIChroma() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSizeIChroma()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)], "sps_log2_diff_max_bt_min_qt_intra_slice_chroma"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSizeIChroma()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)], "sps_log2_diff_max_tt_min_qt_intra_slice_chroma"); + } +#else WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA )] - MIN_CU_LOG2, "log2_minQT_ISliceChroma_minus2" ); WRITE_UVLC( spsNext.getMaxBTDepthIChroma(), "max_bt_depth_i_slice_chroma" ); +#endif } } if( spsNext.getUseSubPuMvp() ) { WRITE_CODE( spsNext.getSubPuMvpLog2Size() - MIN_CU_LOG2, 3, "log2_sub_pu_tmvp_size_minus2" ); -#if ENABLE_BMS -#endif } if( spsNext.getUseIMV() ) @@ -594,6 +620,19 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) { WRITE_UVLC( spsNext.getMTTMode() - 1, "mtt_mode_minus1" ); } +#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET + WRITE_FLAG( spsNext.getLadfEnabled() ? 1 : 0, "sps_ladf_enabled_flag" ); + if ( spsNext.getLadfEnabled() ) + { + WRITE_CODE( spsNext.getLadfNumIntervals() - 2, 2, "sps_num_ladf_intervals_minus2" ); + WRITE_SVLC( spsNext.getLadfQpOffset( 0 ), "sps_ladf_lowest_interval_qp_offset"); + for ( int k = 1; k< spsNext.getLadfNumIntervals(); k++ ) + { + WRITE_SVLC( spsNext.getLadfQpOffset( k ), "sps_ladf_qp_offset" ); + WRITE_UVLC( spsNext.getLadfIntervalLowerBound( k ) - spsNext.getLadfIntervalLowerBound( k - 1 ) - 1, "sps_ladf_delta_threshold_minus1" ); + } + } +#endif // ADD_NEW_TOOL : (sps extension writer) write tool enabling flags and associated parameters here } @@ -651,7 +690,11 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } } CHECK( pcSPS->getMaxCUWidth() != pcSPS->getMaxCUHeight(), "Rectangular CTUs not supported" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 2, "log2_min_luma_coding_block_size_minus2"); +#else WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 3, "log2_min_luma_coding_block_size_minus3" ); +#endif WRITE_UVLC( pcSPS->getLog2DiffMaxMinCodingBlockSize(), "log2_diff_max_min_luma_coding_block_size" ); WRITE_UVLC( pcSPS->getQuadtreeTULog2MinSize() - 2, "log2_min_luma_transform_block_size_minus2" ); WRITE_UVLC( pcSPS->getQuadtreeTULog2MaxSize() - pcSPS->getQuadtreeTULog2MinSize(), "log2_diff_max_min_luma_transform_block_size" ); @@ -1183,6 +1226,36 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) #endif if( pcSlice->getSPS()->getSpsNext().getUseQTBT() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (pcSlice->getSPS()->getSpsNext().getSplitConsOverrideEnabledFlag()) + { + WRITE_FLAG(pcSlice->getSplitConsOverrideFlag() ? 1 : 0, "partition_constrainst_override_flag"); + if (pcSlice->getSplitConsOverrideFlag()) + { + WRITE_UVLC(g_aucLog2[pcSlice->getMinQTSize()] - pcSlice->getSPS()->getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb"); + WRITE_UVLC(pcSlice->getMaxBTDepth(), "max_bt_depth"); + if (pcSlice->getMaxBTDepth() != 0) + { + CHECK(pcSlice->getMaxBTSize() < pcSlice->getMinQTSize(), "maxBtSize is smaller than minQtSize"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxBTSize()] - g_aucLog2[pcSlice->getMinQTSize()], "log2_diff_max_bt_min_qt"); + CHECK(pcSlice->getMaxTTSize() < pcSlice->getMinQTSize(), "maxTtSize is smaller than minQtSize"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxTTSize()] - g_aucLog2[pcSlice->getMinQTSize()], "log2_diff_max_tt_min_qt"); + } + if (pcSlice->isIntra() && pcSlice->getSPS()->getSpsNext().getUseDualITree()) + { + WRITE_UVLC(g_aucLog2[pcSlice->getMinQTSizeIChroma()] - pcSlice->getSPS()->getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb_chroma"); + WRITE_UVLC(pcSlice->getMaxBTDepthIChroma(), "max_mtt_hierarchy_depth_chroma"); + if (pcSlice->getMaxBTDepthIChroma() != 0) + { + CHECK(pcSlice->getMaxBTSizeIChroma() < pcSlice->getMinQTSizeIChroma(), "maxBtSizeC is smaller than minQtSizeC"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxBTSizeIChroma()] - g_aucLog2[pcSlice->getMinQTSizeIChroma()], "log2_diff_max_bt_min_qt_chroma"); + CHECK(pcSlice->getMaxTTSizeIChroma() < pcSlice->getMinQTSizeIChroma(), "maxTtSizeC is smaller than minQtSizeC"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxTTSizeIChroma()] - g_aucLog2[pcSlice->getMinQTSizeIChroma()], "log2_diff_max_tt_min_qt_chroma"); + } + } + } + } +#else if( !pcSlice->isIntra() ) { if( pcSlice->getSPS()->getSpsNext().getCTUSize() > pcSlice->getMaxBTSize() ) @@ -1194,6 +1267,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) WRITE_UVLC( 0, "max_binary_tree_unit_size" ); } } +#endif } if( !pcSlice->isIntra() ) { diff --git a/source/Lib/Utilities/CMakeLists.txt b/source/Lib/Utilities/CMakeLists.txt index 0b0464411f660fffc5e6a3ab431d0c0331724388..2b3e74242f9108c5e38c8574c940a49cbd6e9bad 100644 --- a/source/Lib/Utilities/CMakeLists.txt +++ b/source/Lib/Utilities/CMakeLists.txt @@ -16,10 +16,6 @@ endif() add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} ${NATVIS_FILES} ) target_compile_definitions( ${LIB_NAME} PUBLIC ) -if( ENABLE_VTM ) - target_compile_definitions( ${LIB_NAME} PUBLIC BMS_TOOLS=0 ) -endif() - if( EXTENSION_360_VIDEO ) target_compile_definitions( ${LIB_NAME} PUBLIC EXTENSION_360_VIDEO=1 ) endif()