diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index a5b2793859c6a6739e78821ebb92eb871ed2a246..ea263a36c68697e97d8fd830d83910f40f74e03b 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -1206,6 +1206,9 @@ void EncApp::xInitLibCfg() #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION m_cEncLib.setUseAlfPrecision ( m_alfPrecision ); +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_cEncLib.setUseCCALFPrecision ( m_ccalfPrecision ); #endif m_cEncLib.setTestSAODisableAtPictureLevel ( m_bTestSAODisableAtPictureLevel ); m_cEncLib.setSaoEncodingRate ( m_saoEncodingRate ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index c1dd33f8a37fdfbda38d3d97b8bf4799e849d167..d55f74efba6d61908ffa848fbc627bfa5e774807 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1525,6 +1525,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION ("AlfPrecision", m_alfPrecision, true, "Luma Alf with variable precision coefficients" ) +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + ("CCALFPrecision", m_ccalfPrecision, true, "Cross-component Alf with variable precision coefficients") #endif ("TestSAODisableAtPictureLevel", m_bTestSAODisableAtPictureLevel, false, "Enables the testing of disabling SAO at the picture level after having analysed all blocks") ("SaoEncodingRate", m_saoEncodingRate, 0.75, "When >0 SAO early picture termination is enabled for luma and chroma") diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 8a5dd011f6e9ba514a2fe5c93f0baa6c94643725..5b2b551ed988340459efa8f0e43d963d729b2cde 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -713,6 +713,9 @@ protected: #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION bool m_alfPrecision; +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + bool m_ccalfPrecision; #endif bool m_bTestSAODisableAtPictureLevel; double m_saoEncodingRate; ///< When >0 SAO early picture termination is enabled for luma and chroma diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp index caf2b3059444325101fb984f20db88ca447a3c8d..bf6fb92da5570d2f8e396cc8fb6a4657237f53ae 100644 --- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp +++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp @@ -393,10 +393,11 @@ const int AdaptiveLoopFilter::m_classToFilterMapping[NUM_FIXED_FILTER_SETS][MAX_ { 16, 31, 32, 15, 60, 30, 4, 17, 19, 25, 22, 20, 4, 53, 19, 21, 22, 46, 25, 55, 26, 48, 63, 58, 55 }, }; #endif -void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, - const PelUnitBuf &recYuvExt, uint8_t *filterControl, - const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], - const int selectedFilterIdx) +#if JVET_AH0057_CCALF_COEFF_PRECISION +void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, const PelUnitBuf &recYuvExt, uint8_t *filterControl, const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx, const int coeffPrec) +#else +void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, const PelUnitBuf &recYuvExt, uint8_t *filterControl, const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx) +#endif { bool clipTop = false, clipBottom = false, clipLeft = false, clipRight = false; int numHorVirBndry = 0, numVerVirBndry = 0; @@ -496,10 +497,18 @@ void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compI const Area blkDst(xStart >> chromaScaleX, yStart >> chromaScaleY, w >> chromaScaleX, h >> chromaScaleY); #if ALF_IMPROVEMENT #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, bufResi, m_alfClippingValues[CHANNEL_TYPE_LUMA], coeffPrec ); +#else m_filterCcAlf( dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, bufResi, m_alfClippingValues[CHANNEL_TYPE_LUMA] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, coeffPrec ); #else m_filterCcAlf( dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs ); #endif +#endif #else m_filterCcAlf(dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, m_alfVBLumaPos); #endif @@ -518,10 +527,18 @@ void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compI Area blkSrc(xPos, yPos, width, height); #if ALF_IMPROVEMENT #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, tmpYuvResi, m_alfClippingValues[CHANNEL_TYPE_LUMA], coeffPrec ); +#else m_filterCcAlf( dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, tmpYuvResi, m_alfClippingValues[CHANNEL_TYPE_LUMA] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, coeffPrec ); #else m_filterCcAlf( dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs ); #endif +#endif #else m_filterCcAlf(dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, m_alfVBLumaPos); #endif @@ -1031,10 +1048,18 @@ void AdaptiveLoopFilter::ALFProcess(CodingStructure& cs) const int16_t *filterCoeff = m_ccAlfFilterParam.ccAlfCoeff[compIdx - 1][filterIdx - 1]; #if ALF_IMPROVEMENT #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( recYuv.get( compID ), buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, bufResi, m_alfClippingValues[CHANNEL_TYPE_LUMA], m_ccAlfFilterParam.ccAlfCoeffPrec[compIdx - 1] ); +#else m_filterCcAlf( recYuv.get( compID ), buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, bufResi, m_alfClippingValues[CHANNEL_TYPE_LUMA] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( recYuv.get( compID ), buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_ccAlfFilterParam.ccAlfCoeffPrec[compIdx - 1] ); #else m_filterCcAlf( recYuv.get( compID ), buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs ); #endif +#endif #else m_filterCcAlf(recYuv.get(compID), buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, m_alfVBLumaPos); #endif @@ -1303,10 +1328,18 @@ void AdaptiveLoopFilter::ALFProcess(CodingStructure& cs) #if ALF_IMPROVEMENT #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( recYuv.get( compID ), tmpYuv, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, tmpYuvResi, m_alfClippingValues[CHANNEL_TYPE_LUMA], m_ccAlfFilterParam.ccAlfCoeffPrec[compIdx - 1] ); +#else m_filterCcAlf( recYuv.get( compID ), tmpYuv, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, tmpYuvResi, m_alfClippingValues[CHANNEL_TYPE_LUMA] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_filterCcAlf( recYuv.get( compID ), tmpYuv, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_ccAlfFilterParam.ccAlfCoeffPrec[compIdx - 1] ); #else m_filterCcAlf( recYuv.get( compID ), tmpYuv, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs ); #endif +#endif #else m_filterCcAlf(recYuv.get(compID), tmpYuv, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, m_alfVBLumaPos); #endif @@ -5715,10 +5748,18 @@ void AdaptiveLoopFilter::filterBlk(AlfClassifier **classifier, const PelUnitBuf template<AlfFilterType filtTypeCcAlf> #if ALF_IMPROVEMENT #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION +void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const CPelUnitBuf &resiSrc, const Pel clippingValues[4], const int coeffPrec ) +#else void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const CPelUnitBuf &resiSrc, const Pel clippingValues[4] ) +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION +void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const int coeffPrec) #else void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs) #endif +#endif #else void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, int vbCTUHeight, int vbPos) #endif @@ -5884,7 +5925,11 @@ void AdaptiveLoopFilter::filterBlkCcAlf(const PelBuf &dstBuf, const CPelUnitBuf sum += filterCoeff[5] * (srcCross[offset1 + jj2 + 1] - currSrcCross); sum += filterCoeff[6] * (srcCross[offset3 + jj2 ] - currSrcCross); #endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + sum = (sum + ((1 << coeffPrec) >> 1)) >> coeffPrec; +#else sum = (sum + ((1 << m_scaleBits ) >> 1)) >> m_scaleBits; +#endif const int offset = 1 << clpRngs.comp[compId].bd >> 1; sum = ClipPel(sum + offset, clpRngs.comp[compId]) - offset; sum += srcSelf[jj]; diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.h b/source/Lib/CommonLib/AdaptiveLoopFilter.h index 339346fd5d08d7fb4899961804ff0f8db74ec639..c008829a46a91f96327aa5fb2854231d74cfb5c2 100644 --- a/source/Lib/CommonLib/AdaptiveLoopFilter.h +++ b/source/Lib/CommonLib/AdaptiveLoopFilter.h @@ -237,10 +237,18 @@ public: #endif template<AlfFilterType filtTypeCcAlf> #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + static void filterBlkCcAlf(const PelBuf& dstBuf, const CPelUnitBuf& recSrc, const Area& blkDst, const Area& blkSrc, const ComponentID compId, const int16_t* filterCoeff, const ClpRngs& clpRngs, CodingStructure& cs, const CPelUnitBuf& resiSrc, const Pel clippingValues[4], const int coeffPrec ); +#else static void filterBlkCcAlf(const PelBuf& dstBuf, const CPelUnitBuf& recSrc, const Area& blkDst, const Area& blkSrc, const ComponentID compId, const int16_t* filterCoeff, const ClpRngs& clpRngs, CodingStructure& cs, const CPelUnitBuf& resiSrc, const Pel clippingValues[4] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + static void filterBlkCcAlf(const PelBuf& dstBuf, const CPelUnitBuf& recSrc, const Area& blkDst, const Area& blkSrc, const ComponentID compId, const int16_t* filterCoeff, const ClpRngs& clpRngs, CodingStructure& cs, const int coeffPrec); #else static void filterBlkCcAlf(const PelBuf& dstBuf, const CPelUnitBuf& recSrc, const Area& blkDst, const Area& blkSrc, const ComponentID compId, const int16_t* filterCoeff, const ClpRngs& clpRngs, CodingStructure& cs); #endif +#endif #else static void deriveClassificationBlk(AlfClassifier **classifier, int **laplacian[NUM_DIRECTIONS], const CPelBuf &srcLuma, const Area &blkDst, const Area &blk, const int shift, const int vbCTUHeight, int vbPos); template<AlfFilterType filtTypeCcAlf> @@ -304,9 +312,17 @@ public: #endif #endif #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF +#if JVET_AH0057_CCALF_COEFF_PRECISION + void(*m_filterCcAlf)(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const CPelUnitBuf &resiSrc, const Pel clippingValues[4], const int coeffPrec ); +#else void(*m_filterCcAlf)(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const CPelUnitBuf &resiSrc, const Pel clippingValues[4] ); +#endif +#else +#if JVET_AH0057_CCALF_COEFF_PRECISION + void(*m_filterCcAlf)(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs, const int coeffPrec); #else void(*m_filterCcAlf)(const PelBuf &dstBuf, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blkSrc, const ComponentID compId, const int16_t *filterCoeff, const ClpRngs &clpRngs, CodingStructure &cs); +#endif #endif template<AlfFilterType filtType> static void filterBlk(AlfClassifier **classifier, const PelUnitBuf &recDst, @@ -663,7 +679,11 @@ public: void (*m_filter7x7Blk)(AlfClassifier **classifier, const PelUnitBuf &recDst, const CPelUnitBuf &recSrc, const Area &blkDst, const Area &blk, const ComponentID compId, const short *filterSet, const short *fClipSet, const ClpRng &clpRng, CodingStructure &cs, const int vbCTUHeight, int vbPos); #endif #endif - void applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, const PelUnitBuf &recYuvExt, uint8_t * filterControl, const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx); +#if JVET_AH0057_CCALF_COEFF_PRECISION + void applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, const PelUnitBuf &recYuvExt, uint8_t *filterControl, const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx, const int coeffPrec); +#else + void applyCcAlfFilter(CodingStructure &cs, ComponentID compID, const PelBuf &dstBuf, const PelUnitBuf &recYuvExt, uint8_t *filterControl, const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx); +#endif CcAlfFilterParam &getCcAlfFilterParam() { return m_ccAlfFilterParam; } uint8_t* getCcAlfControlIdc(const ComponentID compID) { return m_ccAlfFilterControl[compID-1]; } @@ -675,7 +695,9 @@ public: protected: bool isCrossedByVirtualBoundaries( const CodingStructure& cs, const int xPos, const int yPos, const int width, const int height, bool& clipTop, bool& clipBottom, bool& clipLeft, bool& clipRight, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], int& rasterSliceAlfPad ); +#if !JVET_AH0057_CCALF_COEFF_PRECISION static constexpr int m_scaleBits = 7; // 8-bits +#endif CcAlfFilterParam m_ccAlfFilterParam; uint8_t* m_ccAlfFilterControl[2]; #if !ALF_IMPROVEMENT diff --git a/source/Lib/CommonLib/AlfParameters.h b/source/Lib/CommonLib/AlfParameters.h index 89dc29a99c4ef12649ccbdbf8ab9630bd821da1d..915ed53d0e0e9bdccd89910bc1285daa52538fd1 100644 --- a/source/Lib/CommonLib/AlfParameters.h +++ b/source/Lib/CommonLib/AlfParameters.h @@ -727,6 +727,9 @@ struct CcAlfFilterParam bool ccAlfFilterEnabled[2]; bool ccAlfFilterIdxEnabled[2][MAX_NUM_CC_ALF_FILTERS]; uint8_t ccAlfFilterCount[2]; +#if JVET_AH0057_CCALF_COEFF_PRECISION + int ccAlfCoeffPrec[2]; +#endif short ccAlfCoeff[2][MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF]; int newCcAlfFilter[2]; int numberValidComponents; @@ -739,6 +742,9 @@ struct CcAlfFilterParam std::memset( ccAlfFilterEnabled, false, sizeof( ccAlfFilterEnabled ) ); std::memset( ccAlfFilterIdxEnabled, false, sizeof( ccAlfFilterIdxEnabled ) ); std::memset( ccAlfCoeff, 0, sizeof( ccAlfCoeff ) ); +#if JVET_AH0057_CCALF_COEFF_PRECISION + ccAlfCoeffPrec[0] = ccAlfCoeffPrec[1] = 0; +#endif ccAlfFilterCount[0] = ccAlfFilterCount[1] = MAX_NUM_CC_ALF_FILTERS; numberValidComponents = 3; newCcAlfFilter[0] = newCcAlfFilter[1] = 0; @@ -753,6 +759,10 @@ struct CcAlfFilterParam numberValidComponents = src.numberValidComponents; newCcAlfFilter[0] = src.newCcAlfFilter[0]; newCcAlfFilter[1] = src.newCcAlfFilter[1]; +#if JVET_AH0057_CCALF_COEFF_PRECISION + ccAlfCoeffPrec[0] = src.ccAlfCoeffPrec[0]; + ccAlfCoeffPrec[1] = src.ccAlfCoeffPrec[1]; +#endif return *this; } }; diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index f648cfcf7c79e0dfa62b5b179aeafa8d9bb55378..03f4a55ab0b4cf650bc2ef122b3a127d76fb7119 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -434,6 +434,10 @@ static const int MAX_NUM_ALF_CHROMA_COEFF = 21 + 5; #else static const int MAX_NUM_ALF_CHROMA_COEFF = 21; #endif +#if JVET_AH0057_CCALF_COEFF_PRECISION +static const int MAX_NUM_CCALF_PREC = 4; +static const int MIN_CCALF_PREC = 7; +#endif #else static const int MAX_NUM_ALF_LUMA_COEFF = 13; static const int MAX_NUM_ALF_CHROMA_COEFF = 7; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 73b38bf22ce4b87b89b16daaaa1a016c2c0dafa4..5fcc7203fc153bb88ca8cc4bb071afddd0aae0df 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1719,6 +1719,9 @@ private: #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION bool m_alfPrecisionFlag; +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + bool m_ccalfPrecisionFlag; #endif bool m_bTemporalIdNestingFlag; // temporal_id_nesting_flag @@ -2172,6 +2175,10 @@ public: #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION bool getAlfPrecisionFlag() const { return m_alfPrecisionFlag; } void setAlfPrecisionFlag( bool b ) { m_alfPrecisionFlag = b; } +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + bool getCCALFPrecisionFlag() const { return m_ccalfPrecisionFlag; } + void setCCALFPrecisionFlag( bool b ) { m_ccalfPrecisionFlag = b; } #endif bool getALFEnabledFlag() const { return m_alfEnabledFlag; } void setALFEnabledFlag( bool b ) { m_alfEnabledFlag = b; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 72561986a327096f54127dc6c7f34461ab7cccd9..c4541c3d796e5db61f41031acf360042ec2a0a0a 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -436,6 +436,7 @@ #define JVET_AG0157_ALF_CHROMA_FIXED_FILTER 1 // JVET-AG0157: Fixed filter for chroma ALF #define JVET_AG0158_ALF_LUMA_COEFF_PRECISION 1 // JVET-AG0158: adaptive precision for luma ALF coefficients #define JVET_AG0145_ADAPTIVE_CLIPPING 1 // JVET-AG0145: Adaptive clipping with signalled lower and upper bounds +#define JVET_AH0057_CCALF_COEFF_PRECISION 1 // JVET-AH0057: adaptive precision for CCALF coefficients // SIMD optimizations #if IF_12TAP diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index d77bb14fc74d90ec7ceec65c611a5f677c6f64aa..f08ef6a7639fe7599536597ad3eedbc7660ad411 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1714,7 +1714,9 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param CHECK( aps->getTemporalId() > pSlice->getTLayer(), "TemporalId shall be less than or equal to the TemporalId of the coded slice NAL unit" ); //ToDO: APS NAL unit containing the APS RBSP shall have nuh_layer_id either equal to the nuh_layer_id of a coded slice NAL unit that referrs it, or equal to the nuh_layer_id of a direct dependent layer of the layer containing a coded slice NAL unit that referrs it. - +#if JVET_AH0057_CCALF_COEFF_PRECISION + filterParam.ccAlfCoeffPrec[COMPONENT_Cb - 1] = aps->getCcAlfAPSParam().ccAlfCoeffPrec[COMPONENT_Cb - 1]; +#endif filterParam.ccAlfFilterCount[COMPONENT_Cb - 1] = aps->getCcAlfAPSParam().ccAlfFilterCount[COMPONENT_Cb - 1]; for (int filterIdx=0; filterIdx < filterParam.ccAlfFilterCount[COMPONENT_Cb - 1]; filterIdx++ ) { @@ -1742,7 +1744,9 @@ void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& param CHECK( aps->getTemporalId() > pSlice->getTLayer(), "TemporalId shall be less than or equal to the TemporalId of the coded slice NAL unit" ); //ToDO: APS NAL unit containing the APS RBSP shall have nuh_layer_id either equal to the nuh_layer_id of a coded slice NAL unit that referrs it, or equal to the nuh_layer_id of a direct dependent layer of the layer containing a coded slice NAL unit that referrs it. - +#if JVET_AH0057_CCALF_COEFF_PRECISION + filterParam.ccAlfCoeffPrec[COMPONENT_Cr - 1] = aps->getCcAlfAPSParam().ccAlfCoeffPrec[COMPONENT_Cr - 1]; +#endif filterParam.ccAlfFilterCount[COMPONENT_Cr - 1] = aps->getCcAlfAPSParam().ccAlfFilterCount[COMPONENT_Cr - 1]; for (int filterIdx=0; filterIdx < filterParam.ccAlfFilterCount[COMPONENT_Cr - 1]; filterIdx++ ) { diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 208049f3b4566df4d214c5d0c8c71b1852e82ad0..db2922cde01247c85f2add41f654c107327867a5 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1242,6 +1242,11 @@ void HLSyntaxReader::parseAlfAps( APS* aps ) { if (ccAlfParam.newCcAlfFilter[ccIdx]) { +#if JVET_AH0057_CCALF_COEFF_PRECISION + READ_CODE(2, code, + ccIdx == 0 ? "alf_cc_cb_frame_precision_idx" : "alf_cc_cr_frame_precision_idx"); + ccAlfParam.ccAlfCoeffPrec[ccIdx] = code + MIN_CCALF_PREC; +#endif if (MAX_NUM_CC_ALF_FILTERS > 1) { READ_UVLC(code, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1"); @@ -2145,7 +2150,16 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) { pcSPS->setCCALFEnabledFlag(false); } - +#if JVET_AH0057_CCALF_COEFF_PRECISION + if (pcSPS->getCCALFEnabledFlag()) + { + READ_FLAG(uiCode, "sps_ccalf_precision_flag"); pcSPS->setCCALFPrecisionFlag(uiCode ? true : false); + } + else + { + pcSPS->setCCALFPrecisionFlag(false); + } +#endif #if SIGN_PREDICTION READ_CODE(4, uiCode, "num_predicted_coef_signs"); pcSPS->setNumPredSigns(uiCode); diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp index 7e9000650b66cf7a8feb270b33fdc91ab90cdd7c..81f0b2674c968c554943e282134a44b2481bd28b 100644 --- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp +++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp @@ -1219,6 +1219,9 @@ void EncAdaptiveLoopFilter::xSetupCcAlfAPS( CodingStructure &cs ) aps->setTemporalId(cs.slice->getTLayer()); } aps->getCcAlfAPSParam().ccAlfFilterEnabled[COMPONENT_Cb - 1] = 1; +#if JVET_AH0057_CCALF_COEFF_PRECISION + aps->getCcAlfAPSParam().ccAlfCoeffPrec[COMPONENT_Cb - 1] = m_ccAlfFilterParam.ccAlfCoeffPrec[COMPONENT_Cb - 1]; +#endif aps->getCcAlfAPSParam().ccAlfFilterCount[COMPONENT_Cb - 1] = m_ccAlfFilterParam.ccAlfFilterCount[COMPONENT_Cb - 1]; for ( int filterIdx = 0; filterIdx < MAX_NUM_CC_ALF_FILTERS; filterIdx++ ) { @@ -1251,6 +1254,9 @@ void EncAdaptiveLoopFilter::xSetupCcAlfAPS( CodingStructure &cs ) aps->setTemporalId(cs.slice->getTLayer()); } aps->getCcAlfAPSParam().ccAlfFilterEnabled[COMPONENT_Cr - 1] = 1; +#if JVET_AH0057_CCALF_COEFF_PRECISION + aps->getCcAlfAPSParam().ccAlfCoeffPrec[COMPONENT_Cr - 1] = m_ccAlfFilterParam.ccAlfCoeffPrec[COMPONENT_Cr - 1]; +#endif aps->getCcAlfAPSParam().ccAlfFilterCount[COMPONENT_Cr - 1] = m_ccAlfFilterParam.ccAlfFilterCount[COMPONENT_Cr - 1]; for ( int filterIdx = 0; filterIdx < MAX_NUM_CC_ALF_FILTERS; filterIdx++ ) { @@ -1772,7 +1778,11 @@ void EncAdaptiveLoopFilter::ALFProcess( CodingStructure& cs, const double *lambd ComponentID compID = ComponentID(compIdx); if (m_ccAlfFilterParam.ccAlfFilterEnabled[compIdx - 1]) { +#if JVET_AH0057_CCALF_COEFF_PRECISION + applyCcAlfFilter(cs, compID, cs.getRecoBuf().get(compID), recYuv, m_ccAlfFilterControl[compIdx - 1], m_ccAlfFilterParam.ccAlfCoeff[compIdx - 1], -1, m_ccAlfFilterParam.ccAlfCoeffPrec[compIdx - 1]); +#else applyCcAlfFilter(cs, compID, cs.getRecoBuf().get(compID), recYuv, m_ccAlfFilterControl[compIdx - 1], m_ccAlfFilterParam.ccAlfCoeff[compIdx - 1], -1); +#endif } } } @@ -7397,7 +7407,11 @@ int EncAdaptiveLoopFilter::getCoeffRateCcAlf(short chromaCoeff[MAX_NUM_CC_ALF_FI return bits; } +#if JVET_AH0057_CCALF_COEFF_PRECISION +void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const PelUnitBuf& recYuv, const PelUnitBuf& recYuvExt, short filterCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const uint8_t filterIdx, int coeffPrec ) +#else void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const PelUnitBuf& recYuv, const PelUnitBuf& recYuvExt, short filterCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const uint8_t filterIdx ) +#endif { int forward_tab[CCALF_CANDS_COEFF_NR * 2 - 1] = {0}; for (int i = 0; i < CCALF_CANDS_COEFF_NR; i++) @@ -7447,7 +7461,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const Pe } m_alfCovarianceFrameCcAlf[0].gnsSolveByChol(kE, ky, filterCoeffDbl, size); +#if JVET_AH0057_CCALF_COEFF_PRECISION + roundFiltCoeffCCALF(filterCoeffInt, filterCoeffDbl, size, (1 << coeffPrec)); +#else roundFiltCoeffCCALF(filterCoeffInt, filterCoeffDbl, size, (1 << m_scaleBits)); +#endif for (int k = 0; k < size; k++) { @@ -7457,7 +7475,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const Pe // Refine quanitzation int modified = 1; +#if JVET_AH0057_CCALF_COEFF_PRECISION + double errRef = m_alfCovarianceFrameCcAlf[0].calcErrorForCcAlfCoeffs(filterCoeffInt, size, (coeffPrec + 1)); +#else double errRef = m_alfCovarianceFrameCcAlf[0].calcErrorForCcAlfCoeffs(filterCoeffInt, size, (m_scaleBits+1)); +#endif while (modified) { @@ -7484,7 +7506,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilterCoeff( ComponentID compID, const Pe continue; filterCoeffInt[k] = forward_tab[org_idx - delta]; +#if JVET_AH0057_CCALF_COEFF_PRECISION + double error = m_alfCovarianceFrameCcAlf[0].calcErrorForCcAlfCoeffs(filterCoeffInt, size, (coeffPrec + 1)); +#else double error = m_alfCovarianceFrameCcAlf[0].calcErrorForCcAlfCoeffs(filterCoeffInt, size, (m_scaleBits+1)); +#endif if( error < errMin ) { errMin = error; @@ -7806,6 +7832,10 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID double bestUnfilteredTotalCost = 1 * m_lambda[compID] + unfilteredDistortion; // 1 bit is for gating flag bool ccAlfFilterIdxEnabled[MAX_NUM_CC_ALF_FILTERS]; +#if JVET_AH0057_CCALF_COEFF_PRECISION + int ccAlfCoeffPrec = MIN_CCALF_PREC; + int bestCoeffPrec = MIN_CCALF_PREC; +#endif short ccAlfFilterCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF]; uint8_t ccAlfFilterCount = MAX_NUM_CC_ALF_FILTERS; double bestFilteredTotalCost = MAX_DOUBLE; @@ -7842,6 +7872,9 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID } // initialize filters +#if JVET_AH0057_CCALF_COEFF_PRECISION + ccAlfCoeffPrec = MIN_CCALF_PREC; +#endif for ( int filterIdx = 0; filterIdx < MAX_NUM_CC_ALF_FILTERS; filterIdx++ ) { ccAlfFilterIdxEnabled[filterIdx] = false; @@ -7857,6 +7890,9 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID memcpy(ccAlfFilterCoeff[filterIdx], m_ccAlfFilterParam.ccAlfCoeff[compID - 1][filterIdx],sizeof(ccAlfFilterCoeff[filterIdx])); } memcpy( ccAlfFilterCoeff, m_apsMap->getPS((apsIds[testFilterIdx] << NUM_APS_TYPE_LEN) + ALF_APS)->getCcAlfAPSParam().ccAlfCoeff[compID - 1], sizeof(ccAlfFilterCoeff) ); +#if JVET_AH0057_CCALF_COEFF_PRECISION + ccAlfCoeffPrec = m_apsMap->getPS((apsIds[testFilterIdx] << NUM_APS_TYPE_LEN) + ALF_APS)->getCcAlfAPSParam().ccAlfCoeffPrec[compID - 1]; +#endif } else { @@ -7879,11 +7915,19 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID } } +#if JVET_AH0057_CCALF_COEFF_PRECISION + const int coeffPrecNum = ( m_encCfg->getUseCCALFPrecision() && ( !referencingExistingAps ) ) ? MAX_NUM_CCALF_PREC : 1; + for (int coeffPrecTest = MIN_CCALF_PREC; coeffPrecTest < coeffPrecNum + MIN_CCALF_PREC; coeffPrecTest++) + { +#endif // compute cost of filtering int trainingIterCount = 0; bool keepTraining = true; bool improvement = false; double prevTotalCost = MAX_DOUBLE; +#if JVET_AH0057_CCALF_COEFF_PRECISION + int coeffPrec = referencingExistingAps ? ccAlfCoeffPrec : coeffPrecTest; +#endif while (keepTraining) { improvement = false; @@ -7894,7 +7938,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID if (!referencingExistingAps) { getFrameStatsCcalf(compID, (filterIdx + 1)); +#if JVET_AH0057_CCALF_COEFF_PRECISION + deriveCcAlfFilterCoeff(compID, dstYuv, tempDecYuvBuf, ccAlfFilterCoeff, filterIdx, coeffPrec); +#else deriveCcAlfFilterCoeff(compID, dstYuv, tempDecYuvBuf, ccAlfFilterCoeff, filterIdx); +#endif } const int numCoeff = m_filterShapesCcAlf[0].numCoeff - 1; int log2BlockWidth = cs.pcv->maxCUWidthLog2 - scaleX; @@ -7904,7 +7952,11 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID for (int x = 0; x < m_buf->width; x += (1 << log2BlockWidth)) { int ctuIdx = (y >> log2BlockHeight) * m_numCTUsInWidth + (x >> log2BlockWidth); +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_trainingDistortion[filterIdx][ctuIdx] = int(m_ctbDistortionUnfilter[compID][ctuIdx] + m_alfCovarianceCcAlf[0][ctuIdx].calcErrorForCcAlfCoeffs(ccAlfFilterCoeff[filterIdx], numCoeff, coeffPrec + 1)); +#else m_trainingDistortion[filterIdx][ctuIdx] = int(m_ctbDistortionUnfilter[compID][ctuIdx] + m_alfCovarianceCcAlf[0][ctuIdx].calcErrorForCcAlfCoeffs(ccAlfFilterCoeff[filterIdx], numCoeff, m_scaleBits + 1)); +#endif } } } @@ -7931,10 +7983,15 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID } else { +#if JVET_AH0057_CCALF_COEFF_PRECISION + curTotalRate += getCoeffRateCcAlf(ccAlfFilterCoeff, ccAlfFilterIdxEnabled, ccAlfFilterCount, compID) + 1 + + 9 + 2; +#else curTotalRate += getCoeffRateCcAlf(ccAlfFilterCoeff, ccAlfFilterIdxEnabled, ccAlfFilterCount, compID) + 1 + 9; // +1 for the enable flag, +9 3-bit for APS ID in slice header, 5-bit for APS ID in APS, a 1-bit // new filter flags (ignore shared cost such as other new-filter flags/NALU header/RBSP // terminating bit/byte alignment bits) +#endif } #if JVET_AF0197_LUMA_RESIDUAL_TAP_IN_CCALF double curTotalCost = curTotalRate * m_lambda[compID] * chromaFactor + curTotalDistortion; @@ -7950,6 +8007,9 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID if (curTotalCost < bestFilteredTotalCost) { bestFilteredTotalCost = curTotalCost; +#if JVET_AH0057_CCALF_COEFF_PRECISION + bestCoeffPrec = coeffPrec; +#endif memcpy(m_bestFilterIdxEnabled, ccAlfFilterIdxEnabled, sizeof(ccAlfFilterIdxEnabled)); memcpy(m_bestFilterCoeffSet, ccAlfFilterCoeff, sizeof(ccAlfFilterCoeff)); memcpy(m_bestFilterControl, m_filterControl, sizeof(uint8_t) * m_numCTUsInPic); @@ -7965,6 +8025,9 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID keepTraining = false; } } +#if JVET_AH0057_CCALF_COEFF_PRECISION + } +#endif } } @@ -8019,6 +8082,9 @@ void EncAdaptiveLoopFilter::deriveCcAlfFilter( CodingStructure& cs, ComponentID } m_ccAlfFilterParam.ccAlfFilterCount[compID - 1] = m_bestFilterCount; +#if JVET_AH0057_CCALF_COEFF_PRECISION + m_ccAlfFilterParam.ccAlfCoeffPrec[compID - 1] = bestCoeffPrec; +#endif // cleanup before copying memset(m_ccAlfFilterControl[compID - 1], 0, sizeof(uint8_t) * m_numCTUsInPic); for ( int filterIdx = 0; filterIdx < MAX_NUM_CC_ALF_FILTERS; filterIdx++ ) diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h index 4415240ee7162cbc54348f51cc837d1700969be1..a4f2270aaa4236d5c0f80037bc46ee58a2dad6d1 100644 --- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h +++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h @@ -699,7 +699,11 @@ private: void copyCtuAlternativeChroma( uint8_t* ctuAltsDst[MAX_NUM_COMPONENT], uint8_t* ctuAltsSrc[MAX_NUM_COMPONENT] ); int getMaxNumAlternativesChroma( ); int getCoeffRateCcAlf(short chromaCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], bool filterEnabled[MAX_NUM_CC_ALF_FILTERS], uint8_t filterCount, ComponentID compID); +#if JVET_AH0057_CCALF_COEFF_PRECISION + void deriveCcAlfFilterCoeff( ComponentID compID, const PelUnitBuf& recYuv, const PelUnitBuf& recYuvExt, short filterCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const uint8_t filterIdx, int coeffPrec ); +#else void deriveCcAlfFilterCoeff( ComponentID compID, const PelUnitBuf& recYuv, const PelUnitBuf& recYuvExt, short filterCoeff[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const uint8_t filterIdx ); +#endif void determineControlIdcValues(CodingStructure &cs, const ComponentID compID, const PelBuf *buf, const int ctuWidthC, const int ctuHeightC, const int picWidthC, const int picHeightC, double **unfilteredDistortion, uint64_t *trainingDistortion[MAX_NUM_CC_ALF_FILTERS], diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 2f0ffbe9d31b0552f63284ba51328a6a811885e2..17eafd18adb86fc9d773709221b8bcbdecd6bbf1 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -674,6 +674,9 @@ protected: #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION bool m_alfPrecision; +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + bool m_ccalfPrecision; #endif bool m_bTestSAODisableAtPictureLevel; double m_saoEncodingRate; // When non-0 SAO early picture termination is enabled for luma and chroma @@ -2279,6 +2282,10 @@ public: #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION void setUseAlfPrecision( bool b ) { m_alfPrecision = b; } bool getUseAlfPrecision() const { return m_alfPrecision; } +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + void setUseCCALFPrecision(bool b) { m_ccalfPrecision = b; } + bool getUseCCALFPrecision() const { return m_ccalfPrecision; } #endif void setTestSAODisableAtPictureLevel (bool bVal) { m_bTestSAODisableAtPictureLevel = bVal; } bool getTestSAODisableAtPictureLevel ( ) const { return m_bTestSAODisableAtPictureLevel; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 6b3710387e36930393b0921dc65befc8e9fa322f..fe0594c14f5ac281cc451c13462f4e4d79a1f1b8 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -2140,6 +2140,9 @@ void EncLib::xInitSPS( SPS& sps ) #endif #if JVET_AG0158_ALF_LUMA_COEFF_PRECISION sps.setAlfPrecisionFlag( m_alfPrecision ); +#endif +#if JVET_AH0057_CCALF_COEFF_PRECISION + sps.setCCALFPrecisionFlag( m_ccalfPrecision ); #endif sps.setJointCbCrEnabledFlag( m_JointCbCrMode ); sps.setMaxTLayers( m_maxTempLayer ); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index c907da30b76e4b5f2b80548af275a0e4aaba5503..16f386e9256b350281f51a5b3f3cf25cdaa94da6 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -776,6 +776,10 @@ void HLSWriter::codeAlfAps( APS* pcAPS ) { if (paramCcAlf.newCcAlfFilter[ccIdx]) { +#if JVET_AH0057_CCALF_COEFF_PRECISION + WRITE_CODE(paramCcAlf.ccAlfCoeffPrec[ccIdx] - MIN_CCALF_PREC, 2, + ccIdx == 0 ? "alf_cc_cb_frame_precision_idx" : "alf_cc_cr_frame_precision_idx"); +#endif const int filterCount = paramCcAlf.ccAlfFilterCount[ccIdx]; CHECK(filterCount > MAX_NUM_CC_ALF_FILTERS, "CC ALF Filter count is too large"); CHECK(filterCount == 0, "CC ALF Filter count is too small"); @@ -1312,7 +1316,12 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { WRITE_FLAG( pcSPS->getCCALFEnabledFlag(), "sps_ccalf_enabled_flag" ); } - +#if JVET_AH0057_CCALF_COEFF_PRECISION + if (pcSPS->getCCALFEnabledFlag()) + { + WRITE_FLAG(pcSPS->getCCALFPrecisionFlag(), "sps_ccalf_precision_flag" ); + } +#endif #if SIGN_PREDICTION WRITE_CODE(pcSPS->getNumPredSigns(), 4, "num_predicted_coef_signs"); #if JVET_Y0141_SIGN_PRED_IMPROVE