Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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      setColocatedMotionCTU      (      CodingStructure &cs, const int ctuX, const int ctuY, const bool applyDmvr );
64
  int       signalModeCons             (const CodingStructure &cs, const UnitArea &currArea, const PartSplit split, const ModeType modeTypeParent);
65
}
66
67
68
// CU tools
69
namespace CU
70
{
71
9.25M
  inline bool isSepTree                 (const CodingUnit &cu)                          { return cu.treeType != TREE_D || CS::isDualITree( *cu.cs ); }
72
0
  inline bool isLocalSepTree            (const CodingUnit &cu)                          { return cu.treeType != TREE_D && !CS::isDualITree(*cu.cs); }
73
471k
  inline bool isConsInter               (const CodingUnit &cu)                          { return cu.modeType == MODE_TYPE_INTER; }
74
180k
  inline bool isConsIntra               (const CodingUnit &cu)                          { return cu.modeType == MODE_TYPE_INTRA; }
75
76
17.6M
  inline bool isIntra                   (const CodingUnit &cu)                          { return cu.predMode == MODE_INTRA; }
77
313k
  inline bool isInter                   (const CodingUnit &cu)                          { return cu.predMode == MODE_INTER; }
78
2.00M
  inline bool isIBC                     (const CodingUnit &cu)                          { return cu.predMode == MODE_IBC; }
79
103k
  inline bool isPLT                     (const CodingUnit &cu)                          { return cu.predMode == MODE_PLT; }
80
356k
  inline bool isSameSlice               (const CodingUnit& cu, const CodingUnit& cu2)   { return cu.slice->independentSliceIdx == cu2.slice->independentSliceIdx; }
81
0
  inline bool isSameTile                (const CodingUnit& cu, const CodingUnit& cu2)   { return cu.tileIdx == cu2.tileIdx; }
82
0
  inline bool isSameSliceAndTile        (const CodingUnit& cu, const CodingUnit& cu2)   { return ( cu.slice->independentSliceIdx == cu2.slice->independentSliceIdx ) && ( cu.tileIdx == cu2.tileIdx ); }
83
84
  uint8_t   checkAllowedSbt             (const CodingUnit &cu);
85
  bool      checkCCLMAllowed            (const CodingUnit &cu);
86
  bool      isSameCtu                   (const CodingUnit &cu, const CodingUnit &cu2);
87
  bool      isSameSubPic                (const CodingUnit &cu, const CodingUnit &cu2);
88
  bool      isLastSubCUOfCtu            (const CodingUnit &cu);
89
  uint32_t  getCtuAddr                  (const CodingUnit &cu);
90
  int       predictQP                   (const CodingUnit& cu, const int prevQP);
91
92
  void saveMotionInHMVP                 (const CodingUnit& cu, const bool isToBeDone );
93
94
  PartSplit getSplitAtDepth             (const CodingUnit& cu, const unsigned depth);
95
  ModeType  getModeTypeAtDepth          (const CodingUnit& cu, const unsigned depth);
96
97
  bool      isPredRegDiffFromTB         (const CodingUnit& cu);
98
  bool      isFirstTBInPredReg          (const CodingUnit& cu, const CompArea& area);
99
  void      adjustPredArea              (CompArea& area);
100
  bool      isBcwIdxCoded               (const CodingUnit& cu);
101
  uint8_t   getValidBcwIdx              (const CodingUnit& cu);
102
  void      setBcwIdx                   (      CodingUnit& cu, uint8_t uh);
103
  bool      bdpcmAllowed                (const CodingUnit& cu, const ComponentID compID);
104
  bool      isMTSAllowed                (const CodingUnit& cu, const ComponentID compID);
105
106
107
  bool      divideTuInRows              (const CodingUnit &cu);
108
  PartSplit getISPType                  (const CodingUnit &cu,                         const ComponentID compID);
109
  bool      isISPLast                   (const CodingUnit &cu, const CompArea& tuArea, const ComponentID compID);
110
  bool      isISPFirst                  (const CodingUnit &cu, const CompArea& tuArea, const ComponentID compID);
111
  bool      canUseISP                   (const CodingUnit &cu,                         const ComponentID compID);
112
  bool      canUseISP                   (const int width, const int height, const int maxTrSize = MAX_TB_SIZEY );
113
  bool      canUseLfnstWithISP          (const CompArea& cuArea, const ISPType ispSplitType );
114
  bool      canUseLfnstWithISP          (const CodingUnit& cu, const ChannelType chType );
115
  uint32_t  getISPSplitDim              (const int width, const int height, const PartSplit ispType);
116
  bool      allLumaCBFsAreZero          (const CodingUnit& cu);
117
118
  TUTraverser  traverseTUs              (      CodingUnit& cu);
119
  cTUTraverser traverseTUs              (const CodingUnit& cu);
120
121
  bool      hasSubCUNonZeroMVd          (const CodingUnit& cu);
122
  bool      hasSubCUNonZeroAffineMVd    (const CodingUnit& cu );
123
  void      resetMVDandMV2Int           (      CodingUnit& cu );
124
125
29.1k
  inline uint8_t   getSbtIdx            ( const uint8_t sbtInfo )                     { return ( sbtInfo >> 0 ) & 0xf; }
126
0
  inline uint8_t   getSbtPos            ( const uint8_t sbtInfo )                     { return ( sbtInfo >> 4 ) & 0x3; }
127
128
0
  inline uint8_t   getSbtMode           (const uint8_t sbtIdx, const uint8_t sbtPos)  { return (sbtIdx<<1) + sbtPos - 2; }
129
0
  inline uint8_t   getSbtIdxFromSbtMode (const uint8_t sbtMode)                       { return (sbtMode>>1)+1; }
130
0
  inline uint8_t   getSbtPosFromSbtMode (const uint8_t sbtMode)                       { return sbtMode&1;}
131
0
  inline uint8_t   targetSbtAllowed     (uint8_t sbtIdx, uint8_t sbtAllowed)          { return ( sbtAllowed >> sbtIdx ) & 0x1; }
132
133
  uint8_t   numSbtModeRdo               (uint8_t sbtAllowed);
134
  PartSplit getSbtTuSplit               ( const uint8_t sbtInfo );
135
  bool      isSbtMode                   (const uint8_t sbtInfo);
136
  bool      isSameSbtSize               (const uint8_t sbtInfo1, const uint8_t sbtInfo2);
137
  bool      getRprScaling               ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale );
138
139
  const CodingUnit* getLeft             (const CodingUnit& curr);
140
  const CodingUnit* getAbove            (const CodingUnit& curr);
141
142
143
  int      getLMSymbolList              (const CodingUnit& cu, int *modeList);
144
  bool     isMIP                        (const CodingUnit& cu, const ChannelType channelType = CH_L);
145
  int      getIntraMPMs                 (const CodingUnit& cu, unsigned *mpm );
146
  bool     isDMChromaMIP                (const CodingUnit& cu);
147
  uint32_t getIntraDirLuma              (const CodingUnit& cu);
148
  void     getIntraChromaCandModes      (const CodingUnit& cu, unsigned modeList[NUM_CHROMA_MODE]);
149
  const CodingUnit &getCoLocatedLumaPU  (const CodingUnit& cu);
150
  uint32_t getFinalIntraMode            (const CodingUnit& cu, const ChannelType chType);
151
  uint32_t getCoLocatedIntraLumaMode    (const CodingUnit& cu);
152
  void     getInterMergeCandidates      (const CodingUnit& cu, MergeCtx& mrgCtx, int mmvdList, const int mrgCandIdx = -1 );
153
  void     getInterMMVDMergeCandidates  (const CodingUnit& cu, MergeCtx& mrgCtx);
154
  int      getDistScaleFactor           (const int currPOC, const int currRefPOC, const int colPOC, const int colRefPOC);
155
  bool     isDiffMER                    (const Position &pos1, const Position &pos2, const unsigned plevel);
156
  bool     getColocatedMVP              (const CodingUnit& cu, const RefPicList refPicList, const Position& pos, Mv& rcMv, const int refIdx, bool sbFlag = false);
157
  void     fillMvpCand                  (      CodingUnit& cu, const RefPicList refPicList, const int refIdx, AMVPInfo &amvpInfo );
158
  bool     addMVPCandUnscaled           (const CodingUnit& cu, const RefPicList refPicList, const int iRefIdx, const Position& pos, const MvpDir dir, AMVPInfo &amvpInfo);
159
  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);
160
  void     addAMVPHMVPCand              (const CodingUnit& cu, const RefPicList refPicList, const int currRefPOC, AMVPInfo &info);
161
  bool     isBipredRestriction          (const CodingUnit& cu);
162
  void     spanMotionInfo               (      CodingUnit& cu, const AffineMergeCtx *mrgCtx = nullptr );
163
  void     restrictBiPredMergeCandsOne  (      CodingUnit& cu);
164
165
  bool     isLMCMode                    (                          unsigned mode);
166
  bool     isLMCModeEnabled             (const CodingUnit& cu, unsigned mode);
167
  void     getGeoMergeCandidates        (const CodingUnit& cu, MergeCtx &GeoMrgCtx);
168
  void     spanGeoMotionInfo            (      CodingUnit& cu, const MergeCtx &GeoMrgCtx, const uint8_t splitDir, const uint8_t candIdx0, const uint8_t candIdx1);
169
  bool     isBiPredFromDifferentDirEqDistPoc(const CodingUnit& cu);
170
  bool     checkDMVRCondition           (const CodingUnit& cu);
