From f185ffee28b158f84ab686c628d8259b1d114180 Mon Sep 17 00:00:00 2001 From: Philippe Hanhart <Philippe.Hanhart@InterDigital.com> Date: Thu, 24 Jan 2019 15:52:36 -0800 Subject: [PATCH] JVET-M0142: Adding support for chroma sample location type 2 in CCLM --- source/App/EncoderApp/EncApp.cpp | 3 + source/App/EncoderApp/EncAppCfg.cpp | 11 +++ source/App/EncoderApp/EncAppCfg.h | 3 + source/Lib/CommonLib/IntraPrediction.cpp | 87 +++++++++++++++++++++--- source/Lib/CommonLib/Slice.cpp | 3 + source/Lib/CommonLib/Slice.h | 7 ++ source/Lib/CommonLib/TypeDef.h | 2 + source/Lib/DecoderLib/VLCReader.cpp | 6 ++ source/Lib/EncoderLib/EncCfg.h | 7 ++ source/Lib/EncoderLib/EncLib.cpp | 3 + source/Lib/EncoderLib/VLCWriter.cpp | 6 ++ 11 files changed, 130 insertions(+), 8 deletions(-) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 42a467a34..4158dbfec 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -224,6 +224,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setDisableMotionCompression ( m_DisableMotionCompression ); m_cEncLib.setMTTMode ( m_MTT ); m_cEncLib.setUseLMChroma ( m_LMChroma ); +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + m_cEncLib.setCclmCollocatedChromaFlag ( m_cclmCollocatedChromaFlag ); +#endif #if ENABLE_WPP_PARALLELISM m_cEncLib.setUseAltDQPCoding ( m_AltDQPCoding ); #endif diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 77d82dd18..238a4deda 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -828,6 +828,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("LMChroma", m_LMChroma, 1, " LMChroma prediction " "\t0: Disable LMChroma\n" "\t1: Enable LMChroma\n") +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + ("CclmCollocatedChroma", m_cclmCollocatedChromaFlag, false, "Specifies the location of the top-left downsampled luma sample in cross-component linear model intra prediction relative to the top-left luma sample\n" + "\t0: horizontally co-sited, vertically shifted by 0.5 units of luma samples\n" + "\t1: collocated\n") +#endif #if JVET_M0464_UNI_MTS ("MTS", m_MTS, 0, "Multiple Transform Set (MTS)\n" "\t0: Disable MTS\n" @@ -3124,6 +3129,12 @@ void EncAppCfg::xPrintParameter() msg( VERBOSE, "AltDQPCoding:%d ", m_AltDQPCoding ); #endif msg( VERBOSE, "LMChroma:%d ", m_LMChroma ); +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + if( m_LMChroma && m_chromaFormatIDC == CHROMA_420 ) + { + msg( VERBOSE, "CclmCollocatedChroma:%d ", m_cclmCollocatedChromaFlag ); + } +#endif #if JVET_M0464_UNI_MTS msg( VERBOSE, "MTS: %1d(intra) %1d(inter) ", m_MTS & 1, ( m_MTS >> 1 ) & 1 ); #else diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 3e56906da..60ee7d6a6 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -214,6 +214,9 @@ protected: bool m_AltDQPCoding; #endif int m_LMChroma; +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + bool m_cclmCollocatedChromaFlag; +#endif #if JVET_M0464_UNI_MTS int m_MTS; ///< XZ: Multiple Transform Set int m_MTSIntraMaxCand; ///< XZ: Number of additional candidates to test diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 3745b4bcc..9f033184e 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -1563,6 +1563,24 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom pDst[i] = ( piSrc[2 * i] * 2 + piSrc[2 * i - 1] + piSrc[2 * i + 1] + 2 ) >> 2; } } +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + else if( pu.cs->sps->getSpsNext().getCclmCollocatedChromaFlag() ) + { + piSrc = pRecSrc0 - iRecStride2; + + if( i == 0 && !bLeftAvaillable ) + { + pDst[i] = ( piSrc[2 * i] * 2 + piSrc[2 * i - iRecStride] + piSrc[2 * i + iRecStride] + 2 ) >> 2; + } + else + { + pDst[i] = ( piSrc[2 * i - iRecStride] + + piSrc[2 * i ] * 4 + piSrc[2 * i - 1] + piSrc[2 * i + 1] + + piSrc[2 * i + iRecStride] + + 4 ) >> 3; + } + } +#endif else { piSrc = pRecSrc0 - iRecStride2; @@ -1592,9 +1610,30 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom } for (int j = 0; j < uiCHeight + addedLeftBelow; j++) { - pDst[0] = ( ( piSrc[1 ] * 2 + piSrc[0 ] + piSrc[2 ] ) - + ( piSrc[1 + iRecStride] * 2 + piSrc[iRecStride] + piSrc[2 + iRecStride] ) - + 4 ) >> 3; +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + if( pu.cs->sps->getSpsNext().getCclmCollocatedChromaFlag() ) + { + if( j == 0 && !bAboveAvaillable ) + { + pDst[0] = ( piSrc[1] * 2 + piSrc[0] + piSrc[2] + 2 ) >> 2; + } + else + { + pDst[0] = ( piSrc[1 - iRecStride] + + piSrc[1 ] * 4 + piSrc[0] + piSrc[2] + + piSrc[1 + iRecStride] + + 4 ) >> 3; + } + } + else + { +#endif + pDst[0] = ( ( piSrc[1 ] * 2 + piSrc[0 ] + piSrc[2 ] ) + + ( piSrc[1 + iRecStride] * 2 + piSrc[iRecStride] + piSrc[2 + iRecStride] ) + + 4 ) >> 3; +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + } +#endif piSrc += iRecStride2; pDst += iDstStride; @@ -1607,16 +1646,48 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom { for( int i = 0; i < uiCWidth; i++ ) { - if( i == 0 && !bLeftAvaillable ) +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + if( pu.cs->sps->getSpsNext().getCclmCollocatedChromaFlag() ) { - pDst0[i] = ( pRecSrc0[2 * i] + pRecSrc0[2 * i + iRecStride] + 1 ) >> 1; + if( i == 0 && !bLeftAvaillable ) + { + if( j == 0 && !bAboveAvaillable ) + { + pDst0[i] = pRecSrc0[2 * i]; + } + else + { + pDst0[i] = ( pRecSrc0[2 * i] * 2 + pRecSrc0[2 * i - iRecStride] + pRecSrc0[2 * i + iRecStride] + 2 ) >> 2; + } + } + else if( j == 0 && !bAboveAvaillable ) + { + pDst0[i] = ( pRecSrc0[2 * i] * 2 + pRecSrc0[2 * i - 1] + pRecSrc0[2 * i + 1] + 2 ) >> 2; + } + else + { + pDst0[i] = ( pRecSrc0[2 * i - iRecStride] + + pRecSrc0[2 * i ] * 4 + pRecSrc0[2 * i - 1] + pRecSrc0[2 * i + 1] + + pRecSrc0[2 * i + iRecStride] + + 4 ) >> 3; + } } else { - pDst0[i] = ( pRecSrc0[2 * i ] * 2 + pRecSrc0[2 * i + 1 ] + pRecSrc0[2 * i - 1 ] - + pRecSrc0[2 * i + iRecStride] * 2 + pRecSrc0[2 * i + 1 + iRecStride] + pRecSrc0[2 * i - 1 + iRecStride] - + 4 ) >> 3; +#endif + if( i == 0 && !bLeftAvaillable ) + { + pDst0[i] = ( pRecSrc0[2 * i] + pRecSrc0[2 * i + iRecStride] + 1 ) >> 1; + } + else + { + pDst0[i] = ( pRecSrc0[2 * i ] * 2 + pRecSrc0[2 * i + 1 ] + pRecSrc0[2 * i - 1 ] + + pRecSrc0[2 * i + iRecStride] * 2 + pRecSrc0[2 * i + 1 + iRecStride] + pRecSrc0[2 * i - 1 + iRecStride] + + 4 ) >> 3; + } +#if JVET_M0142_CCLM_COLLOCATED_CHROMA } +#endif } pDst0 += iDstStride; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 5fb5831f2..4c91e38f9 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1738,6 +1738,9 @@ SPSNext::SPSNext( SPS& sps ) , m_BIO ( false ) , m_DisableMotionCompression ( false ) , m_LMChroma ( false ) +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + , m_cclmCollocatedChromaFlag ( false ) +#endif #if JVET_M0464_UNI_MTS , m_IntraMTS ( false ) , m_InterMTS ( false ) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 6b71c04aa..970579a33 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -804,6 +804,9 @@ private: bool m_BIO; bool m_DisableMotionCompression; // 13 bool m_LMChroma; // 17 +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + bool m_cclmCollocatedChromaFlag; +#endif #if JVET_M0464_UNI_MTS bool m_IntraMTS; // 18 bool m_InterMTS; // 19 @@ -877,6 +880,10 @@ public: #endif void setUseLMChroma ( bool b ) { m_LMChroma = b; } bool getUseLMChroma () const { return m_LMChroma; } +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + void setCclmCollocatedChromaFlag( bool b ) { m_cclmCollocatedChromaFlag = b; } + bool getCclmCollocatedChromaFlag() const { return m_cclmCollocatedChromaFlag; } +#endif #if JVET_M0464_UNI_MTS void setUseIntraMTS ( bool b ) { m_IntraMTS = b; } bool getUseIntraMTS () const { return m_IntraMTS; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index d4a16eb0e..9713e10e5 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_M0142_CCLM_COLLOCATED_CHROMA 1 // Adding support for chroma sample location type 2 in CCLM + #define JVET_M0479_18BITS_MV_CLIP 1 #define JVET_M0464_UNI_MTS 1 diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 0f0bbc947..3c4ccac7d 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -794,6 +794,12 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) READ_FLAG( symbol, "bio_enable_flag" ); spsNext.setUseBIO ( symbol != 0 ); READ_FLAG( symbol, "disable_motion_compression_flag" ); spsNext.setDisableMotCompress ( symbol != 0 ); READ_FLAG( symbol, "lm_chroma_enabled_flag" ); spsNext.setUseLMChroma ( symbol != 0 ); +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + if ( spsNext.getUseLMChroma() && spsNext.getSPS().getChromaFormatIdc() == CHROMA_420 ) + { + READ_FLAG( symbol, "sps_cclm_collocated_chroma_flag" ); spsNext.setCclmCollocatedChromaFlag( symbol != 0 ); + } +#endif #if JVET_M0464_UNI_MTS READ_FLAG( symbol, "mts_intra_enabled_flag" ); spsNext.setUseIntraMTS ( symbol != 0 ); READ_FLAG( symbol, "mts_inter_enabled_flag" ); spsNext.setUseInterMTS ( symbol != 0 ); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index a0020e5a4..eed12e585 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -202,6 +202,9 @@ protected: unsigned m_log2DiffMaxMinCodingBlockSize; int m_LMChroma; +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + bool m_cclmCollocatedChromaFlag; +#endif #if JVET_M0464_UNI_MTS int m_IntraMTS; int m_InterMTS; @@ -681,6 +684,10 @@ public: void setUseLMChroma ( int n ) { m_LMChroma = n; } int getUseLMChroma() const { return m_LMChroma; } +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + void setCclmCollocatedChromaFlag ( bool b ) { m_cclmCollocatedChromaFlag = b; } + bool getCclmCollocatedChromaFlag () const { return m_cclmCollocatedChromaFlag; } +#endif void setSubPuMvpMode(int n) { m_SubPuMvpMode = n; } bool getSubPuMvpMode() const { return m_SubPuMvpMode; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index c996912c6..d62d47abc 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -860,6 +860,9 @@ void EncLib::xInitSPS(SPS &sps) sps.getSpsNext().setDisableMotCompress ( m_DisableMotionCompression ); sps.getSpsNext().setMTTMode ( m_MTTMode ); sps.getSpsNext().setUseLMChroma ( m_LMChroma ? true : false ); +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + sps.getSpsNext().setCclmCollocatedChromaFlag( m_cclmCollocatedChromaFlag ); +#endif #if ENABLE_WPP_PARALLELISM sps.getSpsNext().setUseNextDQP ( m_AltDQPCoding ); #endif diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 410a9dede..81d4fbdd6 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -534,6 +534,12 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) WRITE_FLAG( spsNext.getUseBIO() ? 1 : 0, "bio_enable_flag" ); WRITE_FLAG( spsNext.getDisableMotCompress() ? 1 : 0, "disable_motion_compression_flag" ); WRITE_FLAG( spsNext.getUseLMChroma() ? 1 : 0, "lm_chroma_enabled_flag" ); +#if JVET_M0142_CCLM_COLLOCATED_CHROMA + if ( spsNext.getUseLMChroma() && spsNext.getSPS().getChromaFormatIdc() == CHROMA_420 ) + { + WRITE_FLAG( spsNext.getCclmCollocatedChromaFlag() ? 1 : 0, "sps_cclm_collocated_chroma_flag" ); + } +#endif #if JVET_M0464_UNI_MTS WRITE_FLAG( spsNext.getUseIntraMTS() ? 1 : 0, "mts_intra_enabled_flag" ); WRITE_FLAG( spsNext.getUseInterMTS() ? 1 : 0, "mts_inter_enabled_flag" ); -- GitLab