Commit eddf597b authored by Nan Hu's avatar Nan Hu Committed by Xiang Li

JVET-O0216/O0302/O0648: using 3rd order exponential-Golomb codes for ALF coeff

parent aa1b4837
......@@ -92,10 +92,12 @@ public:
void resetPCMBlkClassInfo(CodingStructure & cs, AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk);
template<AlfFilterType filtType>
static void filterBlk(AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blkDst, const Area& blk, const ComponentID compId, short* filterSet, short* fClipSet, const ClpRng& clpRng, CodingStructure& cs, int vbCTUHeight, int vbPos);
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
inline static int getMaxGolombIdx( AlfFilterType filterType )
{
return filterType == ALF_FILTER_5 ? 2 : 3;
}
#endif
void(*m_deriveClassificationBlk)(AlfClassifier** classifier, int** laplacian[NUM_DIRECTIONS], const CPelBuf& srcLuma, const Area& blkDst, const Area& blk, const int shift, int vbCTUHeight, int vbPos);
......
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_O0216_ALF_COEFF_EG3 1 // JVET-O0216/O0302/O0648: using EG3 for ALF coefficients coding
#define JVET_O0247_ALF_CTB_CODING_REDUNDANCY_REMOVAL 1 // JVET-O0247: not signal APS index when number APS is 2
#define JVET_O0637_CHROMA_GRADIENT_LINE_SELECTION 1 // Choose line0 and line3 for gradient computation when chroma is same size as luma
......@@ -1373,12 +1375,13 @@ struct AlfFilterShape
2, 2, 2,
2, 2, 1, 1
};
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
golombIdx = {
0,
0, 1, 0,
0, 1, 2, 2
};
#endif
filterType = ALF_FILTER_5;
}
......@@ -1400,13 +1403,14 @@ struct AlfFilterShape
2, 2, 2, 2, 2,
2, 2, 2, 1, 1
};
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
golombIdx = {
0,
0, 1, 0,
0, 1, 2, 1, 0,
0, 1, 2, 3, 3
};
#endif
filterType = ALF_FILTER_7;
}
......@@ -1423,7 +1427,9 @@ struct AlfFilterShape
int filterSize;
std::vector<int> pattern;
std::vector<int> weights;
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
std::vector<int> golombIdx;
#endif
};
struct AlfSliceParam
......
......@@ -2599,15 +2599,20 @@ void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChrom
// derive maxGolombIdx
AlfFilterShape alfShape( isChroma ? 5 : 7 );
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
const int maxGolombIdx = AdaptiveLoopFilter::getMaxGolombIdx( alfShape.filterType );
#endif
#if !JVET_O0216_ALF_COEFF_EG3
READ_UVLC( code, isChroma ? "alf_chroma_min_eg_order_minus1" : "alf_luma_min_eg_order_minus1" );
#endif
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
int kMin = code + 1;
static int kMinTab[MAX_NUM_ALF_COEFF];
#endif
const int numFilters = isChroma ? 1 : alfSliceParam.numLumaFilters;
short* coeff = isChroma ? alfSliceParam.chromaCoeff : alfSliceParam.lumaCoeff;
short* clipp = isChroma ? alfSliceParam.chromaClipp : alfSliceParam.lumaClipp;
#if !JVET_O0216_ALF_COEFF_EG3
for( int idx = 0; idx < maxGolombIdx; idx++ )
{
READ_FLAG( code, isChroma ? "alf_chroma_eg_order_increase_flag" : "alf_luma_eg_order_increase_flag" );
......@@ -2615,7 +2620,7 @@ void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChrom
kMinTab[idx] = kMin + code;
kMin = kMinTab[idx];
}
#endif
if( !isChroma )
{
if( alfSliceParam.alfLumaCoeffDeltaFlag )
......@@ -2639,7 +2644,11 @@ void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChrom
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
coeff[ind * MAX_NUM_ALF_LUMA_COEFF + i] = alfGolombDecode( 3 );
#else
coeff[ind * MAX_NUM_ALF_LUMA_COEFF + i] = alfGolombDecode( kMinTab[alfShape.golombIdx[i]] );
#endif
}
}
......
......@@ -985,12 +985,13 @@ int EncAdaptiveLoopFilter::getCoeffRate( AlfSliceParam& alfSliceParam, bool isCh
{
int iBits = 0;
assert( isChroma );
AlfFilterShape alfShape(5);
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
memset( m_bitsCoeffScan, 0, sizeof( m_bitsCoeffScan ) );
AlfFilterShape alfShape( 5 );
const int maxGolombIdx = AdaptiveLoopFilter::getMaxGolombIdx( alfShape.filterType );
const int numFilters = 1;
#endif
#if !JVET_O0216_ALF_COEFF_EG3
// vlc for all
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
......@@ -1015,11 +1016,15 @@ int EncAdaptiveLoopFilter::getCoeffRate( AlfSliceParam& alfSliceParam, bool isCh
iBits += golombOrderIncreaseFlag; //golomb_order_increase_flag
kMin = m_kMinTab[idx];
}
#endif
// Filter coefficients
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
iBits += lengthGolomb( alfSliceParam.chromaCoeff[i], 3 ); // alf_coeff_chroma[i], alf_coeff_luma_delta[i][j]
#else
iBits += lengthGolomb( alfSliceParam.chromaCoeff[i], m_kMinTab[alfShape.golombIdx[i]] ); // alf_coeff_chroma[i], alf_coeff_luma_delta[i][j]
#endif
}
if( m_alfSliceParamTemp.nonLinearFlag[isChroma] )
......@@ -1047,12 +1052,19 @@ int EncAdaptiveLoopFilter::getCoeffRate( AlfSliceParam& alfSliceParam, bool isCh
m_bitsCoeffScan[alfShape.golombIdx[i]][k] += lengthGolomb( coeffVal, k, false );
}
}
#if JVET_O0216_ALF_COEFF_EG3
int kMin = getGolombKMin(alfShape, numFilters, m_kMinTab, m_bitsCoeffScan);
#else
kMin = getGolombKMin( alfShape, numFilters, m_kMinTab, m_bitsCoeffScan );
#endif
// Golomb parameters
iBits += lengthUvlc( kMin - 1 ); // "min_golomb_order"
#if JVET_O0216_ALF_COEFF_EG3
int golombOrderIncreaseFlag = 0;
#else
golombOrderIncreaseFlag = 0;
#endif
for( int idx = 0; idx < maxGolombIdx; idx++ )
{
......@@ -1322,9 +1334,13 @@ int EncAdaptiveLoopFilter::getTBlength( int uiSymbol, const int uiMaxSymbol )
int EncAdaptiveLoopFilter::getCostFilterCoeffForce0( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters, bool* codedVarBins )
{
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
const int maxGolombIdx = getMaxGolombIdx( alfShape.filterType );
memset( m_bitsCoeffScan, 0, sizeof( m_bitsCoeffScan ) );
#endif
#if JVET_O0216_ALF_COEFF_EG3
int len = numFilters; //filter_coefficient_flag[i]
#else
for( int ind = 0; ind < numFilters; ++ind )
{
if( !codedVarBins[ind] )
......@@ -1347,7 +1363,7 @@ int EncAdaptiveLoopFilter::getCostFilterCoeffForce0( AlfFilterShape& alfShape, i
int len = kMin //min_golomb_order
+ maxGolombIdx //golomb_order_increase_flag
+ numFilters; //filter_coefficient_flag[i]
#endif
// Filter coefficients
for( int ind = 0; ind < numFilters; ++ind )
{
......@@ -1355,7 +1371,11 @@ int EncAdaptiveLoopFilter::getCostFilterCoeffForce0( AlfFilterShape& alfShape, i
{
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
len += lengthGolomb( abs( pDiffQFilterCoeffIntPP[ind][i] ), 3 ); // alf_coeff_luma_delta[i][j]
#else
len += lengthGolomb( abs( pDiffQFilterCoeffIntPP[ind][i] ), m_kMinTab[alfShape.golombIdx[i]] ); // alf_coeff_luma_delta[i][j]
#endif
}
}
}
......@@ -1394,8 +1414,11 @@ int EncAdaptiveLoopFilter::getCostFilterCoeffForce0( AlfFilterShape& alfShape, i
}
}
}
#if JVET_O0216_ALF_COEFF_EG3
int kMin = getGolombKMin(alfShape, numFilters, m_kMinTab, m_bitsCoeffScan);
#else
kMin = getGolombKMin( alfShape, numFilters, m_kMinTab, m_bitsCoeffScan );
#endif
// Coding parameters
len += kMin //min_golomb_order
......@@ -1459,8 +1482,10 @@ int EncAdaptiveLoopFilter::deriveFilterCoefficientsPredictionMode( AlfFilterShap
int EncAdaptiveLoopFilter::getCostFilterCoeff( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters )
{
#if JVET_O0216_ALF_COEFF_EG3
return lengthFilterCoeffs( alfShape, numFilters, pDiffQFilterCoeffIntPP ); // alf_coeff_luma_delta[i][j];
#else
const int maxGolombIdx = getMaxGolombIdx( alfShape.filterType );
memset( m_bitsCoeffScan, 0, sizeof( m_bitsCoeffScan ) );
for( int ind = 0; ind < numFilters; ++ind )
......@@ -1485,6 +1510,7 @@ int EncAdaptiveLoopFilter::getCostFilterCoeff( AlfFilterShape& alfShape, int **p
len += lengthFilterCoeffs( alfShape, numFilters, pDiffQFilterCoeffIntPP, m_kMinTab ); // alf_coeff_luma_delta[i][j]
return len;
#endif
}
int EncAdaptiveLoopFilter::getCostFilterClipp( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters )
......@@ -1523,7 +1549,11 @@ int EncAdaptiveLoopFilter::getCostFilterClipp( AlfFilterShape& alfShape, int **p
#endif
}
#if JVET_O0216_ALF_COEFF_EG3
int EncAdaptiveLoopFilter::lengthFilterCoeffs( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff )
#else
int EncAdaptiveLoopFilter::lengthFilterCoeffs( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff, int* kMinTab )
#endif
{
int bitCnt = 0;
......@@ -1531,7 +1561,11 @@ int EncAdaptiveLoopFilter::lengthFilterCoeffs( AlfFilterShape& alfShape, const i
{
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
bitCnt += lengthGolomb( abs( FilterCoeff[ind][i] ), 3 );
#else
bitCnt += lengthGolomb( abs( FilterCoeff[ind][i] ), kMinTab[alfShape.golombIdx[i]] );
#endif
}
}
return bitCnt;
......@@ -1558,8 +1592,10 @@ int EncAdaptiveLoopFilter::lengthFilterClipps( AlfFilterShape& alfShape, const i
double EncAdaptiveLoopFilter::getDistForce0( AlfFilterShape& alfShape, const int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2], bool* codedVarBins )
{
static int bitsVarBin[MAX_NUM_ALF_CLASSES];
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
memset( m_bitsCoeffScan, 0, sizeof( m_bitsCoeffScan ) );
#endif
#if !JVET_O0216_ALF_COEFF_EG3
for( int ind = 0; ind < numFilters; ++ind )
{
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
......@@ -1573,13 +1609,18 @@ double EncAdaptiveLoopFilter::getDistForce0( AlfFilterShape& alfShape, const int
}
getGolombKMin( alfShape, numFilters, m_kMinTab, m_bitsCoeffScan );
#endif
for( int ind = 0; ind < numFilters; ++ind )
{
bitsVarBin[ind] = 0;
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
bitsVarBin[ind] += lengthGolomb( abs( m_filterCoeffSet[ind][i] ), 3 );
#else
bitsVarBin[ind] += lengthGolomb( abs( m_filterCoeffSet[ind][i] ), m_kMinTab[alfShape.golombIdx[i]] );
#endif
}
}
......@@ -1633,7 +1674,7 @@ double EncAdaptiveLoopFilter::getDistForce0( AlfFilterShape& alfShape, const int
return distForce0;
}
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
int EncAdaptiveLoopFilter::getGolombKMin( AlfFilterShape& alfShape, const int numFilters, int kMinTab[MAX_NUM_ALF_LUMA_COEFF], int bitsCoeffScan[m_MAX_SCAN_VAL][m_MAX_EXP_GOLOMB] )
{
int kStart;
......@@ -1683,7 +1724,7 @@ int EncAdaptiveLoopFilter::getGolombKMin( AlfFilterShape& alfShape, const int nu
return minKStart;
}
#endif
double EncAdaptiveLoopFilter::getDistCoeffForce0( bool* codedVarBins, double errorForce0CoeffTab[MAX_NUM_ALF_CLASSES][2], int* bitsVarBin, const int numFilters )
{
double distForce0 = 0;
......
......@@ -219,8 +219,10 @@ private:
class EncAdaptiveLoopFilter : public AdaptiveLoopFilter
{
public:
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
static constexpr int m_MAX_SCAN_VAL = 11;
static constexpr int m_MAX_EXP_GOLOMB = 16;
#endif
int m_alfWSSD;
inline void setAlfWSSD(int alfWSSD) { m_alfWSSD = alfWSSD; }
static std::vector<double> m_lumaLevelToWeightPLUT;
......@@ -245,8 +247,10 @@ private:
int** m_filterCoeffSet;
int** m_filterClippSet;
int** m_diffFilterCoeff;
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
int m_kMinTab[MAX_NUM_ALF_LUMA_COEFF];
int m_bitsCoeffScan[m_MAX_SCAN_VAL][m_MAX_EXP_GOLOMB];
#endif
short m_filterIndices[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES];
unsigned m_bitsNewFilter[MAX_NUM_CHANNEL_TYPE];
int m_apsIdStart;
......@@ -278,7 +282,9 @@ public:
void create( const EncCfg* encCfg, const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE] );
void destroy();
static int lengthGolomb( int coeffVal, int k, bool signed_coeff=true );
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
static int getGolombKMin( AlfFilterShape& alfShape, const int numFilters, int kMinTab[MAX_NUM_ALF_LUMA_COEFF], int bitsCoeffScan[m_MAX_SCAN_VAL][m_MAX_EXP_GOLOMB] );
#endif
private:
void alfEncoder( CodingStructure& cs, AlfSliceParam& alfSliceParam, const PelUnitBuf& orgUnitBuf, const PelUnitBuf& recExtBuf, const PelUnitBuf& recBuf, const ChannelType channel
......@@ -322,7 +328,11 @@ private:
int getCostFilterCoeffForce0( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters, bool* codedVarBins );
int getCostFilterCoeff( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters );
int getCostFilterClipp( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters );
#if JVET_O0216_ALF_COEFF_EG3
int lengthFilterCoeffs( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff );
#else
int lengthFilterCoeffs( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff, int* kMinTab );
#endif
#if !JVET_O0064_SIMP_ALF_CLIP_CODING
int lengthFilterClipps( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff, int* kMinTab );
#endif
......
......@@ -1770,16 +1770,18 @@ void HLSWriter::alfFilter( const AlfSliceParam& alfSliceParam, const bool isChro
}
#endif
}
AlfFilterShape alfShape(isChroma ? 5 : 7);
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
static int bitsCoeffScan[EncAdaptiveLoopFilter::m_MAX_SCAN_VAL][EncAdaptiveLoopFilter::m_MAX_EXP_GOLOMB];
memset( bitsCoeffScan, 0, sizeof( bitsCoeffScan ) );
AlfFilterShape alfShape( isChroma ? 5 : 7 );
const int maxGolombIdx = AdaptiveLoopFilter::getMaxGolombIdx( alfShape.filterType );
#endif
const short* coeff = isChroma ? alfSliceParam.chromaCoeff : alfSliceParam.lumaCoeff;
const short* clipp = isChroma ? alfSliceParam.chromaClipp : alfSliceParam.lumaClipp;
const int numFilters = isChroma ? 1 : alfSliceParam.numLumaFilters;
// vlc for all
#if !JVET_O0216_ALF_COEFF_EG3
for( int ind = 0; ind < numFilters; ++ind )
{
if( isChroma || !alfSliceParam.alfLumaCoeffDeltaFlag || alfSliceParam.alfLumaCoeffFlag[ind] )
......@@ -1795,10 +1797,12 @@ void HLSWriter::alfFilter( const AlfSliceParam& alfSliceParam, const bool isChro
}
}
}
#endif
#if !JVET_O0216_ALF_COEFF_EG3 || !JVET_O0064_SIMP_ALF_CLIP_CODING
static int kMinTab[MAX_NUM_ALF_COEFF];
#endif
#if !JVET_O0216_ALF_COEFF_EG3
int kMin = EncAdaptiveLoopFilter::getGolombKMin( alfShape, numFilters, kMinTab, bitsCoeffScan );
// Golomb parameters
WRITE_UVLC( kMin - 1, isChroma ? "alf_chroma_min_eg_order_minus1" : "alf_luma_min_eg_order_minus1" );
......@@ -1809,7 +1813,7 @@ void HLSWriter::alfFilter( const AlfSliceParam& alfSliceParam, const bool isChro
WRITE_FLAG( golombOrderIncreaseFlag, isChroma ? "alf_chroma_eg_order_increase_flag" : "alf_luma_eg_order_increase_flag" );
kMin = kMinTab[idx];
}
#endif
if( !isChroma )
{
if( alfSliceParam.alfLumaCoeffDeltaFlag )
......@@ -1831,7 +1835,11 @@ void HLSWriter::alfFilter( const AlfSliceParam& alfSliceParam, const bool isChro
for( int i = 0; i < alfShape.numCoeff - 1; i++ )
{
#if JVET_O0216_ALF_COEFF_EG3
alfGolombEncode( coeff[ind* MAX_NUM_ALF_LUMA_COEFF + i], 3 ); // alf_coeff_chroma[i], alf_coeff_luma_delta[i][j]
#else
alfGolombEncode( coeff[ind* MAX_NUM_ALF_LUMA_COEFF + i], kMinTab[alfShape.golombIdx[i]] ); // alf_coeff_chroma[i], alf_coeff_luma_delta[i][j]
#endif
}
}
......@@ -1888,8 +1896,11 @@ void HLSWriter::alfFilter( const AlfSliceParam& alfSliceParam, const bool isChro
}
}
}
#if JVET_O0216_ALF_COEFF_EG3
int kMin = EncAdaptiveLoopFilter::getGolombKMin(alfShape, numFilters, kMinTab, bitsCoeffScan);
#else
kMin = EncAdaptiveLoopFilter::getGolombKMin( alfShape, numFilters, kMinTab, bitsCoeffScan );
#endif
// Golomb parameters
WRITE_UVLC( kMin - 1, "clip_min_golomb_order" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment