Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jvet/VVCSoftware_VTM
  • chenhuanbang/VVCSoftware_VTM
  • ezhizng/VVCSoftware_VTM
  • XZheng/VVCSoftware_VTM
  • YanZhang/VVCSoftware_VTM
  • xiaozhongxu/VVCSoftware_VTM
  • bossen/VVCSoftware_VTM
  • XiangLi/VVCSoftware_VTM
  • s.iwamura/VVCSoftware_VTM
  • yuling.hsiao/VVCSoftware_VTM
  • ccc2384823/VVCSoftware_VTM
  • yuchisu/VVCSoftware_VTM
  • schwarz/VVCSoftware_VTM
  • philippe.hanhart/VVCSoftware_VTM
  • nanh/VVCSoftware_VTM
  • guillaume.laroche/VVCSoftware_VTM
  • Kenneth/VVCSoftware_VTM
  • jonatan/VVCSoftware_VTM
  • Alexey/VVCSoftware_VTM
  • saintspear/VVCSoftware_VTM
  • xinzhao/VVCSoftware_VTM
  • Seungsoo/VVCSoftware_VTM
  • jamesxxiu/VVCSoftware_VTM
  • leolzhao/VVCSoftware_VTM
  • ywchen/VVCSoftware_VTM
  • kevin625/VVCSoftware_VTM
  • Zhang/VVCSoftware_VTM
  • zhangkai/VVCSoftware_VTM
  • YCSun/VVCSoftware_VTM
  • ksuehring/VVCSoftware_VTM
  • AbeKiyo/VVCSoftware_VTM
  • naeri.park/VVCSoftware_VTM
  • ling/VVCSoftware_VTM
  • aikiho/VVCSoftware_VTM
  • JangwonChoi/VVCSoftware_VTM
  • Shelly/VVCSoftware_VTM
  • blaeser/VVCSoftware_VTM
  • crhelmrich/VVCSoftware_VTM
  • keydel/VVCSoftware_VTM
  • adam_wieckowski/VVCSoftware_VTM
  • hashimry/VVCSoftware_VTM
  • yimingli/VVCSoftware_VTM
  • zhipin/VVCSoftware_VTM
  • chernyak/VVCSoftware_VTM
  • jvet-l-ahg-14/VVCSoftware_VTM
  • sauer/VVCSoftware_VTM
  • fbarbier/VVCSoftware_VTM
  • misrak/VVCSoftware_VTM
  • ikai/VVCSoftware_VTM
  • tlu/VVCSoftware_VTM
  • Yasugi/VVCSoftware_VTM
  • peterchuang/VVCSoftware_VTM
  • wanght99/VVCSoftware_VTM
  • yuhan/VVCSoftware_VTM
  • hongbin/VVCSoftware_VTM
  • jiahaoli/VVCSoftware_VTM
  • cfd/VVCSoftware_VTM
  • ruoyangyu/VVCSoftware_VTM
  • chujoh/VVCSoftware_VTM
  • lijingya/VVCSoftware_VTM
  • hinz/VVCSoftware_VTM
  • tamse.anish/VVCSoftware_VTM
  • mcoban/VVCSoftware_VTM
  • george/VVCSoftware_VTM
  • jeeva.raj/VVCSoftware_VTM
  • antoine/VVCSoftware_VTM
  • moonmo.koo/VVCSoftware_VTM
  • deluxan/VVCSoftware_VTM
  • bheng/VVCSoftware_VTM
  • lzz8246/VVCSoftware_VTM
  • delagrangep/VVCSoftware_VTM
  • jiechen/VVCSoftware_VTM
  • hendry197/VVCSoftware_VTM
  • LGE_VCC/VVCSoftware_VTM
  • asegall/VVCSoftware_VTM
  • pbcowan/VVCSoftware_VTM
  • forayr/VVCSoftware_VTM
  • JT/VVCSoftware_VTM
  • Zhou/VVCSoftware_VTM
  • yjpiao/VVCSoftware_VTM
  • fabrice.leleannec/VVCSoftware_VTM
  • tpoirier/VVCSoftware_VTM
  • PoHan.Lin/VVCSoftware_VTM
  • jzxu/VVCSoftware_VTM
  • junghak.nam/VVCSoftware_VTM
  • guichunli/VVCSoftware_VTM
  • xianglinwang/VVCSoftware_VTM
  • chunchic/VVCSoftware_VTM
  • chrisr12/VVCSoftware_VTM
  • ks_kashyap/VVCSoftware_VTM
  • minhua/VVCSoftware_VTM
  • Sheng-Yen.Lin/VVCSoftware_VTM
  • hegilmez/VVCSoftware_VTM
  • swongah/VVCSoftware_VTM
  • merkle/VVCSoftware_VTM
  • sunyucheng/VVCSoftware_VTM
  • kirchhoffer/VVCSoftware_VTM
  • vdrugeon/VVCSoftware_VTM
  • jennylai/VVCSoftware_VTM
  • rickxu/VVCSoftware_VTM
  • seuhong/VVCSoftware_VTM
  • chollmann/VVCSoftware_VTM
  • jvet-n-ce8-public/VVCSoftware_VTM
  • martin.m.pettersson/VVCSoftware_VTM
  • siekmann/VVCSoftware_VTM
  • aramasub/VVCSoftware_VTM
  • zhiyilin/VVCSoftware_VTM
  • EricLin/VVCSoftware_VTM
  • mengwang/VVCSoftware_VTM
  • m.sarwer/VVCSoftware_VTM
  • agnesedong/VVCSoftware_VTM
  • geonjungko/VVCSoftware_VTM
  • bray/VVCSoftware_VTM
  • yhchao/VVCSoftware_VTM
  • Zhu/VVCSoftware_VTM
  • ykato/VVCSoftware_VTM
  • ZhipinDeng/VVCSoftware_VTM
  • jasonjung/VVCSoftware_VTM
  • hanhuang/VVCSoftware_VTM
  • seregin/VVCSoftware_VTM
  • wchen1014/VVCSoftware_VTM
  • Auyeung/VVCSoftware_VTM
  • Morris/VVCSoftware_VTM
  • lphamvan/VVCSoftware_VTM
  • dmehlem/VVCSoftware_VTM
  • shih-ta.hsiang/VVCSoftware_VTM
  • ysanchez/VVCSoftware_VTM
  • baegn74/VVCSoftware_VTM
  • kazui/VVCSoftware_VTM
  • yuwenhe_vvc/VVCSoftware_VTM
  • rickard/VVCSoftware_VTM
  • wangyang.cs/VVCSoftware_VTM
  • xwmeng/VVCSoftware_VTM
  • takeshi.tsukuba/VVCSoftware_VTM
  • yixindu/VVCSoftware_VTM
  • baixiu.wz/VVCSoftware_VTM
  • hm.jang/VVCSoftware_VTM
  • Ted/VVCSoftware_VTM
  • nguyen/VVCSoftware_VTM
  • chaohsiu/VVCSoftware_VTM
  • francoise/VVCSoftware_VTM
  • Yin/VVCSoftware_VTM
  • Morigami/VVCSoftware_VTM
  • sagar.kotecha/VVCSoftware_VTM
  • hwsun/VVCSoftware_VTM
  • pierrick.bouvier/VVCSoftware_VTM
  • XiangMa/VVCSoftware_VTM
  • LouiseLee/VVCSoftware_VTM
  • chenps/VVCSoftware_VTM
  • karls/VVCSoftware_VTM
  • biaowang/VVCSoftware_VTM
  • hangao/VVCSoftware_VTM
  • Jin/VVCSoftware_VTM
  • analci/VVCSoftware_VTM
  • KuiFan/VVCSoftware_VTM
  • hobingzhang/VVCSoftware_VTM
  • audrey.turquin/VVCSoftware_VTM
  • rlliao/VVCSoftware_VTM
  • winken/VVCSoftware_VTM
  • hallapur/VVCSoftware_VTM
  • T.Hashimoto/VVCSoftware_VTM
  • AnandMeher/VVCSoftware_VTM
  • semihese/VVCSoftware_VTM
  • ouedraogo/VVCSoftware_VTM
  • arthurcerveira/VVCSoftware_VTM
  • sunmi.yoo/VVCSoftware_VTM
  • Cynthia/VVCSoftware_VTM
  • yang/VVCSoftware_VTM
  • yuyoon/VVCSoftware_VTM
  • jslee/VVCSoftware_VTM
  • weimin.zeng/VVCSoftware_VTM
  • edrthomas/VVCSoftware_VTM
  • Mitsuru.Katsumata/VVCSoftware_VTM
  • adybrowne/VVCSoftware_VTM
  • jack.enhorn/VVCSoftware_VTM
  • Palanivel/VVCSoftware_VTM
  • olena.chubach/VVCSoftware_VTM
  • juvenalluo/VVCSoftware_VTM
  • yylee/VVCSoftware_VTM
  • bross/VVCSoftware_VTM
  • jvet-ahg-nnvc/VVCSoftware_VTM
  • jacob/VVCSoftware_VTM
  • dmytro.rusanovskyy/VVCSoftware_VTM
  • karamnaser/VVCSoftware_VTM
  • milos.radosavljevic/VVCSoftware_VTM
  • Keming/VVCSoftware_VTM
  • pj/VVCSoftware_VTM
  • cwkuo/VVCSoftware_VTM
  • BD/VVCSoftware_VTM
  • bartnik/VVCSoftware_VTM
  • Fangjun.Pu/VVCSoftware_VTM
  • nikolay.shostak/VVCSoftware_VTM
  • kirill.suverov/VVCSoftware_VTM
  • Xile_Zhou/VVCSoftware_VTM
  • ksuehring/vvc-software-vtm-nnvc
  • guether/VVCSoftware_VTM
  • salmonc/VVCSoftware_VTM
  • eeehey/VVCSoftware_VTM
  • marie-pierre.gallasso/VVCSoftware_VTM
  • jvet-ahg-fgt/VTM
  • liaojq/VVCSoftware_VTM
  • axel.ricard/VVCSoftware_VTM
  • XiangLi/nnvc
  • sw.xie/VVCSoftware_VTM
  • jeeva.raj/vvc-software-vtm-tu-c
  • XiangLi/tu-c
  • msantamaria/nnvc
  • cjj490168650/VVCSoftware_VTM
  • Yun_li/VVCSoftware_VTM
  • Zhengang/vvc-software-vtm
  • lvzhuoyi/vvc-software-vtm-nnvc
  • Kenneth/vvc-software-vtm-nn
  • biatekt/vvc-software-vtm
  • jvet-ahg-gcc/VVCSoftware_VTM
  • JINGYING/VVCSoftware_VTM
  • furban/VVCSoftware_VTM
  • yanning/VVCSoftware_VTM
  • zhuochen/VVCSoftware_VTM
  • Kaifa/VVCSoftware_VTM_AJ0048
  • yueli/VVCSoftware_VTM
  • tokumo/VVCSoftware_VTM
