Commit e9fe4302 authored by Xiang Li's avatar Xiang Li

Merge branch 'master' into 'master'

JVET-L0362 : quantization parameter signalling, including two parts

See merge request jvet/VVCSoftware_VTM!114
parents 14a70bbb c2adafc7
Pipeline #442 failed with stage
......@@ -136,6 +136,9 @@
#define JVET_L0293_CPR 1 // current picture referencing or intra block copy mode
#define JVET_L0362_QG_FIX 1 // QG is the node of qtDepth + mttDepth <= maxDqpDepth
#define JVET_L0362_QG_FIX_CU_REUSE 1 // fix bug on encoder cu coding info reusing fast algorithm (i.e., reuse cu info when having the same neighbor and the same qp)
#ifndef JVET_B0051_NON_MPM_MODE
#define JVET_B0051_NON_MPM_MODE ( 1 && JEM_TOOLS )
#endif
......
......@@ -176,13 +176,32 @@ int CU::predictQP( const CodingUnit& cu, const int prevQP )
return ( a + b + 1 ) >> 1;
}
#if JVET_L0362_QG_FIX
bool CU::isQGStart( const CodingUnit& cu, Partitioner& partitioner )
#else
bool CU::isQGStart( const CodingUnit& cu )
#endif
{
#if JVET_L0362_QG_FIX
int maxDqpDepth = cu.slice->getPPS()->getMaxCuDQPDepth();
if( partitioner.currDepth >= maxDqpDepth )
{
PartLevel splitAtMaxDepth = partitioner.getPartStack().at( maxDqpDepth );
// the parent node of qtDepth + mttDepth == maxDqpDepth
if( splitAtMaxDepth.parts[splitAtMaxDepth.idx].blocks[partitioner.chType].pos() == cu.blocks[partitioner.chType].pos() )
return true;
else
return false;
}
else
return true;
#else
const SPS &sps = *cu.cs->sps;
const PPS &pps = *cu.cs->pps;
return ( cu.blocks[cu.chType].x % ( ( 1 << ( g_aucLog2[sps.getMaxCUWidth()] - pps.getMaxCuDQPDepth() ) ) >> getChannelTypeScaleX( cu.chType, cu.chromaFormat ) ) ) == 0 &&
( cu.blocks[cu.chType].y % ( ( 1 << ( g_aucLog2[sps.getMaxCUHeight()] - pps.getMaxCuDQPDepth() ) ) >> getChannelTypeScaleY( cu.chType, cu.chromaFormat ) ) ) == 0;
#endif
}
uint32_t CU::getNumPUs( const CodingUnit& cu )
......
......@@ -71,7 +71,11 @@ namespace CU
uint32_t getCtuAddr (const CodingUnit &cu);
int predictQP (const CodingUnit& cu, const int prevQP );
#if JVET_L0362_QG_FIX
bool isQGStart (const CodingUnit& cu, Partitioner& partitioner ); // check if start of a Quantization Group
#else
bool isQGStart (const CodingUnit& cu); // check if start of a Quantization Group
#endif
uint32_t getNumPUs (const CodingUnit& cu);
void addPUs ( CodingUnit& cu);
......
......@@ -570,7 +570,11 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
#endif
// Predict QP on start of quantization group
#if JVET_L0362_QG_FIX
if( pps.getUseDQP() && !cuCtx.isDQPCoded && CU::isQGStart( cu, partitioner ) )
#else
if( pps.getUseDQP() && !cuCtx.isDQPCoded && CU::isQGStart( cu ) )
#endif
{
cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
}
......
......@@ -502,7 +502,11 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
}
// Predict QP on start of quantization group
#if JVET_L0362_QG_FIX
if( pps.getUseDQP() && !cuCtx.isDQPCoded && CU::isQGStart( cu, partitioner ) )
#else
if( pps.getUseDQP() && !cuCtx.isDQPCoded && CU::isQGStart( cu ) )
#endif
{
cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
}
......
......@@ -753,13 +753,21 @@ bool BestEncInfoCache::setFromCs( const CodingStructure& cs, const Partitioner&
return true;
}
#if JVET_L0362_QG_FIX_CU_REUSE
bool BestEncInfoCache::isValid( const CodingStructure& cs, const Partitioner& partitioner, int qp )
#else
bool BestEncInfoCache::isValid( const CodingStructure& cs, const Partitioner& partitioner )
#endif
{
unsigned idx1, idx2, idx3, idx4;
getAreaIdx( cs.area.Y(), *m_slice_bencinf->getPPS()->pcv, idx1, idx2, idx3, idx4 );
BestEncodingInfo& encInfo = *m_bestEncInfo[idx1][idx2][idx3][idx4];
#if JVET_L0362_QG_FIX_CU_REUSE
if( encInfo.cu.qp != qp )
return false;
#endif
if( cs.picture->poc != encInfo.poc || CS::getArea( cs, cs.area, partitioner.chType ) != encInfo.cu || !isTheSameNbHood( encInfo.cu, partitioner )
#if JVET_L0293_CPR
|| encInfo.cu.cpr
......@@ -931,7 +939,7 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
cuECtx.set( DID_QUAD_SPLIT, false );
cuECtx.set( IS_BEST_NOSPLIT_SKIP, false );
cuECtx.set( MAX_QT_SUB_DEPTH, 0 );
#if REUSE_CU_RESULTS
#if REUSE_CU_RESULTS && !JVET_L0362_QG_FIX_CU_REUSE
const bool isReusingCu = isValid( cs, partitioner );
cuECtx.set( IS_REUSING_CU, isReusingCu );
#endif
......@@ -1052,7 +1060,7 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
m_ComprCUCtxList.back().testModes.push_back( { ETM_POST_DONT_SPLIT } );
#if REUSE_CU_RESULTS
#if REUSE_CU_RESULTS && !JVET_L0362_QG_FIX_CU_REUSE
if( isReusingCu )
{
m_ComprCUCtxList.back().testModes.push_back( { ETM_RECO_CACHED } );
......@@ -1081,6 +1089,14 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
{
const int qp = std::max( qpLoop, lowestQP );
const bool lossless = useLossless && qpLoop == minQP;
#if REUSE_CU_RESULTS && JVET_L0362_QG_FIX_CU_REUSE
const bool isReusingCu = isValid( cs, partitioner, qp );
cuECtx.set( IS_REUSING_CU, isReusingCu );
if( isReusingCu )
{
m_ComprCUCtxList.back().testModes.push_back( {ETM_RECO_CACHED, SIZE_2Nx2N, ETO_STANDARD, qp, lossless} );
}
#endif
// add intra modes
m_ComprCUCtxList.back().testModes.push_back( { ETM_IPCM, ETO_STANDARD, qp, lossless } );
m_ComprCUCtxList.back().testModes.push_back( { ETM_INTRA, ETO_STANDARD, qp, lossless } );
......
......@@ -422,7 +422,11 @@ protected:
void init ( const Slice &slice );
bool setFromCs( const CodingStructure& cs, const Partitioner& partitioner );
#if JVET_L0362_QG_FIX
bool isValid ( const CodingStructure& cs, const Partitioner& partitioner, int qp );
#else
bool isValid ( const CodingStructure& cs, const Partitioner& partitioner );
#endif
// TODO: implement copyState
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment