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
# Encoder optimization tools
AffineAmvrEncOpt : 0
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ###
......@@ -137,8 +137,9 @@ AMaxBT : 1
# Encoder optimization tools
AffineAmvrEncOpt : 0
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ###
......@@ -153,8 +153,9 @@ AMaxBT : 1
# Encoder optimization tools
AffineAmvrEncOpt : 1
MmvdDisNum : 6
### DO NOT ADD ANYTHING BELOW THIS LINE ###
### DO NOT DELETE THE EMPTY LINE BELOW ###
......@@ -1228,6 +1228,11 @@ Specifies the maximum number of merge candidates to use.
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}
......@@ -1957,6 +1962,18 @@ luma TUs are also skipped.
\par
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}
%%
......
......@@ -279,6 +279,9 @@ void EncApp::xInitLibCfg()
m_cEncLib.setUseAffineAmvr ( m_AffineAmvr );
m_cEncLib.setUseAffineAmvrEncOpt ( m_AffineAmvrEncOpt );
m_cEncLib.setDMVR ( m_DMVR );
#if JVET_N0449_MMVD_SIMP
m_cEncLib.setMmvdDisNum (m_MmvdDisNum);
#endif
m_cEncLib.setIBCMode ( m_IBCMode );
m_cEncLib.setIBCLocalSearchRangeX ( m_IBCLocalSearchRangeX );
m_cEncLib.setIBCLocalSearchRangeY ( m_IBCLocalSearchRangeY );
......@@ -311,6 +314,10 @@ void EncApp::xInitLibCfg()
m_cEncLib.setUseAMaxBT ( m_useAMaxBT );
m_cEncLib.setUseE0023FastEnc ( m_e0023FastEnc );
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.setUseReconBasedCrossCPredictionEstimate ( m_reconBasedCrossCPredictionEstimate );
m_cEncLib.setLog2SaoOffsetScale ( CHANNEL_TYPE_LUMA , m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA] );
......
......@@ -874,6 +874,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("AffineAmvr", m_AffineAmvr, false, "Eanble AMVR for affine inter mode")
("AffineAmvrEncOpt", m_AffineAmvrEncOpt, false, "Enable encoder optimization of affine AMVR")
("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]")
( "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")
......@@ -896,6 +899,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("AMaxBT", m_useAMaxBT, false, "Adaptive maximal BT-size")
("E0023FastEnc", m_e0023FastEnc, true, "Fast encoding setting for QTBT (proposal E0023)")
("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
("MaxCUWidth", m_uiMaxCUWidth, 64u)
("MaxCUHeight", m_uiMaxCUHeight, 64u)
......@@ -1973,6 +1980,9 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara( m_GBiFast, "GBiFast 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");
#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
}
else
......@@ -3159,6 +3169,9 @@ void EncAppCfg::xPrintParameter()
m_AffineAmvrEncOpt = m_AffineAmvr ? m_AffineAmvrEncOpt : false;
msg( VERBOSE, "AffineAmvrEncOpt:%d ", m_AffineAmvrEncOpt );
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, "HashME:%d ", m_HashME );
......@@ -3185,6 +3198,10 @@ void EncAppCfg::xPrintParameter()
msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT );
msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc );
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 );
if( m_numSplitThreads > 1 )
......
......@@ -260,7 +260,9 @@ protected:
bool m_AffineAmvr;
bool m_AffineAmvrEncOpt;
bool m_DMVR;
#if JVET_N0449_MMVD_SIMP
int m_MmvdDisNum;
#endif
unsigned m_IBCMode;
unsigned m_IBCLocalSearchRangeX;
unsigned m_IBCLocalSearchRangeY;
......@@ -290,6 +292,10 @@ protected:
bool m_useFastMrg;
bool m_e0023FastEnc;
bool m_contentBasedFastQtbt;
#if JVET_N0242_NON_LINEAR_ALF
bool m_useNonLinearAlfLuma;
bool m_useNonLinearAlfChroma;
#endif
int m_numSplitThreads;
......
This diff is collapsed.
......@@ -42,6 +42,7 @@
#include "Unit.h"
#include "UnitTools.h"
struct AlfClassifier
{
AlfClassifier() {}
......@@ -66,6 +67,16 @@ enum Direction
class AdaptiveLoopFilter
{
public:
#if JVET_N0242_NON_LINEAR_ALF
static inline int clipALF(const int clip, const short ref, const short val0, const short val1)
{
return Clip3<int>(-clip, +clip, val0-ref) + Clip3<int>(-clip, +clip, val1-ref);
}
static constexpr int AlfNumClippingValues[MAX_NUM_CHANNEL_TYPE] = { 4, 4 };
static constexpr int MaxAlfNumClippingValues = 4;
#endif
static constexpr int m_NUM_BITS = 8;
static constexpr int m_CLASSIFICATION_BLK_SIZE = 32; //non-normative, local buffer size
static constexpr int m_ALF_UNUSED_CLASSIDX = 255;
......@@ -82,15 +93,24 @@ public:
void deriveClassification( AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk );
void resetPCMBlkClassInfo(CodingStructure & cs, AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk);
template<AlfFilterType filtType>
#if JVET_N0242_NON_LINEAR_ALF
static void 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
static void filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng, CodingStructure& cs );
#endif
inline static int getMaxGolombIdx( AlfFilterType filterType )
{
return filterType == ALF_FILTER_5 ? 2 : 3;
}
void( *m_deriveClassificationBlk )( AlfClassifier** classifier, int** laplacian[NUM_DIRECTIONS], const CPelBuf& srcLuma, const Area& blk, const int shift );
#if JVET_N0242_NON_LINEAR_ALF
void( *m_filter5x5Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, short* fClipSet, const ClpRng& clpRng, CodingStructure& cs );
void( *m_filter7x7Blk )( 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( *m_filter5x5Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng, CodingStructure& cs );
void( *m_filter7x7Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng, CodingStructure& cs );
#endif
#ifdef TARGET_SIMD_X86
void initAdaptiveLoopFilterX86();
......@@ -99,9 +119,16 @@ public:
#endif
protected:
#if JVET_N0242_NON_LINEAR_ALF
Pel m_alfClippingValues[MAX_NUM_CHANNEL_TYPE][MaxAlfNumClippingValues];
#endif
std::vector<AlfFilterShape> m_filterShapes[MAX_NUM_CHANNEL_TYPE];
AlfClassifier** m_classifier;
short m_coeffFinal[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF];
#if JVET_N0242_NON_LINEAR_ALF
short m_clippFinal[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF];
short m_chromaClippFinal[MAX_NUM_ALF_LUMA_COEFF];
#endif
int** m_laplacian[NUM_DIRECTIONS];
uint8_t* m_ctuEnableFlag[MAX_NUM_COMPONENT];
PelStorage m_tempBuf;
......
......@@ -359,7 +359,10 @@ static const int MIN_BT_SIZE_C = 4; ///<
static const int MAX_TT_SIZE_INTER = 64; ///< for initialization, [1<<MIN_CU_LOG2, 64]
static const int MIN_TT_SIZE_INTER = 4; ///<
#if JVET_N0137_DUALTREE_CHROMA_SIZE
static const int MIN_DUALTREE_CHROMA_WIDTH = 4;
static const int MIN_DUALTREE_CHROMA_SIZE = 16;
#endif
static const SplitSeries SPLIT_BITS = 5;
static const SplitSeries SPLIT_DMULT = 5;
static const SplitSeries SPLIT_MASK = 31; ///< = (1 << SPLIT_BITS) - 1
......
......@@ -447,11 +447,43 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
{
const int scale = PU::getDistScaleFactor(currPoc, poc0, currPoc, poc1);
tempMv[1] = tempMv[0];
#if JVET_N0332_LTRP_MMVD_FIX
const bool isL0RefLongTerm = slice.getRefPic(REF_PIC_LIST_0, refList0)->longTerm;
const bool isL1RefLongTerm = slice.getRefPic(REF_PIC_LIST_1, refList1)->longTerm;
if (isL0RefLongTerm || isL1RefLongTerm)
{
if ((poc1 - currPoc)*(poc0 - currPoc) > 0)
{
tempMv[0] = tempMv[1];
}
else
{
tempMv[0].set(-1 * tempMv[1].getHor(), -1 * tempMv[1].getVer());
}
}
else
#endif
tempMv[0] = tempMv[1].scaleMv(scale);
}
else
{
const int scale = PU::getDistScaleFactor(currPoc, poc1, currPoc, poc0);
#if JVET_N0332_LTRP_MMVD_FIX
const bool isL0RefLongTerm = slice.getRefPic(REF_PIC_LIST_0, refList0)->longTerm;
const bool isL1RefLongTerm = slice.getRefPic(REF_PIC_LIST_1, refList1)->longTerm;
if (isL0RefLongTerm || isL1RefLongTerm)
{
if ((poc1 - currPoc)*(poc0 - currPoc) > 0)
{
tempMv[1] = tempMv[0];
}
else
{
tempMv[1].set(-1 * tempMv[0].getHor(), -1 * tempMv[0].getVer());
}
}
else
#endif
tempMv[1] = tempMv[0].scaleMv(scale);
}
......
......@@ -45,8 +45,13 @@ const MvPrecision Mv::m_amvrPrecision[3] = { MV_PRECISION_QUARTER, MV_PRECISION_
void roundAffineMv( int& mvx, int& mvy, int nShift )
{
const int nOffset = 1 << (nShift - 1);
#if JVET_N0335_N0085_MV_ROUNDING
mvx = (mvx + nOffset - (mvx >= 0)) >> nShift;
mvy = (mvy + nOffset - (mvy >= 0)) >> nShift;
#else
mvx = mvx >= 0 ? (mvx + nOffset) >> nShift : -((-mvx + nOffset) >> nShift);
mvy = mvy >= 0 ? (mvy + nOffset) >> nShift : -((-mvy + nOffset) >> nShift);
#endif
}
void clipMv( Mv& rcMv, const Position& pos,
......
......@@ -121,6 +121,14 @@ public:
//! shift right with rounding
void divideByPowerOf2 (const int i)
{
#if JVET_N0335_N0085_MV_ROUNDING
if (i != 0)
{
const int offset = (1 << (i - 1));
hor = (hor + offset - (hor >= 0)) >> i;
ver = (ver + offset - (ver >= 0)) >> i;
}
#else
#if ME_ENABLE_ROUNDING_OF_MVS
const int offset = (i == 0) ? 0 : 1 << (i - 1);
hor += offset;
......@@ -128,6 +136,7 @@ public:
#endif
hor >>= i;
ver >>= i;
#endif
}
const Mv& operator<<= (const int i)
......@@ -139,8 +148,17 @@ public:
const Mv& operator>>= ( const int i )
{
#if JVET_N0335_N0085_MV_ROUNDING
if (i != 0)
{
const int offset = (1 << (i - 1));
hor = (hor + offset - (hor >= 0)) >> i;
ver = (ver + offset - (ver >= 0)) >> i;
}
#else
hor >>= i;
ver >>= i;
#endif
return *this;
}
......@@ -166,8 +184,13 @@ public:
const Mv scaleMv( int iScale ) const
{
#if JVET_N0335_N0085_MV_ROUNDING
const int mvx = Clip3(-131072, 131071, (iScale * getHor() + 128 - (iScale * getHor() >= 0)) >> 8);
const int mvy = Clip3(-131072, 131071, (iScale * getVer() + 128 - (iScale * getVer() >= 0)) >> 8);
#else
const int mvx = Clip3( -131072, 131071, (iScale * getHor() + 127 + (iScale * getHor() < 0)) >> 8 );
const int mvy = Clip3( -131072, 131071, (iScale * getVer() + 127 + (iScale * getVer() < 0)) >> 8 );
#endif
return Mv( mvx, mvy );
}
......@@ -182,8 +205,13 @@ public:
{
const int rightShift = -shift;
const int nOffset = 1 << (rightShift - 1);
#if JVET_N0335_N0085_MV_ROUNDING
hor = hor >= 0 ? (hor + nOffset - 1) >> rightShift : (hor + nOffset) >> rightShift;
ver = ver >= 0 ? (ver + nOffset - 1) >> rightShift : (ver + nOffset) >> rightShift;
#else
hor = hor >= 0 ? (hor + nOffset) >> rightShift : -((-hor + nOffset) >> rightShift);
ver = ver >= 0 ? (ver + nOffset) >> rightShift : -((-ver + nOffset) >> rightShift);
#endif
}
}
......
......@@ -52,6 +52,16 @@
#define JVET_N0483_DISABLE_SBT_FOR_TPM 1
#define JVET_N0242_NON_LINEAR_ALF 1 // enable CE5-3.2, Non-linear ALF based on clipping function
#define JVET_N0449_MMVD_SIMP 1 // Configurable number of mmvd distance entries used
#define JVET_N0137_DUALTREE_CHROMA_SIZE 1
#define JVET_N0335_N0085_MV_ROUNDING 1 // MV rounding unification
#define JVET_N0332_LTRP_MMVD_FIX 1 // MMVD scaling considering LTRPs from N0332
#define JVET_N0477_LMCS_CLEANUP 1
#define JVET_N0220_LMCS_SIMPLIFICATION 1
......@@ -1549,8 +1559,17 @@ struct AlfFilterShape
struct AlfSliceParam
{
bool enabledFlag[MAX_NUM_COMPONENT]; // alf_slice_enable_flag, alf_chroma_idc
#if JVET_N0242_NON_LINEAR_ALF
bool nonLinearFlag[MAX_NUM_CHANNEL_TYPE]; // alf_nonlinear_enable_flag[Luma/Chroma]
#endif
short lumaCoeff[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_coeff_luma_delta[i][j]
#if JVET_N0242_NON_LINEAR_ALF
short lumaClipp[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF]; // alf_clipp_luma_[i][j]
#endif
short chromaCoeff[MAX_NUM_ALF_CHROMA_COEFF]; // alf_coeff_chroma[i]
#if JVET_N0242_NON_LINEAR_ALF
short chromaClipp[MAX_NUM_ALF_CHROMA_COEFF]; // alf_clipp_chroma[i]
#endif
short filterCoeffDeltaIdx[MAX_NUM_ALF_CLASSES]; // filter_coeff_delta[i]
bool alfLumaCoeffFlag[MAX_NUM_ALF_CLASSES]; // alf_luma_coeff_flag[i]
int numLumaFilters; // number_of_filters_minus1 + 1
......@@ -1566,8 +1585,17 @@ struct AlfSliceParam
void reset()
{
std::memset( enabledFlag, false, sizeof( enabledFlag ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memset( nonLinearFlag, false, sizeof( nonLinearFlag ) );
#endif
std::memset( lumaCoeff, 0, sizeof( lumaCoeff ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memset( lumaClipp, 0, sizeof( lumaClipp ) );
#endif
std::memset( chromaCoeff, 0, sizeof( chromaCoeff ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memset( chromaClipp, 0, sizeof( chromaClipp ) );
#endif
std::memset( filterCoeffDeltaIdx, 0, sizeof( filterCoeffDeltaIdx ) );
std::memset( alfLumaCoeffFlag, true, sizeof( alfLumaCoeffFlag ) );
numLumaFilters = 1;
......@@ -1578,8 +1606,17 @@ struct AlfSliceParam
const AlfSliceParam& operator = ( const AlfSliceParam& src )
{
std::memcpy( enabledFlag, src.enabledFlag, sizeof( enabledFlag ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memcpy( nonLinearFlag, src.nonLinearFlag, sizeof( nonLinearFlag ) );
#endif
std::memcpy( lumaCoeff, src.lumaCoeff, sizeof( lumaCoeff ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memcpy( lumaClipp, src.lumaClipp, sizeof( lumaClipp ) );
#endif
std::memcpy( chromaCoeff, src.chromaCoeff, sizeof( chromaCoeff ) );
#if JVET_N0242_NON_LINEAR_ALF
std::memcpy( chromaClipp, src.chromaClipp, sizeof( chromaClipp ) );
#endif
std::memcpy( filterCoeffDeltaIdx, src.filterCoeffDeltaIdx, sizeof( filterCoeffDeltaIdx ) );
std::memcpy( alfLumaCoeffFlag, src.alfLumaCoeffFlag, sizeof( alfLumaCoeffFlag ) );
numLumaFilters = src.numLumaFilters;
......
......@@ -351,6 +351,9 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
// the minimal and maximal sizes are given in luma samples
const CompArea& area = currArea().Y();
#if JVET_N0137_DUALTREE_CHROMA_SIZE
const CompArea& areaC = currArea().Cb();
#endif
PartLevel& level = m_partStack.back();
const PartSplit lastSplit = level.split;
......@@ -359,7 +362,9 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
// don't allow QT-splitting below a BT split
if( lastSplit != CTU_LEVEL && lastSplit != CU_QUAD_SPLIT ) canQt = false;
if( area.width <= minQtSize ) canQt = false;
#if JVET_N0137_DUALTREE_CHROMA_SIZE
if( chType == CHANNEL_TYPE_CHROMA && areaC.width <= MIN_DUALTREE_CHROMA_WIDTH ) canQt = false;
#endif
if( implicitSplit != CU_DONT_SPLIT )
{
canNo = canTh = canTv = false;
......@@ -397,17 +402,26 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
// specific check for BT splits
if( area.height <= minBtSize || area.height > maxBtSize ) canBh = false;
if( area.width > MAX_TB_SIZEY && area.height <= MAX_TB_SIZEY ) canBh = false;
#if JVET_N0137_DUALTREE_CHROMA_SIZE
if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE ) canBh = false;
#endif
if( area.width <= minBtSize || area.width > maxBtSize ) canBv = false;
if( area.width <= MAX_TB_SIZEY && area.height > MAX_TB_SIZEY ) canBv = false;
#if JVET_N0137_DUALTREE_CHROMA_SIZE
if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE ) canBv = false;
#endif
if( area.height <= 2 * minTtSize || area.height > maxTtSize || area.width > maxTtSize )
canTh = false;
if( area.width > MAX_TB_SIZEY || area.height > MAX_TB_SIZEY ) canTh = false;
#if JVET_N0137_DUALTREE_CHROMA_SIZE
if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE*2 ) canTh = false;
#endif
if( area.width <= 2 * minTtSize || area.width > maxTtSize || area.height > maxTtSize )
canTv = false;
if( area.width > MAX_TB_SIZEY || area.height > MAX_TB_SIZEY ) canTv = false;
#if JVET_N0137_DUALTREE_CHROMA_SIZE
if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE*2 ) canTv = false;
#endif
}
bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs )
......
......@@ -625,6 +625,17 @@ void HLSyntaxReader::parseAPS(APS* aps)
param.enabledFlag[COMPONENT_Cb] = alfChromaIdc >> 1;
param.enabledFlag[COMPONENT_Cr] = alfChromaIdc & 1;
#if JVET_N0242_NON_LINEAR_ALF
READ_FLAG( code, "alf_luma_clip" );
param.nonLinearFlag[CHANNEL_TYPE_LUMA] = code ? true : false;
if( alfChromaIdc )
{
READ_FLAG( code, "alf_chroma_clip" );
param.nonLinearFlag[CHANNEL_TYPE_CHROMA] = code ? true : false;
}
#endif
xReadTruncBinCode(code, MAX_NUM_ALF_CLASSES); //number_of_filters_minus1
param.numLumaFilters = code + 1;
if (param.numLumaFilters > 1)
......@@ -2522,8 +2533,11 @@ bool HLSyntaxReader::xMoreRbspData()
return (cnt>0);
}
#if JVET_N0242_NON_LINEAR_ALF
int HLSyntaxReader::alfGolombDecode( const int k, const bool signed_val )
#else
int HLSyntaxReader::alfGolombDecode( const int k )
#endif
{
uint32_t uiSymbol;
int q = -1;
......@@ -2555,7 +2569,11 @@ int HLSyntaxReader::alfGolombDecode( const int k )
}
}
nr += q * m; // add the bits and the multiple of M
#if JVET_N0242_NON_LINEAR_ALF
if( signed_val && nr != 0 )
#else
if( nr != 0 )
#endif
{
#if RExt__DECODER_DEBUG_BIT_STATISTICS
xReadFlag( uiSymbol, "" );
......@@ -2604,6 +2622,9 @@ void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChrom
static int kMinTab[MAX_NUM_ALF_COEFF];
const int numFilters = isChroma ? 1 : alfSliceParam.numLumaFilters;
short* coeff = isChroma ? alfSliceParam.chromaCoeff : alfSliceParam.lumaCoeff;
#if JVET_N0242_NON_LINEAR_ALF
short* clipp = isChroma ? alfSliceParam.chromaClipp : alfSliceParam.lumaClipp;
#endif
for( int idx = 0; idx < maxGolombIdx; idx++ )
{
......@@ -2639,6 +2660,70 @@ void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChrom
coeff[ind * MAX_NUM_ALF_LUMA_COEFF + i] = alfGolombDecode( kMinTab[alfShape.golombIdx[i]] );
}
}
#if JVET_N0242_NON_LINEAR_ALF
// Clipping values coding
if ( alfSliceParam.nonLinearFlag[isChroma] )
{
READ_UVLC( code, "clip_min_golomb_order" );
kMin = code + 1;
for( int idx = 0; idx < maxGolombIdx; idx++ )
{
READ_FLAG( code, "clip_golomb_order_increase_flag" );
CHECK( code > 1, "Wrong golomb_order_increase_flag" );
kMinTab[idx] = kMin + code;
kMin = kMinTab[idx];
}
short recCoeff[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF];
if( isChroma )
{
memcpy( recCoeff, coeff, sizeof(short) * MAX_NUM_ALF_CHROMA_COEFF );
}
else
{
memcpy( recCoeff, coeff, sizeof(short) * numFilters * MAX_NUM_ALF_LUMA_COEFF );
if( alfSliceParam.alfLumaCoeffDeltaPredictionFlag )
{
for( int i = 1; i < numFilters; i++ )
{
for( int j = 0; j < alfShape.numCoeff - 1; j++ )
{
recCoeff[i * MAX_NUM_ALF_LUMA_COEFF + j] += recCoeff[( i - 1 ) * MAX_NUM_ALF_LUMA_COEFF + j];
}
}
}
}
// Filter coefficients
for( int ind = 0; ind < numFilters; ++ind )
{
if( !isChroma && !alfSliceParam.alfLumaCoeffFlag[ind] && alfSliceParam.alfLumaCoeffDeltaFlag )
{
std::fill_n( clipp + ind * MAX_NUM_ALF_LUMA_COEFF, alfShape.numCoeff, 0 );
continue;
}
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
if( recCoeff[ind * MAX_NUM_ALF_LUMA_COEFF + i] )
clipp[ind * MAX_NUM_ALF_LUMA_COEFF + i] = alfGolombDecode( kMinTab[alfShape.golombIdx[i]], false );
else
clipp[ind * MAX_NUM_ALF_LUMA_COEFF + i] = 0;
}
}
}
else
{
for( int ind = 0; ind < numFilters; ++ind )
{
std::fill_n( clipp + ind * MAX_NUM_ALF_LUMA_COEFF, alfShape.numCoeff, 0 );
}
}
#endif
}
int HLSyntaxReader::truncatedUnaryEqProb( const int maxSymbol )
......
......@@ -177,7 +177,11 @@ public:
private:
int truncatedUnaryEqProb( const int maxSymbol );
void xReadTruncBinCode( uint32_t& ruiSymbol, const int uiMaxSymbol );
#if JVET_N0242_NON_LINEAR_ALF
int alfGolombDecode( const int k, const bool signed_val=true );
#else
int alfGolombDecode( const int k );
#endif
protected:
bool xMoreRbspData();
......
......@@ -240,6 +240,9 @@ protected:
bool m_HashME;
bool m_AffineAmvrEncOpt;
bool m_DMVR;
#if JVET_N0449_MMVD_SIMP
int m_MmvdDisNum;
#endif
unsigned m_IBCMode;
unsigned m_IBCLocalSearchRangeX;
unsigned m_IBCLocalSearchRangeY;
......@@ -263,6 +266,10 @@ protected:
bool m_useAMaxBT;
bool m_e0023FastEnc;
bool m_contentBasedFastQtbt;
#if JVET_N0242_NON_LINEAR_ALF
bool m_useNonLinearAlfLuma;
bool m_useNonLinearAlfChroma;
#endif
#if MAX_TB_SIZE_SIGNALLING
uint32_t m_log2MaxTbSize;
......@@ -762,7 +769,10 @@ public:
bool getUseAffineAmvrEncOpt () const { return m_AffineAmvrEncOpt; }
void setDMVR ( bool b ) { m_DMVR = b; }
bool getDMVR () const { return m_DMVR; }
#if JVET_N0449_MMVD_SIMP
void setMmvdDisNum ( int b ) { m_MmvdDisNum = b; }
int getMmvdDisNum () const { return m_MmvdDisNum; }
#endif
void setIBCMode (unsigned n) { m_IBCMode = n; }
unsigned getIBCMode () const { return m_IBCMode; }
void setIBCLocalSearchRangeX (unsigned n) { m_IBCLocalSearchRangeX = n; }
......@@ -816,6 +826,12 @@ public:
bool getUseE0023FastEnc () const { return m_e0023FastEnc; }