Commit 5b3b09c3 authored by Xiang Li's avatar Xiang Li
Browse files

Merge branch 'siekmann/VVCSoftware_VTM-JVET-O0094'

parents 33d5b5f4 b406e015
Loading
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -293,10 +293,26 @@ 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;
@@ -304,6 +320,9 @@ public:
  bool      qgStart;
  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
+59 −2
Original line number Diff line number Diff line
@@ -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,6 +1641,7 @@ 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)
@@ -1603,6 +1651,15 @@ namespace DQIntern
      }
      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 =====
+60 −4
Original line number Diff line number Diff line
@@ -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 ) );

+2 −0
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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 )
{
Loading