Commit 6ee74fa0 authored by Karsten Suehring's avatar Karsten Suehring

Merge branch 'JVET-N0415-CtbAlf' into 'master'

JVET-N0415: CTB-based ALF switch

See merge request jvet/VVCSoftware_VTM!499
parents 159f8f84 a3859f82
Pipeline #1463 passed with stage
This diff is collapsed.
......@@ -84,9 +84,17 @@ public:
AdaptiveLoopFilter();
virtual ~AdaptiveLoopFilter() {}
#if JVET_N0415_CTB_ALF
void reconstructCoeffAPSs(CodingStructure& cs, bool luma, bool chroma, bool isRdo);
void ALFProcess(CodingStructure& cs);
#else
void ALFProcess( CodingStructure& cs, AlfSliceParam& alfSliceParam );
void reconstructCoeff( AlfSliceParam& alfSliceParam, ChannelType channel, const bool bRedo = false );
#endif
void reconstructCoeff( AlfSliceParam& alfSliceParam, ChannelType channel,
#if JVET_N0415_CTB_ALF
const bool isRdo = false,
#endif
const bool isRedo = false );
void create( const int picWidth, const int picHeight, const ChromaFormat format, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE] );
void destroy();
#if JVET_N0180_ALF_LINE_BUFFER_REDUCTION
......@@ -146,6 +154,18 @@ public:
#endif
protected:
#if JVET_N0415_CTB_ALF
static const int m_classToFilterMapping[NUM_FIXED_FILTER_SETS][MAX_NUM_ALF_CLASSES];
static const int m_fixedFilterSetCoeff[ALF_FIXED_FILTER_NUM][MAX_NUM_ALF_LUMA_COEFF];
short m_fixedFilterSetCoeffDec[NUM_FIXED_FILTER_SETS][MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF];
short m_coeffApsLuma[6][MAX_NUM_ALF_LUMA_COEFF * MAX_NUM_ALF_CLASSES];
#if JVET_N0242_NON_LINEAR_ALF
short m_clippApsLuma[6][MAX_NUM_ALF_LUMA_COEFF * MAX_NUM_ALF_CLASSES];
short m_clipDefault[MAX_NUM_ALF_CLASSES * MAX_NUM_ALF_LUMA_COEFF];
#endif
bool m_created = false;
short m_chromaCoeffFinal[MAX_NUM_ALF_LUMA_COEFF];
#endif
#if JVET_N0242_NON_LINEAR_ALF
Pel m_alfClippingValues[MAX_NUM_CHANNEL_TYPE][MaxAlfNumClippingValues];
#endif
......@@ -157,7 +177,7 @@ protected:
short m_chromaClippFinal[MAX_NUM_ALF_LUMA_COEFF];
#endif
int** m_laplacian[NUM_DIRECTIONS];
uint8_t* m_ctuEnableFlag[MAX_NUM_COMPONENT];
uint8_t* m_ctuEnableFlag[MAX_NUM_COMPONENT];
PelStorage m_tempBuf;
int m_inputBitDepth[MAX_NUM_CHANNEL_TYPE];
int m_picWidth;
......
......@@ -776,7 +776,11 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
subStruct.vps = vps;
#endif
subStruct.pps = pps;
#if JVET_N0415_CTB_ALF
memcpy(subStruct.apss, apss, sizeof(apss));
#else
subStruct.aps = aps;
#endif
subStruct.slice = slice;
subStruct.baseQP = baseQP;
subStruct.prevQP[_chType]
......
......@@ -94,7 +94,11 @@ public:
bool isLossless;
const SPS *sps;
const PPS *pps;
#if JVET_N0415_CTB_ALF
APS* apss[MAX_NUM_APS];
#else
APS * aps;
#endif
#if HEVC_VPS
const VPS *vps;
#endif
......@@ -257,6 +261,9 @@ public:
const CPelBuf getRecoBuf(const CompArea &blk) const;
PelUnitBuf getRecoBuf(const UnitArea &unit);
const CPelUnitBuf getRecoBuf(const UnitArea &unit) const;
#if JVET_N0415_CTB_ALF
PelUnitBuf& getRecoBufRef() { return m_reco; }
#endif
PelBuf getOrgResiBuf(const CompArea &blk);
const CPelBuf getOrgResiBuf(const CompArea &blk) const;
......
......@@ -178,6 +178,13 @@ static const int MIP_MAX_WIDTH = 64;
static const int MIP_MAX_HEIGHT = 64;
#endif
#if JVET_N0415_CTB_ALF
static const int ALF_FIXED_FILTER_NUM = 64;
static const int ALF_CTB_MAX_NUM_APS = 6;
static const int NUM_FIXED_FILTER_SETS = 16;
static const int NUM_TOTAL_FILTER_SETS = NUM_FIXED_FILTER_SETS + ALF_CTB_MAX_NUM_APS;
#endif
#if JVET_N0178_IMPLICIT_BDOF_SPLIT
static const int MAX_BDOF_APPLICATION_REGION = 16;
#endif
......
......@@ -831,6 +831,29 @@ const CtxSet ContextSetCfg::ctbAlfFlag =
} )
};
#if JVET_N0415_CTB_ALF
const CtxSet ContextSetCfg::AlfUseLatestFilt =
{
ContextSetCfg::addCtxSet
({
{ 154, }, // B
{ 154, }, // P
{ 185, }, // I
{ DWS, },
})
};
const CtxSet ContextSetCfg::AlfUseTemporalFilt =
{
ContextSetCfg::addCtxSet
({
{ 154, },
{ 154, },
{ 154, },
{ DWS, },
})
};
#endif
const CtxSet ContextSetCfg::MHIntraFlag = ContextSetCfg::addCtxSet
({
{ 225, },
......@@ -959,7 +982,9 @@ const unsigned ContextSetCfg::NumberOfContexts = (unsigned)ContextSetCfg::sm_Ini
// combined sets
const CtxSet ContextSetCfg::Sao = { ContextSetCfg::SaoMergeFlag, ContextSetCfg::SaoTypeIdx };
#if JVET_N0415_CTB_ALF
const CtxSet ContextSetCfg::Alf = { ContextSetCfg::ctbAlfFlag, ContextSetCfg::AlfUseLatestFilt, ContextSetCfg::AlfUseTemporalFilt };
#endif
template <class BinProbModel>
CtxStore<BinProbModel>::CtxStore()
......
......@@ -265,6 +265,11 @@ public:
static const CtxSet ImvFlag;
static const CtxSet GBiIdx;
static const CtxSet ctbAlfFlag;
#if JVET_N0415_CTB_ALF
static const CtxSet AlfUseLatestFilt;
static const CtxSet AlfUseTemporalFilt;
static const CtxSet Alf;
#endif
static const CtxSet MHIntraFlag;
#if !JVET_N0302_SIMPLFIED_CIIP
static const CtxSet MHIntraPredMode;
......
......@@ -871,7 +871,11 @@ const CPelUnitBuf Picture::getRecoBuf(const UnitArea &unit) const { return g
PelUnitBuf Picture::getRecoBuf() { return M_BUFS(scheduler.getSplitPicId(), PIC_RECONSTRUCTION); }
const CPelUnitBuf Picture::getRecoBuf() const { return M_BUFS(scheduler.getSplitPicId(), PIC_RECONSTRUCTION); }
#if JVET_N0415_CTB_ALF
void Picture::finalInit(const SPS& sps, const PPS& pps, APS** apss)
#else
void Picture::finalInit(const SPS& sps, const PPS& pps, APS& aps)
#endif
{
for( auto &sei : SEIs )
{
......@@ -905,7 +909,11 @@ void Picture::finalInit(const SPS& sps, const PPS& pps, APS& aps)
cs->picture = this;
cs->slice = nullptr; // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
cs->pps = &pps;
#if JVET_N0415_CTB_ALF
memcpy(cs->apss, apss, sizeof(cs->apss));
#else
cs->aps = &aps;
#endif
#if HEVC_VPS
cs->vps = nullptr;
#endif
......@@ -925,8 +933,11 @@ void Picture::allocateNewSlice()
{
slices.push_back(new Slice);
Slice& slice = *slices.back();
#if JVET_N0415_CTB_ALF
memcpy(slice.getAPSs(), cs->apss, sizeof(cs->apss));
#else
slice.setAPS(cs->aps);
#endif
slice.setPPS( cs->pps);
slice.setSPS( cs->sps);
if(slices.size()>=2)
......@@ -940,13 +951,21 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i)
{
p->setSPS(cs->sps);
p->setPPS(cs->pps);
#if JVET_N0415_CTB_ALF
p->setAPSs(cs->apss);
#else
p->setAPS(cs->aps);
#endif
Slice * pTmp = slices[i];
slices[i] = p;
pTmp->setSPS(0);
pTmp->setPPS(0);
#if JVET_N0415_CTB_ALF
memset(pTmp->getAPSs(), 0, sizeof(*pTmp->getAPSs())*MAX_NUM_APS);
#else
pTmp->setAPS(0);
#endif
return pTmp;
}
......
......@@ -225,7 +225,11 @@ struct Picture : public UnitArea
const CPelUnitBuf getBuf(const UnitArea &unit, const PictureType &type) const;
void extendPicBorder();
#if JVET_N0415_CTB_ALF
void finalInit(const SPS& sps, const PPS& pps, APS** apss);
#else
void finalInit(const SPS& sps, const PPS& pps, APS& aps);
#endif
int getPOC() const { return poc; }
void setBorderExtension( bool bFlag) { m_bIsBorderExtended = bFlag;}
......@@ -324,6 +328,18 @@ public:
std::fill( m_alfCtuEnableFlag[compIdx].begin(), m_alfCtuEnableFlag[compIdx].end(), 0 );
}
}
#if JVET_N0415_CTB_ALF
std::vector<short> m_alfCtbFilterIndex;
short* getAlfCtbFilterIndex() { return m_alfCtbFilterIndex.data(); }
void resizeAlfCtbFilterIndex(int numEntries)
{
m_alfCtbFilterIndex.resize(numEntries);
for (int i = 0; i < numEntries; i++)
{
m_alfCtbFilterIndex[i] = 0;
}
}
#endif
};
int calcAndPrintHashStatus(const CPelUnitBuf& pic, const class SEIDecodedPictureHash* pictureHashSEI, const BitDepths &bitDepths, const MsgLevel msgl);
......
......@@ -139,8 +139,10 @@ Slice::Slice()
, m_uiMaxBTSizeIChroma ( 0 )
, m_uiMaxTTSizeIChroma ( 0 )
, m_uiMaxBTSize ( 0 )
#if !JVET_N0415_CTB_ALF
, m_apsId ( -1 )
, m_aps (NULL)
#endif
{
for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
{
......@@ -186,6 +188,9 @@ Slice::Slice()
m_sliceReshapeInfo.reshaperModelMinBinIdx = 0;
m_sliceReshapeInfo.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1;
memset(m_sliceReshapeInfo.reshaperModelBinCWDelta, 0, PIC_CODE_CW_BINS * sizeof(int));
#if JVET_N0415_CTB_ALF
memset(m_apss, 0, sizeof(m_apss));
#endif
}
Slice::~Slice()
......@@ -2518,6 +2523,9 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
}
else
{
#endif
#if JVET_N0415_CTB_ALF
m_spsMap.clear();
#endif
m_spsMap.setActive(spsId);
#if HEVC_VPS
......@@ -2536,6 +2544,9 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
}
#else
m_activeSPSId = spsId;
#if JVET_N0415_CTB_ALF
m_ppsMap.clear();
#endif
m_ppsMap.setActive(ppsId);
return true;
#endif
......
......@@ -1716,7 +1716,13 @@ public:
void setAPSId(int i) { m_APSId = i; }
void setAlfAPSParam(AlfSliceParam& alfAPSParam) { m_alfAPSParam = alfAPSParam; }
const AlfSliceParam& getAlfAPSParam() const { return m_alfAPSParam; }
#if JVET_N0415_CTB_ALF
void setTemporalId(int i) { m_alfAPSParam.tLayer = i; }
int getTemporalId() { return m_alfAPSParam.tLayer; }
AlfSliceParam& getAlfAPSParam() { return m_alfAPSParam; }
#else
const AlfSliceParam& getAlfAPSParam() const { return m_alfAPSParam; }
#endif
};
struct WPScalingParam
{
......@@ -1741,8 +1747,6 @@ struct WPACDCParam
int64_t iDC;
};
/// slice header class
class Slice
{
......@@ -1877,11 +1881,19 @@ private:
uint32_t m_uiMaxBTDepthIChroma;
uint32_t m_uiMaxBTSizeIChroma;
uint32_t m_uiMaxTTSizeIChroma;
uint32_t m_uiMaxBTSize;
uint32_t m_uiMaxBTSize;
#if JVET_N0415_CTB_ALF
APS* m_apss[MAX_NUM_APS];
bool m_tileGroupAlfEnabledFlag[MAX_NUM_COMPONENT];
int m_tileGroupNumAps;
std::vector<int> m_tileGroupLumaApsId;
int m_tileGroupChromaApsId;
#else
int m_apsId;
APS* m_aps;
bool m_tileGroupAlfEnabledFlag;
#endif
#if JVET_N0329_IBC_SEARCH_IMP
bool m_disableSATDForRd;
#endif
......@@ -1903,10 +1915,15 @@ public:
void setPPSId( int PPSId ) { m_iPPSId = PPSId; }
int getPPSId() const { return m_iPPSId; }
#if JVET_N0415_CTB_ALF
void setAPSs(APS** apss) { memcpy(m_apss, apss, sizeof(m_apss)); }
APS** getAPSs() { return m_apss; }
#else
void setAPS(APS* aps) { m_aps = aps; m_apsId = (aps) ? aps->getAPSId() : -1; }
APS* getAPS() { return m_aps; }
void setAPSId(int apsId) { m_apsId = apsId; }
int getAPSId() const { return m_apsId; }
#endif
void setPicOutputFlag( bool b ) { m_PicOutputFlag = b; }
bool getPicOutputFlag() const { return m_PicOutputFlag; }
void setSaoEnabledFlag(ChannelType chType, bool s) {m_saoEnabledFlag[chType] =s; }
......@@ -2173,8 +2190,27 @@ public:
void resetProcessingTime() { m_dProcessingTime = m_iProcessingStartTime = 0; }
double getProcessingTime() const { return m_dProcessingTime; }
#if JVET_N0415_CTB_ALF
void resetTileGroupAlfEnabledFlag() { memset(m_tileGroupAlfEnabledFlag, 0, sizeof(m_tileGroupAlfEnabledFlag)); }
bool getTileGroupAlfEnabledFlag(ComponentID compId) const { return m_tileGroupAlfEnabledFlag[compId]; }
void setTileGroupAlfEnabledFlag(ComponentID compId, bool b) { m_tileGroupAlfEnabledFlag[compId] = b; }
int getTileGroupNumAps() const { return m_tileGroupNumAps; }
void setTileGroupNumAps(int i) { m_tileGroupNumAps = i; }
int getTileGroupApsIdChroma() const { return m_tileGroupChromaApsId; }
void setTileGroupApsIdChroma(int i) { m_tileGroupChromaApsId = i; }
std::vector<int32_t> getTileGroupApsIdLuma() const { return m_tileGroupLumaApsId; }
void setAPSs(std::vector<int> ApsIDs)
{
m_tileGroupLumaApsId.resize(m_tileGroupNumAps);
for (int i = 0; i < m_tileGroupNumAps; i++)
{
m_tileGroupLumaApsId[i] = ApsIDs[i];
}
}
#else
bool getTileGroupAlfEnabledFlag() const { return m_tileGroupAlfEnabledFlag; }
void setTileGroupAlfEnabledFlag(bool b) { m_tileGroupAlfEnabledFlag = b; }
#endif
#if JVET_N0329_IBC_SEARCH_IMP
void setDisableSATDForRD(bool b) { m_disableSATDForRd = b; }
bool getDisableSATDForRD() { return m_disableSATDForRd; }
......@@ -2186,10 +2222,6 @@ protected:
Picture* xGetLongTermRefPic(PicList& rcListPic, int poc, bool pocHasMsb);
};// END CLASS DEFINITION Slice
void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData);
template <class T> class ParameterSetMap
......@@ -2205,9 +2237,15 @@ public:
ParameterSetMap(int maxId)
:m_maxId (maxId)
#if !JVET_N0415_CTB_ALF
,m_activePsId(-1)
#endif
,m_lastActiveParameterSet(NULL)
{}
{
#if JVET_N0415_CTB_ALF
m_activePsId.clear();
#endif
}
~ParameterSetMap()
{
......@@ -2232,6 +2270,13 @@ public:
return m_paramsetMap[psId].parameterSet;
}
#if JVET_N0415_CTB_ALF
void clearMap()
{
m_paramsetMap.clear();
}
#endif
void storePS(int psId, T *ps, const std::vector<uint8_t> *pNaluData)
{
CHECK( psId >= m_maxId, "Invalid PS id" );
......@@ -2249,7 +2294,11 @@ public:
return;
}
#if JVET_N0415_CTB_ALF
if (find(m_activePsId.begin(), m_activePsId.end(), psId) != m_activePsId.end())
#else
if( m_activePsId == psId )
#endif
{
std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet );
}
......@@ -2317,17 +2366,25 @@ public:
return (m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet;
}
#if JVET_N0415_CTB_ALF
void setActive(int psId) { m_activePsId.push_back(psId); }
void clear() { m_activePsId.clear(); }
#else
void setActive(int psId ) { m_activePsId = psId;}
#endif
private:
std::map<int,MapData<T> > m_paramsetMap;
int m_maxId;
#if JVET_N0415_CTB_ALF
std::vector<int> m_activePsId;
#else
int m_activePsId;
#endif
T* m_lastActiveParameterSet;
static void setID(T* parameterSet, const int psId);
};
class ParameterSetManager
{
public:
......@@ -2371,7 +2428,10 @@ public:
#endif
//! \returns true, if activation is successful
bool activatePPS(int ppsId, bool isIRAP);
#if JVET_N0415_CTB_ALF
APS** getAPSs() { return &m_apss[0]; }
ParameterSetMap<APS>* getApsMap() { return &m_apsMap; }
#endif
void storeAPS(APS *aps, const std::vector<uint8_t> &naluData) { m_apsMap.storePS(aps->getAPSId(), aps, &naluData); };
APS* getAPS(int apsId) { return m_apsMap.getPS(apsId); };
bool getAPSChangedFlag(int apsId) const { return m_apsMap.getChangedFlag(apsId); }
......@@ -2391,6 +2451,10 @@ protected:
ParameterSetMap<PPS> m_ppsMap;
ParameterSetMap<APS> m_apsMap;
#if JVET_N0415_CTB_ALF
APS* m_apss[MAX_NUM_APS];
#endif
#if HEVC_VPS
int m_activeVPSId; // -1 for nothing active
#endif
......
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_N0415_CTB_ALF 1 // JVET-N0415: CTB-based ALF switch
#define JVET_N0105_LFNST_CTX_MODELLING 1 // LFNST index signalled without intra mode dependency and with on ctx-coded bin
#define JVET_N0193_LFNST 1 //Low Frequency Non-Separable Transform (LFNST), previously, Reduced Secondary Transform (RST)
......@@ -1676,6 +1678,13 @@ struct AlfSliceParam
bool alfLumaCoeffDeltaFlag; // alf_luma_coeff_delta_flag
bool alfLumaCoeffDeltaPredictionFlag; // alf_luma_coeff_delta_prediction_flag
std::vector<AlfFilterShape>* filterShapes;
#if JVET_N0415_CTB_ALF
int tLayer;
bool newFilterFlag[MAX_NUM_CHANNEL_TYPE];
int fixedFilterPattern;
int fixedFilterIdx[MAX_NUM_ALF_CLASSES];
int fixedFilterSetIndex;
#endif
AlfSliceParam()
{
......@@ -1701,6 +1710,13 @@ struct AlfSliceParam
numLumaFilters = 1;
alfLumaCoeffDeltaFlag = false;
alfLumaCoeffDeltaPredictionFlag = false;
#if JVET_N0415_CTB_ALF
tLayer = 0;
memset(newFilterFlag, 0, sizeof(newFilterFlag));
fixedFilterPattern = 0;
std::memset(fixedFilterIdx, 0, sizeof(fixedFilterIdx));
fixedFilterSetIndex = 0;;
#endif
}
const AlfSliceParam& operator = ( const AlfSliceParam& src )
......@@ -1723,6 +1739,13 @@ struct AlfSliceParam
alfLumaCoeffDeltaFlag = src.alfLumaCoeffDeltaFlag;
alfLumaCoeffDeltaPredictionFlag = src.alfLumaCoeffDeltaPredictionFlag;
filterShapes = src.filterShapes;
#if JVET_N0415_CTB_ALF
tLayer = src.tLayer;
std::memcpy(newFilterFlag, src.newFilterFlag, sizeof(newFilterFlag));
fixedFilterPattern = src.fixedFilterPattern;
std::memcpy(fixedFilterIdx, src.fixedFilterIdx, sizeof(fixedFilterIdx));
fixedFilterSetIndex = src.fixedFilterSetIndex;
#endif
return *this;
}
};
......
......@@ -142,12 +142,15 @@ bool CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
sao( cs, ctuRsAddr );
#if JVET_N0415_CTB_ALF
if (cs.sps->getALFEnabledFlag() && (cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y)))
{
#else
if (cs.sps->getALFEnabledFlag() && (cs.slice->getTileGroupAlfEnabledFlag()))
{
CHECK(cs.aps == nullptr, "APS not initialized");
const AlfSliceParam& alfSliceParam = cs.aps->getAlfAPSParam();
#endif
const PreCalcValues& pcv = *cs.pcv;
int frame_width_in_ctus = pcv.widthInCtus;
int ry = ctuRsAddr / frame_width_in_ctus;
......@@ -163,7 +166,11 @@ bool CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
for( int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++ )
{
#if JVET_N0415_CTB_ALF
if (cs.slice->getTileGroupAlfEnabledFlag((ComponentID)compIdx))
#else
if( alfSliceParam.enabledFlag[compIdx] )
#endif
{
uint8_t* ctbAlfFlag = cs.slice->getPic()->getAlfCtuEnableFlag( compIdx );
int ctx = 0;
......@@ -172,6 +179,13 @@ bool CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET(STATS__CABAC_BITS__ALF);
ctbAlfFlag[ctuRsAddr] = m_BinDecoder.decodeBin( Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
#if JVET_N0415_CTB_ALF
if (isLuma((ComponentID)compIdx) && ctbAlfFlag[ctuRsAddr])
{
readAlfCtuFilterIndex(cs, ctuRsAddr);
}
#endif
}
}
}
......@@ -208,6 +222,48 @@ bool CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
return isLast;
}
#if JVET_N0415_CTB_ALF
void CABACReader::readAlfCtuFilterIndex(CodingStructure& cs, unsigned ctuRsAddr)
{
short* alfCtbFilterSetIndex = cs.slice->getPic()->getAlfCtbFilterIndex();
unsigned numAps = cs.slice->getTileGroupNumAps();
unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
uint32_t filtIndex = 0;
if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
{
int useLatestFilt = m_BinDecoder.decodeBin(Ctx::AlfUseLatestFilt());
if (useLatestFilt)
{
filtIndex = NUM_FIXED_FILTER_SETS;
}
else
{
if (numAps == 1)
{
xReadTruncBinCode(filtIndex, NUM_FIXED_FILTER_SETS);
}
else
{
unsigned usePrevFilt = m_BinDecoder.decodeBin(Ctx::AlfUseTemporalFilt());
if (usePrevFilt)
{
xReadTruncBinCode(filtIndex, numAvailableFiltSets - (NUM_FIXED_FILTER_SETS + 1));
filtIndex += (unsigned)(NUM_FIXED_FILTER_SETS + 1);
}
else
{
xReadTruncBinCode(filtIndex, NUM_FIXED_FILTER_SETS);
}
}
}
}
else
{
xReadTruncBinCode(filtIndex, NUM_FIXED_FILTER_SETS);
}
alfCtbFilterSetIndex[ctuRsAddr] = filtIndex;
}
#endif
//================================================================================
// clause 7.3.8.3
//--------------------------------------------------------------------------------
......
......@@ -68,6 +68,10 @@ public:
// sao (clause 7.3.8.3)
void sao ( CodingStructure& cs, unsigned ctuRsAddr );
#if JVET_N0415_CTB_ALF
void readAlfCtuFilterIndex(CodingStructure& cs, unsigned ctuRsAddr);
#endif
// coding (quad)tree (clause 7.3.8.4)
bool coding_tree ( CodingStructure& cs, Partitioner& pm, CUCtx& cuCtx, Partitioner* pPartitionerChroma = nullptr, CUCtx* pCuCtxChroma = nullptr);
PartSplit split_cu_mode ( CodingStructure& cs, Partitioner& pm );
......
......@@ -208,9 +208,19 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
for( int i = 0; i < pic->slices.size(); i++ )
{
#if JVET_N0415_CTB_ALF
pcEncPic->slices[i]->setTileGroupNumAps(pic->slices[i]->getTileGroupNumAps());
pcEncPic->slices[i]->setAPSs(pic->slices[i]->getTileGroupApsIdLuma());
pcEncPic->slices[i]->setAPSs(pic->slices[i]->getAPSs());
pcEncPic->slices[i]->setTileGroupApsIdChroma(pic->slices[i]->getTileGroupApsIdChroma());
pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Y, pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Y));
pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Cb, pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Cb));
pcEncPic->slices[i]->setTileGroupAlfEnabledFlag(COMPONENT_Cr, pic->slices[i]->getTileGroupAlfEnabledFlag(COMPONENT_Cr));
#else
pcEncPic->slices[i]->setAPSId(pic->slices[i]->getAPSId());
pcEncPic->slices[i]->setAPS( pic->slices[i]->getAPS());
pcEncPic->slices[i]->setTileGroupAlfEnabledFlag( pic->slices[i]->getTileGroupAlfEnabledFlag());
#endif
}
}
......@@ -559,14 +569,21 @@ void DecLib::executeLoopFilters()
if( cs.sps->getALFEnabledFlag() )
{
#if JVET_N0415_CTB_ALF
if (cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
#else
if (cs.slice->getTileGroupAlfEnabledFlag())
#endif
{
// ALF decodes the differentially coded coefficients and stores them in the parameters structure.
// Code could be restructured to do directly after parsing. So far we just pass a fresh non-const
// copy in case the APS gets used more than once.
#if JVET_N0415_CTB_ALF
m_cALF.ALFProcess(cs);
#else
AlfSliceParam alfParamCopy = cs.aps->getAlfAPSParam();
m_cALF.ALFProcess(cs, alfParamCopy);
#endif
}
}
......@@ -725,11 +742,16 @@ void DecLib::xActivateParameterSets()
{
if (m_bFirstSliceInPicture)