diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index 4f2296d89d8ddfc86a40b055842c345f539a6bce..9f41baa2f13ebd3fb2c9912b3ec24a1ba834bde7 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -198,7 +198,9 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio #endif ctxId += ( cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ) ? 1 : 0; - +#if JVET_L0361_SPLIT_CTX + ctxId += partitioner.currQtDepth < 2 ? 0 : 3; +#else if( cs.sps->getSpsNext().getUseLargeCTU() ) { unsigned minDepth = 0; @@ -213,6 +215,7 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio ctxId = 4; } } +#endif return ctxId; } @@ -319,10 +322,39 @@ unsigned DeriveCtx::CtxBTsplit(const CodingStructure& cs, Partitioner& partition #endif { +#if JVET_L0361_SPLIT_CTX + unsigned widthCurr = partitioner.currArea().lwidth(); + unsigned heightCurr = partitioner.currArea().lheight(); + + if( cuLeft ) + { + unsigned heightLeft = cuLeft->Y().height; + ctx += ( heightLeft < heightCurr ? 1 : 0 ); + } + if( cuAbove ) + { + unsigned widthAbove = cuAbove->Y().width; + ctx += ( widthAbove < widthCurr ? 1 : 0 ); + } + + if( partitioner.chType == CHANNEL_TYPE_CHROMA ) + { + ctx += 9; + } + else + { + int maxBTSize = cs.pcv->getMaxBtSize( *cs.slice, partitioner.chType ); + int th1 = ( maxBTSize == 128 ) ? 128 : ( ( maxBTSize == 64 ) ? 64 : 64 ); + int th2 = ( maxBTSize == 128 ) ? 1024 : ( ( maxBTSize == 64 ) ? 512 : 256 ); + unsigned int sizeCurr = widthCurr * heightCurr; + ctx += sizeCurr > th2 ? 0 : ( sizeCurr > th1 ? 3 : 6 ); + } +#else const unsigned currDepth = partitioner.currQtDepth * 2 + partitioner.currBtDepth; if( cuLeft ) ctx += ( ( 2 * cuLeft->qtDepth + cuLeft->btDepth ) > currDepth ? 1 : 0 ); if( cuAbove ) ctx += ( ( 2 * cuAbove->qtDepth + cuAbove->btDepth ) > currDepth ? 1 : 0 ); +#endif } return ctx; } diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 63576e159053b7ae8bf35f55b6658c5a6141409f..434e66e89c9de59b81126a4def2fbfdc28370c46 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -262,16 +262,29 @@ std::vector<std::vector<uint8_t>> ContextSetCfg::sm_InitTables( NUMBER_OF_SLICE_ const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet ({ +#if JVET_L0361_SPLIT_CTX + { 107, 139, 126, 107, 139, 126, }, + { 107, 139, 126, 107, 139, 126, }, + { 139, 141, 157, 139, 141, 157, }, +#else { 107, 139, 126, 255, 0,}, { 107, 139, 126, 255, 0,}, { 139, 141, 157, 255, 0,}, +#endif }); const CtxSet ContextSetCfg::BTSplitFlag = ContextSetCfg::addCtxSet ({ +#if JVET_L0361_SPLIT_CTX + // |-------- 1st bin, 9 ctx for luma + 3 ctx for chroma------| |--2nd bin--| |3rd bin| + { 107, 139, 126, 107, 139, 126, 107, 139, 126, 107, 139, 126, 154, 154, 154, 154,}, + { 107, 139, 126, 107, 139, 126, 107, 139, 126, 107, 139, 126, 154, 154, 154, 154,}, + { 139, 141, 157, 139, 141, 157, 139, 141, 157, 139, 141, 157, 154, 154, 154, 154,}, +#else { 107, 139, 126, 154, 154, 154, 154, 154, 154, 154, 154, 154,}, { 107, 139, 126, 154, 154, 154, 154, 154, 154, 154, 154, 154,}, { 139, 141, 157, 154, 154, 154, 154, 154, 154, 154, 154, 154,}, +#endif }); const CtxSet ContextSetCfg::SkipFlag = ContextSetCfg::addCtxSet diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp index e0135d1c1dee0841329c7d4bc0d40b6b9baa7792..f4b7522fcca5fa803b7c52569a6fd313297f1966 100644 --- a/source/Lib/CommonLib/LoopFilter.cpp +++ b/source/Lib/CommonLib/LoopFilter.cpp @@ -250,6 +250,10 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir ) xSetEdgefilterMultiple( cu, EDGE_HOR, areaTu, m_stLFCUParam.internalEdge ); } +#if L0074_SUBBLOCK_DEBLOCKING + bool mvSubBlocks = false; + int subBlockSize = 8; +#endif for( auto &currPU : CU::traversePUs( cu ) ) { const Area& areaPu = cu.Y().valid() ? currPU.block( COMPONENT_Y ) : area; @@ -259,8 +263,31 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir ) xSetEdgefilterMultiple( cu, EDGE_VER, areaPu, (xOff ? m_stLFCUParam.internalEdge : m_stLFCUParam.leftEdge), xOff ); xSetEdgefilterMultiple( cu, EDGE_HOR, areaPu, (yOff ? m_stLFCUParam.internalEdge : m_stLFCUParam.topEdge), yOff ); +#if L0074_SUBBLOCK_DEBLOCKING + if ((currPU.mergeFlag && (currPU.mergeType == MRG_TYPE_SUBPU_ATMVP)) || cu.affine) + { + mvSubBlocks = true; + if (edgeDir == EDGE_HOR) + { + for (uint32_t off = subBlockSize; off < areaPu.height; off += subBlockSize) + { + const Area mvBlockH(cu.Y().x, cu.Y().y + off, cu.Y().width, pcv.minCUHeight); + xSetEdgefilterMultiple(cu, EDGE_HOR, mvBlockH, m_stLFCUParam.internalEdge, 1); + } + } + else + { + for (uint32_t off = subBlockSize; off < areaPu.width; off += subBlockSize) + { + const Area mvBlockV(cu.Y().x + off, cu.Y().y, pcv.minCUWidth, cu.Y().height); + xSetEdgefilterMultiple(cu, EDGE_VER, mvBlockV, m_stLFCUParam.internalEdge, 1); + } + } + } +#endif } +#if !L0074_SUBBLOCK_DEBLOCKING if ( cu.affine ) { const int widthInBaseUnits = cu.Y().width >> pcv.minCUWidthLog2; @@ -276,6 +303,7 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir ) xSetEdgefilterMultiple( cu, EDGE_HOR, affiBlockH, m_stLFCUParam.internalEdge, 1 ); } } +#endif const unsigned uiPelsInPart = pcv.minCUWidth; for( int y = 0; y < area.height; y += uiPelsInPart ) @@ -316,12 +344,27 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir ) if (cu.blocks[COMPONENT_Y].valid()) { +#if L0074_SUBBLOCK_DEBLOCKING + if (mvSubBlocks) + { + orthogonalIncrement = subBlockSize / 4; + orthogonalLength = (edgeDir == EDGE_HOR) ? cu.blocks[COMPONENT_Y].height / 4 : cu.blocks[COMPONENT_Y].width / 4; + } +#endif +#if L0074_SUBBLOCK_DEBLOCKING + if ((cu.blocks[COMPONENT_Y].height > 64) && (edgeDir == EDGE_HOR) && !mvSubBlocks) +#else if ((cu.blocks[COMPONENT_Y].height > 64) && (edgeDir == EDGE_HOR)) +#endif { orthogonalIncrement = 64 / 4; orthogonalLength = cu.blocks[COMPONENT_Y].height / 4; } +#if L0074_SUBBLOCK_DEBLOCKING + if ((cu.blocks[COMPONENT_Y].width > 64) && (edgeDir == EDGE_VER) && !mvSubBlocks) +#else if ((cu.blocks[COMPONENT_Y].width > 64) && (edgeDir == EDGE_VER)) +#endif { orthogonalIncrement = 64 / 4; orthogonalLength = cu.blocks[COMPONENT_Y].width / 4; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index afc72b3b03d815888b1ae9afc455379aacbdaf99..af2cf490b7a86a5545535951e2bb5a30a7ca446b 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_L0553_FIX_INITQP 1 + #define JVET_L0147_ALF_SUBSAMPLED_LAPLACIAN 1 // Subsampled Laplacian calculation #define JVET_L0191_LM_WO_LMS 1 // NO LMS regression. min/max are used instead @@ -66,9 +68,13 @@ #define JVET_L0194_ONE_CTX_FOR_MRG_IDX 1 // one context for full-block Merge index +#define JVET_L0361_SPLIT_CTX 1 // context for cu-split-related flags + #define JVET_L0274 1 #define JVET_L0274_ENCODER_SPEED_UP ( 1 && JVET_L0274 ) // encoder speed-up by pre-calculating position dependent parameters +#define L0074_SUBBLOCK_DEBLOCKING 1 + #define JVET_L0256_BIO 1 #if JVET_L0256_BIO #define JVET_L0256_BIO_EXTEND_SIZE 1 @@ -84,6 +90,8 @@ #define JVET_L0093_SIMP_PRUNE 1 +#define JVET_L0257_ATMVP_COLBLK_CLIP 1 + #ifndef JVET_B0051_NON_MPM_MODE #define JVET_B0051_NON_MPM_MODE ( 1 && JEM_TOOLS ) #endif diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 50a027e071af64297cd7c24ed9ea49e4c8c4366e..065e4fe39742efeb66e7cff63714dc3909d5d84f 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -2239,6 +2239,23 @@ static bool deriveScaledMotionTemporal( const Slice& slice, return false; } +#if JVET_L0257_ATMVP_COLBLK_CLIP +void clipColPos(int& posX, int& posY, const PredictionUnit& pu) +{ + Position puPos = pu.lumaPos(); + int log2CtuSize = g_aucLog2[pu.cs->sps->getSpsNext().getCTUSize()]; + int ctuX = ((puPos.x >> log2CtuSize) << log2CtuSize); + int ctuY = ((puPos.y >> log2CtuSize) << log2CtuSize); + + int horMax = std::min((int)pu.cs->sps->getPicWidthInLumaSamples() - 1, ctuX + (int)pu.cs->sps->getSpsNext().getCTUSize() + 3); + int horMin = std::max((int)0, ctuX); + int verMax = std::min((int)pu.cs->sps->getPicHeightInLumaSamples() - 1, ctuY + (int)pu.cs->sps->getSpsNext().getCTUSize() - 1); + int verMin = std::max((int)0, ctuY); + + posX = std::min(horMax, std::max(horMin, posX)); + posY = std::min(verMax, std::max(verMin, posY)); +} +#else void clipColBlkMv(int& mvX, int& mvY, const PredictionUnit& pu) { Position puPos = pu.lumaPos(); @@ -2261,6 +2278,7 @@ void clipColBlkMv(int& mvX, int& mvY, const PredictionUnit& pu) mvX = std::min(horMax, std::max(horMin, mvX)); mvY = std::min(verMax, std::max(verMin, mvY)); } +#endif bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, bool& LICFlag, const int count ) @@ -2303,7 +2321,9 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b #if !REMOVE_MV_ADAPT_PREC } #endif +#if !JVET_L0257_ATMVP_COLBLK_CLIP int mvRndOffs = (1 << mvPrec) >> 1; +#endif Mv cTempVector = cTMv; bool tempLICFlag = false; @@ -2324,6 +2344,15 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b bool found = false; cTempVector = cTMv; +#if JVET_L0257_ATMVP_COLBLK_CLIP + int tempX = cTempVector.getHor() >> mvPrec; + int tempY = cTempVector.getVer() >> mvPrec; + + centerPos.x = puPos.x + (puSize.width >> 1) + tempX; + centerPos.y = puPos.y + (puSize.height >> 1) + tempY; + + clipColPos(centerPos.x, centerPos.y, pu); +#else int tempX = ((cTempVector.getHor() + mvRndOffs) >> mvPrec); int tempY = ((cTempVector.getVer() + mvRndOffs) >> mvPrec); clipColBlkMv(tempX, tempY, pu); @@ -2341,6 +2370,7 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b centerPos.x = Clip3(0, (int)pColPic->lwidth() - 1, centerPos.x); centerPos.y = Clip3(0, (int)pColPic->lheight() - 1, centerPos.y); +#endif centerPos = Position{ PosType(centerPos.x & mask), PosType(centerPos.y & mask) }; @@ -2377,6 +2407,10 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b return false; } +#if JVET_L0257_ATMVP_COLBLK_CLIP + int xOff = (puWidth >> 1) + tempX; + int yOff = (puHeight >> 1) + tempY; +#else int xOff = puWidth / 2; int yOff = puHeight / 2; @@ -2386,6 +2420,7 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b int iPicWidth = pColPic->lwidth() - 1; int iPicHeight = pColPic->lheight() - 1; +#endif MotionBuf& mb = mrgCtx.subPuMvpMiBuf; @@ -2397,8 +2432,12 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b { Position colPos{ x + xOff, y + yOff }; +#if JVET_L0257_ATMVP_COLBLK_CLIP + clipColPos(colPos.x, colPos.y, pu); +#else colPos.x = Clip3(0, iPicWidth, colPos.x); colPos.y = Clip3(0, iPicHeight, colPos.y); +#endif colPos = Position{ PosType(colPos.x & mask), PosType(colPos.y & mask) }; diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 1c7fcab067343d766f7ecab778b6910f90945fd2..70aae0890cdc0a0bd6a842586cf89ef874d7ad75 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -622,10 +622,17 @@ PartSplit CABACReader::split_cu_mode_mt( CodingStructure& cs, Partitioner &parti unsigned btSCtxId = width == height ? 0 : ( width > height ? 1 : 2 ); dt.setCtxId( DTT_SPLIT_DO_SPLIT_DECISION, Ctx::BTSplitFlag( ctxIdBT ) ); // 0- 2 +#if JVET_L0361_SPLIT_CTX + dt.setCtxId( DTT_SPLIT_HV_DECISION, Ctx::BTSplitFlag( 12 + btSCtxId ) );//12-14 + + dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) ); + dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) ); +#else dt.setCtxId( DTT_SPLIT_HV_DECISION, Ctx::BTSplitFlag( 3 + btSCtxId ) ); // 3- 5 dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 6 + btSCtxId ) ); // 6- 8 dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 9 + btSCtxId ) ); // 9-11 +#endif unsigned id = decode_sparse_dt( dt ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 6052f00ae25639b7b5793cc66e052bf9edf14f13..6eb95048a8d34be9fdb4d2bd1d56368420e34b0e 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -565,10 +565,17 @@ void CABACWriter::split_cu_mode_mt(const PartSplit split, const CodingStructure& unsigned btSCtxId = width == height ? 0 : ( width > height ? 1 : 2 ); dt.setCtxId( DTT_SPLIT_DO_SPLIT_DECISION, Ctx::BTSplitFlag( ctxIdBT ) ); +#if JVET_L0361_SPLIT_CTX + dt.setCtxId( DTT_SPLIT_HV_DECISION, Ctx::BTSplitFlag( 12 + btSCtxId ) ); + + dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) ); + dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) ); +#else dt.setCtxId( DTT_SPLIT_HV_DECISION, Ctx::BTSplitFlag( 3 + btSCtxId ) ); dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 6 + btSCtxId ) ); dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 9 + btSCtxId ) ); +#endif encode_sparse_dt( dt, split == CU_DONT_SPLIT ? ( unsigned ) DTT_SPLIT_NO_SPLIT : ( unsigned ) split ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index a261753a769640fa52d07a9cf8aa8268896c78ec..ea5b9913b8c0ef17763ed002151df0548c1aa581 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1237,7 +1237,11 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) { baseQp = getBaseQP()-26; } +#if JVET_L0553_FIX_INITQP + const int maxDQP = 37; +#else const int maxDQP = 25; +#endif const int minDQP = -26 + sps.getQpBDOffset(CHANNEL_TYPE_LUMA); pps.setPicInitQPMinus26( std::min( maxDQP, std::max( minDQP, baseQp ) ));