/* The copyright in this software is being made available under the BSD * License, included below. This software may be subject to other third party * and contributor rights, including patent rights, and no such rights are * granted under this license. * * Copyright (c) 2010-2023, ITU/ISO/IEC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** \file DecLib.h \brief decoder class (header) */ #ifndef __DECLIB__ #define __DECLIB__ #include "DecSlice.h" #include "CABACReader.h" #include "VLCReader.h" #include "SEIread.h" #include "CacheModel.h" #include "CommonLib/CommonDef.h" #include "CommonLib/Picture.h" #include "CommonLib/TrQuant.h" #include "CommonLib/InterPrediction.h" #include "CommonLib/IntraPrediction.h" #include "CommonLib/DeblockingFilter.h" #include "CommonLib/AdaptiveLoopFilter.h" #include "CommonLib/SEI.h" #include "CommonLib/Unit.h" #include "CommonLib/Reshape.h" class InputNALUnit; //! \ingroup DecoderLib //! \{ bool tryDecodePicture(Picture *pcPic, const int expectedPoc, const std::string &bitstreamFileName, EnumArray, ApsType> *apsMap = nullptr, bool bDecodeUntilPocFound = false, int debugCTU = -1, int debugPOC = -1); // Class definition // ==================================================================================================================== /// decoder class class DecLib { private: int m_maxRefPicNum; bool m_isFirstGeneralHrd; GeneralHrdParams m_prevGeneralHrdParams; int m_prevGDRInSameLayerPOC[MAX_VPS_LAYERS]; ///< POC number of the latest GDR picture int m_prevGDRInSameLayerRecoveryPOC[MAX_VPS_LAYERS]; ///< Recovery POC number of the latest GDR picture NalUnitType m_associatedIRAPType[MAX_VPS_LAYERS]; ///< NAL unit type of the previous IRAP picture int m_pocCRA[MAX_VPS_LAYERS]; ///< POC number of the previous CRA picture CheckCRAFlags m_checkCRAFlags[MAX_VPS_LAYERS]; int m_latestDRAPPOC; int m_latestEDRAPPOC; bool m_latestEDRAPIndicationLeadingPicturesDecodableFlag; int m_associatedIRAPDecodingOrderNumber[MAX_VPS_LAYERS]; ///< Decoding order number of the previous IRAP picture int m_decodingOrderCounter; int m_puCounter; bool m_seiInclusionFlag; int m_prevGDRSubpicPOC[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS]; int m_prevIRAPSubpicPOC[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS]; NalUnitType m_prevIRAPSubpicType[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS]; int m_prevIRAPSubpicDecOrderNo[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS]; int m_pocRandomAccess; ///< POC number of the random access point (the first IDR or CRA picture) int m_lastRasPoc; bool m_prevEOS[MAX_VPS_LAYERS]; PicList m_cListPic; // Dynamic buffer ParameterSetManager m_parameterSetManager; // storage for parameter sets PicHeader m_picHeader; // picture header Slice* m_apcSlicePilot; SEIMessages m_SEIs; ///< List of SEI messages that have been received before the first slice and between slices, excluding prefix SEIs... SEIScalabilityDimensionInfo* m_sdiSEIInFirstAU; SEIMultiviewAcquisitionInfo* m_maiSEIInFirstAU; SEIMultiviewViewPosition* m_mvpSEIInFirstAU; // functional classes IntraPrediction m_cIntraPred; InterPrediction m_cInterPred; TrQuant m_cTrQuant; DecSlice m_cSliceDecoder; TrQuant m_cTrQuantScalingList; DecCu m_cCuDecoder; HLSyntaxReader m_HLSReader; CABACDecoder m_CABACDecoder; SEIReader m_seiReader; #if JVET_S0257_DUMP_360SEI_MESSAGE SeiCfgFileDump m_seiCfgDump; #endif DeblockingFilter m_deblockingFilter; SampleAdaptiveOffset m_cSAO; AdaptiveLoopFilter m_cALF; Reshape m_cReshaper; ///< reshaper class HRD m_HRD; // decoder side RD cost computation RdCost m_cRdCost; ///< RD cost computation class #if JVET_J0090_MEMORY_BANDWITH_MEASURE CacheModel m_cacheModel; #endif bool isRandomAccessSkipPicture(int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId); Picture* m_pcPic; uint32_t m_uiSliceSegmentIdx; uint32_t m_prevLayerID; int m_prevPOC; int m_prevPicPOC; int m_prevTid0POC; bool m_bFirstSliceInPicture; bool m_firstPictureInSequence; SEIFilmGrainSynthesizer m_grainCharacteristic; PelStorage m_grainBuf; SEIColourTransformApply m_colourTranfParams; PelStorage m_invColourTransfBuf; bool m_firstSliceInSequence[MAX_VPS_LAYERS]; bool m_firstSliceInBitstream; bool m_isFirstAuInCvs; bool m_accessUnitEos[MAX_VPS_LAYERS]; bool m_prevSliceSkipped; int m_skippedPOC; uint32_t m_skippedLayerID; int m_lastPOCNoOutputPriorPics; bool m_isNoOutputPriorPics; bool m_lastNoOutputBeforeRecoveryFlag[MAX_VPS_LAYERS]; //value of variable NoOutputBeforeRecoveryFlag of the assocated CRA/GDR pic int m_sliceLmcsApsId; //value of LmcsApsId, constraint is same id for all slices in one picture std::ostream *m_pDecodedSEIOutputStream; uint32_t m_audIrapOrGdrAuFlag; #if JVET_S0257_DUMP_360SEI_MESSAGE std::string m_decoded360SeiDumpFileName; #endif int m_decodedPictureHashSEIEnabled; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message uint32_t m_numberOfChecksumErrorsDetected; bool m_warningMessageSkipPicture; std::list m_prefixSEINALUs; /// Buffered up prefix SEI NAL Units. #if JVET_Z0120_SII_SEI_PROCESSING bool m_ShutterFilterEnable; ///< enable Post-processing with Shutter Interval SEI #endif int m_debugPOC; int m_debugCTU; struct AccessUnitInfo { NalUnitType m_nalUnitType; ///< nal_unit_type uint32_t m_temporalId; ///< temporal_id uint32_t m_nuhLayerId; ///< nuh_layer_id }; std::vector m_accessUnitNals; struct AccessUnitPicInfo { NalUnitType m_nalUnitType; ///< nal_unit_type uint32_t m_temporalId; ///< temporal_id uint32_t m_nuhLayerId; ///< nuh_layer_id int m_POC; }; std::vector m_accessUnitPicInfo; std::vector m_firstAccessUnitPicInfo; struct AccessUnitNestedSliSeiInfo { bool m_nestedSliPresent; uint32_t m_numOlssNestedSli; uint32_t m_olsIdxNestedSLI[MAX_NUM_OLSS]; }; std::vector m_accessUnitNestedSliSeiInfo; int m_accessUnitSpsNumSubpic[MAX_VPS_LAYERS]; struct NalUnitInfo { NalUnitType m_nalUnitType; ///< nal_unit_type uint32_t m_nuhLayerId; ///< nuh_layer_id uint32_t m_firstCTUinSlice; /// the first CTU in slice, specified with raster scan order ctu address int m_POC; /// the picture order }; std::vector m_nalUnitInfo[MAX_VPS_LAYERS]; EnumArray, ApsType> m_accessUnitApsNals; std::vector m_accessUnitSeiTids; std::vector m_accessUnitNoOutputPriorPicFlags; // NAL unit type, layer ID, and SEI payloadType std::vector> m_accessUnitSeiPayLoadTypes; std::vector m_pictureUnitNals; std::list m_pictureSeiNalus; std::list m_suffixApsNalus; std::list m_accessUnitSeiNalus; OPI* m_opi; bool m_mTidExternalSet; bool m_mTidOpiSet; bool m_tOlsIdxTidExternalSet; bool m_tOlsIdxTidOpiSet; VPS* m_vps; int m_maxDecSubPicIdx; int m_maxDecSliceAddrInSubPic; int m_clsVPSid; #if GDR_ENABLED int m_lastGdrPoc; int m_lastGdrRecoveryPocCnt; #endif public: int m_targetSubPicIdx; DCI* m_dci; EnumArray, ApsType> *m_apsMapEnc = nullptr; #if GDR_LEAK_TEST public: int m_gdrPocRandomAccess; #endif // GDR_LEAK_TEST public: DecLib(); virtual ~DecLib(); void create (); void destroy (); void setDecodedPictureHashSEIEnabled(int enabled) { m_decodedPictureHashSEIEnabled=enabled; } void init( #if JVET_J0090_MEMORY_BANDWITH_MEASURE const std::string& cacheCfgFileName #endif ); bool decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, int iTargetOlsIdx); void deletePicBuffer(); void executeLoopFilters(); void finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl = INFO, bool associatedWithNewClvs = false); void finishPictureLight(int& poc, PicList*& rpcListPic ); void checkNoOutputPriorPics (PicList* rpcListPic); void checkNalUnitConstraints( uint32_t naluType ); void checkPicTypeAfterEos(); void updateAssociatedIRAP(); void updatePrevGDRInSameLayer(); void updatePrevIRAPAndGDRSubpic(); bool getGDRRecoveryPocReached() { return ( m_pcPic->getPOC() >= m_prevGDRInSameLayerRecoveryPOC[m_pcPic->layerId] ); } bool getNoOutputPriorPicsFlag () const { return m_isNoOutputPriorPics; } void setNoOutputPriorPicsFlag (bool val) { m_isNoOutputPriorPics = val; } void setFirstSliceInPicture (bool val) { m_bFirstSliceInPicture = val; } bool getFirstSliceInPicture () const { return m_bFirstSliceInPicture; } bool getFirstSliceInSequence(int layerId) const { return m_firstSliceInSequence[layerId]; } void setFirstSliceInSequence(bool val, int layerId) { m_firstSliceInSequence[layerId] = val; } void setDecodedSEIMessageOutputStream(std::ostream *pOpStream) { m_pDecodedSEIOutputStream = pOpStream; } #if JVET_S0257_DUMP_360SEI_MESSAGE void setDecoded360SEIMessageFileName(std::string &Dump360SeiFileName) { m_decoded360SeiDumpFileName = Dump360SeiFileName; } #endif uint32_t getNumberOfChecksumErrorsDetected() const { return m_numberOfChecksumErrorsDetected; } #if GDR_ENABLED void setLastGdrPoc(int poc) { m_lastGdrPoc = poc; } int getLastGdrPoc() { return m_lastGdrPoc; } void setLastGdrRecoveryPocCnt(int recoveryPocCnt) { m_lastGdrRecoveryPocCnt = recoveryPocCnt; } int getLastGdrRecoveryPocCnt() { return m_lastGdrRecoveryPocCnt; } #endif int getDebugCTU( ) const { return m_debugCTU; } void setDebugCTU( int debugCTU ) { m_debugCTU = debugCTU; } int getDebugPOC( ) const { return m_debugPOC; }; void setDebugPOC( int debugPOC ) { m_debugPOC = debugPOC; }; void resetAccessUnitNals() { m_accessUnitNals.clear(); } void resetAccessUnitPicInfo() { m_accessUnitPicInfo.clear(); } void resetAccessUnitApsNals() { for (auto &nals: m_accessUnitApsNals) { nals.clear(); } } void resetAccessUnitSeiTids() { m_accessUnitSeiTids.clear(); } void resetAudIrapOrGdrAuFlag() { m_audIrapOrGdrAuFlag = false; } void resetAccessUnitEos() { memset(m_accessUnitEos, false, sizeof(m_accessUnitEos)); } void checkTidLayerIdInAccessUnit(); void resetAccessUnitSeiPayLoadTypes() { m_accessUnitSeiPayLoadTypes.clear(); } void checkSEIInAccessUnit(); void checkSeiContentInAccessUnit(); void resetAccessUnitSeiNalus(); void checkLayerIdIncludedInCvss(); void CheckNoOutputPriorPicFlagsInAccessUnit(); void resetAccessUnitNoOutputPriorPicFlags() { m_accessUnitNoOutputPriorPicFlags.clear(); } void checkMultiSubpicNum(int olsIdx); void resetAccessUnitNestedSliSeiInfo() { m_accessUnitNestedSliSeiInfo.clear(); } void resetIsFirstAuInCvs(); void checkSeiInPictureUnit(); void resetPictureSeiNalus(); void resetPrefixSeiNalus(); bool isSliceNaluFirstInAU( bool newPicture, InputNALUnit &nalu ); void processSuffixApsNalus(); void checkAPSInPictureUnit(); void resetPictureUnitNals() { m_pictureUnitNals.clear(); } const VPS* getVPS() { return m_vps; } void deriveTargetOutputLayerSet( const int targetOlsIdx ) { if( m_vps != nullptr ) m_vps->deriveTargetOutputLayerSet( targetOlsIdx ); } void initScalingList() { m_cTrQuantScalingList.init(nullptr, MAX_TB_SIZEY, false, false, false, false); } void setAPSMapEnc(EnumArray, ApsType> *apsMap) { m_apsMapEnc = apsMap; } bool isNewPicture( std::ifstream *bitstreamFile, class InputByteStream *bytestream ); bool isNewAccessUnit( bool newPicture, std::ifstream *bitstreamFile, class InputByteStream *bytestream ); bool getHTidExternalSetFlag() const { return m_mTidExternalSet; } void setHTidExternalSetFlag(bool mTidExternalSet) { m_mTidExternalSet = mTidExternalSet; } bool getHTidOpiSetFlag() const { return m_mTidOpiSet; } void setHTidOpiSetFlag(bool mTidOpiSet) { m_mTidOpiSet = mTidOpiSet; } bool getTOlsIdxExternalFlag() const { return m_tOlsIdxTidExternalSet; } void setTOlsIdxExternalFlag (bool tOlsIdxExternalSet) { m_tOlsIdxTidExternalSet = tOlsIdxExternalSet; } bool getTOlsIdxOpiFlag() const { return m_tOlsIdxTidOpiSet; } void setTOlsIdxOpiFlag(bool tOlsIdxOpiSet) { m_tOlsIdxTidOpiSet = tOlsIdxOpiSet; } const OPI* getOPI() { return m_opi; } bool getMixedNaluTypesInPicFlag(); #if GREEN_METADATA_SEI_ENABLED FeatureCounterStruct m_featureCounter; bool m_GMFAFramewise; std::string m_GMFAFile; void setFeatureCounter (FeatureCounterStruct b ) {m_featureCounter = b;} FeatureCounterStruct getFeatureCounter (){return m_featureCounter;} void setGMFAFile(std::string b){m_GMFAFile = b;} void setFeatureAnalysisFramewise(bool b){m_GMFAFramewise = b;} #endif #if JVET_Z0120_SII_SEI_PROCESSING bool getShutterFilterFlag() const { return m_ShutterFilterEnable; } void setShutterFilterFlag(bool value) { m_ShutterFilterEnable = value; } #endif protected: void xUpdateRasInit(Slice* slice); Picture * xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_t temporalLayer, const int layerId ); void xCreateLostPicture( int iLostPOC, const int layerId ); void xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag ); void checkParameterSetsInclusionSEIconstraints(const InputNALUnit nalu); void xActivateParameterSets( const InputNALUnit nalu ); void xCheckParameterSetConstraints( const int layerId ); void xDecodePicHeader( InputNALUnit& nalu ); bool xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay); void xDecodeOPI( InputNALUnit& nalu ); void xDecodeVPS( InputNALUnit& nalu ); void xDecodeDCI( InputNALUnit& nalu ); void xDecodeSPS( InputNALUnit& nalu ); void xDecodePPS( InputNALUnit& nalu ); void xDecodeAPS(InputNALUnit& nalu); void xUpdatePreviousTid0POC(Slice *pSlice) { if( (pSlice->getTLayer() == 0) && (pSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL) && (pSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RADL) && !pSlice->getPicHeader()->getNonReferencePictureFlag() ) { m_prevTid0POC = pSlice->getPOC(); } } void xParsePrefixSEImessages(); void xParsePrefixSEIsForUnknownVCLNal(); void xCheckPrefixSEIMessages( SEIMessages& prefixSEIs ); void xCheckDUISEIMessages(SEIMessages &prefixSEIs); void xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType ); void xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu); };// END CLASS DEFINITION DecLib //! \} #endif // __DECTOP__