diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index a38a1174f8f581354335161834968ec88d28b1f2..5f1c4f41db5efd26622f62cda6c91f4414f508b8 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -859,6 +859,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: @@ -875,7 +878,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 } } diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp index e6443eaf190ba9614243af216fa32a4572162f77..2480310f5264da07eb77ebf6dcbc33910cdebc75 100644 --- a/source/App/Parcat/parcat.cpp +++ b/source/App/Parcat/parcat.cpp @@ -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", diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h index 67ca6d94738a476430f8d78f28e61bfc22a143ce..ae2c6e3cc16db66fbfe9b233744057d1bc16ef8b 100644 --- a/source/Lib/CommonLib/CodingStructure.h +++ b/source/Lib/CommonLib/CodingStructure.h @@ -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 diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 6d09dc35f650e11d42a96fe0daf219da1381a6e5..1f23d7a3480d6870ec15a4b073e35e9a844a8077 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -186,6 +186,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) diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 2b8f46593b255789956d72dac002c75ba4d659a0..286810db34d7c2fbc60ffd3463b0ee56201a63fe 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -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; } diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index fd014dcb58987ca7901c3504d16849588c259c18..e9c3a2c625141c8dc15f8e270bd00eee1d7c555d 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -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;} diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index 8494ab1b8e11a2f5d9f9378aaa9b7dac3872859b..31bb0728a56b294032f8f01d7e7b45ee31227706 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -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"; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 8baeacce8e337e6d675e0dc42071aaf458a639ea..4327c885d781c86dbb012b4f663f4acd062e189e 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -139,6 +139,10 @@ Slice::Slice() , m_uiMaxBTSizeIChroma ( 0 ) , m_uiMaxTTSizeIChroma ( 0 ) , m_uiMaxBTSize ( 0 ) +#if JVET_M0132 +, m_iAPSId ( -1 ) +, m_pcAPS (NULL) +#endif , m_MotionCandLut (NULL) #if JVET_M0170_MRG_SHARELIST , m_MotionCandLuTsBkup (NULL) @@ -2102,6 +2106,16 @@ PPS::~PPS() delete pcv; } +#if JVET_M0132 +APS::APS() +: m_APSId(0) +{ +} + +APS::~APS() +{ +} +#endif ReferencePictureSet::ReferencePictureSet() : m_numberOfPictures (0) , m_numberOfNegativePictures (0) @@ -2580,6 +2594,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 @@ -2690,6 +2707,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) { diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ffe92ca71fd05e343df8125d262612e6a2351c46..54ba6b5e4ef51beee52df2ab21ba63521fe8849d 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1573,6 +1573,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, @@ -1730,6 +1748,10 @@ private: uint32_t m_uiMaxTTSizeIChroma; uint32_t m_uiMaxBTSize; +#if JVET_M0132 + int m_iAPSId; + APS* m_pcAPS; +#endif AlfSliceParam m_alfSliceParam; LutMotionCand* m_MotionCandLut; #if JVET_M0427_INLOOP_RESHAPER @@ -1756,6 +1778,12 @@ public: void setPPSId( int PPSId ) { m_iPPSId = PPSId; } int getPPSId() const { return m_iPPSId; } +#if JVET_M0132 + void setAPS(APS* pcAPS) { m_pcAPS = pcAPS; m_iAPSId = (pcAPS) ? pcAPS->getAPSId() : -1; } + APS* getAPS() { return m_pcAPS; } + void setAPSId(int APSId) { m_iAPSId = APSId; } + int getAPSId() const { return m_iAPSId; } +#endif void setPicOutputFlag( bool b ) { m_PicOutputFlag = b; } bool getPicOutputFlag() const { return m_PicOutputFlag; } void setSaoEnabledFlag(ChannelType chType, bool s) {m_saoEnabledFlag[chType] =s; } @@ -2239,6 +2267,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 @@ -2250,6 +2286,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 diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index e5d55f34e371df0ef8693d3ad37b3e2fd137df6c..83efdc016b36f24fe08c6acfbac22eaa79bc86db 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -328,6 +328,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 // ==================================================================================================================== @@ -973,6 +974,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 diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index c45864f6290260c7637df32b15d28df860fa76e8..48af875742eb28dc422f8de39f5b3d355a10c524 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -739,6 +739,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"); @@ -771,7 +778,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(); @@ -785,6 +796,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(); @@ -792,6 +806,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 @@ -863,11 +880,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 @@ -882,6 +904,12 @@ void DecLib::xActivateParameterSets() { EXIT("Error - a new PPS has been decoded while processing a picture"); } +#if JVET_M0132 + if (m_parameterSetManager.getAPSChangedFlag(aps->getAPSId())) + { + EXIT("Error - a new APS has been decoded while processing a picture"); + } +#endif xParsePrefixSEImessages(); @@ -1046,6 +1074,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 @@ -1401,6 +1436,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; @@ -1426,6 +1470,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. diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index ae94530450e6a9402275be64a23afaf6454dd2ba..9eea5fb986d367da97528a3547482fceaa4e5b68 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -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(); diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index b365dd7e042435fcaee8b904e82eedcccb756228..9278575af179c654e4db9b3baacc91e7b37896b8 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -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 diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 56c467b818093085bd982fec12afd724fb325baf..3c4351e78887aa6af8e36ced8acc3abb35982d3c 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -607,6 +607,48 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS ) xReadRbspTrailingBits(); } +#if JVET_M0132 +void HLSyntaxReader::parseAPS(APS* pcAPS) +{ + uint32_t uiCode; + + READ_CODE(5, uiCode, "adaptation_parameter_set_id"); + pcAPS->setAPSId(uiCode); + + uint32_t code = 1; + AlfSliceParam param = pcAPS->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); + } + pcAPS->setAlfAPSParam(param); + + xReadRbspTrailingBits(); +} +#endif void HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS) { #if ENABLE_TRACING @@ -1602,7 +1644,25 @@ 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)); + pcSlice->setAlfSliceParam(pcSlice->getAPS()->getAlfAPSParam()); + 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()) @@ -2427,6 +2487,7 @@ bool HLSyntaxReader::xMoreRbspData() return (cnt>0); } +#if !JVET_M0132 void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam ) { uint32_t code; @@ -2465,6 +2526,7 @@ void HLSyntaxReader::alf( AlfSliceParam& alfSliceParam ) alfFilter( alfSliceParam, true ); } } +#endif int HLSyntaxReader::alfGolombDecode( const int k ) { diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index b8fa2d66a90a105247e1f3e3cc17bfe53e499de4..a7d47899b2511823fd7e0e01dcad6e99b4236160 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -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: diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 1b65607633369ca81e8084292c9cb754496b5962..da2d361916ecf7b5535d323729f99cc9386770ef 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -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) { @@ -2545,6 +2555,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; diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index e2c11c170105b077021b497b661030ac06930798..975609f7b29f92a5dded3f48bada224ae0565a0e 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -281,6 +281,9 @@ protected: #endif int xWriteSPS (AccessUnit &accessUnit, const SPS *sps); int xWritePPS (AccessUnit &accessUnit, const PPS *pps); +#if JVET_M0132 + int xWriteAPS(AccessUnit &accessUnit, APS *aps); +#endif int xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst); void applyDeblockingFilterMetric( Picture* pcPic, uint32_t uiNumSlices ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index c975d68d8e9c510d259ed15273a0adfaa4dcb8b6..b73b3ac67590eb587c3c8c64c68f48fadde97fba 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -60,6 +60,9 @@ EncLib::EncLib() : m_spsMap( MAX_NUM_SPS ) , m_ppsMap( MAX_NUM_PPS ) +#if JVET_M0132 + , m_apsMap( MAX_NUM_APS ) +#endif , m_AUWriterIf( nullptr ) #if JVET_J0090_MEMORY_BANDWITH_MEASURE , m_cacheModel() @@ -214,6 +217,9 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) SPS &sps0=*(m_spsMap.allocatePS(0)); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues. PPS &pps0=*(m_ppsMap.allocatePS(0)); +#if JVET_M0132 + APS &aps0=*(m_apsMap.allocatePS(0)); +#endif // initialize SPS xInitSPS(sps0); @@ -251,6 +257,10 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) // initialize PPS xInitPPS(pps0, sps0); +#if JVET_M0132 + // initialize APS + xInitAPS(aps0); +#endif xInitRPS(sps0, isFieldCoding); #if ER_CHROMA_QP_WCG_PPS @@ -376,7 +386,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) Picture *picBg = new Picture; picBg->create(sps0.getChromaFormatIdc(), Size(sps0.getPicWidthInLumaSamples(), sps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + 16, false); picBg->getRecoBuf().fill(0); +#if JVET_M0132 + picBg->finalInit(sps0, pps0, aps0); +#else picBg->finalInit(sps0, pps0); +#endif picBg->allocateNewSlice(); picBg->createSpliceIdx(pps0.pcv->sizeInCtus); m_cGOPEncoder.setPicBg(picBg); @@ -527,7 +541,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru const SPS *sps = m_spsMap.getPS(pps->getSPSId()); picCurr->M_BUFS(0, PIC_ORIGINAL).copyFrom(m_cGOPEncoder.getPicBg()->getRecoBuf()); +#if JVET_M0132 + APS *aps = m_apsMap.getPS(0); + picCurr->finalInit(*sps, *pps, *aps); +#else picCurr->finalInit(*sps, *pps); +#endif picCurr->poc = m_iPOCLast - 1; m_iPOCLast -= 2; if (getUseAdaptiveQP()) @@ -578,7 +597,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL).swap(*cPicYuvTrueOrg); #endif +#if JVET_M0132 + APS *pAPS = m_apsMap.getPS(0); + pcPicCurr->finalInit(*pSPS, *pPPS, *pAPS); +#else pcPicCurr->finalInit( *pSPS, *pPPS ); +#endif } pcPicCurr->poc = m_iPOCLast; @@ -673,7 +697,12 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr const PPS *pPPS=(ppsID<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsID); const SPS *pSPS=m_spsMap.getPS(pPPS->getSPSId()); +#if JVET_M0132 + APS *pAPS = m_apsMap.getPS(0); + pcField->finalInit(*pSPS, *pPPS, *pAPS); +#else pcField->finalInit( *pSPS, *pPPS ); +#endif } pcField->poc = m_iPOCLast; @@ -1492,6 +1521,12 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) pps.pcv = new PreCalcValues( sps, pps, true ); } +#if JVET_M0132 +void EncLib::xInitAPS(APS &aps) +{ + //Do nothing now +} +#endif //Function for initializing m_RPSList, a list of ReferencePictureSet, based on the GOPEntry objects read from the config file. void EncLib::xInitRPS(SPS &sps, bool isFieldCoding) { @@ -1864,6 +1899,14 @@ void EncLib::setParamSetChanged(int spsId, int ppsId) m_spsMap.setChangedFlag(spsId); } #endif +#if JVET_M0132 +bool EncLib::APSNeedsWriting(int apsId) +{ + bool bChanged = m_apsMap.getChangedFlag(apsId); + m_apsMap.clearChangedFlag(apsId); + return bChanged; +} +#endif bool EncLib::PPSNeedsWriting(int ppsId) { diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index d143e79b28d3d2554017022d95bfe44d2e293f89..9d70ff9db60e626c5eea678933a4bde13fd6eb84 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -116,6 +116,9 @@ private: // SPS ParameterSetMap<SPS> m_spsMap; ///< SPS. This is the base value. This is copied to PicSym ParameterSetMap<PPS> m_ppsMap; ///< PPS. This is the base value. This is copied to PicSym +#if JVET_M0132 + ParameterSetMap<APS> m_apsMap; ///< APS. This is the base value. This is copied to PicSym +#endif // RD cost computation #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM RdCost *m_cRdCost; ///< RD cost computation class @@ -150,6 +153,9 @@ protected: #endif void xInitSPS (SPS &sps); ///< initialize SPS from encoder options void xInitPPS (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options +#if JVET_M0132 + void xInitAPS (APS &aps); ///< initialize APS from encoder options +#endif #if HEVC_USE_SCALING_LISTS void xInitScalingLists (SPS &sps, PPS &pps); ///< initialize scaling lists #endif @@ -219,10 +225,16 @@ public: #if JCTVC_Y0038_PARAMS void setParamSetChanged(int spsId, int ppsId); +#endif +#if JVET_M0132 + bool APSNeedsWriting(int apsId); #endif bool PPSNeedsWriting(int ppsId); bool SPSNeedsWriting(int spsId); const PPS* getPPS( int Id ) { return m_ppsMap.getPS( Id); } +#if JVET_M0132 + const APS* getAPS(int Id) { return m_apsMap.getPS(Id); } +#endif #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM void setNumCuEncStacks( int n ) { m_numCuEncStacks = n; } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index e28d975da3553ebe0de3d39031ab4750dc348b75..50accf3328b191cdecaf3c86c3d8783bea88730c 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -365,6 +365,33 @@ void HLSWriter::codePPS( const PPS* pcPPS ) xWriteRbspTrailingBits(); } +#if JVET_M0132 +void HLSWriter::codeAPS( APS* pcAPS) +{ + AlfSliceParam param = pcAPS->getAlfAPSParam(); + WRITE_CODE(pcAPS->getAPSId(), 5, "adaptation_parameter_set_id"); + + const int alfChromaIdc = param.enabledFlag[COMPONENT_Cb] * 2 + param.enabledFlag[COMPONENT_Cr]; + truncatedUnaryEqProb(alfChromaIdc, 3); // alf_chroma_idc + + xWriteTruncBinCode(param.numLumaFilters - 1, MAX_NUM_ALF_CLASSES); //number_of_filters_minus1 + if (param.numLumaFilters > 1) + { + for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++) + { + xWriteTruncBinCode((uint32_t)param.filterCoeffDeltaIdx[i], param.numLumaFilters); //filter_coeff_delta[i] + } + } + + alfFilter(param, false); + + if (alfChromaIdc) + { + alfFilter(param, true); + } + xWriteRbspTrailingBits(); +} +#endif void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS ) { #if ENABLE_TRACING @@ -1179,7 +1206,15 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) if( pcSlice->getSPS()->getALFEnabledFlag() ) { +#if JVET_M0132 + WRITE_FLAG(pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y], "tile_group_alf_enabled_flag"); + if (pcSlice->getAlfSliceParam().enabledFlag[COMPONENT_Y]) + { + WRITE_CODE(pcSlice->getAPSId(), 5, "tile_group_aps_id"); + } +#else alf( pcSlice->getAlfSliceParam() ); +#endif } //check if numrefidxes match the defaults. If not, override @@ -1729,6 +1764,7 @@ bool HLSWriter::xFindMatchingLTRP(Slice* pcSlice, uint32_t *ltrpsIndex, int ltrp return false; } +#if !JVET_M0132 void HLSWriter::alf( const AlfSliceParam& alfSliceParam ) { WRITE_FLAG( alfSliceParam.enabledFlag[COMPONENT_Y], "tile_group_alf_enabled_flag" ); @@ -1756,6 +1792,7 @@ void HLSWriter::alf( const AlfSliceParam& alfSliceParam ) alfFilter( alfSliceParam, true ); } } +#endif void HLSWriter::alfGolombEncode( int coeff, int k ) { diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index b3866e8ab3a78c22f66574ec4eda016167dc362d..e1e3fd853e7c866b0306e94b1cf4785f03198bd2 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -122,6 +122,9 @@ public: void codeVUI ( const VUI *pcVUI, const SPS* pcSPS ); void codeSPS ( const SPS* pcSPS ); void codePPS ( const PPS* pcPPS ); +#if JVET_M0132 + void codeAPS ( APS* pcAPS); +#endif #if HEVC_VPS void codeVPS ( const VPS* pcVPS ); #endif @@ -136,7 +139,9 @@ public: void codeScalingList ( const ScalingList &scalingList ); #endif +#if !JVET_M0132 void alf( const AlfSliceParam& alfSliceParam ); +#endif void alfFilter( const AlfSliceParam& alfSliceParam, const bool isChroma ); private: