/src/vvenc/source/Lib/CommonLib/UnitTools.h
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | /** \file UnitTool.h |
43 | | * \brief defines operations for basic units |
44 | | */ |
45 | | |
46 | | #pragma once |
47 | | |
48 | | #include "Unit.h" |
49 | | #include "UnitPartitioner.h" |
50 | | #include "ContextModelling.h" |
51 | | #include "InterPrediction.h" |
52 | | |
53 | | //! \ingroup CommonLib |
54 | | //! \{ |
55 | | |
56 | | namespace vvenc { |
57 | | |
58 | | // CS tools |
59 | | namespace CS |
60 | | { |
61 | | UnitArea getArea (const CodingStructure &cs, const UnitArea& area, const ChannelType chType, const TreeType treeType); |
62 | | bool isDualITree (const CodingStructure &cs); |
63 | | void setRefinedMotionFieldCTU ( CodingStructure &cs, const int ctuX, const int ctuY ); |
64 | | void setRefinedMotionField ( CodingStructure &cs); |
65 | | int signalModeCons (const CodingStructure &cs, const UnitArea &currArea, const PartSplit split, const ModeType modeTypeParent); |
66 | | } |
67 | | |
68 | | |
69 | | // CU tools |
70 | | namespace CU |
71 | | { |
72 | 0 | inline bool isSepTree (const CodingUnit &cu) { return cu.treeType != TREE_D || CS::isDualITree( *cu.cs ); } |
73 | 0 | inline bool isLocalSepTree (const CodingUnit &cu) { return cu.treeType != TREE_D && !CS::isDualITree(*cu.cs); } |
74 | 0 | inline bool isConsInter (const CodingUnit &cu) { return cu.modeType == MODE_TYPE_INTER; } |
75 | 0 | inline bool isConsIntra (const CodingUnit &cu) { return cu.modeType == MODE_TYPE_INTRA; } |
76 | | |
77 | 0 | inline bool isIntra (const CodingUnit &cu) { return cu.predMode == MODE_INTRA; } |
78 | 0 | inline bool isInter (const CodingUnit &cu) { return cu.predMode == MODE_INTER; } |
79 | 0 | inline bool isIBC (const CodingUnit &cu) { return cu.predMode == MODE_IBC; } |
80 | 0 | inline bool isPLT (const CodingUnit &cu) { return cu.predMode == MODE_PLT; } |
81 | 0 | inline bool isSameSlice (const CodingUnit& cu, const CodingUnit& cu2) { return cu.slice->independentSliceIdx == cu2.slice->independentSliceIdx; } |
82 | 0 | inline bool isSameTile (const CodingUnit& cu, const CodingUnit& cu2) { return cu.tileIdx == cu2.tileIdx; } |
83 | 0 | inline bool isSameSliceAndTile (const CodingUnit& cu, const CodingUnit& cu2) { return ( cu.slice->independentSliceIdx == cu2.slice->independentSliceIdx ) && ( cu.tileIdx == cu2.tileIdx ); } |
84 | | |
85 | | uint8_t checkAllowedSbt (const CodingUnit &cu); |
86 | | bool checkCCLMAllowed (const CodingUnit &cu); |
87 | | bool isSameCtu (const CodingUnit &cu, const CodingUnit &cu2); |
88 | | bool isSameSubPic (const CodingUnit &cu, const CodingUnit &cu2); |
89 | | bool isLastSubCUOfCtu (const CodingUnit &cu); |
90 | | uint32_t getCtuAddr (const CodingUnit &cu); |
91 | | int predictQP (const CodingUnit& cu, const int prevQP); |
92 | | |
93 | | void saveMotionInHMVP (const CodingUnit& cu, const bool isToBeDone ); |
94 | | |
95 | | PartSplit getSplitAtDepth (const CodingUnit& cu, const unsigned depth); |
96 | | ModeType getModeTypeAtDepth (const CodingUnit& cu, const unsigned depth); |
97 | | |
98 | | bool isPredRegDiffFromTB (const CodingUnit& cu); |
99 | | bool isFirstTBInPredReg (const CodingUnit& cu, const CompArea& area); |
100 | | void adjustPredArea (CompArea& area); |
101 | | bool isBcwIdxCoded (const CodingUnit& cu); |
102 | | uint8_t getValidBcwIdx (const CodingUnit& cu); |
103 | | void setBcwIdx ( CodingUnit& cu, uint8_t uh); |
104 | | bool bdpcmAllowed (const CodingUnit& cu, const ComponentID compID); |
105 | | bool isMTSAllowed (const CodingUnit& cu, const ComponentID compID); |
106 | | |
107 | | |
108 | | bool divideTuInRows (const CodingUnit &cu); |
109 | | PartSplit getISPType (const CodingUnit &cu, const ComponentID compID); |
110 | | bool isISPLast (const CodingUnit &cu, const CompArea& tuArea, const ComponentID compID); |
111 | | bool isISPFirst (const CodingUnit &cu, const CompArea& tuArea, const ComponentID compID); |
112 | | bool canUseISP (const CodingUnit &cu, const ComponentID compID); |
113 | | bool canUseISP (const int width, const int height, const int maxTrSize = MAX_TB_SIZEY ); |
114 | | bool canUseLfnstWithISP (const CompArea& cuArea, const ISPType ispSplitType ); |
115 | | bool canUseLfnstWithISP (const CodingUnit& cu, const ChannelType chType ); |
116 | | uint32_t getISPSplitDim (const int width, const int height, const PartSplit ispType); |
117 | | bool allLumaCBFsAreZero (const CodingUnit& cu); |
118 | | |
119 | | TUTraverser traverseTUs ( CodingUnit& cu); |
120 | | cTUTraverser traverseTUs (const CodingUnit& cu); |
121 | | |
122 | | bool hasSubCUNonZeroMVd (const CodingUnit& cu); |
123 | | bool hasSubCUNonZeroAffineMVd (const CodingUnit& cu ); |
124 | | void resetMVDandMV2Int ( CodingUnit& cu ); |
125 | | |
126 | 0 | inline uint8_t getSbtIdx ( const uint8_t sbtInfo ) { return ( sbtInfo >> 0 ) & 0xf; } |
127 | 0 | inline uint8_t getSbtPos ( const uint8_t sbtInfo ) { return ( sbtInfo >> 4 ) & 0x3; } |
128 | | |
129 | 0 | inline uint8_t getSbtMode (const uint8_t sbtIdx, const uint8_t sbtPos) { return (sbtIdx<<1) + sbtPos - 2; } |
130 | 0 | inline uint8_t getSbtIdxFromSbtMode (const uint8_t sbtMode) { return (sbtMode>>1)+1; } |
131 | 0 | inline uint8_t getSbtPosFromSbtMode (const uint8_t sbtMode) { return sbtMode&1;} |
132 | 0 | inline uint8_t targetSbtAllowed (uint8_t sbtIdx, uint8_t sbtAllowed) { return ( sbtAllowed >> sbtIdx ) & 0x1; } |
133 | | |
134 | | uint8_t numSbtModeRdo (uint8_t sbtAllowed); |
135 | | PartSplit getSbtTuSplit ( const uint8_t sbtInfo ); |
136 | | bool isSbtMode (const uint8_t sbtInfo); |
137 | | bool isSameSbtSize (const uint8_t sbtInfo1, const uint8_t sbtInfo2); |
138 | | bool getRprScaling ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale ); |
139 | | |
140 | | const CodingUnit* getLeft (const CodingUnit& curr); |
141 | | const CodingUnit* getAbove (const CodingUnit& curr); |
142 | | |
143 | | |
144 | | int getLMSymbolList (const CodingUnit& cu, int *modeList); |
145 | | bool isMIP (const CodingUnit& cu, const ChannelType channelType = CH_L); |
146 | | int getIntraMPMs (const CodingUnit& cu, unsigned *mpm ); |
147 | | bool isDMChromaMIP (const CodingUnit& cu); |
148 | | uint32_t getIntraDirLuma (const CodingUnit& cu); |
149 | | void getIntraChromaCandModes (const CodingUnit& cu, unsigned modeList[NUM_CHROMA_MODE]); |
150 | | const CodingUnit &getCoLocatedLumaPU (const CodingUnit& cu); |
151 | | uint32_t getFinalIntraMode (const CodingUnit& cu, const ChannelType chType); |
152 | | uint32_t getCoLocatedIntraLumaMode (const CodingUnit& cu); |
153 | | void getInterMergeCandidates (const CodingUnit& cu, MergeCtx& mrgCtx, int mmvdList, const int mrgCandIdx = -1 ); |
154 | | void getInterMMVDMergeCandidates (const CodingUnit& cu, MergeCtx& mrgCtx); |
155 | | int getDistScaleFactor (const int currPOC, const int currRefPOC, const int colPOC, const int colRefPOC); |
156 | | bool isDiffMER (const Position &pos1, const Position &pos2, const unsigned plevel); |
157 | | bool getColocatedMVP (const CodingUnit& cu, const RefPicList refPicList, const Position& pos, Mv& rcMv, const int refIdx, bool sbFlag = false); |
158 | | void fillMvpCand ( CodingUnit& cu, const RefPicList refPicList, const int refIdx, AMVPInfo &amvpInfo ); |
159 | | bool addMVPCandUnscaled (const CodingUnit& cu, const RefPicList refPicList, const int iRefIdx, const Position& pos, const MvpDir dir, AMVPInfo &amvpInfo); |
160 | | bool addMergeHMVPCand (const CodingStructure &cs, MergeCtx& mrgCtx, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const bool isAvailableA1, const MotionInfo &miLeft, const bool isAvailableB1, const MotionInfo &miAbove, const bool ibcFlag, const bool isGt4x4); |
161 | | void addAMVPHMVPCand (const CodingUnit& cu, const RefPicList refPicList, const int currRefPOC, AMVPInfo &info); |
162 | | bool isBipredRestriction (const CodingUnit& cu); |
163 | | void spanMotionInfo ( CodingUnit& cu, const AffineMergeCtx *mrgCtx = nullptr ); |
164 | | void restrictBiPredMergeCandsOne ( CodingUnit& cu); |
165 | | |
166 | | bool isLMCMode ( unsigned mode); |
167 | | bool isLMCModeEnabled (const CodingUnit& cu, unsigned mode); |
168 | | void getGeoMergeCandidates (const CodingUnit& cu, MergeCtx &GeoMrgCtx); |
169 | | void spanGeoMotionInfo ( CodingUnit& cu, const MergeCtx &GeoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1); |
170 | | bool isBiPredFromDifferentDirEqDistPoc(const CodingUnit& cu); |
171 | | bool checkDMVRCondition (const CodingUnit& cu); |
172 | | void getAffineControlPointCand (const CodingUnit& cu, MotionInfo mi[4], bool isAvailable[4], int verIdx[4], int8_t BcwIdx, int modelIdx, int verNum, AffineMergeCtx& affMrgCtx); |
173 | | void getAffineMergeCand ( CodingUnit& cu, AffineMergeCtx& affMrgCtx, const int mrgCandIdx = -1); |
174 | | void setAllAffineMvField ( CodingUnit& cu, const MvField *mvField, RefPicList eRefList); |
175 | | void setAllAffineMv ( CodingUnit& cu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool clipCPMVs = false); |
176 | | void xInheritedAffineMv (const CodingUnit& cu, const CodingUnit* cuNeighbour, RefPicList refPicList, Mv rcMv[3]); |
177 | | void fillAffineMvpCand ( CodingUnit& cu, const RefPicList refPicList, const int refIdx, AffineAMVPInfo &affiAMVPInfo); |
178 | | bool addAffineMVPCandUnscaled (const CodingUnit& cu, const RefPicList refPicList, const int refIdx, const Position& pos, const MvpDir dir, AffineAMVPInfo &affiAmvpInfo); |
179 | | bool getInterMergeSbTMVPCand (const CodingUnit& cu, AffineMergeCtx &mrgCtx, const int count); |
180 | | |
181 | | void getIBCMergeCandidates (const CodingUnit& cu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); |
182 | | void fillIBCMvpCand (CodingUnit& cu, AMVPInfo& amvpInfo); |
183 | | void getIbcMVPsEncOnly (CodingUnit& cu, Mv* mvPred, int& nbPred); |
184 | | bool isMvInRangeFPP (const int yB, const int nH, const int yMv, const int ifpLines, const PreCalcValues& pcv, const int yCompScale = 0, const int mvPrecShift = MV_FRACTIONAL_BITS_INTERNAL); |
185 | | bool isMotionBufInRangeFPP (const CodingUnit& cu, const int ifpLines); |
186 | | } |
187 | | |
188 | | // TU tools |
189 | | namespace TU |
190 | | { |
191 | | bool getCbf (const TransformUnit& tu, const ComponentID compID); |
192 | | bool getCbfAtDepth (const TransformUnit& tu, const ComponentID compID, const unsigned depth); |
193 | | void setCbfAtDepth ( TransformUnit& tu, const ComponentID compID, const unsigned depth, const bool cbf); |
194 | | bool isTSAllowed (const TransformUnit& tu, const ComponentID compID); |
195 | | |
196 | | bool needsSqrt2Scale (const TransformUnit& tu, const ComponentID compID); |
197 | | TransformUnit* getPrevTU (const TransformUnit& tu, const ComponentID compID); |
198 | | bool getPrevTuCbfAtDepth (const TransformUnit& tu, const ComponentID compID, const int trDepth ); |
199 | | int getICTMode (const TransformUnit& tu, int jointCbCr = -1); |
200 | | } |
201 | | |
202 | | uint32_t getCtuAddr (const Position& pos, const PreCalcValues &pcv); |
203 | | uint32_t getCtuAddrFromCtuSize (const Position& pos, const unsigned maxCUSizeLog2, const unsigned widthInCtus); |
204 | | |
205 | | int getNumModesMip (const Size& block); |
206 | | int getMipSizeId (const Size& block); |
207 | | bool allowLfnstWithMip (const Size& block); |
208 | | |
209 | | bool refPicCtuLineReady (const Slice& slice, const int refCtuRow, const PreCalcValues& pcv); |
210 | | |
211 | | template<typename T, size_t N> |
212 | | uint32_t updateCandList( T uiMode, double uiCost, static_vector<T, N> &candModeList, static_vector<double, N> &candCostList, size_t uiFastCandNum = N, int *iserttPos = nullptr ) |
213 | 0 | { |
214 | 0 | CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" ); |
215 | 0 | CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" ); |
216 | |
|
217 | 0 | size_t i; |
218 | 0 | size_t shift = 0; |
219 | 0 | size_t currSize = std::min( uiFastCandNum, candCostList.size() ); |
220 | |
|
221 | 0 | while( shift < uiFastCandNum && shift < currSize && uiCost < candCostList[currSize - 1 - shift] ) |
222 | 0 | { |
223 | 0 | shift++; |
224 | 0 | } |
225 | |
|
226 | 0 | if( candModeList.size() >= uiFastCandNum && shift != 0 ) |
227 | 0 | { |
228 | 0 | for( i = 1; i < shift; i++ ) |
229 | 0 | { |
230 | 0 | candModeList[currSize - i] = candModeList[currSize - 1 - i]; |
231 | 0 | candCostList[currSize - i] = candCostList[currSize - 1 - i]; |
232 | 0 | } |
233 | 0 | candModeList[currSize - shift] = uiMode; |
234 | 0 | candCostList[currSize - shift] = uiCost; |
235 | 0 | if (iserttPos != nullptr) |
236 | 0 | { |
237 | 0 | *iserttPos = int(currSize - shift); |
238 | 0 | } |
239 | 0 | return 1; |
240 | 0 | } |
241 | 0 | else if( currSize < uiFastCandNum ) |
242 | 0 | { |
243 | 0 | candModeList.insert( candModeList.end() - shift, uiMode ); |
244 | 0 | candCostList.insert( candCostList.end() - shift, uiCost ); |
245 | 0 | if (iserttPos != nullptr) |
246 | 0 | { |
247 | 0 | *iserttPos = int(candModeList.size() - shift - 1); |
248 | 0 | } |
249 | 0 | return 1; |
250 | 0 | } |
251 | 0 | if (iserttPos != nullptr) |
252 | 0 | { |
253 | 0 | *iserttPos = -1; |
254 | 0 | } |
255 | 0 | return 0; |
256 | 0 | } Unexecuted instantiation: unsigned int vvenc::updateCandList<unsigned int, 6ul>(unsigned int, double, vvenc::static_vector<unsigned int, 6ul>&, vvenc::static_vector<double, 6ul>&, unsigned long, int*) Unexecuted instantiation: unsigned int vvenc::updateCandList<vvenc::IntraSearch::ModeInfo, 16ul>(vvenc::IntraSearch::ModeInfo, double, vvenc::static_vector<vvenc::IntraSearch::ModeInfo, 16ul>&, vvenc::static_vector<double, 16ul>&, unsigned long, int*) Unexecuted instantiation: unsigned int vvenc::updateCandList<unsigned char, 16ul>(unsigned char, double, vvenc::static_vector<unsigned char, 16ul>&, vvenc::static_vector<double, 16ul>&, unsigned long, int*) |
257 | | |
258 | | } // namespace vvenc |
259 | | |
260 | | //! \} |
261 | | |