Commit 520aeb5f authored by Karsten Suehring's avatar Karsten Suehring

Merge remote-tracking branch 'hendry/master' into aps

APS implementation from Hendry
parents b0411ca2 fb5d5e2b
......@@ -904,6 +904,9 @@ void EncApp::rateStatsAccum(const AccessUnit& au, const std::vector<uint32_t>& a
#endif
case NAL_UNIT_SPS:
case NAL_UNIT_PPS:
#if JVET_M0132
case NAL_UNIT_APS:
#endif
m_essentialBytes += *it_stats;
break;
default:
......@@ -920,7 +923,11 @@ void EncApp::printRateSummary()
msg( DETAILS,"Bytes written to file: %u (%.3f kbps)\n", m_totalBytes, 0.008 * m_totalBytes / time );
if (m_summaryVerboseness > 0)
{
#if JVET_M0132
msg(DETAILS, "Bytes for SPS/PPS/APS/Slice (Incl. Annex B): %u (%.3f kbps)\n", m_essentialBytes, 0.008 * m_essentialBytes / time);
#else
msg( DETAILS,"Bytes for SPS/PPS/Slice (Incl. Annex B): %u (%.3f kbps)\n", m_essentialBytes, 0.008 * m_essentialBytes / time );
#endif
}
}
......
......@@ -221,6 +221,9 @@ const char * NALU_TYPE[] =
#endif
"SPS_NUT",
"PPS_NUT",
#if JVET_M0132
"APS_NUT",
#endif
"AUD_NUT",
"EOS_NUT",
"EOB_NUT",
......
......@@ -101,6 +101,9 @@ public:
bool isLossless;
const SPS *sps;
const PPS *pps;
#if JVET_M0132
APS * aps;
#endif
#if HEVC_VPS
const VPS *vps;
#endif
......
......@@ -192,6 +192,9 @@ static const int C2FLAG_NUMBER = 1; ///< maxi
static const int MAX_NUM_VPS = 16;
static const int MAX_NUM_SPS = 16;
static const int MAX_NUM_PPS = 64;
#if JVET_M0132
static const int MAX_NUM_APS = 32; //Currently APS ID has 5 bits
#endif
static const int MLS_GRP_NUM = 1024; ///< Max number of coefficient groups, max(16, 256)
......
......@@ -881,7 +881,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_M0132
void Picture::finalInit(const SPS& sps, const PPS& pps, APS& aps)
#else
void Picture::finalInit( const SPS& sps, const PPS& pps )
#endif
{
for( auto &sei : SEIs )
{
......@@ -917,6 +921,9 @@ void Picture::finalInit( const SPS& sps, const PPS& pps )
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_M0132
cs->aps = &aps;
#endif
#if HEVC_VPS
cs->vps = nullptr;
#endif
......@@ -939,6 +946,9 @@ void Picture::allocateNewSlice()
slices.push_back(new Slice);
Slice& slice = *slices.back();
#if JVET_M0132
slice.setAPS(cs->aps);
#endif
slice.setPPS( cs->pps);
slice.setSPS( cs->sps);
if(slices.size()>=2)
......@@ -952,11 +962,17 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i)
{
p->setSPS(cs->sps);
p->setPPS(cs->pps);
#if JVET_M0132
p->setAPS(cs->aps);
#endif
Slice * pTmp = slices[i];
slices[i] = p;
pTmp->setSPS(0);
pTmp->setPPS(0);
#if JVET_M0132
pTmp->setAPS(0);
#endif
return pTmp;
}
......
......@@ -233,7 +233,11 @@ struct Picture : public UnitArea
const CPelUnitBuf getBuf(const UnitArea &unit, const PictureType &type) const;
void extendPicBorder();
#if JVET_M0132
void finalInit(const SPS& sps, const PPS& pps, APS& aps);
#else
void finalInit( const SPS& sps, const PPS& pps );
#endif
int getPOC() const { return poc; }
void setBorderExtension( bool bFlag) { m_bIsBorderExtended = bFlag;}
......
......@@ -86,6 +86,9 @@ const char* nalUnitTypeToString(NalUnitType type)
#endif
case NAL_UNIT_SPS: return "SPS";
case NAL_UNIT_PPS: return "PPS";
#if JVET_M0132
case NAL_UNIT_APS: return "APS";
#endif
case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
case NAL_UNIT_EOS: return "EOS";
case NAL_UNIT_EOB: return "EOB";
......
......@@ -138,6 +138,10 @@ Slice::Slice()
, m_uiMaxBTSizeIChroma ( 0 )
, m_uiMaxTTSizeIChroma ( 0 )
, m_uiMaxBTSize ( 0 )
#if JVET_M0132
, m_apsId ( -1 )
, m_aps (NULL)
#endif
{
for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
{
......@@ -1932,6 +1936,16 @@ PPS::~PPS()
delete pcv;
}
#if JVET_M0132
APS::APS()
: m_APSId(0)
{
}
APS::~APS()
{
}
#endif
ReferencePictureSet::ReferencePictureSet()
: m_numberOfPictures (0)
, m_numberOfNegativePictures (0)
......@@ -2410,6 +2424,9 @@ ParameterSetManager::ParameterSetManager()
: m_spsMap(MAX_NUM_SPS)
#endif
, m_ppsMap(MAX_NUM_PPS)
#if JVET_M0132
, m_apsMap(MAX_NUM_APS)
#endif
#if HEVC_VPS
, m_activeVPSId(-1)
#endif
......@@ -2520,6 +2537,28 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
return false;
}
#if JVET_M0132
bool ParameterSetManager::activateAPS(int apsId)
{
APS *aps = m_apsMap.getPS(apsId);
if (aps)
{
m_apsMap.setActive(apsId);
return true;
}
else
{
msg(WARNING, "Warning: tried to activate non-existing APS.");
}
return false;
}
template <>
void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId)
{
parameterSet->setAPSId(psId);
}
#endif
template <>
void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId)
{
......@@ -2645,6 +2684,13 @@ void xTracePPSHeader()
DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set ===========\n" );
}
#if JVET_M0132
void xTraceAPSHeader()
{
DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set ===========\n");
}
#endif
void xTraceSliceHeader()
{
DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
......
......@@ -1563,6 +1563,24 @@ public:
PPSRExt& getPpsRangeExtension() { return m_ppsRangeExtension; }
};
#if JVET_M0132
class APS
{
private:
int m_APSId; // adaptation_parameter_set_id
AlfSliceParam m_alfAPSParam;
public:
APS();
virtual ~APS();
int getAPSId() const { return m_APSId; }
void setAPSId(int i) { m_APSId = i; }
void setAlfAPSParam(AlfSliceParam& alfAPSParam) { m_alfAPSParam = alfAPSParam; }
AlfSliceParam getAlfAPSParam() { return m_alfAPSParam; }
};
#endif
struct WPScalingParam
{
// Explicit weighted prediction parameters parsed in slice header,
......@@ -1719,6 +1737,10 @@ private:
uint32_t m_uiMaxTTSizeIChroma;
uint32_t m_uiMaxBTSize;
#if JVET_M0132
int m_apsId;
APS* m_aps;
#endif
AlfSliceParam m_alfSliceParam;
#if JVET_M0427_INLOOP_RESHAPER
SliceReshapeInfo m_sliceReshapeInfo;
......@@ -1740,6 +1762,12 @@ public:
void setPPSId( int PPSId ) { m_iPPSId = PPSId; }
int getPPSId() const { return m_iPPSId; }
#if JVET_M0132
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; }
......@@ -2197,6 +2225,14 @@ public:
//! \returns true, if activation is successful
bool activatePPS(int ppsId, bool isIRAP);
#if JVET_M0132
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); }
void clearAPSChangedFlag(int apsId) { m_apsMap.clearChangedFlag(apsId); }
APS* getFirstAPS() { return m_apsMap.getFirstPS(); };
bool activateAPS(int apsId);
#endif
#if HEVC_VPS
const VPS* getActiveVPS()const { return m_vpsMap.getPS(m_activeVPSId); };
#endif
......@@ -2208,6 +2244,9 @@ protected:
#endif
ParameterSetMap<SPS> m_spsMap;
ParameterSetMap<PPS> m_ppsMap;
#if JVET_M0132
ParameterSetMap<APS> m_apsMap;
#endif
#if HEVC_VPS
int m_activeVPSId; // -1 for nothing active
......@@ -2302,6 +2341,9 @@ void xTraceVPSHeader();
#endif
void xTraceSPSHeader();
void xTracePPSHeader();
#if JVET_M0132
void xTraceAPSHeader();
#endif
void xTraceSliceHeader();
void xTraceAccessUnitDelimiter();
#endif
......
......@@ -332,6 +332,7 @@ typedef std::pair<int, int> TrCost;
#define X0038_LAMBDA_FROM_QP_CAPABILITY 1 ///< This approach derives lambda from QP+QPoffset+QPoffset2. QPoffset2 is derived from QP+QPoffset using a linear model that is clipped between 0 and 3.
// To use this capability enable config parameter LambdaFromQpEnable
#define JVET_M0132 1
// ====================================================================================================================
// Tool Switches
// ====================================================================================================================
......@@ -977,6 +978,9 @@ enum NalUnitType
#endif
NAL_UNIT_SPS, // 33
NAL_UNIT_PPS, // 34
#if JVET_M0132
NAL_UNIT_APS, //NAL unit type number needs to be reaaranged.
#endif
NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35
NAL_UNIT_EOS, // 36
NAL_UNIT_EOB, // 37
......
......@@ -738,6 +738,13 @@ void DecLib::xActivateParameterSets()
{
if (m_bFirstSliceInPicture)
{
#if JVET_M0132
APS *aps = m_parameterSetManager.getAPS(m_apcSlicePilot->getAPSId()); // this is a temporary APS object. Do not store this value
if (m_apcSlicePilot->getAPSId() != -1)
{
CHECK(aps == 0, "No APS present");
}
#endif
const PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId()); // this is a temporary PPS object. Do not store this value
CHECK(pps == 0, "No PPS present");
......@@ -751,6 +758,11 @@ void DecLib::xActivateParameterSets()
m_parameterSetManager.clearSPSChangedFlag(sps->getSPSId());
m_parameterSetManager.clearPPSChangedFlag(pps->getPPSId());
#if JVET_M0132 //Hendry
if (aps != 0)
m_parameterSetManager.clearAPSChangedFlag(aps->getAPSId());
#endif
if (false == m_parameterSetManager.activatePPS(m_apcSlicePilot->getPPSId(),m_apcSlicePilot->isIRAP()))
{
THROW("Parameter set activation failed!");
......@@ -770,7 +782,11 @@ void DecLib::xActivateParameterSets()
m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS());
#if JVET_M0132
m_pcPic->finalInit(*sps, *pps, *aps);
#else
m_pcPic->finalInit( *sps, *pps );
#endif
m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth );
m_pcPic->cs->createCoeffs();
......@@ -784,6 +800,9 @@ void DecLib::xActivateParameterSets()
Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
// Update the PPS and SPS pointers with the ones of the picture.
#if JVET_M0132
aps= pSlice->getAPS();
#endif
pps=pSlice->getPPS();
sps=pSlice->getSPS();
......@@ -791,6 +810,9 @@ void DecLib::xActivateParameterSets()
m_pcPic->cs->slice = pSlice;
m_pcPic->cs->sps = sps;
m_pcPic->cs->pps = pps;
#if JVET_M0132
m_pcPic->cs->aps = aps;
#endif
#if HEVC_VPS
m_pcPic->cs->vps = pSlice->getVPS();
#endif
......@@ -866,11 +888,16 @@ void DecLib::xActivateParameterSets()
const SPS *sps = pSlice->getSPS();
const PPS *pps = pSlice->getPPS();
#if JVET_M0132
APS *aps = pSlice->getAPS();
#endif
// fix Parameter Sets, now that we have the real slice
m_pcPic->cs->slice = pSlice;
m_pcPic->cs->sps = sps;
m_pcPic->cs->pps = pps;
#if JVET_M0132
m_pcPic->cs->aps = aps;
#endif
#if HEVC_VPS
m_pcPic->cs->vps = pSlice->getVPS();
#endif
......@@ -885,6 +912,12 @@ void DecLib::xActivateParameterSets()
{
EXIT("Error - a new PPS has been decoded while processing a picture");
}
#if JVET_M0132
if (aps && m_parameterSetManager.getAPSChangedFlag(aps->getAPSId()))
{
EXIT("Error - a new APS has been decoded while processing a picture");
}
#endif
xParsePrefixSEImessages();
......@@ -1049,6 +1082,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
int iMaxPOClsb = 1 << sps->getBitsForPOC();
m_apcSlicePilot->setPOC( m_apcSlicePilot->getPOC() & (iMaxPOClsb - 1) );
xUpdatePreviousTid0POC(m_apcSlicePilot);
#if JVET_M0132
if (m_apcSlicePilot->getAPSId() != -1)
{
APS *aps = m_parameterSetManager.getAPS(m_apcSlicePilot->getAPSId());
CHECK(aps == 0, "No APS present");
}
#endif
}
// Skip pictures due to random access
......@@ -1403,6 +1443,15 @@ void DecLib::xDecodePPS( InputNALUnit& nalu )
m_parameterSetManager.storePPS( pps, nalu.getBitstream().getFifo() );
}
#if JVET_M0132
void DecLib::xDecodeAPS(InputNALUnit& nalu)
{
APS* aps = new APS();
m_HLSReader.setBitstream(&nalu.getBitstream());
m_HLSReader.parseAPS(aps);
m_parameterSetManager.storeAPS(aps, nalu.getBitstream().getFifo());
}
#endif
bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
{
bool ret;
......@@ -1428,6 +1477,11 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
case NAL_UNIT_PPS:
xDecodePPS( nalu );
return false;
#if JVET_M0132
case NAL_UNIT_APS:
xDecodeAPS(nalu);
return false;
#endif
case NAL_UNIT_PREFIX_SEI:
// Buffer up prefix SEI messages until SPS of associated VCL is known.
......
......@@ -184,6 +184,9 @@ protected:
#endif
void xDecodeSPS( InputNALUnit& nalu );
void xDecodePPS( InputNALUnit& nalu );
#if JVET_M0132
void xDecodeAPS(InputNALUnit& nalu);
#endif
void xUpdatePreviousTid0POC( Slice *pSlice ) { if ((pSlice->getTLayer()==0) && (pSlice->isReferenceNalu() && (pSlice->getNalUnitType()!=NAL_UNIT_CODED_SLICE_RASL_R)&& (pSlice->getNalUnitType()!=NAL_UNIT_CODED_SLICE_RADL_R))) { m_prevTid0POC=pSlice->getPOC(); } }
void xParsePrefixSEImessages();
void xParsePrefixSEIsForUnknownVCLNal();
......
......@@ -91,6 +91,9 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream )
cs.slice = slice;
cs.sps = sps;
cs.pps = slice->getPPS();
#if JVET_M0132
cs.aps = slice->getAPS();
#endif
#if HEVC_VPS
cs.vps = slice->getVPS();
#endif
......
......@@ -607,6 +607,52 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
xReadRbspTrailingBits();
}
#if JVET_M0132
void HLSyntaxReader::parseAPS(APS* aps)
{
#if ENABLE_TRACING
xTraceAPSHeader();
#endif
uint32_t code;
READ_CODE(5, code, "adaptation_parameter_set_id");
aps->setAPSId(code);
AlfSliceParam param = aps->getAlfAPSParam();
param.enabledFlag[COMPONENT_Y] = true;
int alfChromaIdc = truncatedUnaryEqProb(3); //alf_chroma_idc
param.enabledFlag[COMPONENT_Cb] = alfChromaIdc >> 1;
param.enabledFlag[COMPONENT_Cr] = alfChromaIdc & 1;
xReadTruncBinCode(code, MAX_NUM_ALF_CLASSES); //number_of_filters_minus1
param.numLumaFilters = code + 1;
if (param.numLumaFilters > 1)
{
for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++)
{
xReadTruncBinCode(code, param.numLumaFilters);
param.filterCoeffDeltaIdx[i] = code;
}
}
else
{
memset(param.filterCoeffDeltaIdx, 0, sizeof(param.filterCoeffDeltaIdx));
}
alfFilter(param, false);
if (alfChromaIdc)
{
alfFilter(param, true);
}
aps->setAlfAPSParam(param);
xReadRbspTrailingBits();
}
#endif
void HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS)
{
#if ENABLE_TRACING
......@@ -1601,7 +1647,26 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
if( sps->getALFEnabledFlag() )
{
#if JVET_M0132
READ_FLAG(uiCode, "tile_group_alf_enabled_flag");
if (uiCode)
{
READ_CODE(5, uiCode, "tile_group_aps_id");
pcSlice->setAPSId(uiCode);
pcSlice->setAPS(parameterSetManager->getAPS(uiCode));
AlfSliceParam alfParam = pcSlice->getAPS()->getAlfAPSParam();
pcSlice->setAlfSliceParam(alfParam);
pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y] = true;
}
else
{
pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y] = false;
pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Cb] = false;
pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Cr] = false;
}
#else
alf( pcSlice->getAlfSliceParam() );
#endif
}
if (pcSlice->getIdrPicFlag())
......@@ -2426,6 +2491,7 @@ bool HLSyntaxReader::xMoreRbspData()
return (cnt>0);
}
#if !JVET_M0132
void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam )
{
uint32_t code;
......@@ -2464,6 +2530,7 @@ void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam )
alfFilter( alfSliceParam, true );
}
}
#endif
int HLSyntaxReader::alfGolombDecode( const int k )
{
......
......@@ -149,6 +149,9 @@ public:
#endif
void parseSPS ( SPS* pcSPS );
void parsePPS ( PPS* pcPPS );
#if JVET_M0132
void parseAPS ( APS* pcAPS);
#endif
void parseVUI ( VUI* pcVUI, SPS* pcSPS );
void parsePTL ( PTL *rpcPTL, bool profilePresentFlag, int maxNumSubLayersMinus1 );
void parseProfileTier ( ProfileTierLevel *ptl, const bool bIsSubLayer );
......@@ -165,7 +168,9 @@ public:
#if JVET_M0427_INLOOP_RESHAPER
void parseReshaper ( SliceReshapeInfo& sliceReshaperInfo, const SPS* pcSPS, const bool isIntra );
#endif
#if !JVET_M0132
void alf( AlfSliceParam& alfSliceParam );
#endif
void alfFilter( AlfSliceParam& alfSliceParam, const bool isChroma );
private:
......
......@@ -237,6 +237,16 @@ int EncGOP::xWritePPS (AccessUnit &accessUnit, const PPS *pps)
return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
}
#if JVET_M0132
int EncGOP::xWriteAPS(AccessUnit &accessUnit, APS *aps)
{
OutputNALUnit nalu(NAL_UNIT_APS);
m_HLSWriter->setBitstream(&nalu.m_Bitstream);
m_HLSWriter->codeAPS(aps);
accessUnit.push_back(new NALUnitEBSP(nalu));
return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
}
#endif
int EncGOP::xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst)
{
......@@ -2549,6 +2559,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
{
xWriteAccessUnitDelimiter(accessUnit, pcSlice);
}
#if JVET_M0132
if (pcSlice->getSPS()->getALFEnabledFlag() && pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y])
{
pcSlice->setAPSId(pcSlice->getAPS()->getAPSId());
pcSlice->getAPS()->setAlfAPSParam(pcSlice->getAlfSliceParam());
actualTotalBits += xWriteAPS(accessUnit, pcSlice->getAPS());
}
#endif
// reset presence of BP SEI indication
m_bufferingPeriodSEIPresentInAU = false;
......
......@@ -281,6 +281,9 @@ protected:
#endif
int xWriteSPS (AccessUnit &accessUnit, const SPS *sps);
int xWritePPS (AccessUnit &accessUnit, const PPS *pps);
#if JVET_M0132