Commit 92962217 authored by Shunsuke Iwamura's avatar Shunsuke Iwamura

L0414 (Luma adaptive deblocking filter QP offset) with explit signalling of...

L0414 (Luma adaptive deblocking filter QP offset) with explit signalling of number of intervals, thresholds, and QPoffsets
parent 0311bd34
......@@ -246,6 +246,18 @@ void EncApp::xInitLibCfg()
m_cEncLib.setUseGBi ( m_GBi );
m_cEncLib.setUseGBiFast ( m_GBiFast );
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
m_cEncLib.setUseLadf ( m_LadfEnabed );
if ( m_LadfEnabed )
{
m_cEncLib.setLadfNumIntervals ( m_LadfNumIntervals);
for ( int k = 0; k < m_LadfNumIntervals; k++ )
{
m_cEncLib.setLadfQpOffset( m_LadfQpOffset[k], k );
m_cEncLib.setLadfIntervalLowerBound(m_LadfIntervalLowerBound[k], k);
}
}
#endif
// ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here
m_cEncLib.setMaxCUWidth ( m_QTBT ? m_uiCTUSize : m_uiMaxCUWidth );
......
......@@ -699,6 +699,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
SMultiValueInput<bool> cfg_timeCodeSeiHoursFlag (0, 1, 0, MAX_TIMECODE_SEI_SETS);
SMultiValueInput<int> cfg_timeCodeSeiTimeOffsetLength (0, 31, 0, MAX_TIMECODE_SEI_SETS);
SMultiValueInput<int> cfg_timeCodeSeiTimeOffsetValue (std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), 0, MAX_TIMECODE_SEI_SETS);
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
const int defaultLadfQpOffset[3] = { 1, 0, 1 };
const int defaultLadfIntervalLowerBound[2] = { 350, 833 };
SMultiValueInput<int> cfg_LadfQpOffset ( -MAX_QP, MAX_QP, 2, MAX_LADF_INTERVALS, defaultLadfQpOffset, 3 );
SMultiValueInput<int> cfg_LadfIntervalLowerBound ( 0, std::numeric_limits<int>::max(), 1, MAX_LADF_INTERVALS - 1, defaultLadfIntervalLowerBound, 2 );
#endif
int warnUnknowParameter = 0;
#if ENABLE_TRACING
......@@ -850,6 +856,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
#if JVET_L0646_GBI
("GBi", m_GBi, false, "Enable Generalized Bi-prediction(GBi)")
("GBiFast", m_GBiFast, false, "Fast methods for Generalized Bi-prediction(GBi)\n")
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
("LADF", m_LadfEnabed, false, "Luma adaptive deblocking filter QP Offset(L0414)")
("LadfNumIntervals", m_LadfNumIntervals, 3, "LADF number of intervals (2-5, inclusive)")
("LadfQpOffset", cfg_LadfQpOffset, cfg_LadfQpOffset, "LADF QP offset")
("LadfIntervalLowerBound", cfg_LadfIntervalLowerBound, cfg_LadfIntervalLowerBound, "LADF lower bound for 2nd lowest interval")
#endif
// ADD_NEW_TOOL : (encoder app) add parsing parameters here
......@@ -1686,6 +1698,19 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
}
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
if ( m_LadfEnabed )
{
CHECK( m_LadfNumIntervals != cfg_LadfQpOffset.values.size(), "size of LadfQpOffset must be equal to LadfNumIntervals");
CHECK( m_LadfNumIntervals - 1 != cfg_LadfIntervalLowerBound.values.size(), "size of LadfIntervalLowerBound must be equal to LadfNumIntervals - 1");
m_LadfQpOffset = cfg_LadfQpOffset.values;
for (int k = 1; k < m_LadfNumIntervals; k++)
{
m_LadfIntervalLowerBound[k] = cfg_LadfIntervalLowerBound.values[k - 1];
}
}
#endif
// reading external dQP description from file
if ( !m_dQPFileName.empty() )
{
......@@ -3130,6 +3155,9 @@ void EncAppCfg::xPrintParameter()
#if JVET_L0646_GBI
msg( VERBOSE, "GBi:%d ", m_GBi );
msg( VERBOSE, "GBiFast:%d ", m_GBiFast );
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
msg( VERBOSE, "LADF:%d ", m_LadfEnabed );
#endif
}
// ADD_NEW_TOOL (add some output indicating the usage of tools)
......
......@@ -227,6 +227,12 @@ protected:
#if JVET_L0646_GBI
bool m_GBi;
bool m_GBiFast;
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
bool m_LadfEnabed;
int m_LadfNumIntervals;
std::vector<int> m_LadfQpOffset;
int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS];
#endif
// ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here
......
......@@ -364,6 +364,10 @@ static const unsigned C806_ALF_TEMPPRED_NUM = 6;
static const int NTAPS_LUMA = 8; ///< Number of taps for luma
static const int NTAPS_CHROMA = 4; ///< Number of taps for chroma
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
static const int MAX_LADF_INTERVALS = 5; /// max number of luma adaptive deblocking filter qp offset intervals
#endif
// ====================================================================================================================
// Macro functions
// ====================================================================================================================
......
......@@ -560,6 +560,36 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
return ( ( abs( mvQ0.getHor() - mvP0.getHor() ) >= nThreshold ) || ( abs( mvQ0.getVer() - mvP0.getVer() ) >= nThreshold ) ) ? 1 : 0;
}
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
void LoopFilter::deriveLADFShift( const Pel* piSrc, const int iStride, int& iShift, const DeblockEdgeDir edgeDir, const SPS sps )
{
uint32_t uiLevel = 0;
iShift = sps.getSpsNext().getLadfQpOffset(0);
if (edgeDir == EDGE_VER)
{
uiLevel = (piSrc[0] + piSrc[3*iStride] + piSrc[-1] + piSrc[3*iStride - 1]) >> 2;
}
else // (edgeDir == EDGE_HOR)
{
uiLevel = (piSrc[0] + piSrc[3] + piSrc[-iStride] + piSrc[-iStride + 3]) >> 2;
}
for ( int k = 1; k < sps.getSpsNext().getLadfNumIntervals(); k++ )
{
const int th = sps.getSpsNext().getLadfIntervalLowerBound( k );
if ( uiLevel > th )
{
iShift = sps.getSpsNext().getLadfQpOffset( k );
}
else
{
break;
}
}
}
#endif
void LoopFilter::xEdgeFilterLuma(const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge)
{
const CompArea& lumaArea = cu.block(COMPONENT_Y);
......@@ -645,6 +675,14 @@ void LoopFilter::xEdgeFilterLuma(const CodingUnit& cu, const DeblockEdgeDir edge
iQP = (cuP.qp + cuQ.qp + 1) >> 1;
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
if ( sps.getSpsNext().getLadfEnabled() )
{
int iShift = 0;
deriveLADFShift( piTmpSrc + iSrcStep * (iIdx*pelsInPart), iStride, iShift, edgeDir, sps );
iQP += iShift;
}
#endif
const int iIndexTC = Clip3(0, MAX_QP + DEFAULT_INTRA_TC_OFFSET, int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs - 1) + (tcOffsetDiv2 << 1)));
const int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
......
......@@ -62,7 +62,7 @@ private:
private:
/// CU-level deblocking function
void xDeblockCU ( CodingUnit& cu, const DeblockEdgeDir edgeDir );
// set / get functions
void xSetLoopfilterParam ( const CodingUnit& cu );
......@@ -79,6 +79,9 @@ private:
void xEdgeFilterLuma ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge );
void xEdgeFilterChroma ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const int iEdge );
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
void deriveLADFShift( const Pel* piSrc, const int iStride, int& iShift, const DeblockEdgeDir edgeDir, const SPS sps );
#endif
inline void xPelFilterLuma ( Pel* piSrc, const int iOffset, const int tc, const bool sw, const bool bPartPNoFilter, const bool bPartQNoFilter, const int iThrCut, const bool bFilterSecondP, const bool bFilterSecondQ, const ClpRng& clpRng ) const;
inline void xPelFilterChroma ( Pel* piSrc, const int iOffset, const int tc, const bool bPartPNoFilter, const bool bPartQNoFilter, const ClpRng& clpRng ) const;
......
......@@ -1663,6 +1663,12 @@ SPSNext::SPSNext( SPS& sps )
#if ENABLE_WPP_PARALLELISM
, m_NextDQP ( false )
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
, m_LadfEnabled ( false )
, m_LadfNumIntervals ( 0 )
, m_LadfQpOffset { 0 }
, m_LadfIntervalLowerBound { 0 }
#endif
// default values for additional parameters
, m_CTUSize ( 0 )
......
......@@ -817,6 +817,12 @@ private:
#if ENABLE_WPP_PARALLELISM
bool m_NextDQP;
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
bool m_LadfEnabled;
int m_LadfNumIntervals;
int m_LadfQpOffset[MAX_LADF_INTERVALS];
int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS];
#endif
public:
const static int NumReservedFlags = 32 - 27; /* current number of tool enabling flags */
......@@ -888,6 +894,16 @@ public:
#if JVET_L0646_GBI
void setUseGBi ( bool b ) { m_GBi = b; }
bool getUseGBi () const { return m_GBi; }
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
void setLadfEnabled ( bool b ) { m_LadfEnabled = b; }
bool getLadfEnabled () const { return m_LadfEnabled; }
void setLadfNumIntervals ( int i ) { m_LadfNumIntervals = i; }
int getLadfNumIntervals () const { return m_LadfNumIntervals; }
void setLadfQpOffset ( int value, int idx ) { m_LadfQpOffset[ idx ] = value; }
int getLadfQpOffset ( int idx ) const { return m_LadfQpOffset[ idx ]; }
void setLadfIntervalLowerBound( int value, int idx ) { m_LadfIntervalLowerBound[ idx ] = value; }
int getLadfIntervalLowerBound( int idx ) const { return m_LadfIntervalLowerBound[ idx ]; }
#endif
//===== additional parameters =====
// qtbt
......
......@@ -285,6 +285,7 @@
#define QP_SWITCHING_FOR_PARALLEL 1 ///< Replace floating point QP with a source-file frame number. After switching POC, increase base QP instead of frame level QP.
#define LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET 1 /// JVET-L0414 (CE11.2.2) with explicit signalling of num interval, threshold and qpOffset
// ====================================================================================================================
// Derived macros
// ====================================================================================================================
......
......@@ -910,6 +910,21 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM )
}
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
READ_FLAG( symbol, "sps_ladf_enabled_flag" ); spsNext.setLadfEnabled( symbol != 0 );
if ( spsNext.getLadfEnabled() )
{
int signedSymbol = 0;
READ_CODE( 2, symbol, "sps_num_ladf_intervals_minus2"); spsNext.setLadfNumIntervals( symbol + 2 );
READ_SVLC(signedSymbol, "sps_ladf_lowest_interval_qp_offset" ); spsNext.setLadfQpOffset( signedSymbol, 0 );
for ( int k = 1; k < spsNext.getLadfNumIntervals(); k++ )
{
READ_SVLC(signedSymbol, "sps_ladf_qp_offset" ); spsNext.setLadfQpOffset( signedSymbol, k );
READ_UVLC( symbol, "sps_ladf_delta_threshold_minus1");
spsNext.setLadfIntervalLowerBound(symbol + spsNext.getLadfIntervalLowerBound(k - 1) + 1, k);
}
}
#endif
// ADD_NEW_TOOL : (sps extension parser) read tool enabling flags and associated parameters here
}
......
......@@ -210,6 +210,12 @@ protected:
#if JVET_L0646_GBI
bool m_GBi;
bool m_GBiFast;
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
bool m_LadfEnabled;
int m_LadfNumIntervals;
int m_LadfQpOffset[MAX_LADF_INTERVALS];
int m_LadfIntervalLowerBound[MAX_LADF_INTERVALS];
#endif
// ADD_NEW_TOOL : (encoder lib) add tool enabling flags and associated parameters here
......@@ -657,6 +663,18 @@ public:
bool getUseGBi () const { return m_GBi; }
void setUseGBiFast ( uint32_t b ) { m_GBiFast = b; }
bool getUseGBiFast () const { return m_GBiFast; }
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
void setUseLadf ( bool b ) { m_LadfEnabled = b; }
bool getUseLadf () const { return m_LadfEnabled; }
void setLadfNumIntervals ( int i ) { m_LadfNumIntervals = i; }
int getLadfNumIntervals () const { return m_LadfNumIntervals; }
void setLadfQpOffset ( int value, int idx ){ m_LadfQpOffset[ idx ] = value; }
int getLadfQpOffset ( int idx ) const { return m_LadfQpOffset[ idx ]; }
void setLadfIntervalLowerBound ( int value, int idx ){ m_LadfIntervalLowerBound[ idx ] = value; }
int getLadfIntervalLowerBound ( int idx ) const { return m_LadfIntervalLowerBound[ idx ]; }
#endif
// ADD_NEW_TOOL : (encoder lib) add access functions here
......
......@@ -858,6 +858,20 @@ void EncLib::xInitSPS(SPS &sps)
#if JVET_L0646_GBI
sps.getSpsNext().setUseGBi ( m_GBi );
#endif
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
sps.getSpsNext().setLadfEnabled ( m_LadfEnabled );
if ( m_LadfEnabled )
{
sps.getSpsNext().setLadfNumIntervals ( m_LadfNumIntervals );
for ( int k = 0; k < m_LadfNumIntervals; k++ )
{
sps.getSpsNext().setLadfQpOffset( m_LadfQpOffset[k], k );
sps.getSpsNext().setLadfIntervalLowerBound( m_LadfIntervalLowerBound[k], k );
}
CHECK( m_LadfIntervalLowerBound[0] != 0, "abnormal value set to LadfIntervalLowerBound[0]" );
}
#endif
// ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here
int minCUSize = ( /*sps.getSpsNext().getUseQTBT() ? 1 << MIN_CU_LOG2 :*/ sps.getMaxCUWidth() >> sps.getLog2DiffMaxMinCodingBlockSize() );
......
......@@ -619,6 +619,19 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM )
{
WRITE_UVLC( spsNext.getMTTMode() - 1, "mtt_mode_minus1" );
}
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
WRITE_FLAG( spsNext.getLadfEnabled() ? 1 : 0, "sps_ladf_enabled_flag" );
if ( spsNext.getLadfEnabled() )
{
WRITE_CODE( spsNext.getLadfNumIntervals() - 2, 2, "sps_num_ladf_intervals_minus2" );
WRITE_SVLC( spsNext.getLadfQpOffset( 0 ), "sps_ladf_lowest_interval_qp_offset");
for ( int k = 1; k< spsNext.getLadfNumIntervals(); k++ )
{
WRITE_SVLC( spsNext.getLadfQpOffset( k ), "sps_ladf_qp_offset" );
WRITE_UVLC( spsNext.getLadfIntervalLowerBound( k ) - spsNext.getLadfIntervalLowerBound( k - 1 ) - 1, "sps_ladf_delta_threshold_minus1" );
}
}
#endif
// ADD_NEW_TOOL : (sps extension writer) write tool enabling flags and associated parameters here
}
......
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