Commit 42eae432 authored by Christian Helmrich's avatar Christian Helmrich

Merge branch 'master' of https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM...

Merge branch 'master' of https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM into JVET_O0105_O0543_JCC
parents f83271a0 5b3b09c3
......@@ -293,17 +293,36 @@ class CUCtx
public:
CUCtx() : isDQPCoded(false), isChromaQpAdjCoded(false),
qgStart(false),
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
numNonZeroCoeffNonTs(0)
{
violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false;
violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
}
#else
numNonZeroCoeffNonTs(0) {}
#endif
CUCtx(int _qp) : isDQPCoded(false), isChromaQpAdjCoded(false),
qgStart(false),
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
numNonZeroCoeffNonTs(0), qp(_qp)
{
violatesLfnstConstrained[CHANNEL_TYPE_LUMA ] = false;
violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
}
#else
numNonZeroCoeffNonTs(0), qp(_qp) {}
#endif
~CUCtx() {}
public:
bool isDQPCoded;
bool isChromaQpAdjCoded;
bool qgStart;
uint32_t numNonZeroCoeffNonTs;
int8_t qp; // used as a previous(last) QP and for QP prediction
uint32_t numNonZeroCoeffNonTs;
int8_t qp; // used as a previous(last) QP and for QP prediction
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
bool violatesLfnstConstrained[MAX_NUM_CHANNEL_TYPE];
#endif
};
class MergeCtx
......
......@@ -882,13 +882,17 @@ namespace DQIntern
m_goRicePar = 0;
m_goRiceZero = 0;
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB ) const
#else
void checkRdCosts( const ScanPosType spt, const PQData& pqDataA, const PQData& pqDataB, Decision& decisionA, Decision& decisionB, bool zeroOut ) const
#endif
{
const int32_t* goRiceTab = g_goRiceBits[m_goRicePar];
int64_t rdCostA = m_rdCost + pqDataA.deltaDist;
int64_t rdCostB = m_rdCost + pqDataB.deltaDist;
int64_t rdCostZ = m_rdCost;
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( zeroOut )
{
rdCostZ = m_rdCost;
......@@ -924,6 +928,7 @@ namespace DQIntern
}
else
{
#endif
if( m_remRegBins >= 4 )
{
if( pqDataA.absLevel < 4 )
......@@ -988,7 +993,9 @@ namespace DQIntern
decisionB.prevId = m_stateId;
}
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
}
#endif
inline void checkRdCostStart(int32_t lastOffset, const PQData &pqData, Decision &decision) const
{
......@@ -1409,15 +1416,36 @@ namespace DQIntern
{
::memcpy( decisions, startDec, 8*sizeof(Decision) );
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( zeroOut )
{
if( spt==SCAN_EOCSBB )
{
m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] );
m_skipStates[1].checkRdCostSkipSbbZeroOut( decisions[1] );
m_skipStates[2].checkRdCostSkipSbbZeroOut( decisions[2] );
m_skipStates[3].checkRdCostSkipSbbZeroOut( decisions[3] );
}
return;
}
#endif
PQData pqData[4];
m_quant.preQuantCoeff( absCoeff, pqData, quanCoeff );
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2]);
m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0]);
m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3]);
m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1]);
#else
m_prevStates[0].checkRdCosts( spt, pqData[0], pqData[2], decisions[0], decisions[2], zeroOut );
m_prevStates[1].checkRdCosts( spt, pqData[0], pqData[2], decisions[2], decisions[0], zeroOut );
m_prevStates[2].checkRdCosts( spt, pqData[3], pqData[1], decisions[1], decisions[3], zeroOut );
m_prevStates[3].checkRdCosts( spt, pqData[3], pqData[1], decisions[3], decisions[1], zeroOut );
#endif
if( spt==SCAN_EOCSBB )
{
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( zeroOut )
{
m_skipStates[0].checkRdCostSkipSbbZeroOut( decisions[0] );
......@@ -1427,17 +1455,25 @@ namespace DQIntern
}
else
{
#endif
m_skipStates[0].checkRdCostSkipSbb( decisions[0] );
m_skipStates[1].checkRdCostSkipSbb( decisions[1] );
m_skipStates[2].checkRdCostSkipSbb( decisions[2] );
m_skipStates[3].checkRdCostSkipSbb( decisions[3] );
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
}
#endif
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( !zeroOut )
{
#endif
m_startState.checkRdCostStart( lastOffset, pqData[0], decisions[0] );
m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] );
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
}
#endif
}
void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff )
......@@ -1459,7 +1495,11 @@ namespace DQIntern
m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3] );
::memcpy( decisions+4, decisions, 4*sizeof(Decision) );
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
else if( !zeroOut )
#else
else
#endif
{
switch( scanInfo.nextNbInfoSbb.num )
{
......@@ -1544,10 +1584,17 @@ namespace DQIntern
zeroOutforThres = zeroOut || (32 < tuPars.m_height || 32 < tuPars.m_width);
//===== find first test position =====
int firstTestPos = numCoeff - 1;
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 )
{
firstTestPos = ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ? 7 : 15 ;
}
#else
if( lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) )
{
firstTestPos = 7;
}
#endif
const TCoeff defaultQuantisationCoefficient = (TCoeff)m_quant.getQScale();
const TCoeff thres = m_quant.getLastThreshold();
for( ; firstTestPos >= 0; firstTestPos-- )
......@@ -1594,15 +1641,25 @@ namespace DQIntern
for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- )
{
const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ];
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
bool lfnstZeroOut = lfnstIdx > 0 && tu.mtsIdx != MTS_SKIP && width >= 4 && height >= 4 &&
( ( ( ( width >= 8 && height >= 8 ) && scanIdx >= 16 ) || ( ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) && scanIdx >= 8 ) ) && scanIdx < 48 );
if (enableScalingLists)
{
m_quant.initQuantBlock(tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos]);
xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)) || lfnstZeroOut, quantCoeff[scanInfo.rasterPos] );
}
}
else
xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)) || lfnstZeroOut, defaultQuantisationCoefficient );
#else
if (enableScalingLists)
{
m_quant.initQuantBlock(tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos]);
xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), quantCoeff[scanInfo.rasterPos] );
}
else
xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos]), scanInfo, (zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight)), defaultQuantisationCoefficient );
#endif
}
//===== find best path =====
......
......@@ -366,13 +366,15 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID )
#endif
bool transposeFlag = getTransposeFlag( intraMode );
const int sbSize = whge3 ? 8 : 4;
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1;
const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1;
#endif
bool tu4x4Flag = ( width == 4 && height == 4 );
bool tu8x8Flag = ( width == 8 && height == 8 );
TCoeff* lfnstTemp;
TCoeff* coeffTemp;
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ )
{
for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ )
......@@ -382,7 +384,11 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID )
int y;
lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement
coeffTemp = m_plTempCoeff + offsetX + offsetY;
#else
int y;
lfnstTemp = m_tempInMatrix; // inverse spectral rearrangement
coeffTemp = m_plTempCoeff;
#endif
TCoeff * dst = lfnstTemp;
const ScanElement * scanPtr = scan;
for( y = 0; y < 16; y++ )
......@@ -433,8 +439,10 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID )
coeffTemp += width;
}
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
}
} // subGroupX
#endif
}
}
}
......@@ -464,14 +472,17 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons
bool transposeFlag = getTransposeFlag( intraMode );
const int sbSize = whge3 ? 8 : 4;
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
const int subGrpXMax = ( height == 4 && width > 8 ) ? 2 : 1;
const int subGrpYMax = ( width == 4 && height > 8 ) ? 2 : 1;
#endif
bool tu4x4Flag = ( width == 4 && height == 4 );
bool tu8x8Flag = ( width == 8 && height == 8 );
TCoeff* lfnstTemp;
TCoeff* coeffTemp;
TCoeff* tempCoeff = loadTr ? m_mtsCoeffs[ tu.mtsIdx ] : m_plTempCoeff;
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
for( int subGroupX = 0; subGroupX < subGrpXMax; subGroupX++ )
{
for( int subGroupY = 0; subGroupY < subGrpYMax; subGroupY++ )
......@@ -481,6 +492,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons
int y;
lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform
coeffTemp = tempCoeff + offsetX + offsetY;
#else
int y;
lfnstTemp = m_tempInMatrix; // forward low frequency non-separable transform
coeffTemp = tempCoeff;
#endif
if( transposeFlag )
{
......@@ -524,8 +540,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons
fwdLfnstNxN( m_tempInMatrix, m_tempOutMatrix, g_lfnstLut[ intraMode ], lfnstIdx - 1, sbSize, ( tu4x4Flag || tu8x8Flag ) ? 8 : 16 );
lfnstTemp = m_tempOutMatrix; // forward spectral rearrangement
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
coeffTemp = tempCoeff + offsetX + offsetY;
#else
coeffTemp = tempCoeff;
#endif
const ScanElement * scanPtr = scan;
int lfnstCoeffNum = ( sbSize == 4 ) ? sbSize * sbSize : 48;
for( y = 0; y < lfnstCoeffNum; y++ )
......@@ -533,8 +552,10 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons
coeffTemp[ scanPtr->idx ] = *lfnstTemp++;
scanPtr++;
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
}
} // subGroupX
#endif
}
}
}
......@@ -823,8 +844,26 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel
getTrTypes ( tu, compID, trTypeHor, trTypeVer );
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0;
const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0;
#else
int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0;
int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0;
if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx )
{
if( (width == 4 && height > 4) || (width > 4 && height == 4) )
{
skipWidth = width - 4;
skipHeight = height - 4;
}
else if( (width >= 8 && height >= 8) )
{
skipWidth = width - 8;
skipHeight = height - 8;
}
}
#endif
#if RExt__DECODER_DEBUG_TOOL_STATISTICS
if ( trTypeHor != DCT2 )
......@@ -890,9 +929,26 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo
int trTypeVer = DCT2;
getTrTypes ( tu, compID, trTypeHor, trTypeVer );
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
const int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0;
const int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0;
#else
int skipWidth = ( trTypeHor != DCT2 && width == 32 ) ? 16 : width > JVET_C0024_ZERO_OUT_TH ? width - JVET_C0024_ZERO_OUT_TH : 0;
int skipHeight = ( trTypeVer != DCT2 && height == 32 ) ? 16 : height > JVET_C0024_ZERO_OUT_TH ? height - JVET_C0024_ZERO_OUT_TH : 0;
if( tu.cs->sps->getUseLFNST() && tu.cu->lfnstIdx )
{
if( (width == 4 && height > 4) || (width > 4 && height == 4) )
{
skipWidth = width - 4;
skipHeight = height - 4;
}
else if( (width >= 8 && height >= 8) )
{
skipWidth = width - 8;
skipHeight = height - 8;
}
}
#endif
TCoeff *block = ( TCoeff * ) alloca( width * height * sizeof( TCoeff ) );
......
......@@ -100,6 +100,8 @@
#define JVET_O0364_PDPC_DC 1 // JVET-O0364 Part 4: align PDPC process for DC with the one for Planar
#define JVET_O0364_PDPC_ANGULAR 1 // JVET-O0364 Part 5: simplify PDPC process for angular modes
#define JVET_O0094_LFNST_ZERO_PRIM_COEFFS 1 // JVET-O0049: CE6-2.1a, LFNST involves zeroing of primary only coefficient positions
#define JVET_O0294_TRANSFORM_CLEANUP 1 // JVET-O0294: Context modelling for MTS index
#define JVET_O1124_ALLOW_CCLM_COND 1 // JVET-O1124/JVET-O0196: CCLM restriction to reduce luma-chroma latency for chroma separate tree
......
......@@ -261,6 +261,7 @@ uint32_t CU::getNumNonZeroCoeffNonTs( const CodingUnit& cu, const bool lumaFlag,
return count;
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool lumaFlag, const bool chromaFlag )
{
uint32_t count = 0;
......@@ -271,6 +272,7 @@ uint32_t CU::getNumNonZeroCoeffNonTsCorner8x8( const CodingUnit& cu, const bool
return count;
}
#endif
bool CU::divideTuInRows( const CodingUnit &cu )
{
......@@ -4552,7 +4554,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTS( const TransformUnit& tu, const bool bLuma
}
return count;
}
#if !JVET_O0094_LFNST_ZERO_PRIM_COEFFS
uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const bool lumaFlag, const bool chromaFlag )
{
const uint32_t lumaWidth = tu.blocks[ 0 ].width, chromaWidth = tu.blocks[ 1 ].width;
......@@ -4594,6 +4596,7 @@ uint32_t TU::getNumNonZeroCoeffsNonTSCorner8x8( const TransformUnit& tu, const b
}
return count;
}
#endif
bool TU::needsSqrt2Scale( const TransformUnit &tu, const ComponentID &compID )
{
......
......@@ -1365,6 +1365,10 @@ void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx&
return;
}
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false;
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
#endif
ChromaCbfs chromaCbfs;
if( cu.ispMode && isLuma( partitioner.chType ) )
......@@ -1376,8 +1380,11 @@ void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx&
{
transform_tree( *cu.cs, partitioner, cuCtx, chromaCbfs );
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
residual_lfnst_mode( cu, cuCtx );
#else
residual_lfnst_mode( cu );
#endif
}
void CABACReader::rqt_root_cbf( CodingUnit& cu )
......@@ -2353,7 +2360,11 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c
}
if( cbfLuma )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
residual_coding( tu, COMPONENT_Y, cuCtx );
#else
residual_coding( tu, COMPONENT_Y );
#endif
}
if( !lumaOnly )
{
......@@ -2365,7 +2376,11 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c
}
if( tu.cbf[ compID ] )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
residual_coding( tu, compID, cuCtx );
#else
residual_coding( tu, compID );
#endif
}
}
}
......@@ -2447,7 +2462,11 @@ void CABACReader::joint_cb_cr( TransformUnit& tu )
}
#endif
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID, CUCtx& cuCtx )
#else
void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID )
#endif
{
const CodingUnit& cu = *tu.cu;
DTRACE( g_trace_ctx, D_SYNTAX, "residual_coding() etype=%d pos=(%d,%d) size=%dx%d predMode=%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height, cu.predMode );
......@@ -2495,7 +2514,13 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID )
// parse last coeff position
cctx.setScanPosLast( last_sig_coeff( cctx, tu, compID ) );
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
{
const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15;
cuCtx.violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
}
#endif
// parse subblocks
const int stateTransTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 );
int state = 0;
......@@ -2649,7 +2674,11 @@ void CABACReader::explicit_rdpcm_mode( TransformUnit& tu, ComponentID compID )
}
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void CABACReader::residual_lfnst_mode( CodingUnit& cu, CUCtx& cuCtx )
#else
void CABACReader::residual_lfnst_mode( CodingUnit& cu )
#endif
{
if( cu.ispMode != NOT_INTRA_SUBPARTITIONS || cu.mipFlag == true ||
( CS::isDualITree( *cu.cs ) && cu.chType == CHANNEL_TYPE_CHROMA && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 ) )
......@@ -2664,7 +2693,11 @@ void CABACReader::residual_lfnst_mode( CodingUnit& cu )
const bool lumaFlag = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? true : false ) : true;
const bool chromaFlag = CS::isDualITree( *cu.cs ) ? ( isChroma( cu.chType ) ? true : false ) : true;
bool nonZeroCoeffNonTs;
bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0;
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] );
#else
bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0;
#endif
const int nonZeroCoeffThr = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA;
nonZeroCoeffNonTs = CU::getNumNonZeroCoeffNonTs( cu, lumaFlag, chromaFlag ) > nonZeroCoeffThr;
......
......@@ -129,9 +129,17 @@ public:
void cu_chroma_qp_offset ( CodingUnit& cu );
// residual coding (clause 7.3.8.11)
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void residual_coding ( TransformUnit& tu, ComponentID compID, CUCtx& cuCtx );
#else
void residual_coding ( TransformUnit& tu, ComponentID compID );
#endif
void mts_coding ( TransformUnit& tu, ComponentID compID );
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void residual_lfnst_mode ( CodingUnit& cu, CUCtx& cuCtx );
#else
void residual_lfnst_mode ( CodingUnit& cu );
#endif
void isp_mode ( CodingUnit& cu );
void explicit_rdpcm_mode ( TransformUnit& tu, ComponentID compID );
int last_sig_coeff ( CoeffCodingContext& cctx, TransformUnit& tu, ComponentID compID );
......
......@@ -1263,6 +1263,10 @@ void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, C
}
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false;
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
#endif
ChromaCbfs chromaCbfs;
if( cu.ispMode && isLuma( partitioner.chType ) )
......@@ -2237,7 +2241,11 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaC
}
if( cbfLuma )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
residual_coding( tu, COMPONENT_Y, &cuCtx );
#else
residual_coding( tu, COMPONENT_Y );
#endif
}
if( !lumaOnly )
{
......@@ -2249,7 +2257,11 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaC
}
if( cbf[ compID ] )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
residual_coding( tu, compID, &cuCtx );
#else
residual_coding( tu, compID );
#endif
}
}
}
......@@ -2332,7 +2344,11 @@ void CABACWriter::joint_cb_cr( const TransformUnit& tu )
}
#endif
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID )
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
#else
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID)
#endif
{
const CodingUnit& cu = *tu.cu;
DTRACE( g_trace_ctx, D_SYNTAX, "residual_coding() etype=%d pos=(%d,%d) size=%dx%d predMode=%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height, cu.predMode );
......@@ -2393,6 +2409,13 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID )
CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
cctx.setScanPosLast(scanPosLast);
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
if( cuCtx && tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
{
const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15;
cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
}
#endif
// code last coeff position
last_sig_coeff( cctx, tu, compID );
......@@ -2547,7 +2570,11 @@ void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
const bool lumaFlag = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? true : false ) : true;
const bool chromaFlag = CS::isDualITree( *cu.cs ) ? ( isChroma( cu.chType ) ? true : false ) : true;
bool nonZeroCoeffNonTs;
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] );
#else
bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0;
#endif
const int nonZeroCoeffThr = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA;
cuCtx.numNonZeroCoeffNonTs = CU::getNumNonZeroCoeffNonTs( cu, lumaFlag, chromaFlag );
nonZeroCoeffNonTs = cuCtx.numNonZeroCoeffNonTs > nonZeroCoeffThr;
......
......@@ -141,7 +141,11 @@ public:
void cu_chroma_qp_offset ( const CodingUnit& cu );
// residual coding (clause 7.3.8.11)
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS
void residual_coding ( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx = nullptr );
#else
void residual_coding ( const TransformUnit& tu, ComponentID compID );
#endif
void mts_coding ( const TransformUnit& tu, ComponentID compID );
void residual_lfnst_mode ( const CodingUnit& cu, CUCtx& cuCtx );
void isp_mode ( const CodingUnit& cu );
......
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