From 2d15ef72ddcd3273ed9122197bbac661478112cc Mon Sep 17 00:00:00 2001 From: "moonmo.koo" <moonmo.koo@lge.com> Date: Sat, 24 Aug 2019 10:50:13 +0900 Subject: [PATCH] JVET_O0299: Support for user defined Scaling List Matrices in the APS - This merge request provides the implementation for JVET_O0299, i.e., Support for user defined Scaling List Matrics in the APS. --- source/Lib/CommonLib/CodingStructure.cpp | 3 + source/Lib/CommonLib/CodingStructure.h | 3 + source/Lib/CommonLib/Picture.cpp | 16 +++++ source/Lib/CommonLib/Picture.h | 4 ++ source/Lib/CommonLib/Slice.cpp | 19 ++++++ source/Lib/CommonLib/Slice.h | 31 ++++++++++ source/Lib/CommonLib/TypeDef.h | 5 ++ source/Lib/DecoderLib/DecLib.cpp | 63 ++++++++++++++++++++ source/Lib/DecoderLib/DecSlice.cpp | 3 + source/Lib/DecoderLib/VLCReader.cpp | 39 +++++++++++++ source/Lib/DecoderLib/VLCReader.h | 3 + source/Lib/EncoderLib/EncGOP.cpp | 52 +++++++++++++++++ source/Lib/EncoderLib/EncGOP.h | 3 + source/Lib/EncoderLib/EncLib.cpp | 74 +++++++++++++++++++++++- source/Lib/EncoderLib/EncLib.h | 7 +++ source/Lib/EncoderLib/VLCWriter.cpp | 28 +++++++++ source/Lib/EncoderLib/VLCWriter.h | 3 + 17 files changed, 354 insertions(+), 2 deletions(-) diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp index 93faa5f5aa..2df5fd5627 100644 --- a/source/Lib/CommonLib/CodingStructure.cpp +++ b/source/Lib/CommonLib/CodingStructure.cpp @@ -1026,6 +1026,9 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe memcpy(subStruct.alfApss, alfApss, sizeof(alfApss)); subStruct.lmcsAps = lmcsAps; +#if JVET_O0299_APS_SCALINGLIST + subStruct.scalinglistAps = scalinglistAps; +#endif subStruct.slice = slice; subStruct.baseQP = baseQP; diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h index 082238419a..d3c5c248f2 100644 --- a/source/Lib/CommonLib/CodingStructure.h +++ b/source/Lib/CommonLib/CodingStructure.h @@ -107,6 +107,9 @@ public: APS* alfApss[MAX_NUM_APS]; #endif APS * lmcsAps; +#if JVET_O0299_APS_SCALINGLIST + APS * scalinglistAps; +#endif const VPS *vps; const PreCalcValues* pcv; diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 776b2fa956..73d3e108ad 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -886,7 +886,11 @@ const CPelUnitBuf Picture::getRecoBuf(const UnitArea &unit, bool wrap) const PelUnitBuf Picture::getRecoBuf(bool wrap) { return M_BUFS(scheduler.getSplitPicId(), wrap ? PIC_RECON_WRAP : PIC_RECONSTRUCTION); } const CPelUnitBuf Picture::getRecoBuf(bool wrap) const { return M_BUFS(scheduler.getSplitPicId(), wrap ? PIC_RECON_WRAP : PIC_RECONSTRUCTION); } +#if JVET_O0299_APS_SCALINGLIST +void Picture::finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS& lmcsAps, APS& scalingListAps ) +#else void Picture::finalInit(const SPS& sps, const PPS& pps, APS** alfApss, APS& lmcsAps) +#endif { for( auto &sei : SEIs ) { @@ -927,6 +931,9 @@ void Picture::finalInit(const SPS& sps, const PPS& pps, APS** alfApss, APS& lmcs cs->pps = &pps; memcpy(cs->alfApss, alfApss, sizeof(cs->alfApss)); cs->lmcsAps = &lmcsAps; +#if JVET_O0299_APS_SCALINGLIST + cs->scalinglistAps = &scalingListAps; +#endif cs->pcv = pps.pcv; @@ -947,6 +954,9 @@ void Picture::allocateNewSlice() memcpy(slice.getAlfAPSs(), cs->alfApss, sizeof(cs->alfApss)); slice.setLmcsAPS(cs->lmcsAps); +#if JVET_O0299_APS_SCALINGLIST + slice.setscalingListAPS( cs->scalinglistAps ); +#endif slice.setPPS( cs->pps); slice.setSPS( cs->sps); @@ -964,6 +974,9 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i) p->setAlfAPSs(cs->alfApss); p->setLmcsAPS(cs->lmcsAps); +#if JVET_O0299_APS_SCALINGLIST + p->setscalingListAPS( cs->scalinglistAps ); +#endif Slice * pTmp = slices[i]; slices[i] = p; @@ -976,6 +989,9 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i) #endif pTmp->setLmcsAPS(0); +#if JVET_O0299_APS_SCALINGLIST + pTmp->setscalingListAPS( 0 ); +#endif return pTmp; } diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index ae97b1d917..f8e62a92c0 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -237,7 +237,11 @@ struct Picture : public UnitArea const CPelUnitBuf getBuf(const UnitArea &unit, const PictureType &type) const; void extendPicBorder(); +#if JVET_O0299_APS_SCALINGLIST + void finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS& lmcsAps, APS& scalingListAps ); +#else void finalInit(const SPS& sps, const PPS& pps, APS** alfApss, APS& lmcsAps); +#endif int getPOC() const { return poc; } void setBorderExtension( bool bFlag) { m_bIsBorderExtended = bFlag;} diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index d068d5c875..9c75bcf3cb 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -125,6 +125,11 @@ Slice::Slice() , m_lmcsAps (nullptr) , m_tileGroupLmcsEnabledFlag (false) , m_tileGroupLmcsChromaResidualScaleFlag (false) +#if JVET_O0299_APS_SCALINGLIST +, m_scalingListApsId ( -1 ) +, m_scalingListAps ( nullptr ) +, m_tileGroupscalingListPresentFlag ( false ) +#endif { for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++) { @@ -734,6 +739,12 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) m_tileGroupLmcsChromaResidualScaleFlag = pSrc->m_tileGroupLmcsChromaResidualScaleFlag; m_lmcsAps = pSrc->m_lmcsAps; m_lmcsApsId = pSrc->m_lmcsApsId; + +#if JVET_O0299_APS_SCALINGLIST + m_tileGroupscalingListPresentFlag = pSrc->m_tileGroupscalingListPresentFlag; + m_scalingListAps = pSrc->m_scalingListAps; + m_scalingListApsId = pSrc->m_scalingListApsId; +#endif } @@ -2298,7 +2309,11 @@ uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chTy } #if JVET_O1164_RPR +#if JVET_O0299_APS_SCALINGLIST +void Slice::scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS& lmcsAps, APS& scalingListAps, const bool isDecoder ) +#else void Slice::scaleRefPicList( Picture *scaledRefPic[], APS** apss, APS& lmcsAps, const bool isDecoder ) +#endif { int i; const SPS* sps = getSPS(); @@ -2373,7 +2388,11 @@ void Slice::scaleRefPicList( Picture *scaledRefPic[], APS** apss, APS& lmcsAps, scaledRefPic[j]->reconstructed = false; scaledRefPic[j]->referenced = true; +#if JVET_O0299_APS_SCALINGLIST + scaledRefPic[ j ]->finalInit( *sps, *pps, apss, lmcsAps, scalingListAps ); +#else scaledRefPic[j]->finalInit( *sps, *pps, apss, lmcsAps ); +#endif scaledRefPic[j]->poc = -1; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ab8699180a..8af8b24927 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1065,10 +1065,12 @@ public: bool getScalingListFlag() const { return m_scalingListEnabledFlag; } void setScalingListFlag( bool b ) { m_scalingListEnabledFlag = b; } +#if !JVET_O0299_APS_SCALINGLIST // remove from SPS bool getScalingListPresentFlag() const { return m_scalingListPresentFlag; } void setScalingListPresentFlag( bool b ) { m_scalingListPresentFlag = b; } ScalingList& getScalingList() { return m_scalingList; } const ScalingList& getScalingList() const { return m_scalingList; } +#endif uint32_t getMaxDecPicBuffering(uint32_t tlayer) const { return m_uiMaxDecPicBuffering[tlayer]; } void setMaxDecPicBuffering( uint32_t ui, uint32_t tlayer ) { CHECK(tlayer >= MAX_TLAYER, "Invalid T-layer"); m_uiMaxDecPicBuffering[tlayer] = ui; } uint32_t getMaxLatencyIncreasePlus1(uint32_t tlayer) const { return m_uiMaxLatencyIncreasePlus1[tlayer]; } @@ -1315,8 +1317,10 @@ private: bool m_ppsDeblockingFilterDisabledFlag; int m_deblockingFilterBetaOffsetDiv2; //< beta offset for deblocking filter int m_deblockingFilterTcOffsetDiv2; //< tc offset for deblocking filter +#if !JVET_O0299_APS_SCALINGLIST // PPS bool m_scalingListPresentFlag; ScalingList m_scalingList; //!< ScalingList class +#endif bool m_listsModificationPresentFlag; uint32_t m_log2ParallelMergeLevelMinus2; int m_numExtraSliceHeaderBits; @@ -1473,10 +1477,12 @@ public: int getDeblockingFilterBetaOffsetDiv2() const { return m_deblockingFilterBetaOffsetDiv2; } //!< get beta offset for deblocking filter void setDeblockingFilterTcOffsetDiv2(int val) { m_deblockingFilterTcOffsetDiv2 = val; } //!< set tc offset for deblocking filter int getDeblockingFilterTcOffsetDiv2() const { return m_deblockingFilterTcOffsetDiv2; } //!< get tc offset for deblocking filter +#if! JVET_O0299_APS_SCALINGLIST // PPS bool getScalingListPresentFlag() const { return m_scalingListPresentFlag; } void setScalingListPresentFlag( bool b ) { m_scalingListPresentFlag = b; } ScalingList& getScalingList() { return m_scalingList; } const ScalingList& getScalingList() const { return m_scalingList; } +#endif bool getListsModificationPresentFlag() const { return m_listsModificationPresentFlag; } void setListsModificationPresentFlag( bool b ) { m_listsModificationPresentFlag = b; } uint32_t getLog2ParallelMergeLevelMinus2() const { return m_log2ParallelMergeLevelMinus2; } @@ -1521,6 +1527,9 @@ private: int m_APSType; // aps_params_type AlfParam m_alfAPSParam; SliceReshapeInfo m_reshapeAPSInfo; +#if JVET_O0299_APS_SCALINGLIST + ScalingList m_scalingListApsInfo; +#endif public: APS(); @@ -1539,6 +1548,10 @@ public: void setReshaperAPSInfo(SliceReshapeInfo& reshapeAPSInfo) { m_reshapeAPSInfo = reshapeAPSInfo; } SliceReshapeInfo& getReshaperAPSInfo() { return m_reshapeAPSInfo; } +#if JVET_O0299_APS_SCALINGLIST + void setScalingList( ScalingList& scalingListAPSInfo ) { m_scalingListApsInfo = scalingListAPSInfo; } + ScalingList& getScalingList() { return m_scalingListApsInfo; } +#endif }; struct WPScalingParam { @@ -1706,6 +1719,11 @@ private: APS* m_lmcsAps; bool m_tileGroupLmcsEnabledFlag; bool m_tileGroupLmcsChromaResidualScaleFlag; +#if JVET_O0299_APS_SCALINGLIST + int m_scalingListApsId; + APS* m_scalingListAps; + bool m_tileGroupscalingListPresentFlag; +#endif public: Slice(); virtual ~Slice(); @@ -1734,6 +1752,15 @@ public: void setLmcsChromaResidualScaleFlag(bool b) { m_tileGroupLmcsChromaResidualScaleFlag = b; } bool getLmcsChromaResidualScaleFlag() { return m_tileGroupLmcsChromaResidualScaleFlag; } const bool getLmcsChromaResidualScaleFlag() const { return m_tileGroupLmcsChromaResidualScaleFlag; } +#if JVET_O0299_APS_SCALINGLIST + void setscalingListAPS( APS* scalingListAps ) { m_scalingListAps = scalingListAps; m_scalingListApsId = ( scalingListAps ) ? scalingListAps->getAPSId() : -1; } + APS* getscalingListAPS() { return m_scalingListAps; } + void setscalingListAPSId( int scalingListApsId ) { m_scalingListApsId = scalingListApsId; } + int getscalingListAPSId() const { return m_scalingListApsId; } + void setscalingListPresentFlag( bool b ) { m_tileGroupscalingListPresentFlag = b; } + bool getscalingListPresentFlag() { return m_tileGroupscalingListPresentFlag; } + const bool getscalingListPresentFlag() const { return m_tileGroupLmcsEnabledFlag; } +#endif void setPicOutputFlag( bool b ) { m_PicOutputFlag = b; } bool getPicOutputFlag() const { return m_PicOutputFlag; } void setSaoEnabledFlag(ChannelType chType, bool s) {m_saoEnabledFlag[chType] =s; } @@ -2003,7 +2030,11 @@ public: void setDisableSATDForRD(bool b) { m_disableSATDForRd = b; } bool getDisableSATDForRD() { return m_disableSATDForRd; } #if JVET_O1164_RPR +#if JVET_O0299_APS_SCALINGLIST + void scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS& lmcsAps, APS& scalingListAps, const bool isDecoder ); +#else void scaleRefPicList( Picture *scaledRefPic[], APS** apss, APS& lmcsAps, const bool isDecoder ); +#endif void freeScaledRefPicList( Picture *scaledRefPic[] ); bool checkRPR(); const std::pair<int, int>& getScalingRatio( const RefPicList refPicList, const int refIdx ) const { return m_scalingRatio[refPicList][refIdx]; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 88063fe2c0..0b81ef8e0c 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_O0299_APS_SCALINGLIST 1 // JVET-O0299: Scaling List Matrices Support in APS + #define JVET_O1164_RPR 1 // JVET-O1164: Reference picture resampling #if JVET_O1164_RPR #define JVET_O1164_PS 1 @@ -493,6 +495,9 @@ enum ApsTypeValues { ALF_APS = 0, LMCS_APS = 1, +#if JVET_O0299_APS_SCALINGLIST + SCALING_LIST_APS = 2, +#endif }; enum QuantFlags diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index e820fbfcf3..b85e9bc583 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -838,6 +838,24 @@ void DecLib::xActivateParameterSets() } } +#if JVET_O0299_APS_SCALINGLIST + APS* scalinglistAPS = NULL; + if( m_apcSlicePilot->getscalingListAPSId() != -1 ) + { + scalinglistAPS = m_parameterSetManager.getAPS( m_apcSlicePilot->getscalingListAPSId(), SCALING_LIST_APS ); + CHECK( scalinglistAPS == 0, "No SCALING LIST APS present" ); + } + + if( scalinglistAPS ) + { + m_parameterSetManager.clearAPSChangedFlag( m_apcSlicePilot->getscalingListAPSId(), SCALING_LIST_APS ); + if( false == m_parameterSetManager.activateAPS( m_apcSlicePilot->getscalingListAPSId(), SCALING_LIST_APS ) ) + { + THROW( "SCALING LIST APS activation failed!" ); + } + } +#endif + xParsePrefixSEImessages(); #if RExt__HIGH_BIT_DEPTH_SUPPORT==0 @@ -851,7 +869,11 @@ void DecLib::xActivateParameterSets() m_pcPic = xGetNewPicBuffer (*sps, *pps, m_apcSlicePilot->getTLayer()); m_apcSlicePilot->applyReferencePictureListBasedMarking(m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1()); +#if JVET_O0299_APS_SCALINGLIST + m_pcPic->finalInit( *sps, *pps, apss, *lmcsAPS, *scalinglistAPS ); +#else m_pcPic->finalInit(*sps, *pps, apss, *lmcsAPS); +#endif m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId())->setNumBricksInPic((int)m_pcPic->brickMap->bricks.size()); m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth ); m_pcPic->cs->createCoeffs(); @@ -874,6 +896,9 @@ void DecLib::xActivateParameterSets() m_pcPic->cs->pps = pps; memcpy(m_pcPic->cs->alfApss, apss, sizeof(m_pcPic->cs->alfApss)); m_pcPic->cs->lmcsAps = lmcsAPS; +#if JVET_O0299_APS_SCALINGLIST + m_pcPic->cs->scalinglistAps = scalinglistAPS; +#endif m_pcPic->cs->pcv = pps->pcv; @@ -957,6 +982,9 @@ void DecLib::xActivateParameterSets() const PPS *pps = pSlice->getPPS(); APS** apss = pSlice->getAlfAPSs(); APS *lmcsAPS = pSlice->getLmcsAPS(); +#if JVET_O0299_APS_SCALINGLIST + APS *scalinglistAPS = pSlice->getscalingListAPS(); +#endif // fix Parameter Sets, now that we have the real slice m_pcPic->cs->slice = pSlice; @@ -964,6 +992,9 @@ void DecLib::xActivateParameterSets() m_pcPic->cs->pps = pps; memcpy(m_pcPic->cs->alfApss, apss, sizeof(m_pcPic->cs->alfApss)); m_pcPic->cs->lmcsAps = lmcsAPS; +#if JVET_O0299_APS_SCALINGLIST + m_pcPic->cs->scalinglistAps = scalinglistAPS; +#endif m_pcPic->cs->pcv = pps->pcv; @@ -993,6 +1024,12 @@ void DecLib::xActivateParameterSets() { EXIT("Error - a new LMCS APS has been decoded while processing a picture"); } +#if JVET_O0299_APS_SCALINGLIST + if( scalinglistAPS && m_parameterSetManager.getAPSChangedFlag( scalinglistAPS->getAPSId(), SCALING_LIST_APS ) ) + { + EXIT( "Error - a new SCALING LIST APS has been decoded while processing a picture" ); + } +#endif xParsePrefixSEImessages(); @@ -1269,7 +1306,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl pcSlice->constructRefPicList(m_cListPic); #if JVET_O1164_RPR +#if JVET_O0299_APS_SCALINGLIST + pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), *pcSlice->getLmcsAPS(), *pcSlice->getscalingListAPS(), true ); +#else pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), *pcSlice->getLmcsAPS(), true ); +#endif #endif if (!pcSlice->isIntra()) @@ -1405,6 +1446,27 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl Quant *quant = m_cTrQuant.getQuant(); +#if JVET_O0299_APS_SCALINGLIST + if( pcSlice->getSPS()->getScalingListFlag() ) + { + ScalingList scalingList; + if( pcSlice->getscalingListPresentFlag() ) + { + APS* scalingListAPS = pcSlice->getscalingListAPS(); + scalingList = scalingListAPS->getScalingList(); + } + else + { + scalingList.setDefaultScalingList(); + } + quant->setScalingListDec( scalingList ); + quant->setUseScalingList( true ); + } + else + { + quant->setUseScalingList( false ); + } +#else if(pcSlice->getSPS()->getScalingListFlag()) { ScalingList scalingList; @@ -1427,6 +1489,7 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl { quant->setUseScalingList(false); } +#endif if (pcSlice->getSPS()->getUseReshaper()) diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index 42b66acdae..909f680967 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -88,6 +88,9 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb memcpy(cs.alfApss, slice->getAlfAPSs(), sizeof(cs.alfApss)); cs.lmcsAps = slice->getLmcsAPS(); +#if JVET_O0299_APS_SCALINGLIST + cs.scalinglistAps = slice->getscalingListAPS(); +#endif cs.pcv = slice->getPPS()->pcv; cs.chromaQpAdj = 0; diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index ac9997d2ee..adafe8c56c 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -670,11 +670,13 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana } } +#if !JVET_O0299_APS_SCALINGLIST READ_FLAG( uiCode, "pps_scaling_list_data_present_flag" ); pcPPS->setScalingListPresentFlag( uiCode ? true : false ); if(pcPPS->getScalingListPresentFlag ()) { parseScalingList( &(pcPPS->getScalingList()) ); } +#endif READ_UVLC( uiCode, "log2_parallel_merge_level_minus2"); @@ -804,6 +806,20 @@ void HLSyntaxReader::parseAPS( APS* aps ) READ_CODE(3, code, "aps_params_type"); aps->setAPSType(code); +#if JVET_O0299_APS_SCALINGLIST + if( code == ALF_APS ) + { + parseAlfAps( aps ); + } + else if( code == LMCS_APS ) + { + parseLmcsAps( aps ); + } + else if( code == SCALING_LIST_APS ) + { + parseScalingListAps( aps ); + } +#else if (code == ALF_APS) { parseAlfAps(aps); @@ -812,6 +828,7 @@ void HLSyntaxReader::parseAPS( APS* aps ) { parseLmcsAps(aps); } +#endif READ_FLAG(code, "aps_extension_flag"); if (code) { @@ -946,6 +963,13 @@ void HLSyntaxReader::parseLmcsAps( APS* aps ) aps->setReshaperAPSInfo(info); } +#if JVET_O0299_APS_SCALINGLIST +void HLSyntaxReader::parseScalingListAps( APS* aps ) +{ + ScalingList& info = aps->getScalingList(); + parseScalingList( &info ); +} +#endif void HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS) { @@ -1484,6 +1508,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) // KJS: remove scaling lists? READ_FLAG( uiCode, "scaling_list_enabled_flag" ); pcSPS->setScalingListFlag ( uiCode ); +#if !JVET_O0299_APS_SCALINGLIST if(pcSPS->getScalingListFlag()) { READ_FLAG( uiCode, "sps_scaling_list_data_present_flag" ); pcSPS->setScalingListPresentFlag ( uiCode ); @@ -1492,6 +1517,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) parseScalingList( &(pcSPS->getScalingList()) ); } } +#endif TimingInfo *timingInfo = pcSPS->getTimingInfo(); READ_FLAG( uiCode, "timing_info_present_flag"); timingInfo->setTimingInfoPresentFlag (uiCode ? true : false); @@ -2414,6 +2440,19 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para } } +#if JVET_O0299_APS_SCALINGLIST + if( sps->getScalingListFlag() ) + { + READ_FLAG( uiCode, "slice_scaling_list_present_flag" ); + pcSlice->setscalingListPresentFlag( uiCode ); + } + if( pcSlice->getscalingListPresentFlag() ) + { + READ_CODE( 3, uiCode, "slice_scaling_list_aps_id" ); + pcSlice->setscalingListAPSId( uiCode ); + } +#endif + if( pcSlice->getSliceCurStartBrickIdx() == 0 ) { pcSlice->setDefaultClpRng( *sps ); diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index fb11bd8807..9bf0f8a1cd 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -153,6 +153,9 @@ public: void parseAPS ( APS* pcAPS ); void parseAlfAps ( APS* pcAPS ); void parseLmcsAps ( APS* pcAPS ); +#if JVET_O0299_APS_SCALINGLIST + void parseScalingListAps ( APS* pcAPS ); +#endif void parseVUI ( VUI* pcVUI, SPS* pcSPS ); void parseConstraintInfo (ConstraintInfo *cinfo); void parseProfileTierLevel ( ProfileTierLevel *ptl, int maxNumSubLayersMinus1); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 5835f3c649..1d94bcdda8 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2069,8 +2069,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, // Set reference list pcSlice->constructRefPicList(rcListPic); #if JVET_O1164_RPR +#if JVET_O0299_APS_SCALINGLIST + pcSlice->scaleRefPicList( scaledRefPic, m_pcEncLib->getApss(), *pcSlice->getLmcsAPS(), *pcSlice->getscalingListAPS(), false ); +#else pcSlice->scaleRefPicList( scaledRefPic, m_pcEncLib->getApss(), *pcSlice->getLmcsAPS(), false ); #endif +#endif #if JVET_O1164_PS xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic ); @@ -2499,6 +2503,20 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, xPicInitLMCS(pcPic, pcSlice); +#if JVET_O0299_APS_SCALINGLIST + if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) + { + pcSlice->setscalingListPresentFlag( true ); + int apsId = 0; + pcSlice->setscalingListAPSId( apsId ); + + ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap(); + APS* scalingListAPS = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS ); + assert( scalingListAPS != NULL ); + pcSlice->setscalingListAPS( scalingListAPS ); + } +#endif + if( encPic ) // now compress (trial encode) the various slice segments (slices, and dependent slices) { @@ -2599,6 +2617,23 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } #endif +#if JVET_O0299_APS_SCALINGLIST + if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) + { + pcSlice->setscalingListPresentFlag( true ); + int apsId = 0; + pcSlice->setscalingListAPSId( apsId ); + } + for( int s = 0; s < uiNumSliceSegments; s++ ) + { + pcPic->slices[ s ]->setscalingListPresentFlag( pcSlice->getscalingListPresentFlag() ); + if( pcSlice->getscalingListPresentFlag() ) + { + pcPic->slices[ s ]->setscalingListAPSId( pcSlice->getscalingListAPSId() ); + } + } +#endif + // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas if( pcSlice->getSPS()->getSAOEnabledFlag() && m_pcCfg->getSaoCtuBoundary() ) { @@ -2769,6 +2804,23 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } } +#if JVET_O0299_APS_SCALINGLIST + // only 1 SCALING LIST data for 1 picture + if( pcSlice->getSPS()->getScalingListFlag() && ( m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) ) + { + int apsId = pcSlice->getscalingListAPSId(); + ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap(); + APS* aps = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS ); + bool writeAPS = aps && apsMap->getChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS ); + if( writeAPS ) + { + actualTotalBits += xWriteAPS( accessUnit, aps ); + apsMap->clearChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS ); + CHECK( aps != pcSlice->getscalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" ); + } + } +#endif + if (pcSlice->getSPS()->getALFEnabledFlag() && pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y)) { #if JVET_O_MAX_NUM_ALF_APS_8 diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 9d0785afc3..aa0eda372f 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -127,6 +127,9 @@ private: bool m_bFirst; int m_iLastRecoveryPicPOC; int m_lastRasPoc; +#if JVET_O0299_APS_SCALINGLIST + ScalingListMode m_ScalingListId; +#endif // Access channel EncLib* m_pcEncLib; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 963cd63e6f..3332d894b5 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -66,6 +66,9 @@ EncLib::EncLib() , m_cacheModel() #endif , m_lmcsAPS(nullptr) +#if JVET_O0299_APS_SCALINGLIST + , m_scalinglistAPS( nullptr ) +#endif #if JVET_O0119_BASE_PALETTE_444 , m_doPlt( true ) #endif @@ -241,6 +244,11 @@ 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_O0299_APS_SCALINGLIST + APS &aps0 = *( m_apsMap.allocatePS( SCALING_LIST_APS ) ); + aps0.setAPSId( 0 ); + aps0.setAPSType( SCALING_LIST_APS ); +#endif // initialize SPS xInitSPS(sps0); @@ -438,18 +446,31 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) #if ER_CHROMA_QP_WCG_PPS if( m_wcgChromaQpControl.isEnabled() ) { +#if JVET_O0299_APS_SCALINGLIST + xInitScalingLists( sps0, *m_apsMap.getPS( 1 ) ); + xInitScalingLists( sps0, aps0 ); +#else xInitScalingLists( sps0, *m_ppsMap.getPS(1) ); xInitScalingLists( sps0, pps0 ); +#endif } else #endif { +#if JVET_O0299_APS_SCALINGLIST + xInitScalingLists( sps0, aps0 ); +#else xInitScalingLists( sps0, pps0 ); +#endif } #if JVET_O1164_RPR if( m_rprEnabled ) { +#if JVET_O0299_APS_SCALINGLIST + xInitScalingLists( sps0, *m_apsMap.getPS( ENC_PPS_ID_RPR ) ); +#else xInitScalingLists( sps0, *m_ppsMap.getPS( ENC_PPS_ID_RPR ) ); +#endif } #endif #if ENABLE_WPP_PARALLELISM @@ -464,7 +485,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) picBg->create(sps0.getChromaFormatIdc(), Size(sps0.getPicWidthInLumaSamples(), sps0.getPicHeightInLumaSamples()), sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + 16, false); #endif picBg->getRecoBuf().fill(0); +#if JVET_O0299_APS_SCALINGLIST + picBg->finalInit( sps0, pps0, m_apss, *m_lmcsAPS, *m_scalinglistAPS ); +#else picBg->finalInit(sps0, pps0, m_apss, *m_lmcsAPS); +#endif pps0.setNumBricksInPic((int)picBg->brickMap->bricks.size()); picBg->allocateNewSlice(); picBg->createSpliceIdx(pps0.pcv->sizeInCtus); @@ -480,14 +505,18 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) } } +#if JVET_O0299_APS_SCALINGLIST +void EncLib::xInitScalingLists( SPS &sps, APS &aps ) +#else void EncLib::xInitScalingLists(SPS &sps, PPS &pps) +#endif { // Initialise scaling lists // The encoder will only use the SPS scaling lists. The PPS will never be marked present. const int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE] = { - sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_LUMA), - sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_CHROMA) + sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_LUMA), + sps.getMaxLog2TrDynamicRange(CHANNEL_TYPE_CHROMA) }; Quant* quant = getTrQuant()->getQuant(); @@ -503,16 +532,23 @@ void EncLib::xInitScalingLists(SPS &sps, PPS &pps) getTrQuant( jId )->getQuant()->setUseScalingList( false ); } #endif +#if !JVET_O0299_APS_SCALINGLIST sps.setScalingListPresentFlag(false); pps.setScalingListPresentFlag(false); +#endif } else if(getUseScalingListId() == SCALING_LIST_DEFAULT) { +#if JVET_O0299_APS_SCALINGLIST + aps.getScalingList().setDefaultScalingList (); + quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() ); +#else sps.getScalingList().setDefaultScalingList (); sps.setScalingListPresentFlag(false); pps.setScalingListPresentFlag(false); quant->setScalingList(&(sps.getScalingList()), maxLog2TrDynamicRange, sps.getBitDepths()); +#endif quant->setUseScalingList(true); #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM for( int jId = 1; jId < m_numCuEncStacks; jId++ ) @@ -523,6 +559,19 @@ void EncLib::xInitScalingLists(SPS &sps, PPS &pps) } else if(getUseScalingListId() == SCALING_LIST_FILE_READ) { +#if JVET_O0299_APS_SCALINGLIST + aps.getScalingList().setDefaultScalingList(); + if( aps.getScalingList().xParseScalingList( getScalingListFileName() ) ) + { + THROW( "parse scaling list" ); + } + aps.getScalingList().checkDcOfMatrix(); + if( aps.getScalingList().checkDefaultScalingList() == false ) + { + setUseScalingListId( SCALING_LIST_DEFAULT ); + } + quant->setScalingList( &( aps.getScalingList() ), maxLog2TrDynamicRange, sps.getBitDepths() ); +#else sps.getScalingList().setDefaultScalingList (); if(sps.getScalingList().xParseScalingList(getScalingListFileName())) { @@ -533,6 +582,7 @@ void EncLib::xInitScalingLists(SPS &sps, PPS &pps) pps.setScalingListPresentFlag(false); quant->setScalingList(&(sps.getScalingList()), maxLog2TrDynamicRange, sps.getBitDepths()); +#endif quant->setUseScalingList(true); #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM for( int jId = 1; jId < m_numCuEncStacks; jId++ ) @@ -546,7 +596,11 @@ void EncLib::xInitScalingLists(SPS &sps, PPS &pps) THROW("error : ScalingList == " << getUseScalingListId() << " not supported\n"); } +#if JVET_O0299_APS_SCALINGLIST + if( getUseScalingListId() == SCALING_LIST_FILE_READ ) +#else if (getUseScalingListId() == SCALING_LIST_FILE_READ && sps.getScalingListPresentFlag()) +#endif { // Prepare delta's: for (uint32_t sizeId = SCALING_LIST_2x2; sizeId <= SCALING_LIST_64x64; sizeId++) @@ -558,7 +612,11 @@ void EncLib::xInitScalingLists(SPS &sps, PPS &pps) { continue; } +#if JVET_O0299_APS_SCALINGLIST + aps.getScalingList().checkPredMode( sizeId, listId ); +#else sps.getScalingList().checkPredMode( sizeId, listId ); +#endif } } } @@ -621,7 +679,11 @@ 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_O0299_APS_SCALINGLIST + picCurr->finalInit( *sps, *pps, m_apss, *m_lmcsAPS, *m_scalinglistAPS ); +#else picCurr->finalInit(*sps, *pps, m_apss, *m_lmcsAPS); +#endif picCurr->poc = m_iPOCLast - 1; m_iPOCLast -= 2; if (getUseAdaptiveQP()) @@ -717,7 +779,11 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL ).swap(*cPicYuvTrueOrg ); #endif +#if JVET_O0299_APS_SCALINGLIST + pcPicCurr->finalInit( *pSPS, *pPPS, m_apss, *m_lmcsAPS, *m_scalinglistAPS ); +#else pcPicCurr->finalInit(*pSPS, *pPPS, m_apss, *m_lmcsAPS); +#endif PPS *ptrPPS = (ppsID<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsID); ptrPPS->setNumBricksInPic((int)pcPicCurr->brickMap->bricks.size()); } @@ -816,7 +882,11 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr int ppsID=-1; // Use default PPS ID const PPS *pPPS=(ppsID<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsID); const SPS *pSPS=m_spsMap.getPS(pPPS->getSPSId()); +#if JVET_O0299_APS_SCALINGLIST + pcField->finalInit( *pSPS, *pPPS, m_apss, *m_lmcsAPS, *m_scalinglistAPS ); +#else pcField->finalInit(*pSPS, *pPPS, m_apss, *m_lmcsAPS); +#endif } pcField->poc = m_iPOCLast; diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index 69bfefeb20..0aa443cd76 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -145,6 +145,9 @@ private: #endif APS* m_lmcsAPS; +#if JVET_O0299_APS_SCALINGLIST + APS* m_scalinglistAPS; +#endif EncHRD m_encHRD; @@ -172,7 +175,11 @@ protected: void xInitSPS (SPS &sps); ///< initialize SPS from encoder options void xInitPPS (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options void xInitAPS (APS &aps); ///< initialize APS from encoder options +#if JVET_O0299_APS_SCALINGLIST + void xInitScalingLists ( SPS &sps, APS &aps ); ///< initialize scaling lists +#else void xInitScalingLists (SPS &sps, PPS &pps); ///< initialize scaling lists +#endif void xInitPPSforLT(PPS& pps); void xInitHrdParameters(SPS &sps); ///< initialize HRDParameters parameters diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index a6f1441865..7ca2dec687 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -396,11 +396,13 @@ void HLSWriter::codePPS( const PPS* pcPPS ) } } +#if !JVET_O0299_APS_SCALINGLIST WRITE_FLAG( pcPPS->getScalingListPresentFlag() ? 1 : 0, "pps_scaling_list_data_present_flag" ); if( pcPPS->getScalingListPresentFlag() ) { codeScalingList( pcPPS->getScalingList() ); } +#endif WRITE_UVLC( pcPPS->getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2"); WRITE_FLAG( pcPPS->getSliceHeaderExtensionPresentFlag() ? 1 : 0, "slice_segment_header_extension_present_flag"); @@ -508,6 +510,12 @@ void HLSWriter::codeAPS( APS* pcAPS ) { codeLmcsAps (pcAPS); } +#if JVET_O0299_APS_SCALINGLIST + else if( pcAPS->getAPSType() == SCALING_LIST_APS ) + { + codeScalingListAps( pcAPS ); + } +#endif WRITE_FLAG(0, "aps_extension_flag"); //Implementation when this flag is equal to 1 should be added when it is needed. Currently in the spec we don't have case when this flag is equal to 1 xWriteRbspTrailingBits(); } @@ -610,6 +618,14 @@ void HLSWriter::codeLmcsAps( APS* pcAPS ) } } +#if JVET_O0299_APS_SCALINGLIST +void HLSWriter::codeScalingListAps( APS* pcAPS ) +{ + ScalingList param = pcAPS->getScalingList(); + codeScalingList( param ); +} +#endif + void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS ) { #if ENABLE_TRACING @@ -1038,6 +1054,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) // KJS: remove scaling lists? WRITE_FLAG( pcSPS->getScalingListFlag() ? 1 : 0, "scaling_list_enabled_flag" ); +#if !JVET_O0299_APS_SCALINGLIST if(pcSPS->getScalingListFlag()) { WRITE_FLAG( pcSPS->getScalingListPresentFlag() ? 1 : 0, "sps_scaling_list_data_present_flag" ); @@ -1046,6 +1063,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) codeScalingList( pcSPS->getScalingList() ); } } +#endif const TimingInfo *timingInfo = pcSPS->getTimingInfo(); WRITE_FLAG(timingInfo->getTimingInfoPresentFlag(), "timing_info_present_flag"); @@ -1691,6 +1709,16 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) } } +#if JVET_O0299_APS_SCALINGLIST + if( pcSlice->getSPS()->getScalingListFlag() ) + { + WRITE_FLAG( pcSlice->getscalingListPresentFlag() ? 1 : 0, "slice_scaling_list_present_flag" ); + if( pcSlice->getscalingListPresentFlag() ) + { + WRITE_CODE( pcSlice->getscalingListAPSId(), 3, "slice_scaling_list_aps_id" ); + } + } +#endif if(pcSlice->getPPS()->getSliceHeaderExtensionPresentFlag()) { WRITE_UVLC(0,"slice_segment_header_extension_length"); diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index cca3346414..e18ab25ff9 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -132,6 +132,9 @@ public: void codeAPS ( APS* pcAPS ); void codeAlfAps ( APS* pcAPS ); void codeLmcsAps ( APS* pcAPS ); +#if JVET_O0299_APS_SCALINGLIST + void codeScalingListAps ( APS* pcAPS ); +#endif void codeVPS ( const VPS* pcVPS ); void codeDPS ( const DPS* dps ); void codeSliceHeader ( Slice* pcSlice ); -- GitLab