171
  void     getAffineControlPointCand    (const CodingUnit& cu, MotionInfo mi[4], bool isAvailable[4], int verIdx[4], int8_t BcwIdx, int modelIdx, int verNum, AffineMergeCtx& affMrgCtx);
172
  void     getAffineMergeCand           (      CodingUnit& cu, AffineMergeCtx& affMrgCtx, const int mrgCandIdx = -1);
173
  void     setAllAffineMvField          (      CodingUnit& cu, const MvField *mvField, RefPicList eRefList);
174
  void     setAllAffineMv               (      CodingUnit& cu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList, bool clipCPMVs = false);
175
  void     xInheritedAffineMv           (const CodingUnit& cu, const CodingUnit* cuNeighbour, RefPicList refPicList, Mv rcMv[3]);
176
  void     fillAffineMvpCand            (      CodingUnit& cu, const RefPicList refPicList, const int refIdx, AffineAMVPInfo &affiAMVPInfo);
177
  bool     addAffineMVPCandUnscaled     (const CodingUnit& cu, const RefPicList refPicList, const int refIdx, const Position& pos, const MvpDir dir, AffineAMVPInfo &affiAmvpInfo);
178
  bool     getInterMergeSbTMVPCand      (const CodingUnit& cu, AffineMergeCtx &mrgCtx, const int count);
179
180
  void     getIBCMergeCandidates        (const CodingUnit& cu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1);
181
  void     fillIBCMvpCand               (CodingUnit& cu, AMVPInfo& amvpInfo);
182
  void     getIbcMVPsEncOnly            (CodingUnit& cu, Mv* mvPred, int& nbPred);
183
  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);
184
  bool     isMotionBufInRangeFPP        (const CodingUnit& cu, const int ifpLines);
