/* 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 CodingStructure.h * \brief A class managing the coding information for a specific image part */ #ifndef __CODINGSTRUCTURE__ #define __CODINGSTRUCTURE__ #include "Unit.h" #include "Buffer.h" #include "CommonDef.h" #include "UnitPartitioner.h" #include "Slice.h" #include struct Picture; enum PictureType { PIC_RECONSTRUCTION = 0, PIC_ORIGINAL, PIC_TRUE_ORIGINAL, PIC_FILTERED_ORIGINAL, PIC_FILTERED_ORIGINAL_FG, PIC_PREDICTION, PIC_RESIDUAL, PIC_ORG_RESI, PIC_RECON_WRAP, PIC_ORIGINAL_INPUT, PIC_TRUE_ORIGINAL_INPUT, PIC_FILTERED_ORIGINAL_INPUT, #if JVET_Z0120_SII_SEI_PROCESSING PIC_YUV_POST_REC, #endif NUM_PIC_TYPES }; extern XuPool g_xuPool; // --------------------------------------------------------------------------- // coding structure // --------------------------------------------------------------------------- class CodingStructure { public: UnitArea area; Picture *picture; CodingStructure *parent; CodingStructure *bestCS; //ALBERTO Slice *slice = nullptr; //END ALBERTO UnitScale unitScale[MAX_NUM_COMPONENT]; int baseQP; EnumArray prevQP; EnumArray currQP; int chromaQpAdj; //ALBERTO const SPS *sps = nullptr; const PPS *pps = nullptr; //END ALBERTO PicHeader *picHeader; APS* alfApss[ALF_CTB_MAX_NUM_APS]; //ALBERTO APS * lmcsAps = nullptr; APS * scalinglistAps = nullptr; const VPS *vps = nullptr; const PreCalcValues* pcv = nullptr; //END ALBERTO CodingStructure(XuPool &); //ALBERTO CodingStructure(const CodingStructure& other) : area(other.area) //, picture(other.picture ? new Picture(*other.picture) : nullptr) , parent(other.parent ? new CodingStructure(*other.parent) : nullptr) , bestCS(other.bestCS ? new CodingStructure(*other.bestCS) : nullptr) , slice(other.slice ? new Slice(*other.slice) : nullptr) , baseQP(other.baseQP) , prevQP(other.prevQP) , currQP(other.currQP) , chromaQpAdj(other.chromaQpAdj) , sps(other.sps ? new SPS(*other.sps) : nullptr) , pps(other.pps ? new PPS(*other.pps) : nullptr) , picHeader(other.picHeader ? new PicHeader(*other.picHeader) : nullptr) , lmcsAps(other.lmcsAps ? new APS(*other.lmcsAps) : nullptr) , scalinglistAps(other.scalinglistAps ? new APS(*other.scalinglistAps) : nullptr) , vps(other.vps ? new VPS(*other.vps) : nullptr) , pcv(other.pcv ? new PreCalcValues(*other.pcv) : nullptr) , cus(other.cus) , pus(other.pus) , tus(other.tus) , motionLut(other.motionLut) , m_isTuEnc(other.m_isTuEnc) , m_cuIdx(other.m_cuIdx) , m_puIdx(other.m_puIdx) , m_tuIdx(other.m_tuIdx) , m_isDecomp(other.m_isDecomp) , m_numCUs(other.m_numCUs) , m_numPUs(other.m_numPUs) , m_numTUs(other.m_numTUs) , m_cuPool(other.m_cuPool) , m_puPool(other.m_puPool) , m_tuPool(other.m_tuPool) , m_sao(other.m_sao) , m_pred(other.m_pred) , m_resi(other.m_resi) , m_reco(other.m_reco) , m_orgr(other.m_orgr) , m_runType(other.m_runType) , m_motionBuf(other.m_motionBuf ? new MotionInfo(*other.m_motionBuf) : nullptr) , bestParent(other.bestParent ? new CodingStructure(*other.bestParent) : nullptr) , tmpColorSpaceCost(other.tmpColorSpaceCost) , firstColorSpaceSelected(other.firstColorSpaceSelected) , firstColorSpaceTestOnly(other.firstColorSpaceTestOnly) , resetIBCBuffer(other.resetIBCBuffer) , features(other.features) , splitRdCostBest(other.splitRdCostBest? new double(*other.splitRdCostBest):nullptr) , useDbCost(other.useDbCost) , costDbOffset(other.costDbOffset) , lumaCost(other.lumaCost) , fracBits(other.fracBits) , dist(other.dist) , interHad(other.interHad) , treeType(other.treeType) , modeType(other.modeType) { for (int i = 0; i < MAX_NUM_COMPONENT; i++) { unitScale[i] = UnitScale(other.unitScale[i]); m_coeffs[i] = other.m_coeffs[i] ? new TCoeff(*other.m_coeffs[i]) : nullptr; m_pcmbuf[i] = other.m_pcmbuf[i] ? new Pel(*other.m_pcmbuf[i]) : nullptr; m_offsets[i] = other.m_offsets[i]; } for (int i = 0; i < ALF_CTB_MAX_NUM_APS; i++) { alfApss[i] = other.alfApss[i]; } for (int i = 0; i < 2; i++) { tmpColorSpaceIntraCost[i] = other.tmpColorSpaceIntraCost[i]; } prevPLT = *new PLTBuf(other.prevPLT); } //END ALBERTO void create(const UnitArea &_unit, const bool isTopLayer, const bool isPLTused); void create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused); void destroy(); void releaseIntermediateData(); #if GDR_ENABLED bool containRefresh(int begX, int endX) const; bool overlapRefresh() const; bool overlapRefresh(int begX, int endX) const; bool withinRefresh(int begX, int endX) const; bool refreshCrossTTV(int begX, int endX) const; bool refreshCrossBTV(int begX, int endX) const; bool overlapDirty() const; bool dirtyCrossTTV() const; bool dirtyCrossBTV() const; bool isClean(const ChannelType effChType) const; bool isClean(const Position &intPos, RefPicList e, int refIdx) const; bool isClean(const Position &intPos, const Picture* const ref_pic) const; bool isClean(const Position &intPos, const Mv &fracMv) const; bool isClean(const Position &intPos, const Mv &fracMv, const Picture* const refPic) const; bool isClean(const Position &intPos, const Mv &fracMv, RefPicList e, int refIdx, bool isSubPu = false) const; bool isClean(const Position &intPos, const ChannelType effChType) const; bool isClean(const int x, const int y, const ChannelType effChType) const; bool isClean(const Area &area, const ChannelType effChType) const; bool isSubPuClean(const PredictionUnit &pu, const Mv *mv) const; #endif void rebindPicBufs(); void createCoeffs(const bool isPLTused); void destroyCoeffs(); void allocateVectorsAtPicLevel(); // --------------------------------------------------------------------------- // global accessors // --------------------------------------------------------------------------- bool isDecomp (const Position &pos, const ChannelType _chType) const; bool isDecomp (const Position &pos, const ChannelType _chType); void setDecomp(const CompArea &area, const bool _isCoded = true); void setDecomp(const UnitArea &area, const bool _isCoded = true); const CodingUnit *getCU(const Position &pos, const ChannelType _chType) const; const PredictionUnit *getPU(const Position &pos, const ChannelType _chType) const; const TransformUnit *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1) const; CodingUnit *getCU(const Position &pos, const ChannelType _chType); CodingUnit *getLumaCU( const Position &pos ); PredictionUnit *getPU(const Position &pos, const ChannelType _chType); TransformUnit *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1); const CodingUnit *getCU(const ChannelType _chType) const { return getCU(area.block(_chType).pos(), _chType); } const PredictionUnit *getPU(const ChannelType _chType) const { return getPU(area.block(_chType).pos(), _chType); } const TransformUnit *getTU(const ChannelType _chType) const { return getTU(area.block(_chType).pos(), _chType); } CodingUnit *getCU(const ChannelType _chType) { return getCU(area.block(_chType).pos(), _chType); } PredictionUnit *getPU(const ChannelType _chType) { return getPU(area.block(_chType).pos(), _chType); } TransformUnit *getTU(const ChannelType _chType) { return getTU(area.block(_chType).pos(), _chType); } const CodingUnit *getCURestricted(const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType) const; const CodingUnit *getCURestricted(const Position &pos, const CodingUnit& curCu, const ChannelType _chType) const; const PredictionUnit *getPURestricted(const Position &pos, const PredictionUnit& curPu, const ChannelType _chType) const; const TransformUnit *getTURestricted(const Position &pos, const TransformUnit& curTu, const ChannelType _chType) const; CodingUnit& addCU(const UnitArea &unit, const ChannelType _chType); PredictionUnit& addPU(const UnitArea &unit, const ChannelType _chType); TransformUnit& addTU(const UnitArea &unit, const ChannelType _chType); void addEmptyTUs(Partitioner &partitioner); CUTraverser traverseCUs(const UnitArea& _unit, const ChannelType _chType); PUTraverser traversePUs(const UnitArea& _unit, const ChannelType _chType); TUTraverser traverseTUs(const UnitArea& _unit, const ChannelType _chType); cCUTraverser traverseCUs(const UnitArea& _unit, const ChannelType _chType) const; cPUTraverser traversePUs(const UnitArea& _unit, const ChannelType _chType) const; cTUTraverser traverseTUs(const UnitArea& _unit, const ChannelType _chType) const; // --------------------------------------------------------------------------- // encoding search utilities // --------------------------------------------------------------------------- static_vector features; //ALBERTO double *splitRdCostBest = nullptr; //[Partition::NUM_PART_SPLIT]; //END ALBERTO double cost; bool useDbCost; double costDbOffset; double lumaCost; uint64_t fracBits; Distortion dist; Distortion interHad; TreeType treeType; //because partitioner can not go deep to tu and cu coding (e.g., addCU()), need another variable for indicating treeType ModeType modeType; #if GREEN_METADATA_SEI_ENABLED FeatureCounterStruct m_featureCounter; #endif void initStructData (const int &QP = MAX_INT, const bool &skipMotBuf = false); void initSubStructure( CodingStructure& cs, const ChannelType chType, const UnitArea &subArea, const bool &isTuEnc); void copyStructure (const CodingStructure& cs, const ChannelType chType, const bool copyTUs = false, const bool copyRecoBuffer = false); void useSubStructure (const CodingStructure& cs, const ChannelType chType, const UnitArea &subArea, const bool cpyPred, const bool cpyReco, const bool cpyOrgResi, const bool cpyResi, const bool updateCost); void useSubStructure (const CodingStructure& cs, const ChannelType chType, const bool cpyPred, const bool cpyReco, const bool cpyOrgResi, const bool cpyResi, const bool updateCost) { useSubStructure(cs, chType, cs.area, cpyPred, cpyReco, cpyOrgResi, cpyResi, updateCost); } void clearTUs(); void clearPUs(); void clearCUs(); const int signalModeCons( const PartSplit split, Partitioner &partitioner, const ModeType modeTypeParent ) const; void clearCuPuTuIdxMap ( const UnitArea &_area, uint32_t numCu, uint32_t numPu, uint32_t numTu, uint32_t* pOffset ); void getNumCuPuTuOffset ( uint32_t* pArray ) { pArray[0] = m_numCUs; pArray[1] = m_numPUs; pArray[2] = m_numTUs; pArray[3] = m_offsets[0]; pArray[4] = m_offsets[1]; pArray[5] = m_offsets[2]; } private: void createInternals(const UnitArea& _unit, const bool isTopLayer, const bool isPLTused); public: std::vector< CodingUnit*> cus; std::vector pus; std::vector< TransformUnit*> tus; LutMotionCand motionLut; void addMiToLut(static_vector& lut, const MotionInfo &mi); PLTBuf prevPLT; void resetPrevPLT(PLTBuf& prevPLT); void reorderPrevPLT(PLTBuf& prevPLT, uint8_t curPLTSize[MAX_NUM_CHANNEL_TYPE], Pel curPLT[MAX_NUM_COMPONENT][MAXPLTSIZE], bool reuseflag[MAX_NUM_CHANNEL_TYPE][MAXPLTPREDSIZE], uint32_t compBegin, uint32_t numComp, bool jointPLT); void setPrevPLT(PLTBuf predictor); void storePrevPLT(PLTBuf& predictor); private: // needed for TU encoding bool m_isTuEnc; EnumArray m_cuIdx; EnumArray m_puIdx; EnumArray m_tuIdx; EnumArray m_isDecomp; unsigned m_numCUs; unsigned m_numPUs; unsigned m_numTUs; CuPool &m_cuPool; PuPool &m_puPool; TuPool &m_tuPool; std::vector m_sao; PelStorage m_pred; PelStorage m_resi; PelStorage m_reco; PelStorage m_orgr; TCoeff *m_coeffs [ MAX_NUM_COMPONENT ]; Pel *m_pcmbuf [ MAX_NUM_COMPONENT ]; EnumArray m_runType; int m_offsets[ MAX_NUM_COMPONENT ]; MotionInfo *m_motionBuf; public: CodingStructure *bestParent; double tmpColorSpaceCost; bool firstColorSpaceSelected; double tmpColorSpaceIntraCost[2]; bool firstColorSpaceTestOnly; bool resetIBCBuffer; MotionBuf getMotionBuf( const Area& _area ); MotionBuf getMotionBuf( const UnitArea& _area ) { return getMotionBuf( _area.Y() ); } MotionBuf getMotionBuf() { return getMotionBuf( area.Y() ); } const CMotionBuf getMotionBuf( const Area& _area ) const; const CMotionBuf getMotionBuf( const UnitArea& _area ) const { return getMotionBuf( _area.Y() ); } const CMotionBuf getMotionBuf() const { return getMotionBuf( area.Y() ); } MotionInfo& getMotionInfo( const Position& pos ); const MotionInfo& getMotionInfo( const Position& pos ) const; public: // --------------------------------------------------------------------------- // temporary (shadowed) data accessors // --------------------------------------------------------------------------- PelBuf getPredBuf(const CompArea &blk); const CPelBuf getPredBuf(const CompArea &blk) const; PelUnitBuf getPredBuf(const UnitArea &unit); const CPelUnitBuf getPredBuf(const UnitArea &unit) const; PelBuf getResiBuf(const CompArea &blk); const CPelBuf getResiBuf(const CompArea &blk) const; PelUnitBuf getResiBuf(const UnitArea &unit); const CPelUnitBuf getResiBuf(const UnitArea &unit) const; PelBuf getRecoBuf(const CompArea &blk); const CPelBuf getRecoBuf(const CompArea &blk) const; PelUnitBuf getRecoBuf(const UnitArea &unit); const CPelUnitBuf getRecoBuf(const UnitArea &unit) const; PelUnitBuf& getRecoBufRef() { return m_reco; } PelBuf getOrgResiBuf(const CompArea &blk); const CPelBuf getOrgResiBuf(const CompArea &blk) const; PelUnitBuf getOrgResiBuf(const UnitArea &unit); const CPelUnitBuf getOrgResiBuf(const UnitArea &unit) const; PelBuf getOrgBuf(const CompArea &blk); const CPelBuf getOrgBuf(const CompArea &blk) const; PelUnitBuf getOrgBuf(const UnitArea &unit); const CPelUnitBuf getOrgBuf(const UnitArea &unit) const; PelBuf getOrgBuf(const ComponentID &compID); const CPelBuf getOrgBuf(const ComponentID &compID) const; PelUnitBuf getOrgBuf(); const CPelUnitBuf getOrgBuf() const; PelUnitBuf getTrueOrgBuf(); const CPelUnitBuf getTrueOrgBuf() const; // pred buffer PelBuf getPredBuf(const ComponentID &compID) { return m_pred.get(compID); } const CPelBuf getPredBuf(const ComponentID &compID) const { return m_pred.get(compID); } PelUnitBuf getPredBuf() { return m_pred; } const CPelUnitBuf getPredBuf() const { return m_pred; } // resi buffer PelBuf getResiBuf(const ComponentID compID) { return m_resi.get(compID); } const CPelBuf getResiBuf(const ComponentID compID) const { return m_resi.get(compID); } PelUnitBuf getResiBuf() { return m_resi; } const CPelUnitBuf getResiBuf() const { return m_resi; } // org-resi buffer PelBuf getOrgResiBuf(const ComponentID &compID) { return m_orgr.get(compID); } const CPelBuf getOrgResiBuf(const ComponentID &compID) const { return m_orgr.get(compID); } PelUnitBuf getOrgResiBuf() { return m_orgr; } const CPelUnitBuf getOrgResiBuf() const { return m_orgr; } // reco buffer PelBuf getRecoBuf(const ComponentID compID) { return m_reco.get(compID); } const CPelBuf getRecoBuf(const ComponentID compID) const { return m_reco.get(compID); } PelUnitBuf getRecoBuf() { return m_reco; } const CPelUnitBuf getRecoBuf() const { return m_reco; } private: inline PelBuf getBuf(const CompArea &blk, const PictureType &type); inline const CPelBuf getBuf(const CompArea &blk, const PictureType &type) const; inline PelUnitBuf getBuf(const UnitArea &unit, const PictureType &type); inline const CPelUnitBuf getBuf(const UnitArea &unit, const PictureType &type) const; }; static inline uint32_t getNumberValidTBlocks(const PreCalcValues& pcv) { return (pcv.chrFormat==CHROMA_400) ? 1 : ( pcv.multiBlock422 ? MAX_NUM_TBLOCKS : MAX_NUM_COMPONENT ); } #endif