diff --git a/cmake/CMakeBuild/bin/pyhhi/__init__.pyc b/cmake/CMakeBuild/bin/pyhhi/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cde6cada74dfa8f81e6b2224df0edabf75d754f8 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/__init__.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/__init__.pyc b/cmake/CMakeBuild/bin/pyhhi/build/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f93098d45cd975f3c40b1c545c4538d9443e50ef Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/__init__.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/app/__init__.pyc b/cmake/CMakeBuild/bin/pyhhi/build/app/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aae725b6e2216d20f01a4ef68a0d82508032d423 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/app/__init__.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/app/cmk.pyc b/cmake/CMakeBuild/bin/pyhhi/build/app/cmk.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4346bb6eb002aa92f8c6890ccca123c874de6c68 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/app/cmk.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/cmkfnd.pyc b/cmake/CMakeBuild/bin/pyhhi/build/cmkfnd.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5b791b883732da774be809d26b4184660e79ac7 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/cmkfnd.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/cmksupp.pyc b/cmake/CMakeBuild/bin/pyhhi/build/cmksupp.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fa3750f0dba19655d62061f57dc628cf836dabf Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/cmksupp.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/__init__.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5fc6976798ba15db1f1066481f2feb7f9c75959 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/__init__.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/bldtools.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/bldtools.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c27b7273fb8f5986f5fbb8d711430d544c67d5d9 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/bldtools.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/cmbldver.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/cmbldver.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae1c9c223ffe227c0819bcb9e8eb437591857ec9 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/cmbldver.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/error.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/error.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c206770122f234037123152ecb12bc9d39b3991 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/error.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/system.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/system.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f03cdc0f704dd8e5324592bda42e80ef253dea6 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/system.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/util.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9681ad0bd5db345a2a5a36d29fb3b250364b21b6 Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/util.pyc differ diff --git a/cmake/CMakeBuild/bin/pyhhi/build/common/ver.pyc b/cmake/CMakeBuild/bin/pyhhi/build/common/ver.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c0615f71febf28ce8bd3c68433486d54cf860cd Binary files /dev/null and b/cmake/CMakeBuild/bin/pyhhi/build/common/ver.pyc differ diff --git a/enc.bit b/enc.bit new file mode 100644 index 0000000000000000000000000000000000000000..38b6a9dcd19461ad04583bb7104989f05d76bf8d Binary files /dev/null and b/enc.bit differ diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp index c72a3e938bff37029a212213c08cb35a5eb26878..04dac8b388b6667c600f37482c92619f48239b75 100644 --- a/source/App/DecoderApp/DecAppCfg.cpp +++ b/source/App/DecoderApp/DecAppCfg.cpp @@ -111,6 +111,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] ) "\t1: enable bit statistic\n" "\t2: enable tool statistic\n" "\t3: enable bit and tool statistic\n") +#endif +#if JVET_M0445_MCTS_DEC_CHECK + ("MCTSCheck", m_mctsCheck, false, "If enabled, the decoder checks for violations of mc_exact_sample_value_match_flag in Temporal MCTS ") #endif ; @@ -148,6 +151,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] ) } #endif +#if JVET_M0445_MCTS_DEC_CHECK + g_mctsDecCheckEnabled = m_mctsCheck; +#endif // Chroma output bit-depth if( m_outputBitDepth[CHANNEL_TYPE_LUMA] != 0 && m_outputBitDepth[CHANNEL_TYPE_CHROMA] == 0 ) { @@ -230,6 +236,9 @@ DecAppCfg::DecAppCfg() , m_bClipOutputVideoToRec709Range(false) , m_packedYUVMode(false) , m_statMode(0) +#if JVET_M0445_MCTS_DEC_CHECK +, m_mctsCheck(false) +#endif { for (uint32_t channelTypeIndex = 0; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++) { diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h index 8674f99e816bcaf180b608e2a6e92ab6c13ff322..029ad15ebd4847fafc14c10503c4eaa6ddae05cd 100644 --- a/source/App/DecoderApp/DecAppCfg.h +++ b/source/App/DecoderApp/DecAppCfg.h @@ -73,6 +73,9 @@ protected: bool m_packedYUVMode; ///< If true, output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data std::string m_cacheCfgFile; ///< Config file of cache model int m_statMode; ///< Config statistic mode (0 - bit stat, 1 - tool stat, 3 - both) +#if JVET_M0445_MCTS_DEC_CHECK + bool m_mctsCheck; +#endif public: DecAppCfg(); diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 53d2b214bb3c21a5d90dfb32e8b86b51a895551b..a38a1174f8f581354335161834968ec88d28b1f2 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -435,6 +435,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setSOPDescriptionSEIEnabled ( m_SOPDescriptionSEIEnabled ); m_cEncLib.setScalableNestingSEIEnabled ( m_scalableNestingSEIEnabled ); m_cEncLib.setTMCTSSEIEnabled ( m_tmctsSEIEnabled ); +#if JVET_M0445_MCTS + m_cEncLib.setMCTSEncConstraint ( m_MCTSEncConstraint); +#endif m_cEncLib.setTimeCodeSEIEnabled ( m_timeCodeSEIEnabled ); m_cEncLib.setNumberOfTimeSets ( m_timeCodeSEINumTs ); for(int i = 0; i < m_timeCodeSEINumTs; i++) diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index b6b2e470f22766f1519232163bf11431d15162be..a4b20c5cfd4e474d57b682f13555ffff596e1255 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1296,6 +1296,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #endif ("SEIGreenMetadataType", m_greenMetadataType, 0u, "Value for the green_metadata_type specifies the type of metadata that is present in the SEI message. If green_metadata_type is 1, then metadata enabling quality recovery after low-power encoding is present") ("SEIXSDMetricType", m_xsdMetricType, 0u, "Value for the xsd_metric_type indicates the type of the objective quality metric. PSNR is the only type currently supported") +#if JVET_M0445_MCTS + ("MCTSEncConstraint", m_MCTSEncConstraint, false, "For MCTS, constrain motion vectors at tile boundaries") +#endif #if ENABLE_TRACING ("TraceChannelsList", bTracingChannelsList, false, "List all available tracing channels") ("TraceRule", sTracingRule, string( "" ), "Tracing rule (ex: \"D_CABAC:poc==8\" or \"D_REC_CB_LUMA:poc==8\")") @@ -2840,6 +2843,30 @@ bool EncAppCfg::xCheckParameter() #endif } +#if JVET_M0445_MCTS + g_mctsEncConstraint = m_MCTSEncConstraint; + if ((m_MCTSEncConstraint) && (m_bLFCrossTileBoundaryFlag)) + { + printf("Warning: Constrained Encoding for Motion Constrained Tile Sets (MCTS) is enabled. Disabling filtering across tile boundaries!\n"); + m_bLFCrossTileBoundaryFlag = false; + } + if ((m_MCTSEncConstraint) && (m_TMVPModeId)) + { + printf("Warning: Constrained Encoding for Motion Constrained Tile Sets (MCTS) is enabled. Disabling TMVP!\n"); + m_TMVPModeId = 0; + } + + if ((m_MCTSEncConstraint) && ( m_alf )) + { + printf("Warning: Constrained Encoding for Motion Constrained Tile Sets (MCTS) is enabled. Disabling ALF!\n"); + m_alf = false; + } + if( ( m_MCTSEncConstraint ) && ( m_BIO ) ) + { + printf( "Warning: Constrained Encoding for Motion Constrained Tile Sets (MCTS) is enabled. Disabling BIO!\n" ); + m_BIO = false; + } +#endif if (m_toneMappingInfoSEIEnabled) { @@ -3137,6 +3164,9 @@ void EncAppCfg::xPrintParameter() { msg( VERBOSE, "A=%d ", m_sliceSegmentArgument); } +#endif +#if JVET_M0445_MCTS + msg( VERBOSE, "Tiles:%dx%d ", m_numTileColumnsMinus1 + 1, m_numTileRowsMinus1 + 1 ); #endif msg( VERBOSE, "CIP:%d ", m_bUseConstrainedIntraPred); msg( VERBOSE, "SAO:%d ", (m_bUseSAO)?(1):(0)); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index b4b3705ecfe8cc449df2e9eab2498165211cb371..09f665f46e179f0121e8457ce05b1ad11d60e463 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -465,6 +465,10 @@ protected: uint32_t m_greenMetadataType; uint32_t m_xsdMetricType; +#if JVET_M0445_MCTS + bool m_MCTSEncConstraint; +#endif + // weighted prediction bool m_useWeightedPred; ///< Use of weighted prediction in P slices bool m_useWeightedBiPred; ///< Use of bi-directional weighted prediction in B slices diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 473d844c98a0b024bc37dab51e6684a192f0233e..62493a2f8d5716bd0a710b48f56e39993e1de35d 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -39,6 +39,9 @@ #include "Buffer.h" #include "UnitTools.h" +#if JVET_M0445_MCTS +#include "MCTS.h" +#endif #include <memory.h> #include <algorithm> @@ -1447,10 +1450,27 @@ void InterPrediction::motionCompensation4Triangle( CodingUnit &cu, MergeCtx &tri PU::spanMotionInfo( pu ); motionCompensation( pu, tmpTriangleBuf ); +#if JVET_M0445_MCTS_DEC_CHECK + { + if( g_mctsDecCheckEnabled && !MCTSHelper::checkMvBufferForMCTSConstraint( pu, true ) ) + { + printf( "DECODER_TRIANGLE_PU: pu motion vector across tile boundaries (%d,%d,%d,%d)\n", pu.lx(), pu.ly(), pu.lwidth(), pu.lheight() ); + } + } +#endif + triangleMrgCtx.setMergeInfo( pu, candIdx1 ); PU::spanMotionInfo( pu ); motionCompensation( pu, predBuf ); +#if JVET_M0445_MCTS_DEC_CHECK + { + if( g_mctsDecCheckEnabled && !MCTSHelper::checkMvBufferForMCTSConstraint( pu, true ) ) + { + printf( "DECODER_TRIANGLE_PU: pu motion vector across tile boundaries (%d,%d,%d,%d)\n", pu.lx(), pu.ly(), pu.lwidth(), pu.lheight() ); + } + } +#endif #if JVET_M0328_KEEP_ONE_WEIGHT_GROUP weightedTriangleBlk( pu, splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, tmpTriangleBuf, predBuf ); #else diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 3be7081794d6505d02b79839fd46dd94072caa14..6e6dcc1f60ad669321b89694376e6fab42f509b6 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -49,6 +49,9 @@ #if JVET_M0253_HASH_ME #include "Hash.h" #endif +#if JVET_M0445_MCTS +#include "MCTS.h" +#endif #include <deque> #if ENABLE_WPP_PARALLELISM || ENABLE_SPLIT_PARALLELISM @@ -286,6 +289,9 @@ public: #if HEVC_TILES_WPP TileMap* tileMap; +#endif +#if JVET_M0445_MCTS + MCTSInfo mctsInfo; #endif std::vector<AQpLayer*> aqlayer; diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index d2e45089664850f87bf095c792926f52eb326c4b..e9e873d575c1c508741ee2351f3d43b199f2ae69 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -51,6 +51,12 @@ #if ENABLE_TRACING CDTrace *g_trace_ctx = NULL; #endif +#if JVET_M0445_MCTS +bool g_mctsEncConstraint = false; +#endif +#if JVET_M0445_MCTS_DEC_CHECK +bool g_mctsDecCheckEnabled = false; +#endif //! \ingroup CommonLib diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h index f7b795621be0edde887cd2700663a8f2a8a2a60b..712092901f2f49b669ca00230b956e07e6a174ff 100644 --- a/source/Lib/CommonLib/Rom.h +++ b/source/Lib/CommonLib/Rom.h @@ -262,5 +262,12 @@ extern const uint8_t g_triangleCombination[TRIANGLE_MAX_NUM_CANDS][3]; extern const uint8_t g_triangleIdxBins[TRIANGLE_MAX_NUM_CANDS]; #endif +#if JVET_M0445_MCTS +extern bool g_mctsEncConstraint; +#endif +#if JVET_M0445_MCTS_DEC_CHECK +extern bool g_mctsDecCheckEnabled; +#endif + #endif //__TCOMROM__ diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 6c591033bf365a4da7343a2afcbdf4ecda1562be..28061f9604c4c1d5a9fbe9a5543a57895f71502b 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,10 @@ #include <assert.h> #include <cassert> +#define JVET_M0445_MCTS 1 // Motion constrained tile sets +#if JVET_M0445_MCTS +#define JVET_M0445_MCTS_DEC_CHECK 1 // Check at decoder side the MCTS restrictions +#endif #define JCTVC_Y0038_PARAMS 1 #define JVET_M0600_RATE_CTRL 1 //frame level bit allocation by qdf @@ -261,6 +265,15 @@ typedef std::pair<int, int> TrCost; #define HEVC_TILES_WPP 1 #endif +#if JVET_M0445_MCTS +#ifndef HEVC_TILES_WPP +#define HEVC_TILES_WPP 1 +#endif +#if !HEVC_TILES_WPP +#error JVET_M0445_MCTS_NEEDS_TILES_ENABLED +#endif +#endif + #define KEEP_PRED_AND_RESI_SIGNALS 0 diff --git a/source/Lib/CommonLib/dtrace_buffer.h b/source/Lib/CommonLib/dtrace_buffer.h index 3d4712b33bd27e2a2a4380d100d8ed325a9ce39a..f5fcbdf61a542990ed952845786472b1e40d6077 100644 --- a/source/Lib/CommonLib/dtrace_buffer.h +++ b/source/Lib/CommonLib/dtrace_buffer.h @@ -165,6 +165,25 @@ inline void dtraceCCRC( CDTrace *trace_ctx, DTRACE_CHANNEL channel, const Coding calcCheckSum( pelBuf, cs.sps->getBitDepth ( toChannelType(compId) ))); } +inline void dtraceMotField( CDTrace *trace_ctx, const PredictionUnit& pu ) +{ + DTRACE( trace_ctx, D_MOT_FIELD, "PU %d,%d @ %d,%d\n", pu.lwidth(), pu.lheight(), pu.lx(), pu.ly() ); + const CMotionBuf mb = pu.getMotionBuf(); + for( uint32_t listIdx = 0; listIdx < 2; listIdx++ ) + { + RefPicList eListIdx = RefPicList( listIdx ); + for( int y = 0, i = 0; y < pu.lheight(); y += 4 ) + { + for( int x = 0; x < pu.lwidth(); x += 4, i++ ) + { + const MotionInfo &mi = mb.at( x >> 2, y >> 2 ); + DTRACE( trace_ctx, D_MOT_FIELD, "%d,%d:%d ", mi.mv[eListIdx].getHor(), mi.mv[eListIdx].getVer(), mi.refIdx[eListIdx] ); + } + DTRACE( trace_ctx, D_MOT_FIELD, "\n" ); + } + DTRACE( trace_ctx, D_MOT_FIELD, "\n" ); + } +} #define DTRACE_PEL_BUF(...) dtracePelBuf( __VA_ARGS__ ) #define DTRACE_COEFF_BUF(...) dtraceCoeffBuf( __VA_ARGS__ ) @@ -175,6 +194,7 @@ inline void dtraceCCRC( CDTrace *trace_ctx, DTRACE_CHANNEL channel, const Coding #define DTRACE_UNIT_COMP(...) dtraceUnitComp( __VA_ARGS__ ) #define DTRACE_CRC(...) dtraceCRC( __VA_ARGS__ ) #define DTRACE_CCRC(...) dtraceCCRC( __VA_ARGS__ ) +#define DTRACE_MOT_FIELD(...) dtraceMotField( __VA_ARGS__ ) #else @@ -187,6 +207,7 @@ inline void dtraceCCRC( CDTrace *trace_ctx, DTRACE_CHANNEL channel, const Coding #define DTRACE_UNIT_COMP(...) #define DTRACE_CRC(...) #define DTRACE_CCRC(...) +#define DTRACE_MOT_FIELD(...) #endif diff --git a/source/Lib/CommonLib/dtrace_next.h b/source/Lib/CommonLib/dtrace_next.h index 2aa746d8a139c8854ae62924de8a90738aa7a6d1..23e7ef98e15808b98b6ef11b03b101b055da8ce0 100644 --- a/source/Lib/CommonLib/dtrace_next.h +++ b/source/Lib/CommonLib/dtrace_next.h @@ -141,6 +141,7 @@ enum DTRACE_CHANNEL D_RDOQ_MORE, D_RDOQ_COST, D_TMP, + D_MOT_FIELD, D_CRC #if K0149_BLOCK_STATISTICS , @@ -242,6 +243,7 @@ inline CDTrace* tracing_init( std::string& sTracingFile, std::string& sTracingRu _CNL_DEF( D_RDOQ_MORE ), _CNL_DEF( D_RDOQ_COST ), _CNL_DEF( D_TMP ), + _CNL_DEF( D_MOT_FIELD ), _CNL_DEF( D_CRC ) #if K0149_BLOCK_STATISTICS , diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 723ccb3dce81f83f8625567717bd644f5bf7eccb..9d6b2a035dc959857c69c8efcb469cdc40be783c 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -905,6 +905,15 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) PU::spanMotionInfo( pu, mrgCtx ); } } +#if JVET_M0445_MCTS_DEC_CHECK + if( !cu.triangle ) + { + if( g_mctsDecCheckEnabled && !MCTSHelper::checkMvBufferForMCTSConstraint( pu, true ) ) + { + printf( "DECODER: pu motion vector across tile boundaries (%d,%d,%d,%d)\n", pu.lx(), pu.ly(), pu.lwidth(), pu.lheight() ); + } + } +#endif } } //! \} diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index 5e12acbcfcc5ef91dfe4c63995acfb24eada8ac4..b365dd7e042435fcaee8b904e82eedcccb756228 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -235,6 +235,12 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream ) cs.slice->resetMotionLUTs(); } +#if JVET_M0445_MCTS_DEC_CHECK + if( !cs.slice->isIntra() ) + { + pic->mctsInfo.init( &cs, getCtuAddr( ctuArea.lumaPos(), *( cs.pcv ) ) ); + } +#endif #if JVET_M0055_DEBUG_CTU if( ctuRsAddr == debugCTU ) diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 84faf6062336fdfae584bffb0d3432723aaabd80..64db89dfbe06b25a5fc26ea45f2bb655e14b1c19 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -478,6 +478,9 @@ protected: bool m_SOPDescriptionSEIEnabled; bool m_scalableNestingSEIEnabled; bool m_tmctsSEIEnabled; +#if JVET_M0445_MCTS + bool m_MCTSEncConstraint; +#endif bool m_timeCodeSEIEnabled; int m_timeCodeSEINumTs; SEITimeSet m_timeSetArray[MAX_TIMECODE_SEI_SETS]; @@ -1278,6 +1281,10 @@ public: bool getScalableNestingSEIEnabled() const { return m_scalableNestingSEIEnabled; } void setTMCTSSEIEnabled(bool b) { m_tmctsSEIEnabled = b; } bool getTMCTSSEIEnabled() { return m_tmctsSEIEnabled; } +#if JVET_M0445_MCTS + void setMCTSEncConstraint(bool b) { m_MCTSEncConstraint = b; } + bool getMCTSEncConstraint() { return m_MCTSEncConstraint; } +#endif void setTimeCodeSEIEnabled(bool b) { m_timeCodeSEIEnabled = b; } bool getTimeCodeSEIEnabled() { return m_timeCodeSEIEnabled; } void setNumberOfTimeSets(int value) { m_timeCodeSEINumTs = value; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 55fdef4db785a19724d8f19190f8feaad6950448..2f294c1694d82ccb68fb8239e521f0e1655665c7 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -44,6 +44,9 @@ #include "CommonLib/dtrace_codingstruct.h" #include "CommonLib/Picture.h" #include "CommonLib/UnitTools.h" +#if JVET_M0445_MCTS +#include "MCTS.h" +#endif #include "CommonLib/dtrace_buffer.h" @@ -2612,6 +2615,14 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } PU::spanMotionInfo( pu, mergeCtx ); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() && ( !( MCTSHelper::checkMvBufferForMCTSConstraint( pu ) ) ) ) + { + // Do not use this mode + tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); + continue; + } +#endif if( mrgTempBufSet ) { #if JVET_M0147_DMVR @@ -2697,7 +2708,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip && !pu.mhIntraFlag) { +#if JVET_M0445_MCTS + bestIsSkip = !bestCS->cus.empty() && bestCS->getCU( partitioner.chType )->rootCbf == 0; +#else bestIsSkip = bestCS->getCU( partitioner.chType )->rootCbf == 0; +#endif } tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); }// end loop uiMrgHADIdx @@ -2807,6 +2822,14 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru triangleMrgCtx.setMergeInfo( pu, mergeCand ); PU::spanMotionInfo( pu, triangleMrgCtx ); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() && ( !( MCTSHelper::checkMvBufferForMCTSConstraint( pu ) ) ) ) + { + // Do not use this mode + tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); + return; + } +#endif m_pcInterSearch->motionCompensation( pu, triangleBuffer[mergeCand] ); } } @@ -3012,6 +3035,14 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru PU::spanTriangleMotionInfo(pu, triangleMrgCtx, mergeCand, splitDir, candIdx0, candIdx1 ); #endif +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() && ( !( MCTSHelper::checkMvBufferForMCTSConstraint( *cu.firstPU ) ) ) ) + { + // Do not use this mode + tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); + return; + } +#endif if( tempBufSet ) { tempCS->getPredBuf().copyFrom( triangleWeightedBuffer[mergeCand] ); @@ -3293,6 +3324,14 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct PU::spanMotionInfo( pu ); } +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() && ( !( MCTSHelper::checkMvBufferForMCTSConstraint( *cu.firstPU ) ) ) ) + { + // Do not use this mode + tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); + return; + } +#endif if ( mrgTempBufSet ) { tempCS->getPredBuf().copyFrom( acMergeBuffer[uiMergeCand] ); @@ -4228,6 +4267,14 @@ bool EncCu::xCheckRDCostInterIMV( CodingStructure *&tempCS, CodingStructure *&be #endif } +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() && ( ( cu.firstPU->refIdx[L0] < 0 && cu.firstPU->refIdx[L1] < 0 ) || ( !( MCTSHelper::checkMvBufferForMCTSConstraint( *cu.firstPU ) ) ) ) ) + { + // Do not use this mode + tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); + continue; + } +#endif if( testGbi && gbiIdx == GBI_DEFAULT ) // Enabled GBi but the search results is uni. { tempCS->initStructData(encTestMode.qp, encTestMode.lossless); diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index 6dd2b484302b4bd7c4a41556e14d1c79f38d8ccb..775413103b4db2af56a0ee732bacd93e33130c36 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -1492,9 +1492,13 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt if (cs.sps->getIBCMode() && !cuECtx.bestTU) #endif return true; + #if !JVET_M0445_MCTS CHECK( !slice.isIntra() && !cuECtx.bestTU, "No possible non-intra encoding for a P- or B-slice found" ); if( !( slice.isIRAP() || bestMode.type == ETM_INTRA || +#else + if( !( slice.isIRAP() || bestMode.type == ETM_INTRA || !cuECtx.bestTU || +#endif #if JVET_M0483_IBC ((!m_pcEncCfg->getDisableIntraPUsInInterSlices()) && (!relatedCU.isInter || !relatedCU.isIBC) && ( #else diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index a9d137a9fc0801ee4677e5f3f982b2ac8d36cc6e..ed3246256d25cd7e9d0f644fb8b8d03d04335384 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1663,6 +1663,12 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons m_pcCuEncoder->setDecCuReshaperInEncCU(m_pcLib->getReshaper(), pcSlice->getSPS()->getChromaFormatIdc()); } #endif +#if JVET_M0445_MCTS + if( !cs.slice->isIntra() && pCfg->getMCTSEncConstraint() ) + { + pcPic->mctsInfo.init( &cs, ctuRsAddr ); + } +#endif #if JVET_M0055_DEBUG_CTU if (pCfg->getSwitchPOC() != pcPic->poc || ctuRsAddr >= pCfg->getDebugCTU()) diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index b4fe070d4f7dfb0ae90019bb0512d7f8d990561f..a21dcc20e30b66309f139112c66dc66b069cc297 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -45,6 +45,9 @@ #include "CommonLib/UnitTools.h" #include "CommonLib/dtrace_next.h" #include "CommonLib/dtrace_buffer.h" +#if JVET_M0445_MCTS +#include "CommonLib/MCTS.h" +#endif #include "EncModeCtrl.h" #include "EncLib.h" @@ -1945,7 +1948,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) AMVPInfo aacAMVPInfo[2][33]; int iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage. +#if JVET_M0445_MCTS + int iRefIdxBi[2] = { -1, -1 }; +#else int iRefIdxBi[2]; +#endif uint32_t uiMbBits[3] = {1, 1, 0}; @@ -2149,6 +2156,9 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) && (cu.slice->getCheckLDC() || gbiIdx == GBI_DEFAULT || !m_affineModeSelected || !m_pcEncCfg->getUseGBiFast()) ) { +#if JVET_M0445_MCTS + bool doBiPred = true; +#endif cMvBi[0] = cMv[0]; cMvBi[1] = cMv[1]; iRefIdxBi[0] = iRefIdx[0]; @@ -2172,6 +2182,21 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1]; pu.mvpIdx[REF_PIC_LIST_1] = bestBiPMvpL1; +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + Mv restrictedMv = pu.mv[REF_PIC_LIST_1]; + Area curTileAreaRestricted; + curTileAreaRestricted = pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ); + MCTSHelper::clipMvToArea( restrictedMv, pu.cu->Y(), curTileAreaRestricted, *pu.cs->sps ); + // If sub-pel filter samples are not inside of allowed area + if( restrictedMv != pu.mv[REF_PIC_LIST_1] ) + { + uiCostBi = std::numeric_limits<Distortion>::max(); + doBiPred = false; + } + } +#endif PelUnitBuf predBufTmp = m_tmpPredStorage[REF_PIC_LIST_1].getBuf( UnitAreaRelative(cu, pu) ); motionCompensation( pu, predBufTmp, REF_PIC_LIST_1 ); @@ -2200,6 +2225,10 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; } +#if JVET_M0445_MCTS + if( doBiPred ) + { +#endif // 4-times iteration (default) int iNumIter = 4; @@ -2330,6 +2359,9 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) break; } } // for loop-iter +#if JVET_M0445_MCTS + } +#endif cu.refIdxBi[0] = iRefIdxBi[0]; cu.refIdxBi[1] = iRefIdxBi[1]; @@ -2425,6 +2457,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) symCost += m_pcRdCost->getCost(bits); cTarMvField.setMvField(cCurMvField.mv.getSymmvdMv(cMvPredSym[curRefList], cMvPredSym[tarRefList]), refIdxTar); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + if( !( MCTSHelper::checkMvForMCTSConstraint( pu, cCurMvField.mv ) && MCTSHelper::checkMvForMCTSConstraint( pu, cTarMvField.mv ) ) ) + symCost = std::numeric_limits<Distortion>::max(); + } +#endif // save results if ( symCost < uiCostBi ) { @@ -2648,6 +2687,15 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) uiAffineCost += m_pcRdCost->getCost( 1 ); // add one bit for affine_type } +#if JVET_M0445_MCTS + if( uiAffineCost < uiHevcCost ) + { + if( m_pcEncCfg->getMCTSEncConstraint() && !MCTSHelper::checkMvBufferForMCTSConstraint( pu ) ) + { + uiAffineCost = std::numeric_limits<Distortion>::max(); + } + } +#endif if ( uiHevcCost <= uiAffineCost ) { // set hevc me result @@ -3086,6 +3134,20 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref // sub-pel refinement for sub-pel resolution if( pu.cu->imv == 0 ) { +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + Area curTileAreaSubPelRestricted = pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ); + Area targetArea = pu.cu->Y(); + targetArea.repositionTo( targetArea.offset( rcMv.getHor(), rcMv.getVer() ) ); + // If sub-pel filter samples are not inside of allowed area + // Variant 1: clip full-pel vector, do sub-pel refinement for clipped MV + if( !curTileAreaSubPelRestricted.contains( targetArea ) ) + { + MCTSHelper::clipMvToArea( rcMv, pu.cu->Y(), curTileAreaSubPelRestricted, *pu.cs->sps, 0 ); + } + } +#endif xPatternSearchFracDIF( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, cMvHalf, cMvQter, ruiCost ); m_pcRdCost->setCostScale( 0 ); rcMv <<= 2; @@ -3121,12 +3183,29 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu, Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift)); Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift)); +#if JVET_M0445_MCTS + if (m_pcEncCfg->getMCTSEncConstraint()) + { + MCTSHelper::clipMvToArea( mvTL, pu.Y(), pu.cs->picture->mctsInfo.getTileArea(), *pu.cs->sps ); + MCTSHelper::clipMvToArea( mvBR, pu.Y(), pu.cs->picture->mctsInfo.getTileArea(), *pu.cs->sps ); + } + else + { + xClipMv( mvTL, pu.cu->lumaPos(), + pu.cu->lumaSize(), + *pu.cs->sps ); + xClipMv( mvBR, pu.cu->lumaPos(), + pu.cu->lumaSize(), + *pu.cs->sps ); + } +#else xClipMv( mvTL, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); xClipMv( mvBR, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); +#endif mvTL.divideByPowerOf2( iMvShift ); mvBR.divideByPowerOf2( iMvShift ); @@ -3270,6 +3349,13 @@ void InterSearch::xTZSearch( const PredictionUnit& pu, int iSearchRange = m_iSearchRange; rcMv.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + MCTSHelper::clipMvToArea( rcMv, pu.Y(), pu.cs->picture->mctsInfo.getTileArea(), *pu.cs->sps ); + } + else +#endif clipMv( rcMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); @@ -3306,6 +3392,13 @@ void InterSearch::xTZSearch( const PredictionUnit& pu, { Mv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred; integerMv2Nx2NPred.changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + MCTSHelper::clipMvToArea( integerMv2Nx2NPred, pu.Y(), pu.cs->picture->mctsInfo.getTileArea(), *pu.cs->sps ); + } + else +#endif clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); @@ -3758,14 +3851,37 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct& cTestMv[iMVPIdx] += cBaseMvd[iMVPIdx]; cTestMv[iMVPIdx] += amvpInfo.mvCand[iMVPIdx]; +#if JVET_M0445_MCTS + // MCTS and IMV + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + Mv cTestMVRestr = cTestMv[iMVPIdx]; + cTestMVRestr.changePrecision( MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL ); + MCTSHelper::clipMvToArea( cTestMVRestr, pu.cu->Y(), pu.cs->picture->mctsInfo.getTileAreaIntPelRestricted( pu ), *pu.cs->sps ); + cTestMVRestr.changePrecision( MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER ); + + if( cTestMVRestr != cTestMv[iMVPIdx] ) + { + // Skip this IMV pos, cause clipping affects IMV scaling + continue; + } + } +#endif if ( iMVPIdx == 0 || cTestMv[0] != cTestMv[1]) { Mv cTempMV = cTestMv[iMVPIdx]; +#if JVET_M0445_MCTS + if( !m_pcEncCfg->getMCTSEncConstraint() ) + { +#endif cTempMV.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL); clipMv(cTempMV, pu.cu->lumaPos(), pu.cu->lumaSize(), sps); cTempMV.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER); +#if JVET_M0445_MCTS + } +#endif m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * (cTempMV.getVer() >> 2) + (cTempMV.getHor() >> 2); uiDist = uiSATD = (Distortion) (m_cDistParam.distFunc( m_cDistParam ) * fWeight); } @@ -3788,6 +3904,13 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct& } } } +#if JVET_M0445_MCTS + if( uiBestDist == std::numeric_limits<Distortion>::max() ) + { + ruiCost = std::numeric_limits<Distortion>::max(); + return; + } +#endif rcMv = cBestMv; rcMvPred = amvpInfo.mvCand[iBestMVPIdx]; @@ -3961,6 +4084,13 @@ Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf& MvField mvCand = mvCurCenter, mvPair; mvCand.mv += mvOffset; +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + if( !( MCTSHelper::checkMvForMCTSConstraint( pu, mvCand.mv ) ) ) + continue; // Skip this this pos + } +#endif // get MVD cost m_pcRdCost->setPredictor( rcMvCurPred ); m_pcRdCost->setCostScale( 0 ); @@ -3970,6 +4100,13 @@ Distortion InterSearch::xSymmeticRefineMvSearch( PredictionUnit &pu, PelUnitBuf& // get MVD pair and set target MV mvPair.refIdx = rTarMvField.refIdx; mvPair.mv.set( rcMvTarPred.hor - (mvCand.mv.hor - rcMvCurPred.hor), rcMvTarPred.ver - (mvCand.mv.ver - rcMvCurPred.ver) ); +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + if( !( MCTSHelper::checkMvForMCTSConstraint( pu, mvPair.mv ) ) ) + continue; // Skip this this pos + } +#endif uiCost += xGetSymmetricCost( pu, origBuf, eRefPicList, mvCand, mvPair, gbiIdx ); if ( uiCost < uiMinCost ) { @@ -4515,6 +4652,9 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, ::memcpy( aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx) ); uint32_t uiMotBits[2]; +#if JVET_M0445_MCTS + bool doBiPred = true; +#endif if ( slice.getMvdL1ZeroFlag() ) // GPB, list 1 only use Mvp { @@ -4531,6 +4671,27 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, ::memcpy( cMvTemp[1][bestBiPRefIdxL1], pcMvTemp, sizeof(Mv)*3 ); iRefIdxBi[1] = bestBiPRefIdxL1; +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + Area curTileAreaRestricted; + curTileAreaRestricted = pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ); + for( int i = 0; i < mvNum; i++ ) + { + Mv restrictedMv = pcMvTemp[i]; + restrictedMv.changePrecision( MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL ); + MCTSHelper::clipMvToArea( restrictedMv, pu.cu->Y(), curTileAreaRestricted, *pu.cs->sps ); + restrictedMv.changePrecision( MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER ); + + // If sub-pel filter samples are not inside of allowed area + if( restrictedMv != pcMvTemp[i] ) + { + uiCostBi = std::numeric_limits<Distortion>::max(); + doBiPred = false; + } + } + } +#endif // Get list1 prediction block PU::setAllAffineMv( pu, cMvBi[1][0], cMvBi[1][1], cMvBi[1][2], REF_PIC_LIST_1 #if JVET_M0246_AFFINE_AMVR @@ -4566,6 +4727,10 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; } +#if JVET_M0445_MCTS + if( doBiPred ) + { +#endif // 4-times iteration (default) int iNumIter = 4; // fast encoder setting or GPB: only one iteration @@ -4713,6 +4878,9 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, break; } } // for loop-iter +#if JVET_M0445_MCTS + } +#endif } // if (B_SLICE) pu.mv [REF_PIC_LIST_0] = Mv(); @@ -5094,6 +5262,19 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, uint32_t uiBitsBest = 0; // do motion compensation with origin mv +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + Area curTileAreaRestricted = pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ); + MCTSHelper::clipMvToArea( acMvTemp[0], pu.cu->Y(), curTileAreaRestricted, *pu.cs->sps ); + MCTSHelper::clipMvToArea( acMvTemp[1], pu.cu->Y(), curTileAreaRestricted, *pu.cs->sps ); + if( pu.cu->affineType == AFFINEMODEL_6PARAM ) + { + MCTSHelper::clipMvToArea( acMvTemp[2], pu.cu->Y(), curTileAreaRestricted, *pu.cs->sps ); + } + } + else +#endif clipMv( acMvTemp[0], pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); @@ -5336,6 +5517,20 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, { acMvTemp[i].roundToPrecision( MV_PRECISION_INTERNAL, MV_PRECISION_INT ); } +#endif +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + MCTSHelper::clipMvToArea( acMvTemp[i], pu.cu->Y(), pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ), *pu.cs->sps ); + } + else +#endif +#if JVET_M0445_MCTS + if( m_pcEncCfg->getMCTSEncConstraint() ) + { + MCTSHelper::clipMvToArea( acMvTemp[i], pu.cu->Y(), pu.cs->picture->mctsInfo.getTileAreaSubPelRestricted( pu ), *pu.cs->sps ); + } + else #endif clipMv(acMvTemp[i], pu.cu->lumaPos(), pu.cu->lumaSize(), diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 485a25e8e5ae6f97a7e6c85d8d88eba78c6f86b9..6ecc3e20810d7afe759c770fd7e68a9a380b8ae9 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -359,6 +359,18 @@ void SEIEncoder::initSEITempMotionConstrainedTileSets (SEITempMotionConstrainedT if(pps->getTilesEnabledFlag()) { +#if JVET_M0445_MCTS + if (m_pcCfg->getMCTSEncConstraint()) + { + sei->m_mc_all_tiles_exact_sample_value_match_flag = true; + sei->m_each_tile_one_tile_set_flag = true; + sei->m_limited_tile_set_display_flag = false; + sei->m_max_mcs_tier_level_idc_present_flag = false; + sei->setNumberOfTileSets(0); + } + else + { +#endif sei->m_mc_all_tiles_exact_sample_value_match_flag = false; sei->m_each_tile_one_tile_set_flag = false; sei->m_limited_tile_set_display_flag = false; @@ -379,6 +391,9 @@ void SEIEncoder::initSEITempMotionConstrainedTileSets (SEITempMotionConstrainedT sei->tileSetData(i).m_mcts_tier_level_idc_present_flag = false; } } +#if JVET_M0445_MCTS + } +#endif else { CHECK(!(!"Tile is not enabled"), "Unspecified error");