185
}
186
187
// TU tools
188
namespace TU
189
{
190
  bool getCbf                           (const TransformUnit& tu, const ComponentID compID);
191
  bool getCbfAtDepth                    (const TransformUnit& tu, const ComponentID compID, const unsigned depth);
192
  void setCbfAtDepth                    (      TransformUnit& tu, const ComponentID compID, const unsigned depth, const bool cbf);
193
  bool isTSAllowed                      (const TransformUnit& tu, const ComponentID compID);
194
195
  bool needsSqrt2Scale                  (const TransformUnit& tu, const ComponentID compID);
196
  TransformUnit* getPrevTU              (const TransformUnit& tu, const ComponentID compID);
197
  bool           getPrevTuCbfAtDepth    (const TransformUnit& tu, const ComponentID compID, const int trDepth );
198
  int            getICTMode             (const TransformUnit& tu, int jointCbCr = -1);
199
}
200
201
uint32_t  getCtuAddr                    (const Position& pos, const PreCalcValues &pcv);
202
uint32_t  getCtuAddrFromCtuSize         (const Position& pos, const unsigned maxCUSizeLog2, const unsigned widthInCtus);
203
204
int       getNumModesMip                (const Size& block);
205
int       getMipSizeId                  (const Size& block);
206
bool      allowLfnstWithMip             (const Size& block);
207
208
bool      refPicCtuLineReady            (const Slice& slice, const int refCtuRow, const PreCalcValues& pcv);
209
210
template<typename T, size_t N>
211
uint32_t updateCandList( T uiMode, double uiCost, static_vector<T, N> &candModeList, static_vector<double, N> &candCostList, size_t uiFastCandNum = N, int *iserttPos = nullptr )
212
2.49M
{
213
2.49M
  CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" );
214
2.49M
  CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" );
215
216
2.49M
  size_t i;
217
2.49M
  size_t shift = 0;
218
2.49M
  size_t currSize = std::min( uiFastCandNum, candCostList.size() );
219
220
2.64M
  while( shift < uiFastCandNum && shift < currSize && uiCost < candCostList[currSize - 1 - shift] )
221
149k
  {
222
149k
    shift++;
223
149k
  }
224
225
2.49M
  if( candModeList.size() >= uiFastCandNum && shift != 0 )
226
73.0k
  {
227
131k
    for( i = 1; i < shift; i++ )
228
58.7k
    {
229
58.7k
      candModeList[currSize - i] = candModeList[currSize - 1 - i];
230
58.7k
      candCostList[currSize - i] = candCostList[currSize - 1 - i];
231
58.7k
    }
232
73.0k
    candModeList[currSize - shift] = uiMode;
233
73.0k
    candCostList[currSize - shift] = uiCost;
234
73.0k
    if (iserttPos != nullptr)
235
49.5k
    {
236
49.5k
      *iserttPos = int(currSize - shift);
237
49.5k
    }
238
73.0k
    return 1;
239
73.0k
  }
240
2.41M
  else if( currSize < uiFastCandNum )
241
361k
  {
242
361k
    candModeList.insert( candModeList.end() - shift, uiMode );
243
361k
    candCostList.insert( candCostList.end() - shift, uiCost );
244
361k
    if (iserttPos != nullptr)
245
122k
    {
246
122k
      *iserttPos = int(candModeList.size() - shift - 1);
247
122k
    }
248
361k
    return 1;
249
361k
  }
250
2.05M
  if (iserttPos != nullptr)
251
1.04M
  {
252
1.04M
    *iserttPos = -1;
253
1.04M
  }
254
2.05M
  return 0;
255
2.49M
}
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*)
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*)
Line
Count
Source
212
2.42M
{
213
2.42M
  CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" );
214
2.42M
  CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" );
215
216
2.42M
  size_t i;
217
2.42M
  size_t shift = 0;
218
2.42M
  size_t currSize = std::min( uiFastCandNum, candCostList.size() );
219
220
2.57M
  while( shift < uiFastCandNum && shift < currSize && uiCost < candCostList[currSize - 1 - shift] )
221
149k
  {
222
149k
    shift++;
223
149k
  }
224
225
2.42M
  if( candModeList.size() >= uiFastCandNum && shift != 0 )
226
73.0k
  {
227
131k
    for( i = 1; i < shift; i++ )
228
58.7k
    {
229
58.7k
      candModeList[currSize - i] = candModeList[currSize - 1 - i];
230
58.7k
      candCostList[currSize - i] = candCostList[currSize - 1 - i];
231
58.7k
    }
232
73.0k
    candModeList[currSize - shift] = uiMode;
233
73.0k
    candCostList[currSize - shift] = uiCost;
234
73.0k
    if (iserttPos != nullptr)
235
49.5k
    {
236
49.5k
      *iserttPos = int(currSize - shift);
237
49.5k
    }
238
73.0k
    return 1;
239
73.0k
  }
240
2.35M
  else if( currSize < uiFastCandNum )
241
293k
  {
242
293k
    candModeList.insert( candModeList.end() - shift, uiMode );
243
293k
    candCostList.insert( candCostList.end() - shift, uiCost );
244
293k
    if (iserttPos != nullptr)
245
122k
    {
246
122k
      *iserttPos = int(candModeList.size() - shift - 1);
247
122k
    }
248
293k
    return 1;
249
293k
  }
250
2.05M
  if (iserttPos != nullptr)
251
1.04M
  {
252
1.04M
    *iserttPos = -1;
253
1.04M
  }
254
2.05M
  return 0;
255
2.42M
}
unsigned int vvenc::updateCandList<unsigned char, 16ul>(unsigned char, double, vvenc::static_vector<unsigned char, 16ul>&, vvenc::static_vector<double, 16ul>&, unsigned long, int*)
Line
Count
Source
212
67.2k
{
213
67.2k
  CHECK( std::min( uiFastCandNum, candModeList.size() ) != std::min( uiFastCandNum, candCostList.size() ), "Sizes do not match!" );
214
67.2k
  CHECK( uiFastCandNum > candModeList.capacity(), "The vector is to small to hold all the candidates!" );
215
216
67.2k
  size_t i;
217
67.2k
  size_t shift = 0;
218
67.2k
  size_t currSize = std::min( uiFastCandNum, candCostList.size() );
219
220
67.3k
  while( shift < uiFastCandNum && shift < currSize && uiCost < candCostList[currSize - 1 - shift] )
221
84
  {
222
84
    shift++;
223
84
  }
224
225
67.2k
  if( candModeList.size() >= uiFastCandNum && shift != 0 )
226
0
  {
227
0
    for( i = 1; i < shift; i++ )
228
0
    {
229
0
      candModeList[currSize - i] = candModeList[currSize - 1 - i];
230
0
      candCostList[currSize - i] = candCostList[currSize - 1 - i];
231
0
    }
232
0
    candModeList[currSize - shift] = uiMode;
233
0
    candCostList[currSize - shift] = uiCost;
234
0
    if (iserttPos != nullptr)
235
0
    {
236
0
      *iserttPos = int(currSize - shift);
237
0
    }
238
0
    return 1;
239
0
  }
240
67.2k
  else if( currSize < uiFastCandNum )
241
67.2k
  {
242
67.2k
    candModeList.insert( candModeList.end() - shift, uiMode );
243
67.2k
    candCostList.insert( candCostList.end() - shift, uiCost );
244
67.2k
    if (iserttPos != nullptr)
245
0
    {
246
0
      *iserttPos = int(candModeList.size() - shift - 1);
247
0
    }
248
67.2k
    return 1;
249
67.2k
  }
250
0
  if (iserttPos != nullptr)
251
0
  {
252
0
    *iserttPos = -1;
253
0
  }
254
0
  return 0;
255
67.2k
}
256
257
} // namespace vvenc
258
259
//! \}
260