Commit 66a03dc1 authored by Xiang Li's avatar Xiang Li

Merge branch 'master' into 'N0483-SBT-TPM'

parents 2132897b 356c647e
...@@ -134,8 +134,9 @@ AMaxBT : 1 ...@@ -134,8 +134,9 @@ AMaxBT : 1
# Encoder optimization tools # Encoder optimization tools
AffineAmvrEncOpt : 0 AffineAmvrEncOpt : 0
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ### ### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ### ### DO NOT DELETE THE EMPTY LINE BELOW ###
...@@ -137,8 +137,9 @@ AMaxBT : 1 ...@@ -137,8 +137,9 @@ AMaxBT : 1
# Encoder optimization tools # Encoder optimization tools
AffineAmvrEncOpt : 0 AffineAmvrEncOpt : 0
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ### ### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ### ### DO NOT DELETE THE EMPTY LINE BELOW ###
...@@ -153,8 +153,9 @@ AMaxBT : 1 ...@@ -153,8 +153,9 @@ AMaxBT : 1
# Encoder optimization tools # Encoder optimization tools
AffineAmvrEncOpt : 1 AffineAmvrEncOpt : 1
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ### ### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ### ### DO NOT DELETE THE EMPTY LINE BELOW ###
...@@ -1228,6 +1228,11 @@ Specifies the maximum number of merge candidates to use. ...@@ -1228,6 +1228,11 @@ Specifies the maximum number of merge candidates to use.
Flag to disable intra PUs in inter slices. Flag to disable intra PUs in inter slices.
\\ \\
\Option{MmvdDisNum} &
%\ShortOption{\None} &
\Default{6} &
Specifies the number of MMVD distance entries used from the distance table at encoder.
\\
\end{OptionTableNoShorthand} \end{OptionTableNoShorthand}
...@@ -1957,6 +1962,18 @@ luma TUs are also skipped. ...@@ -1957,6 +1962,18 @@ luma TUs are also skipped.
\par \par
This option has no effect if TransformSkip is disabled. This option has no effect if TransformSkip is disabled.
\\ \\
\Option{UseNonLinearAlfLuma} &
%\ShortOption{\None} &
\Default{true} &
Enables optimization of non-linear filters for ALF on Luma channel.
\\
\Option{UseNonLinearAlfChroma} &
%\ShortOption{\None} &
\Default{true} &
Enables optimization of non-linear filters for ALF on Chroma channels.
\\
\end{OptionTableNoShorthand} \end{OptionTableNoShorthand}
%% %%
......
...@@ -279,6 +279,9 @@ void EncApp::xInitLibCfg() ...@@ -279,6 +279,9 @@ void EncApp::xInitLibCfg()
m_cEncLib.setUseAffineAmvr ( m_AffineAmvr ); m_cEncLib.setUseAffineAmvr ( m_AffineAmvr );
m_cEncLib.setUseAffineAmvrEncOpt ( m_AffineAmvrEncOpt ); m_cEncLib.setUseAffineAmvrEncOpt ( m_AffineAmvrEncOpt );
m_cEncLib.setDMVR ( m_DMVR ); m_cEncLib.setDMVR ( m_DMVR );
#if JVET_N0449_MMVD_SIMP
m_cEncLib.setMmvdDisNum (m_MmvdDisNum);
#endif
m_cEncLib.setIBCMode ( m_IBCMode ); m_cEncLib.setIBCMode ( m_IBCMode );
m_cEncLib.setIBCLocalSearchRangeX ( m_IBCLocalSearchRangeX ); m_cEncLib.setIBCLocalSearchRangeX ( m_IBCLocalSearchRangeX );
m_cEncLib.setIBCLocalSearchRangeY ( m_IBCLocalSearchRangeY ); m_cEncLib.setIBCLocalSearchRangeY ( m_IBCLocalSearchRangeY );
...@@ -311,6 +314,10 @@ void EncApp::xInitLibCfg() ...@@ -311,6 +314,10 @@ void EncApp::xInitLibCfg()
m_cEncLib.setUseAMaxBT ( m_useAMaxBT ); m_cEncLib.setUseAMaxBT ( m_useAMaxBT );
m_cEncLib.setUseE0023FastEnc ( m_e0023FastEnc ); m_cEncLib.setUseE0023FastEnc ( m_e0023FastEnc );
m_cEncLib.setUseContentBasedFastQtbt ( m_contentBasedFastQtbt ); m_cEncLib.setUseContentBasedFastQtbt ( m_contentBasedFastQtbt );
#if JVET_N0242_NON_LINEAR_ALF
m_cEncLib.setUseNonLinearAlfLuma ( m_useNonLinearAlfLuma );
m_cEncLib.setUseNonLinearAlfChroma ( m_useNonLinearAlfChroma );
#endif
m_cEncLib.setCrossComponentPredictionEnabledFlag ( m_crossComponentPredictionEnabledFlag ); m_cEncLib.setCrossComponentPredictionEnabledFlag ( m_crossComponentPredictionEnabledFlag );
m_cEncLib.setUseReconBasedCrossCPredictionEstimate ( m_reconBasedCrossCPredictionEstimate ); m_cEncLib.setUseReconBasedCrossCPredictionEstimate ( m_reconBasedCrossCPredictionEstimate );
m_cEncLib.setLog2SaoOffsetScale ( CHANNEL_TYPE_LUMA , m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] ); m_cEncLib.setLog2SaoOffsetScale ( CHANNEL_TYPE_LUMA , m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] );
......
...@@ -874,6 +874,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ...@@ -874,6 +874,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("AffineAmvr", m_AffineAmvr, false, "Eanble AMVR for affine inter mode") ("AffineAmvr", m_AffineAmvr, false, "Eanble AMVR for affine inter mode")
("AffineAmvrEncOpt", m_AffineAmvrEncOpt, false, "Enable encoder optimization of affine AMVR") ("AffineAmvrEncOpt", m_AffineAmvrEncOpt, false, "Enable encoder optimization of affine AMVR")
("DMVR", m_DMVR, false, "Decoder-side Motion Vector Refinement") ("DMVR", m_DMVR, false, "Decoder-side Motion Vector Refinement")
#if JVET_N0449_MMVD_SIMP
("MmvdDisNum", m_MmvdDisNum, 8, "Number of MMVD Distance Entries")
#endif
( "IBC", m_IBCMode, 0u, "IBCMode (0x1:enabled, 0x0:disabled) [default: disabled]") ( "IBC", m_IBCMode, 0u, "IBCMode (0x1:enabled, 0x0:disabled) [default: disabled]")
( "IBCLocalSearchRangeX", m_IBCLocalSearchRangeX, 128u, "Search range of IBC local search in x direction") ( "IBCLocalSearchRangeX", m_IBCLocalSearchRangeX, 128u, "Search range of IBC local search in x direction")
( "IBCLocalSearchRangeY", m_IBCLocalSearchRangeY, 128u, "Search range of IBC local search in y direction") ( "IBCLocalSearchRangeY", m_IBCLocalSearchRangeY, 128u, "Search range of IBC local search in y direction")
...@@ -896,6 +899,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ...@@ -896,6 +899,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("AMaxBT", m_useAMaxBT, false, "Adaptive maximal BT-size") ("AMaxBT", m_useAMaxBT, false, "Adaptive maximal BT-size")
("E0023FastEnc", m_e0023FastEnc, true, "Fast encoding setting for QTBT (proposal E0023)") ("E0023FastEnc", m_e0023FastEnc, true, "Fast encoding setting for QTBT (proposal E0023)")
("ContentBasedFastQtbt", m_contentBasedFastQtbt, false, "Signal based QTBT speed-up") ("ContentBasedFastQtbt", m_contentBasedFastQtbt, false, "Signal based QTBT speed-up")
#if JVET_N0242_NON_LINEAR_ALF
("UseNonLinearAlfLuma", m_useNonLinearAlfLuma, true, "Non-linear adaptive loop filters for Luma Channel")
("UseNonLinearAlfChroma", m_useNonLinearAlfChroma, true, "Non-linear adaptive loop filters for Chroma Channels")
#endif
// Unit definition parameters // Unit definition parameters
("MaxCUWidth", m_uiMaxCUWidth, 64u) ("MaxCUWidth", m_uiMaxCUWidth, 64u)
("MaxCUHeight", m_uiMaxCUHeight, 64u) ("MaxCUHeight", m_uiMaxCUHeight, 64u)
...@@ -1973,6 +1980,9 @@ bool EncAppCfg::xCheckParameter() ...@@ -1973,6 +1980,9 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara( m_GBiFast, "GBiFast is only allowed with NEXT profile" ); xConfirmPara( m_GBiFast, "GBiFast is only allowed with NEXT profile" );
xConfirmPara( m_Triangle, "Triangle is only allowed with NEXT profile" ); xConfirmPara( m_Triangle, "Triangle is only allowed with NEXT profile" );
xConfirmPara(m_DMVR, "DMVR only allowed with NEXT profile"); xConfirmPara(m_DMVR, "DMVR only allowed with NEXT profile");
#if JVET_N0449_MMVD_SIMP
xConfirmPara(m_MmvdDisNum, "Number of distance MMVD entry setting only allowed with NEXT profile");
#endif
// ADD_NEW_TOOL : (parameter check) add a check for next tools here // ADD_NEW_TOOL : (parameter check) add a check for next tools here
} }
else else
...@@ -3159,6 +3169,9 @@ void EncAppCfg::xPrintParameter() ...@@ -3159,6 +3169,9 @@ void EncAppCfg::xPrintParameter()
m_AffineAmvrEncOpt = m_AffineAmvr ? m_AffineAmvrEncOpt : false; m_AffineAmvrEncOpt = m_AffineAmvr ? m_AffineAmvrEncOpt : false;
msg( VERBOSE, "AffineAmvrEncOpt:%d ", m_AffineAmvrEncOpt ); msg( VERBOSE, "AffineAmvrEncOpt:%d ", m_AffineAmvrEncOpt );
msg(VERBOSE, "DMVR:%d ", m_DMVR); msg(VERBOSE, "DMVR:%d ", m_DMVR);
#if JVET_N0449_MMVD_SIMP
msg(VERBOSE, "MmvdDisNum:%d ", m_MmvdDisNum);
#endif
} }
msg(VERBOSE, "IBC:%d ", m_IBCMode); msg(VERBOSE, "IBC:%d ", m_IBCMode);
msg( VERBOSE, "HashME:%d ", m_HashME ); msg( VERBOSE, "HashME:%d ", m_HashME );
...@@ -3185,6 +3198,10 @@ void EncAppCfg::xPrintParameter() ...@@ -3185,6 +3198,10 @@ void EncAppCfg::xPrintParameter()
msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT ); msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT );
msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc ); msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc );
msg( VERBOSE, "ContentBasedFastQtbt:%d ", m_contentBasedFastQtbt ); msg( VERBOSE, "ContentBasedFastQtbt:%d ", m_contentBasedFastQtbt );
#if JVET_N0242_NON_LINEAR_ALF
msg( VERBOSE, "UseNonLinearALFLuma:%d ", m_useNonLinearAlfLuma );
msg( VERBOSE, "UseNonLinearALFChroma:%d ", m_useNonLinearAlfChroma );
#endif
msg( VERBOSE, "NumSplitThreads:%d ", m_numSplitThreads ); msg( VERBOSE, "NumSplitThreads:%d ", m_numSplitThreads );
if( m_numSplitThreads > 1 ) if( m_numSplitThreads > 1 )
......
...@@ -260,7 +260,9 @@ protected: ...@@ -260,7 +260,9 @@ protected:
bool m_AffineAmvr; bool m_AffineAmvr;
bool m_AffineAmvrEncOpt; bool m_AffineAmvrEncOpt;
bool m_DMVR; bool m_DMVR;
#if JVET_N0449_MMVD_SIMP
int m_MmvdDisNum;
#endif
unsigned m_IBCMode; unsigned m_IBCMode;
unsigned m_IBCLocalSearchRangeX; unsigned m_IBCLocalSearchRangeX;
unsigned m_IBCLocalSearchRangeY; unsigned m_IBCLocalSearchRangeY;
...@@ -290,6 +292,10 @@ protected: ...@@ -290,6 +292,10 @@ protected:
bool m_useFastMrg; bool m_useFastMrg;
bool m_e0023FastEnc; bool m_e0023FastEnc;
bool m_contentBasedFastQtbt; bool m_contentBasedFastQtbt;
#if JVET_N0242_NON_LINEAR_ALF
bool m_useNonLinearAlfLuma;
bool m_useNonLinearAlfChroma;
#endif
int m_numSplitThreads; int m_numSplitThreads;
......
...@@ -39,6 +39,14 @@ ...@@ -39,6 +39,14 @@
#include "CodingStructure.h" #include "CodingStructure.h"
#include "Picture.h" #include "Picture.h"
#if JVET_N0242_NON_LINEAR_ALF
#include <array>
#include <cmath>
#endif
#if JVET_N0242_NON_LINEAR_ALF
constexpr int AdaptiveLoopFilter::AlfNumClippingValues[];
#endif
AdaptiveLoopFilter::AdaptiveLoopFilter() AdaptiveLoopFilter::AdaptiveLoopFilter()
: m_classifier( nullptr ) : m_classifier( nullptr )
...@@ -83,6 +91,9 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic ...@@ -83,6 +91,9 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
m_ctuEnableFlag[compIdx] = cs.picture->getAlfCtuEnableFlag( compIdx ); m_ctuEnableFlag[compIdx] = cs.picture->getAlfCtuEnableFlag( compIdx );
} }
reconstructCoeff( alfSliceParam, CHANNEL_TYPE_LUMA ); reconstructCoeff( alfSliceParam, CHANNEL_TYPE_LUMA );
#if JVET_N0242_NON_LINEAR_ALF
if( alfSliceParam.enabledFlag[COMPONENT_Cb] || alfSliceParam.enabledFlag[COMPONENT_Cr] )
#endif
reconstructCoeff( alfSliceParam, CHANNEL_TYPE_CHROMA ); reconstructCoeff( alfSliceParam, CHANNEL_TYPE_CHROMA );
PelUnitBuf recYuv = cs.getRecoBuf(); PelUnitBuf recYuv = cs.getRecoBuf();
...@@ -106,7 +117,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic ...@@ -106,7 +117,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
deriveClassification( m_classifier, tmpYuv.get( COMPONENT_Y ), blk ); deriveClassification( m_classifier, tmpYuv.get( COMPONENT_Y ), blk );
Area blkPCM(xPos, yPos, width, height); Area blkPCM(xPos, yPos, width, height);
resetPCMBlkClassInfo(cs, m_classifier, tmpYuv.get(COMPONENT_Y), blkPCM); resetPCMBlkClassInfo(cs, m_classifier, tmpYuv.get(COMPONENT_Y), blkPCM);
#if JVET_N0242_NON_LINEAR_ALF
m_filter7x7Blk( m_classifier, recYuv, tmpYuv, blk, COMPONENT_Y, m_coeffFinal, m_clippFinal, m_clpRngs.comp[COMPONENT_Y], cs );
#else
m_filter7x7Blk(m_classifier, recYuv, tmpYuv, blk, COMPONENT_Y, m_coeffFinal, m_clpRngs.comp[COMPONENT_Y], cs ); m_filter7x7Blk(m_classifier, recYuv, tmpYuv, blk, COMPONENT_Y, m_coeffFinal, m_clpRngs.comp[COMPONENT_Y], cs );
#endif
} }
for( int compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ ) for( int compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ )
...@@ -119,7 +134,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic ...@@ -119,7 +134,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
{ {
Area blk( xPos >> chromaScaleX, yPos >> chromaScaleY, width >> chromaScaleX, height >> chromaScaleY ); Area blk( xPos >> chromaScaleX, yPos >> chromaScaleY, width >> chromaScaleX, height >> chromaScaleY );
#if JVET_N0242_NON_LINEAR_ALF
m_filter5x5Blk( m_classifier, recYuv, tmpYuv, blk, compID, alfSliceParam.chromaCoeff, m_chromaClippFinal, m_clpRngs.comp[compIdx], cs );
#else
m_filter5x5Blk( m_classifier, recYuv, tmpYuv, blk, compID, alfSliceParam.chromaCoeff, m_clpRngs.comp[compIdx], cs ); m_filter5x5Blk( m_classifier, recYuv, tmpYuv, blk, compID, alfSliceParam.chromaCoeff, m_clpRngs.comp[compIdx], cs );
#endif
} }
} }
ctuIdx++; ctuIdx++;
...@@ -136,6 +155,9 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel ...@@ -136,6 +155,9 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
int numCoeffMinus1 = numCoeff - 1; int numCoeffMinus1 = numCoeff - 1;
int numFilters = isLuma( channel ) ? alfSliceParam.numLumaFilters : 1; int numFilters = isLuma( channel ) ? alfSliceParam.numLumaFilters : 1;
short* coeff = isLuma( channel ) ? alfSliceParam.lumaCoeff : alfSliceParam.chromaCoeff; short* coeff = isLuma( channel ) ? alfSliceParam.lumaCoeff : alfSliceParam.chromaCoeff;
#if JVET_N0242_NON_LINEAR_ALF
short* clipp = isLuma( channel ) ? alfSliceParam.lumaClipp : alfSliceParam.chromaClipp;
#endif
if( alfSliceParam.alfLumaCoeffDeltaPredictionFlag && isLuma( channel ) ) if( alfSliceParam.alfLumaCoeffDeltaPredictionFlag && isLuma( channel ) )
{ {
...@@ -150,16 +172,26 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel ...@@ -150,16 +172,26 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
for( int filterIdx = 0; filterIdx < numFilters; filterIdx++ ) for( int filterIdx = 0; filterIdx < numFilters; filterIdx++ )
{ {
#if JVET_N0242_NON_LINEAR_ALF
coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = factor;
#else
int sum = 0; int sum = 0;
for( int i = 0; i < numCoeffMinus1; i++ ) for( int i = 0; i < numCoeffMinus1; i++ )
{ {
sum += ( coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + i] << 1 ); sum += ( coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + i] << 1 );
} }
coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = factor - sum; coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = factor - sum;
#endif
} }
if( isChroma( channel ) ) if( isChroma( channel ) )
{ {
#if JVET_N0242_NON_LINEAR_ALF
for( int coeffIdx = 0; coeffIdx < numCoeffMinus1; ++coeffIdx )
{
m_chromaClippFinal[coeffIdx] = alfSliceParam.nonLinearFlag[channel] ? m_alfClippingValues[channel][clipp[coeffIdx]] : m_alfClippingValues[channel][0];
}
#endif
return; return;
} }
...@@ -167,6 +199,12 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel ...@@ -167,6 +199,12 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
{ {
int filterIdx = alfSliceParam.filterCoeffDeltaIdx[classIdx]; int filterIdx = alfSliceParam.filterCoeffDeltaIdx[classIdx];
memcpy( m_coeffFinal + classIdx * MAX_NUM_ALF_LUMA_COEFF, coeff + filterIdx * MAX_NUM_ALF_LUMA_COEFF, sizeof( short ) * numCoeff ); memcpy( m_coeffFinal + classIdx * MAX_NUM_ALF_LUMA_COEFF, coeff + filterIdx * MAX_NUM_ALF_LUMA_COEFF, sizeof( short ) * numCoeff );
#if JVET_N0242_NON_LINEAR_ALF
for( int coeffIdx = 0; coeffIdx < numCoeffMinus1; ++coeffIdx )
{
(m_clippFinal + classIdx * MAX_NUM_ALF_LUMA_COEFF)[coeffIdx] = alfSliceParam.nonLinearFlag[channel] ? m_alfClippingValues[channel][(clipp + filterIdx * MAX_NUM_ALF_LUMA_COEFF)[coeffIdx]] : m_alfClippingValues[channel][0];
}
#endif
} }
if( bRedo && alfSliceParam.alfLumaCoeffDeltaPredictionFlag ) if( bRedo && alfSliceParam.alfLumaCoeffDeltaPredictionFlag )
...@@ -197,6 +235,31 @@ void AdaptiveLoopFilter::create( const int picWidth, const int picHeight, const ...@@ -197,6 +235,31 @@ void AdaptiveLoopFilter::create( const int picWidth, const int picHeight, const
m_filterShapes[CHANNEL_TYPE_LUMA].push_back( AlfFilterShape( 7 ) ); m_filterShapes[CHANNEL_TYPE_LUMA].push_back( AlfFilterShape( 7 ) );
m_filterShapes[CHANNEL_TYPE_CHROMA].push_back( AlfFilterShape( 5 ) ); m_filterShapes[CHANNEL_TYPE_CHROMA].push_back( AlfFilterShape( 5 ) );
#if JVET_N0242_NON_LINEAR_ALF
static_assert( AlfNumClippingValues[CHANNEL_TYPE_LUMA] > 0, "AlfNumClippingValues[CHANNEL_TYPE_LUMA] must be at least one" );
for( int i = 0; i < AlfNumClippingValues[CHANNEL_TYPE_LUMA]; ++i )
{
m_alfClippingValues[CHANNEL_TYPE_LUMA][i] =
(Pel) std::round(
std::pow(
2.,
double( m_inputBitDepth[CHANNEL_TYPE_LUMA] * ( AlfNumClippingValues[CHANNEL_TYPE_LUMA] - i ) ) / AlfNumClippingValues[CHANNEL_TYPE_LUMA]
) );
}
static_assert( AlfNumClippingValues[CHANNEL_TYPE_CHROMA] > 0, "AlfNumClippingValues[CHANNEL_TYPE_CHROMA] must be at least one" );
m_alfClippingValues[CHANNEL_TYPE_CHROMA][0] = 1 << m_inputBitDepth[CHANNEL_TYPE_CHROMA];
for( int i = 1; i < AlfNumClippingValues[CHANNEL_TYPE_CHROMA]; ++i )
{
m_alfClippingValues[CHANNEL_TYPE_CHROMA][i] =
(Pel) std::round(
std::pow(
2.,
m_inputBitDepth[CHANNEL_TYPE_CHROMA] - 8
+ 8. * ( AlfNumClippingValues[CHANNEL_TYPE_CHROMA] - i - 1 ) / ( AlfNumClippingValues[CHANNEL_TYPE_CHROMA] - 1 )
) );
}
#endif
m_tempBuf.destroy(); m_tempBuf.destroy();
m_tempBuf.create( format, Area( 0, 0, picWidth, picHeight ), maxCUWidth, MAX_ALF_FILTER_LENGTH >> 1, 0, false ); m_tempBuf.create( format, Area( 0, 0, picWidth, picHeight ), maxCUWidth, MAX_ALF_FILTER_LENGTH >> 1, 0, false );
...@@ -496,7 +559,11 @@ void AdaptiveLoopFilter::deriveClassificationBlk( AlfClassifier** classifier, in ...@@ -496,7 +559,11 @@ void AdaptiveLoopFilter::deriveClassificationBlk( AlfClassifier** classifier, in
} }
template<AlfFilterType filtType> template<AlfFilterType filtType>
#if JVET_N0242_NON_LINEAR_ALF
void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, short* fClipSet, const ClpRng& clpRng, CodingStructure& cs )
#else
void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng, CodingStructure& cs ) void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng, CodingStructure& cs )
#endif
{ {
const bool bChroma = isChroma( compId ); const bool bChroma = isChroma( compId );
if( bChroma ) if( bChroma )
...@@ -526,6 +593,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -526,6 +593,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
const Pel *pImg0, *pImg1, *pImg2, *pImg3, *pImg4, *pImg5, *pImg6; const Pel *pImg0, *pImg1, *pImg2, *pImg3, *pImg4, *pImg5, *pImg6;
short *coef = filterSet; short *coef = filterSet;
#if JVET_N0242_NON_LINEAR_ALF
short *clip = fClipSet;
#endif
const int shift = m_NUM_BITS - 1; const int shift = m_NUM_BITS - 1;
...@@ -547,7 +617,12 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -547,7 +617,12 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
int dstStride2 = dstStride * clsSizeY; int dstStride2 = dstStride * clsSizeY;
int srcStride2 = srcStride * clsSizeY; int srcStride2 = srcStride * clsSizeY;
#if JVET_N0242_NON_LINEAR_ALF
std::array<int, MAX_NUM_ALF_LUMA_COEFF> filterCoeff;
std::array<int, MAX_NUM_ALF_LUMA_COEFF> filterClipp;
#else
std::vector<Pel> filterCoeff( MAX_NUM_ALF_LUMA_COEFF ); std::vector<Pel> filterCoeff( MAX_NUM_ALF_LUMA_COEFF );
#endif
pImgYPad0 = src + startHeight * srcStride + startWidth; pImgYPad0 = src + startHeight * srcStride + startWidth;
pImgYPad1 = pImgYPad0 + srcStride; pImgYPad1 = pImgYPad0 + srcStride;
...@@ -578,6 +653,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -578,6 +653,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
continue; continue;
} }
coef = filterSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF; coef = filterSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF;
#if JVET_N0242_NON_LINEAR_ALF
clip = fClipSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF;
#endif
} }
else if( isPCMFilterDisabled ) else if( isPCMFilterDisabled )
{ {
...@@ -609,18 +687,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -609,18 +687,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
if( transposeIdx == 1 ) if( transposeIdx == 1 )
{ {
filterCoeff = { coef[9], coef[4], coef[10], coef[8], coef[1], coef[5], coef[11], coef[7], coef[3], coef[0], coef[2], coef[6], coef[12] }; filterCoeff = { coef[9], coef[4], coef[10], coef[8], coef[1], coef[5], coef[11], coef[7], coef[3], coef[0], coef[2], coef[6], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[9], clip[4], clip[10], clip[8], clip[1], clip[5], clip[11], clip[7], clip[3], clip[0], clip[2], clip[6], clip[12] };
#endif
} }
else if( transposeIdx == 2 ) else if( transposeIdx == 2 )
{ {
filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[8], coef[7], coef[6], coef[5], coef[4], coef[9], coef[10], coef[11], coef[12] }; filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[8], coef[7], coef[6], coef[5], coef[4], coef[9], coef[10], coef[11], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[0], clip[3], clip[2], clip[1], clip[8], clip[7], clip[6], clip[5], clip[4], clip[9], clip[10], clip[11], clip[12] };
#endif
} }
else if( transposeIdx == 3 ) else if( transposeIdx == 3 )
{ {
filterCoeff = { coef[9], coef[8], coef[10], coef[4], coef[3], coef[7], coef[11], coef[5], coef[1], coef[0], coef[2], coef[6], coef[12] }; filterCoeff = { coef[9], coef[8], coef[10], coef[4], coef[3], coef[7], coef[11], coef[5], coef[1], coef[0], coef[2], coef[6], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[9], clip[8], clip[10], clip[4], clip[3], clip[7], clip[11], clip[5], clip[1], clip[0], clip[2], clip[6], clip[12] };
#endif
} }
else else
{ {
filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6], coef[7], coef[8], coef[9], coef[10], coef[11], coef[12] }; filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6], coef[7], coef[8], coef[9], coef[10], coef[11], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[0], clip[1], clip[2], clip[3], clip[4], clip[5], clip[6], clip[7], clip[8], clip[9], clip[10], clip[11], clip[12] };
#endif
} }
} }
else else
...@@ -628,18 +718,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -628,18 +718,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
if( transposeIdx == 1 ) if( transposeIdx == 1 )
{ {
filterCoeff = { coef[4], coef[1], coef[5], coef[3], coef[0], coef[2], coef[6] }; filterCoeff = { coef[4], coef[1], coef[5], coef[3], coef[0], coef[2], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[4], clip[1], clip[5], clip[3], clip[0], clip[2], clip[6] };
#endif
} }
else if( transposeIdx == 2 ) else if( transposeIdx == 2 )
{ {
filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[4], coef[5], coef[6] }; filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[4], coef[5], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[0], clip[3], clip[2], clip[1], clip[4], clip[5], clip[6] };
#endif
} }
else if( transposeIdx == 3 ) else if( transposeIdx == 3 )
{ {
filterCoeff = { coef[4], coef[3], coef[5], coef[1], coef[0], coef[2], coef[6] }; filterCoeff = { coef[4], coef[3], coef[5], coef[1], coef[0], coef[2], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[4], clip[3], clip[5], clip[1], clip[0], clip[2], clip[6] };
#endif
} }
else else
{ {
filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6] }; filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
filterClipp = { clip[0], clip[1], clip[2], clip[3], clip[4], clip[5], clip[6] };
#endif
} }
} }
...@@ -675,39 +777,121 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf ...@@ -675,39 +777,121 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
} }
int sum = 0; int sum = 0;
#if JVET_N0242_NON_LINEAR_ALF
const Pel curr = pImg0[+0];
#endif
if( filtType == ALF_FILTER_7 ) if( filtType == ALF_FILTER_7 )
{ {
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[0] * ( pImg5[0] + pImg6[0] ); sum += filterCoeff[0] * ( pImg5[0] + pImg6[0] );
#else
sum += filterCoeff[0] * ( clipALF(filterClipp[0], curr, pImg5[+0], pImg6[+0]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[1] * ( pImg3[+1] + pImg4[-1] ); sum += filterCoeff[1] * ( pImg3[+1] + pImg4[-1] );
#else
sum += filterCoeff[1] * ( clipALF(filterClipp[1], curr, pImg3[+1], pImg4[-1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[2] * ( pImg3[+0] + pImg4[+0] ); sum += filterCoeff[2] * ( pImg3[+0] + pImg4[+0] );
#else
sum += filterCoeff[2] * ( clipALF(filterClipp[2], curr, pImg3[+0], pImg4[+0]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[3] * ( pImg3[-1] + pImg4[+1] ); sum += filterCoeff[3] * ( pImg3[-1] + pImg4[+1] );
#else
sum += filterCoeff[3] * ( clipALF(filterClipp[3], curr, pImg3[-1], pImg4[+1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[4] * ( pImg1[+2] + pImg2[-2] ); sum += filterCoeff[