221 results
Show changes
Commits on Source (10)
Showing
with 2607 additions and 4 deletions
......@@ -1962,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}
%%
......
......@@ -314,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] );
......
......@@ -899,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)
......@@ -3194,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 )
......
......@@ -292,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;
......
......@@ -39,6 +39,14 @@
#include "CodingStructure.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()
: m_classifier( nullptr )
......@@ -83,6 +91,9 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
m_ctuEnableFlag[compIdx] = cs.picture->getAlfCtuEnableFlag( compIdx );
}
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 );
PelUnitBuf recYuv = cs.getRecoBuf();
......@@ -106,7 +117,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
deriveClassification( m_classifier, tmpYuv.get( COMPONENT_Y ), blk );
Area blkPCM(xPos, yPos, width, height);
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 );
#endif
}
for( int compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ )
......@@ -119,7 +134,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
{
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 );
#endif
}
}
ctuIdx++;
......@@ -136,6 +155,9 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
int numCoeffMinus1 = numCoeff - 1;
int numFilters = isLuma( channel ) ? alfSliceParam.numLumaFilters : 1;
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 ) )
{
......@@ -150,16 +172,26 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
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;
for( int i = 0; i < numCoeffMinus1; i++ )
{
sum += ( coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + i] << 1 );
}
coeff[filterIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = factor - sum;
#endif
}
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;
}
......@@ -167,6 +199,12 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfSliceParam& alfSliceParam, Channel
{
int filterIdx = alfSliceParam.filterCoeffDeltaIdx[classIdx];
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 )
......@@ -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_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.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
}
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 )
#endif
{
const bool bChroma = isChroma( compId );
if( bChroma )
......@@ -526,6 +593,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
const Pel *pImg0, *pImg1, *pImg2, *pImg3, *pImg4, *pImg5, *pImg6;
short *coef = filterSet;
#if JVET_N0242_NON_LINEAR_ALF
short *clip = fClipSet;
#endif
const int shift = m_NUM_BITS - 1;
......@@ -547,7 +617,12 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
int dstStride2 = dstStride * 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 );
#endif
pImgYPad0 = src + startHeight * srcStride + startWidth;
pImgYPad1 = pImgYPad0 + srcStride;
......@@ -578,6 +653,9 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
continue;
}
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 )
{
......@@ -609,18 +687,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
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] };
#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 )
{
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 )
{
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
{
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
......@@ -628,18 +718,30 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
if( transposeIdx == 1 )
{
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 )
{
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 )
{
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
{
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
}
int sum = 0;
#if JVET_N0242_NON_LINEAR_ALF
const Pel curr = pImg0[+0];
#endif
if( filtType == ALF_FILTER_7 )
{
#if !JVET_N0242_NON_LINEAR_ALF
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] );
#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] );
#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] );
#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] );
#else
sum += filterCoeff[4] * ( clipALF(filterClipp[4], curr, pImg1[+2], pImg2[-2]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[5] * ( pImg1[+1] + pImg2[-1] );
#else
sum += filterCoeff[5] * ( clipALF(filterClipp[5], curr, pImg1[+1], pImg2[-1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[6] * ( pImg1[+0] + pImg2[+0] );
#else
sum += filterCoeff[6] * ( clipALF(filterClipp[6], curr, pImg1[+0], pImg2[+0]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[7] * ( pImg1[-1] + pImg2[+1] );
#else
sum += filterCoeff[7] * ( clipALF(filterClipp[7], curr, pImg1[-1], pImg2[+1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[8] * ( pImg1[-2] + pImg2[+2] );
#else
sum += filterCoeff[8] * ( clipALF(filterClipp[8], curr, pImg1[-2], pImg2[+2]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[9] * ( pImg0[+3] + pImg0[-3] );
#else
sum += filterCoeff[9] * ( clipALF(filterClipp[9], curr, pImg0[+3], pImg0[-3]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[10] * ( pImg0[+2] + pImg0[-2] );
#else
sum += filterCoeff[10] * ( clipALF(filterClipp[10], curr, pImg0[+2], pImg0[-2]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[11] * ( pImg0[+1] + pImg0[-1] );
#else
sum += filterCoeff[11] * ( clipALF(filterClipp[11], curr, pImg0[+1], pImg0[-1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[12] * ( pImg0[+0] );
#endif
}
else
{
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[0] * ( pImg3[+0] + pImg4[+0] );
#else
sum += filterCoeff[0] * ( clipALF(filterClipp[0], curr, pImg3[+0], pImg4[+0]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[1] * ( pImg1[+1] + pImg2[-1] );
#else
sum += filterCoeff[1] * ( clipALF(filterClipp[1], curr, pImg1[+1], pImg2[-1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[2] * ( pImg1[+0] + pImg2[+0] );
#else
sum += filterCoeff[2] * ( clipALF(filterClipp[2], curr, pImg1[+0], pImg2[+0]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[3] * ( pImg1[-1] + pImg2[+1] );
#else
sum += filterCoeff[3] * ( clipALF(filterClipp[3], curr, pImg1[-1], pImg2[+1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[4] * ( pImg0[+2] + pImg0[-2] );
#else
sum += filterCoeff[4] * ( clipALF(filterClipp[4], curr, pImg0[+2], pImg0[-2]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[5] * ( pImg0[+1] + pImg0[-1] );
#else
sum += filterCoeff[5] * ( clipALF(filterClipp[5], curr, pImg0[+1], pImg0[-1]) );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
sum += filterCoeff[6] * ( pImg0[+0] );
#endif
}
sum = ( sum + offset ) >> shift;
#if JVET_N0242_NON_LINEAR_ALF
sum += curr;
#endif
pRec1[jj] = ClipPel( sum, clpRng );
pImg0++;
......
......@@ -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;
......
......@@ -556,5 +556,16 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
pu.cu->GBiIdx = (interDirNeighbours[fPosBaseIdx] == 3) ? GBiIdx[fPosBaseIdx] : GBI_DEFAULT;
#if JVET_N0334_MVCLIPPING
for (int refList = 0; refList < 2; refList++)
{
if (pu.refIdx[refList] >= 0)
{
pu.mv[refList].clipToStorageBitDepth();
}
}
#endif
PU::restrictBiPredMergeCandsOne(pu);
}
......@@ -1767,6 +1767,10 @@ void InterPrediction::xProcessDMVR(PredictionUnit& pu, PelUnitBuf &pcYuvDst, con
subPu.mv[0] = mergeMv[REF_PIC_LIST_0] + pu.mvdL0SubPu[num];
subPu.mv[1] = mergeMv[REF_PIC_LIST_1] - pu.mvdL0SubPu[num];
#if JVET_N0334_MVCLIPPING
subPu.mv[0].clipToStorageBitDepth();
subPu.mv[1].clipToStorageBitDepth();
#endif
m_cYuvRefBuffSubCuDMVRL0 = m_cYuvRefBuffDMVRL0.subBuf(UnitAreaRelative(pu, subPu));
m_cYuvRefBuffSubCuDMVRL1 = m_cYuvRefBuffDMVRL1.subBuf(UnitAreaRelative(pu, subPu));
xFinalPaddedMCForDMVR(subPu, srcPred0, srcPred1, m_cYuvRefBuffSubCuDMVRL0, m_cYuvRefBuffSubCuDMVRL1, bioApplied, mergeMv);
......
......@@ -61,6 +61,10 @@ class Mv
{
private:
static const MvPrecision m_amvrPrecision[3];
#if JVET_N0334_MVCLIPPING
static const int mvClipPeriod = (1 << 18);
static const int halMvClipPeriod = (1 << 17);
#endif
public:
int hor; ///< horizontal component of motion vector
......@@ -241,6 +245,15 @@ public:
hor = Clip3( -(1 << 17), (1 << 17) - 1, hor );
ver = Clip3( -(1 << 17), (1 << 17) - 1, ver );
}
#if JVET_N0334_MVCLIPPING
void mvCliptoStorageBitDepth() // periodic clipping
{
hor = (hor + mvClipPeriod) & (mvClipPeriod - 1);
hor = (hor >= halMvClipPeriod) ? (hor - mvClipPeriod) : hor;
ver = (ver + mvClipPeriod) & (mvClipPeriod - 1);
ver = (ver >= halMvClipPeriod) ? (ver - mvClipPeriod) : ver;
}
#endif
};// END CLASS DEFINITION MV
namespace std
......
......@@ -50,6 +50,14 @@
#include <assert.h>
#include <cassert>
#define JVET_N0334_MVCLIPPING 1 // prevention of MV stroage overflow and alignment with spec of MV/CPMV modular for AMVP mode
#define JVET_N0481_BCW_CONSTRUCTED_AFFINE 1
#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
......@@ -1555,8 +1563,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
......@@ -1572,8 +1589,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;
......@@ -1584,8 +1610,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;
......
......@@ -338,6 +338,12 @@ const uint8_t CodingUnit::checkAllowedSbt() const
{
return 0;
}
#if JVET_N0483_DISABLE_SBT_FOR_TPM
if( triangle )
{
return 0;
}
#endif
uint8_t sbtAllowed = 0;
int cuWidth = lwidth();
......
......@@ -87,6 +87,10 @@ void CS::setRefinedMotionField(CodingStructure &cs)
subPu.mv[1] = pu.mv[1];
subPu.mv[REF_PIC_LIST_0] += pu.mvdL0SubPu[num];
subPu.mv[REF_PIC_LIST_1] -= pu.mvdL0SubPu[num];
#if JVET_N0334_MVCLIPPING
subPu.mv[REF_PIC_LIST_0].clipToStorageBitDepth();
subPu.mv[REF_PIC_LIST_1].clipToStorageBitDepth();
#endif
pu.mvdL0SubPu[num].setZero();
num++;
PU::spanMotionInfo(subPu);
......@@ -3100,8 +3104,11 @@ bool PU::isBipredRestriction(const PredictionUnit &pu)
}
return false;
}
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
void PU::getAffineControlPointCand(const PredictionUnit &pu, MotionInfo mi[4], int8_t neighGbi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgType)
#else
void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgType )
#endif
{
int cuW = pu.Y().width;
int cuH = pu.Y().height;
......@@ -3113,6 +3120,9 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
Mv cMv[2][4];
int refIdx[2] = { -1, -1 };
int dir = 0;
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
int8_t gbiIdx = GBI_DEFAULT;
#endif
EAffineModel curType = (verNum == 2) ? AFFINEMODEL_4PARAM : AFFINEMODEL_6PARAM;
if ( verNum == 2 )
......@@ -3135,6 +3145,16 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
}
}
}
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
if (dir == 3)
{
if (neighGbi[idx0] == neighGbi[idx1])
{
gbiIdx = neighGbi[idx0];
}
}
#endif
}
else if ( verNum == 3 )
{
......@@ -3156,6 +3176,31 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
}
}
}
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
int gbiClass[5] = { -1,0,0,0,1 };
if (dir == 3)
{
if (neighGbi[idx0] == neighGbi[idx1] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx2]])
{
gbiIdx = neighGbi[idx0];
}
else if (neighGbi[idx0] == neighGbi[idx2] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx1]])
{
gbiIdx = neighGbi[idx0];
}
else if (neighGbi[idx1] == neighGbi[idx2] && gbiClass[neighGbi[idx0]] == gbiClass[neighGbi[idx1]])
{
gbiIdx = neighGbi[idx1];
}
else
{
gbiIdx = GBI_DEFAULT;
}
}
#endif
}
if ( dir == 0 )
......@@ -3182,16 +3227,25 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
case 1: // 1 : LT, RT, RB
cMv[l][2].hor = cMv[l][3].hor + cMv[l][0].hor - cMv[l][1].hor;
cMv[l][2].ver = cMv[l][3].ver + cMv[l][0].ver - cMv[l][1].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][2].clipToStorageBitDepth();
#endif
break;
case 2: // 2 : LT, LB, RB
cMv[l][1].hor = cMv[l][3].hor + cMv[l][0].hor - cMv[l][2].hor;
cMv[l][1].ver = cMv[l][3].ver + cMv[l][0].ver - cMv[l][2].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][1].clipToStorageBitDepth();
#endif
break;
case 3: // 3 : RT, LB, RB
cMv[l][0].hor = cMv[l][1].hor + cMv[l][2].hor - cMv[l][3].hor;
cMv[l][0].ver = cMv[l][1].ver + cMv[l][2].ver - cMv[l][3].ver;
#if JVET_N0334_MVCLIPPING
cMv[l][0].clipToStorageBitDepth();
#endif
break;
case 4: // 4 : LT, RT
......@@ -3202,6 +3256,9 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
vy = (cMv[l][0].ver << shift) - ((cMv[l][2].hor - cMv[l][0].hor) << shiftHtoW);
roundAffineMv( vx, vy, shift );
cMv[l][1].set( vx, vy );
#if JVET_N0334_MVCLIPPING
cMv[l][1].clipToStorageBitDepth();
#endif
break;
default:
......@@ -3229,6 +3286,9 @@ void PU::getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4],
}
affMrgType.interDirNeighbours[affMrgType.numValidMergeCand] = dir;
affMrgType.affineType[affMrgType.numValidMergeCand] = curType;
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
affMrgType.GBiIdx[affMrgType.numValidMergeCand] = gbiIdx;
#endif
affMrgType.numValidMergeCand++;
......@@ -3435,7 +3495,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
{
MotionInfo mi[4];
bool isAvailable[4] = { false };
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
int8_t neighGbi[4] = { GBI_DEFAULT };
#endif
// control point: LT B2->B3->A2
const Position posLT[3] = { pu.Y().topLeft().offset( -1, -1 ), pu.Y().topLeft().offset( 0, -1 ), pu.Y().topLeft().offset( -1, 0 ) };
for ( int i = 0; i < 3; i++ )
......@@ -3448,6 +3510,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
{
isAvailable[0] = true;
mi[0] = puNeigh->getMotionInfo( pos );
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
neighGbi[0] = puNeigh->cu->GBiIdx;
#endif
break;
}
}
......@@ -3465,6 +3530,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
{
isAvailable[1] = true;
mi[1] = puNeigh->getMotionInfo( pos );
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
neighGbi[1] = puNeigh->cu->GBiIdx;
#endif
break;
}
}
......@@ -3482,6 +3550,9 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
{
isAvailable[2] = true;
mi[2] = puNeigh->getMotionInfo( pos );
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
neighGbi[2] = puNeigh->cu->GBiIdx;
#endif
break;
}
}
......@@ -3565,7 +3636,11 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
for ( int idx = startIdx; idx < modelNum; idx++ )
{
int modelIdx = order[idx];
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
getAffineControlPointCand(pu, mi, neighGbi, isAvailable, model[modelIdx], modelIdx, verNum[modelIdx], affMrgCtx);
#else
getAffineControlPointCand( pu, mi, isAvailable, model[modelIdx], modelIdx, verNum[modelIdx], affMrgCtx );
#endif
if ( affMrgCtx.numValidMergeCand != 0 && affMrgCtx.numValidMergeCand - 1 == mrgCandIdx )
{
return;
......@@ -3625,7 +3700,11 @@ void PU::setAllAffineMvField( PredictionUnit &pu, MvField *mvField, RefPicList e
pu.refIdx[eRefList] = mvField[0].refIdx;
}
#if JVET_N0334_MVCLIPPING
void PU::setAllAffineMv(PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool setHighPrec, bool clipCPMVs)
#else
void PU::setAllAffineMv( PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool setHighPrec)
#endif
{
int width = pu.Y().width;
int shift = MAX_CU_DEPTH;
......@@ -3635,6 +3714,17 @@ void PU::setAllAffineMv( PredictionUnit& pu, Mv affLT, Mv affRT, Mv affLB, RefPi
affRT.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
affLB.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
}
#if JVET_N0334_MVCLIPPING
if (clipCPMVs)
{
affLT.mvCliptoStorageBitDepth();
affRT.mvCliptoStorageBitDepth();
if (pu.cu->affineType == AFFINEMODEL_6PARAM)
{
affLB.mvCliptoStorageBitDepth();
}
}
#endif
int deltaMvHorX, deltaMvHorY, deltaMvVerX, deltaMvVerY;
deltaMvHorX = (affRT - affLT).getHor() << (shift - g_aucLog2[width]);
deltaMvHorY = (affRT - affLT).getVer() << (shift - g_aucLog2[width]);
......@@ -4039,6 +4129,9 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP
pu.mvpIdx[0] = mvp_idx;
pu.mv [0] = amvpInfo.mvCand[mvp_idx] + pu.mvd[0];
pu.mv[0].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[0].mvCliptoStorageBitDepth();
#endif
}
if (pu.interDir != 1 /* PRED_L0 */)
......@@ -4054,6 +4147,9 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP
pu.mvpIdx[1] = mvp_idx;
pu.mv [1] = amvpInfo.mvCand[mvp_idx] + pu.mvd[1];
pu.mv[1].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[1].mvCliptoStorageBitDepth();
#endif
}
}
else
......
......@@ -155,11 +155,18 @@ namespace PU
bool isBipredRestriction (const PredictionUnit &pu);
void spanMotionInfo ( PredictionUnit &pu, const MergeCtx &mrgCtx = MergeCtx() );
void applyImv ( PredictionUnit &pu, MergeCtx &mrgCtx, InterPrediction *interPred = NULL );
#if JVET_N0481_BCW_CONSTRUCTED_AFFINE
void getAffineControlPointCand(const PredictionUnit &pu, MotionInfo mi[4], int8_t neighGbi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgCtx);
#else
void getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4], bool isAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgCtx );
#endif
void getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx, const int mrgCandIdx = -1 );
void setAllAffineMvField ( PredictionUnit &pu, MvField *mvField, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList
, bool setHighPrec = false
#if JVET_N0334_MVCLIPPING
, bool clipCPMVs = false
#endif
);
bool getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx &mrgCtx, bool& LICFlag, const int count
, int mmvdList
......
......@@ -745,7 +745,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
mvLB.changePrecision( MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL );
}
}
#if JVET_N0334_MVCLIPPING
PU::setAllAffineMv(pu, mvLT, mvRT, mvLB, eRefList, false, true);
#else
PU::setAllAffineMv( pu, mvLT, mvRT, mvLB, eRefList );
#endif
}
}
}
......@@ -761,6 +765,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
mvd <<= 2;
pu.mv[REF_PIC_LIST_0] = amvpInfo.mvCand[pu.mvpIdx[REF_PIC_LIST_0]] + mvd;
pu.mv[REF_PIC_LIST_0].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[REF_PIC_LIST_0].mvCliptoStorageBitDepth();
#endif
}
else
{
......@@ -774,6 +781,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
pu.mvpNum [eRefList] = amvpInfo.numCand;
pu.mv[eRefList] = amvpInfo.mvCand[pu.mvpIdx[eRefList]] + pu.mvd[eRefList];
pu.mv[eRefList].changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
#if JVET_N0334_MVCLIPPING
pu.mv[eRefList].mvCliptoStorageBitDepth();
#endif
}
}
}
......
......@@ -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();
......
......@@ -41,20 +41,46 @@
#include "CommonLib/AdaptiveLoopFilter.h"
#include "CABACWriter.h"
#if JVET_N0242_NON_LINEAR_ALF
#include "EncCfg.h"
#endif
struct AlfCovariance
{
#if JVET_N0242_NON_LINEAR_ALF
static constexpr int MaxAlfNumClippingValues = AdaptiveLoopFilter::MaxAlfNumClippingValues;
using TE = double[MAX_NUM_ALF_LUMA_COEFF][MAX_NUM_ALF_LUMA_COEFF];
using Ty = double[MAX_NUM_ALF_LUMA_COEFF];
using TKE = TE[AdaptiveLoopFilter::MaxAlfNumClippingValues][AdaptiveLoopFilter::MaxAlfNumClippingValues];
using TKy = Ty[AdaptiveLoopFilter::MaxAlfNumClippingValues];
#endif
int numCoeff;
#if JVET_N0242_NON_LINEAR_ALF
int numBins;
TKy y;
TKE E;
#else
double *y;
double **E;
#endif
double pixAcc;
AlfCovariance() {}
~AlfCovariance() {}
#if JVET_N0242_NON_LINEAR_ALF
void create( int size, int num_bins = MaxAlfNumClippingValues )
#else
void create( int size )
#endif
{
numCoeff = size;
#if JVET_N0242_NON_LINEAR_ALF
numBins = num_bins;
std::memset( y, 0, sizeof( y ) );
std::memset( E, 0, sizeof( E ) );
#else
y = new double[numCoeff];
E = new double*[numCoeff];
......@@ -63,10 +89,12 @@ struct AlfCovariance
{
E[i] = new double[numCoeff];
}
#endif
}
void destroy()
{
#if !JVET_N0242_NON_LINEAR_ALF
for( int i = 0; i < numCoeff; i++ )
{
delete[] E[i];
......@@ -78,25 +106,46 @@ struct AlfCovariance
delete[] y;
y = nullptr;
#endif
}
#if JVET_N0242_NON_LINEAR_ALF
void reset( int num_bins = -1 )
#else
void reset()
#endif
{
#if JVET_N0242_NON_LINEAR_ALF
if ( num_bins > 0 )
numBins = num_bins;
#endif
pixAcc = 0;
#if JVET_N0242_NON_LINEAR_ALF
std::memset( y, 0, sizeof( y ) );
std::memset( E, 0, sizeof( E ) );
#else
std::memset( y, 0, sizeof( *y ) * numCoeff );
for( int i = 0; i < numCoeff; i++ )
{
std::memset( E[i], 0, sizeof( *E[i] ) * numCoeff );
}
#endif
}
const AlfCovariance& operator=( const AlfCovariance& src )
{
#if JVET_N0242_NON_LINEAR_ALF
numCoeff = src.numCoeff;
numBins = src.numBins;
std::memcpy( E, src.E, sizeof( E ) );
std::memcpy( y, src.y, sizeof( y ) );
#else
for( int i = 0; i < numCoeff; i++ )
{
std::memcpy( E[i], src.E[i], sizeof( *E[i] ) * numCoeff );
}
std::memcpy( y, src.y, sizeof( *y ) * numCoeff );
#endif
pixAcc = src.pixAcc;
return *this;
......@@ -104,6 +153,30 @@ struct AlfCovariance
void add( const AlfCovariance& lhs, const AlfCovariance& rhs )
{
#if JVET_N0242_NON_LINEAR_ALF
numCoeff = lhs.numCoeff;
numBins = lhs.numBins;
for( int b0 = 0; b0 < numBins; b0++ )
{
for( int b1 = 0; b1 < numBins; b1++ )
{
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
{
E[b0][b1][j][i] = lhs.E[b0][b1][j][i] + rhs.E[b0][b1][j][i];
}
}
}
}
for( int b = 0; b < numBins; b++ )
{
for( int j = 0; j < numCoeff; j++ )
{
y[b][j] = lhs.y[b][j] + rhs.y[b][j];
}
}
#else
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
......@@ -112,11 +185,34 @@ struct AlfCovariance
}
y[j] = lhs.y[j] + rhs.y[j];
}
#endif
pixAcc = lhs.pixAcc + rhs.pixAcc;
}
const AlfCovariance& operator+= ( const AlfCovariance& src )
{
#if JVET_N0242_NON_LINEAR_ALF
for( int b0 = 0; b0 < numBins; b0++ )
{
for( int b1 = 0; b1 < numBins; b1++ )
{
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
{
E[b0][b1][j][i] += src.E[b0][b1][j][i];
}
}
}
}
for( int b = 0; b < numBins; b++ )
{
for( int j = 0; j < numCoeff; j++ )
{
y[b][j] += src.y[b][j];
}
}
#else
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
......@@ -125,6 +221,7 @@ struct AlfCovariance
}
y[j] += src.y[j];
}
#endif
pixAcc += src.pixAcc;
return *this;
......@@ -132,6 +229,28 @@ struct AlfCovariance
const AlfCovariance& operator-= ( const AlfCovariance& src )
{
#if JVET_N0242_NON_LINEAR_ALF
for( int b0 = 0; b0 < numBins; b0++ )
{
for( int b1 = 0; b1 < numBins; b1++ )
{
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
{
E[b0][b1][j][i] -= src.E[b0][b1][j][i];
}
}
}
}
for( int b = 0; b < numBins; b++ )
{
for( int j = 0; j < numCoeff; j++ )
{
y[b][j] -= src.y[b][j];
}
}
#else
for( int j = 0; j < numCoeff; j++ )
{
for( int i = 0; i < numCoeff; i++ )
......@@ -140,10 +259,55 @@ struct AlfCovariance
}
y[j] -= src.y[j];
}
#endif
pixAcc -= src.pixAcc;
return *this;
}
#if JVET_N0242_NON_LINEAR_ALF
void setEyFromClip(const int* clip, TE _E, Ty _y, int size) const
{
for (int k=0; k<size; k++)
{
_y[k] = y[clip[k]][k];
for (int l=0; l<size; l++)
{
_E[k][l] = E[clip[k]][clip[l]][k][l];
}
}
}
double optimizeFilter(const int* clip, double *f, int size) const
{
gnsSolveByChol( clip, f, size );
return calculateError( clip, f );
}
double optimizeFilter(const AlfFilterShape& alfShape, int* clip, double *f, bool optimize_clip) const;
double optimizeFilterClip(const AlfFilterShape& alfShape, int* clip) const
{
Ty f;
return optimizeFilter(alfShape, clip, f, true);
}
double calculateError( const int *clip ) const;
double calculateError( const int *clip, const double *coeff ) const { return calculateError(clip, coeff, numCoeff); }
double calculateError( const int *clip, const double *coeff, const int numCoeff ) const;
double calcErrorForCoeffs( const int *clip, const int *coeff, const int numCoeff, const int bitDepth ) const;
void getClipMax(const AlfFilterShape& alfShape, int *clip_max) const;
void reduceClipCost(const AlfFilterShape& alfShape, int *clip) const;
private:
// Cholesky decomposition
int gnsSolveByChol( const int *clip, double *x, int numEq ) const;
int gnsSolveByChol( TE LHS, double* rhs, double *x, int numEq ) const;
void gnsBacksubstitution( TE R, double* z, int size, double* A ) const;
void gnsTransposeBacksubstitution( TE U, double* rhs, double* x, int order ) const;
int gnsCholeskyDec( TE inpMatr, TE outMatr, int numEq ) const;
#endif
};
class EncAdaptiveLoopFilter : public AdaptiveLoopFilter
......@@ -157,6 +321,9 @@ public:
inline std::vector<double>& getLumaLevelWeightTable() { return m_lumaLevelToWeightPLUT; }
private:
#if JVET_N0242_NON_LINEAR_ALF
const EncCfg* m_encCfg;
#endif
AlfCovariance*** m_alfCovariance[MAX_NUM_COMPONENT]; // [compIdx][shapeIdx][ctbAddr][classIdx]
AlfCovariance** m_alfCovarianceFrame[MAX_NUM_CHANNEL_TYPE]; // [CHANNEL][shapeIdx][classIdx]
uint8_t* m_ctuEnableFlagTmp[MAX_NUM_COMPONENT];
......@@ -164,13 +331,21 @@ private:
//for RDO
AlfSliceParam m_alfSliceParamTemp;
AlfCovariance m_alfCovarianceMerged[ALF_NUM_OF_FILTER_TYPES][MAX_NUM_ALF_CLASSES + 1];
#if JVET_N0242_NON_LINEAR_ALF
int m_alfClipMerged[ALF_NUM_OF_FILTER_TYPES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_LUMA_COEFF];
#endif
CABACWriter* m_CABACEstimator;
CtxCache* m_CtxCache;
double m_lambda[MAX_NUM_COMPONENT];
const double FracBitsScale = 1.0 / double( 1 << SCALE_BITS );
#if !JVET_N0242_NON_LINEAR_ALF
int* m_filterCoeffQuant;
#endif
int** m_filterCoeffSet;
#if JVET_N0242_NON_LINEAR_ALF
int** m_filterClippSet;
#endif
int** m_diffFilterCoeff;
int m_kMinTab[MAX_NUM_ALF_LUMA_COEFF];
int m_bitsCoeffScan[m_MAX_SCAN_VAL][m_MAX_EXP_GOLOMB];
......@@ -186,9 +361,17 @@ public:
#endif
AlfSliceParam& alfSliceParam );
void initCABACEstimator( CABACEncoder* cabacEncoder, CtxCache* ctxCache, Slice* pcSlice );
#if JVET_N0242_NON_LINEAR_ALF
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] );
#else
void create( 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] );
#endif
void destroy();
#if JVET_N0242_NON_LINEAR_ALF
static int lengthGolomb( int coeffVal, int k, bool signed_coeff=true );
#else
static int lengthGolomb( int coeffVal, int k );
#endif
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] );
private:
......@@ -199,21 +382,41 @@ private:
);
void copyAlfSliceParam( AlfSliceParam& alfSliceParamDst, AlfSliceParam& alfSliceParamSrc, ChannelType channel );
#if JVET_N0242_NON_LINEAR_ALF
double mergeFiltersAndCost( AlfSliceParam& alfSliceParam, AlfFilterShape& alfShape, AlfCovariance* covFrame, AlfCovariance* covMerged, int clipMerged[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_LUMA_COEFF], int& uiCoeffBits );
#else
double mergeFiltersAndCost( AlfSliceParam& alfSliceParam, AlfFilterShape& alfShape, AlfCovariance* covFrame, AlfCovariance* covMerged, int& uiCoeffBits );
#endif
void getFrameStats( ChannelType channel, int iShapeIdx );
void getFrameStat( AlfCovariance* frameCov, AlfCovariance** ctbCov, uint8_t* ctbEnableFlags, const int numClasses );
void deriveStatsForFiltering( PelUnitBuf& orgYuv, PelUnitBuf& recYuv );
#if JVET_N0242_NON_LINEAR_ALF
void getBlkStats( AlfCovariance* alfCovariace, const AlfFilterShape& shape, AlfClassifier** classifier, Pel* org, const int orgStride, Pel* rec, const int recStride, const CompArea& area, const ChannelType channel );
void calcCovariance( int ELocal[MAX_NUM_ALF_LUMA_COEFF][MaxAlfNumClippingValues], const Pel *rec, const int stride, const AlfFilterShape& shape, const int transposeIdx, const ChannelType channel );
void mergeClasses( const AlfFilterShape& alfShape, AlfCovariance* cov, AlfCovariance* covMerged, int clipMerged[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_LUMA_COEFF], const int numClasses, short filterIndices[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES] );
#else
void getBlkStats( AlfCovariance* alfCovariace, const AlfFilterShape& shape, AlfClassifier** classifier, Pel* org, const int orgStride, Pel* rec, const int recStride, const CompArea& area );
void calcCovariance( int *ELocal, const Pel *rec, const int stride, const int *filterPattern, const int halfFilterLength, const int transposeIdx );
void mergeClasses( AlfCovariance* cov, AlfCovariance* covMerged, const int numClasses, short filterIndices[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES] );
#endif
#if !JVET_N0242_NON_LINEAR_ALF
double calculateError( AlfCovariance& cov );
double calcErrorForCoeffs( double **E, double *y, int *coeff, const int numCoeff, const int bitDepth );
#endif
double getFilterCoeffAndCost( CodingStructure& cs, double distUnfilter, ChannelType channel, bool bReCollectStat, int iShapeIdx, int& uiCoeffBits );
#if JVET_N0242_NON_LINEAR_ALF
double deriveFilterCoeffs( AlfCovariance* cov, AlfCovariance* covMerged, int clipMerged[MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_CLASSES][MAX_NUM_ALF_LUMA_COEFF], AlfFilterShape& alfShape, short* filterIndices, int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2] );
#else
double deriveFilterCoeffs( AlfCovariance* cov, AlfCovariance* covMerged, AlfFilterShape& alfShape, short* filterIndices, int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2] );
#endif
int deriveFilterCoefficientsPredictionMode( AlfFilterShape& alfShape, int **filterSet, int** filterCoeffDiff, const int numFilters, int& predMode );
#if JVET_N0242_NON_LINEAR_ALF
double deriveCoeffQuant( int *filterClipp, int *filterCoeffQuant, const AlfCovariance& cov, const AlfFilterShape& shape, const int bitDepth, const bool optimizeClip );
#else
double deriveCoeffQuant( int *filterCoeffQuant, double **E, double *y, const int numCoeff, std::vector<int>& weights, const int bitDepth, const bool bChroma = false );
#endif
double deriveCtbAlfEnableFlags( CodingStructure& cs, const int iShapeIdx, ChannelType channel,
#if ENABLE_QPA
const double chromaWeight,
......@@ -229,7 +432,13 @@ private:
int getCostFilterCoeffForce0( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters, bool* codedVarBins );
int getCostFilterCoeff( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters );
#if JVET_N0242_NON_LINEAR_ALF
int getCostFilterClipp( AlfFilterShape& alfShape, int **pDiffQFilterCoeffIntPP, const int numFilters );
#endif
int lengthFilterCoeffs( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff, int* kMinTab );
#if JVET_N0242_NON_LINEAR_ALF
int lengthFilterClipps( AlfFilterShape& alfShape, const int numFilters, int **FilterCoeff, int* kMinTab );
#endif
double getDistForce0( AlfFilterShape& alfShape, const int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2], bool* codedVarBins );
int getCoeffRate( AlfSliceParam& alfSliceParam, bool isChroma );
......@@ -237,12 +446,14 @@ private:
double getUnfilteredDistortion( AlfCovariance* cov, const int numClasses );
double getFilteredDistortion( AlfCovariance* cov, const int numClasses, const int numFiltersMinus1, const int numCoeff );
#if !JVET_N0242_NON_LINEAR_ALF
// Cholesky decomposition
int gnsSolveByChol( double **LHS, double *rhs, double *x, int numEq );
void gnsBacksubstitution( double R[MAX_NUM_ALF_COEFF][MAX_NUM_ALF_COEFF], double* z, int size, double* A );
void gnsTransposeBacksubstitution( double U[MAX_NUM_ALF_COEFF][MAX_NUM_ALF_COEFF], double* rhs, double* x, int order );
int gnsCholeskyDec( double **inpMatr, double outMatr[MAX_NUM_ALF_COEFF][MAX_NUM_ALF_COEFF], int numEq );
#endif
void setEnableFlag( AlfSliceParam& alfSlicePara, ChannelType channel, bool val );
void setEnableFlag( AlfSliceParam& alfSlicePara, ChannelType channel, uint8_t** ctuFlags );
void setCtuEnableFlag( uint8_t** ctuFlags, ChannelType channel, uint8_t val );
......
......@@ -266,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;
......@@ -822,6 +826,12 @@ public:
bool getUseE0023FastEnc () const { return m_e0023FastEnc; }
void setUseContentBasedFastQtbt ( bool b ) { m_contentBasedFastQtbt = b; }
bool getUseContentBasedFastQtbt () const { return m_contentBasedFastQtbt; }
#if JVET_N0242_NON_LINEAR_ALF
void setUseNonLinearAlfLuma ( bool b ) { m_useNonLinearAlfLuma = b; }
bool getUseNonLinearAlfLuma () const { return m_useNonLinearAlfLuma; }
void setUseNonLinearAlfChroma ( bool b ) { m_useNonLinearAlfChroma = b; }
bool getUseNonLinearAlfChroma () const { return m_useNonLinearAlfChroma; }
#endif
#if MAX_TB_SIZE_SIGNALLING
void setLog2MaxTbSize ( uint32_t u ) { m_log2MaxTbSize = u; }
......