Coverage Report

Created: 2026-05-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/EncoderLib/EncModeCtrl.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     EncModeCtrl.h
43
    \brief    Encoder controller for trying out specific modes
44
*/
45
46
#pragma once
47
48
#include "InterSearch.h"
49
#include "CommonLib/CommonDef.h"
50
#include "CommonLib/CodingStructure.h"
51
52
#include <typeinfo>
53
#include <vector>
54
55
//! \ingroup EncoderLib
56
//! \{
57
58
namespace vvenc {
59
60
//////////////////////////////////////////////////////////////////////////
61
// Encoder modes to try out
62
//////////////////////////////////////////////////////////////////////////
63
64
65
enum EncTestModeType
66
{
67
  ETM_MERGE_SKIP,
68
  ETM_INTER_ME,
69
  ETM_INTER_IMV,
70
  ETM_INTRA,
71
  ETM_SPLIT_QT,
72
  ETM_SPLIT_BT_H,
73
  ETM_SPLIT_BT_V,
74
  ETM_SPLIT_TT_H,
75
  ETM_SPLIT_TT_V,
76
  ETM_RECO_CACHED,
77
  ETM_IBC,
78
  ETM_IBC_MERGE,
79
  ETM_INVALID
80
};
81
82
enum EncTestModeOpts
83
{
84
  ETO_STANDARD    =  0,                   // empty      (standard option)
85
  ETO_FORCE_MERGE =  1<<0,                // bit   0    (indicates forced merge)
86
  ETO_IMV_SHIFT   =  1,                   // bits  1-3  (imv parameter starts at bit 1)
87
  ETO_IMV         =  7<<ETO_IMV_SHIFT,    // bits  1-3  (imv parameter uses 3 bits)
88
  ETO_DUMMY       =  1<<5,                // bit   5    (dummy)
89
  ETO_INVALID     = 0xffffffff            // bits 0-31  (invalid option)
90
};
91
92
static inline void getAreaIdxNew(const Area& area, const PreCalcValues &pcv, unsigned& idx1, unsigned& idx2, unsigned& idx3, unsigned& idx4)
93
347k
{
94
347k
  idx1 = Log2( area.width  )-2;
95
347k
  idx2 = Log2( area.height )-2;
96
347k
  idx3 = (area.x & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
97
347k
  idx4 = (area.y & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
98
347k
}
Unexecuted instantiation: vvencimpl.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: EncLib.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: EncGOP.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: EncPicture.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: EncSlice.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: InterSearch.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Unexecuted instantiation: EncCu.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
EncModeCtrl.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
Line
Count
Source
93
347k
{
94
347k
  idx1 = Log2( area.width  )-2;
95
347k
  idx2 = Log2( area.height )-2;
96
347k
  idx3 = (area.x & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
97
347k
  idx4 = (area.y & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
98
347k
}
Unexecuted instantiation: IntraSearch.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
99
100
struct EncTestMode
101
{
102
  EncTestMode()
103
1.60M
    : type( ETM_INVALID ), opts( ETO_INVALID  ), qp( -1  ), lossless( false ) {}
104
  EncTestMode( EncTestModeType _type )
105
0
    : type( _type       ), opts( ETO_STANDARD ), qp( -1  ), lossless( false ) {}
106
  EncTestMode( EncTestModeType _type, int _qp, bool _lossless )
107
0
    : type( _type       ), opts( ETO_STANDARD ), qp( _qp ), lossless( _lossless ) {}
108
  EncTestMode( EncTestModeType _type, EncTestModeOpts _opts, int _qp, bool _lossless )
109
452k
    : type( _type       ), opts( _opts        ), qp( _qp ), lossless( _lossless ) {}
110
111
  EncTestModeType type;
112
  EncTestModeOpts opts;
113
  int             qp;
114
  bool            lossless;
115
  double          maxCostAllowed;
116
};
117
118
119
inline bool isModeSplit( const EncTestMode& encTestmode )
120
497k
{
121
497k
  switch( encTestmode.type )
122
497k
  {
123
100k
  case ETM_SPLIT_QT     :
124
154k
  case ETM_SPLIT_BT_H   :
125
204k
  case ETM_SPLIT_BT_V   :
126
234k
  case ETM_SPLIT_TT_H   :
127
258k
  case ETM_SPLIT_TT_V   :
128
258k
    return true;
129
239k
  default:
130
239k
    return false;
131
497k
  }
132
497k
}
133
134
inline bool isModeNoSplit( const EncTestMode& encTestmode )
135
0
{
136
0
  return !isModeSplit( encTestmode );
137
0
}
138
139
inline bool isModeInter( const EncTestMode& encTestmode ) // perhaps remove
140
156k
{
141
156k
  return (   encTestmode.type == ETM_INTER_ME
142
156k
          || encTestmode.type == ETM_INTER_IMV
143
156k
          || encTestmode.type == ETM_MERGE_SKIP
144
156k
         );
145
156k
}
146
147
inline PartSplit getPartSplit( const EncTestMode& encTestmode )
148
628k
{
149
628k
  switch( encTestmode.type )
150
628k
  {
151
162k
  case ETM_SPLIT_QT     : return CU_QUAD_SPLIT;
152
209k
  case ETM_SPLIT_BT_H   : return CU_HORZ_SPLIT;
153
198k
  case ETM_SPLIT_BT_V   : return CU_VERT_SPLIT;
154
32.7k
  case ETM_SPLIT_TT_H   : return CU_TRIH_SPLIT;
155
25.7k
  case ETM_SPLIT_TT_V   : return CU_TRIV_SPLIT;
156
0
  default:                return CU_DONT_SPLIT;
157
628k
  }
158
628k
}
159
160
//////////////////////////////////////////////////////////////////////////
161
// EncModeCtrl controls if specific modes should be tested
162
//////////////////////////////////////////////////////////////////////////
163
164
struct ComprCUCtx
165
{
166
  ComprCUCtx()
167
549k
  {
168
549k
  }
169
170
  ComprCUCtx( const CodingStructure& cs, const uint32_t _minDepth, const uint32_t _maxDepth )
171
130k
    : minDepth      ( _minDepth  )
172
130k
    , maxDepth      ( _maxDepth  )
173
130k
    , bestCS        ( nullptr    )
174
130k
    , bestCU        ( nullptr    )
175
130k
    , bestTU        ( nullptr    )
176
130k
    , bestMode      ()
177
130k
    , bestCostBeforeSplit   (MAX_DOUBLE)
178
130k
    , bestCostVertSplit     (MAX_DOUBLE)
179
130k
    , bestCostHorzSplit     (MAX_DOUBLE)
180
130k
    , bestCostNoImv         (MAX_DOUBLE *.5)
181
130k
    , grad_horVal           (0)
182
130k
    , grad_verVal           (0)
183
130k
    , grad_dupVal           (0)
184
130k
    , grad_dowVal           (0)
185
130k
    , interHad              (MAX_DISTORTION)
186
130k
    , maxQtSubDepth         (0)
187
130k
    , isReusingCu           (false)
188
130k
    , qtBeforeBt            (false)
189
130k
    , doTriHorzSplit        (false)
190
130k
    , doTriVertSplit        (false)
191
130k
    , didQuadSplit          (false)
192
130k
    , didHorzSplit          (false)
193
130k
    , didVertSplit          (false)
194
130k
    , doHorChromaSplit      (false)
195
130k
    , doVerChromaSplit      (false)
196
130k
    , doQtChromaSplit       (false)
197
130k
    , isBestNoSplitSkip     (false)
198
130k
    , intraWasTested        (false)
199
130k
    , relatedCuIsValid      (false)
200
130k
    , isIntra               (false)
201
130k
    , nonSkipWasTested      (false)
202
130k
    , bestNsPredMode        (EncTestMode())
203
130k
  {
204
130k
  }
205
206
  unsigned          minDepth;
207
  unsigned          maxDepth;
208
  CodingStructure*  bestCS;
209
  CodingUnit*       bestCU;
210
  TransformUnit*    bestTU;
211
  EncTestMode       bestMode;
212
  double            bestCostBeforeSplit;
213
  double            bestCostVertSplit;
214
  double            bestCostHorzSplit;
215
  double            bestCostNoImv;
216
  double            grad_horVal;
217
  double            grad_verVal;
218
  double            grad_dupVal;
219
  double            grad_dowVal;
220
  Distortion        interHad;
221
  int               maxQtSubDepth;
222
  bool              isReusingCu;
223
  bool              qtBeforeBt;
224
  bool              doTriHorzSplit;
225
  bool              doTriVertSplit;
226
  int               doMoreSplits;
227
  bool              didQuadSplit;
228
  bool              didHorzSplit;
229
  bool              didVertSplit;
230
  bool              doHorChromaSplit;
231
  bool              doVerChromaSplit;
232
  bool              doQtChromaSplit;
233
  bool              isBestNoSplitSkip;
234
  bool              intraWasTested;
235
  bool              relatedCuIsValid;
236
  bool              isIntra;
237
  bool              nonSkipWasTested;
238
  EncTestMode       bestNsPredMode;
239
};
240
241
//////////////////////////////////////////////////////////////////////////
242
// some utility interfaces that expose some functionality that can be used without concerning about which particular controller is used
243
//////////////////////////////////////////////////////////////////////////
244
245
static const int MAX_STORED_CU_INFO_REFS = 4;
246
247
struct CodedCUInfo
248
{
249
  bool      relatedCuIsValid;
250
  bool      isInter;
251
  bool      isIntra;
252
  bool      isSkip;
253
  bool      isMMVDSkip;
254
  bool      isIBC;
255
  uint8_t   BcwIdx;
256
  uint8_t   numPuInfoStored;
257
  int       poc, ctuRsAddr;
258
  bool      validMv[NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS];
259
  Mv        saveMv [NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS];
260
  uint32_t  puSse  [SBT_NUM_SL];
261
  uint8_t   puSbt  [SBT_NUM_SL];
262
  double    bestCost;
263
264
  bool getMv  ( const RefPicList refPicList, const int iRefIdx,       Mv& rMv ) const;
265
  void setMv  ( const RefPicList refPicList, const int iRefIdx, const Mv& rMv );
266
};
267
268
class CacheBlkInfoCtrl
269
{
270
protected:
271
  // x in CTU, y in CTU, width, height
272
  CodedCUInfo*         m_codedCUInfo[6][6][MAX_CU_SIZE >> MIN_CU_LOG2][MAX_CU_SIZE >> MIN_CU_LOG2];
273
  CodedCUInfo*         m_codedCUInfoBuf;
274
  const PreCalcValues* m_pcv;
275
276
protected:
277
278
  void create   ( int ctuSize );
279
  void destroy  ();
280
  void init     ( const Slice &slice );
281
282
public:
283
19.6k
  CacheBlkInfoCtrl() : m_codedCUInfoBuf( nullptr ) {}
284
19.6k
  ~CacheBlkInfoCtrl () {}
285
286
  CodedCUInfo& getBlkInfo   ( const UnitArea& area );
287
  void         initBlk      ( const UnitArea& area, int poc );
288
289
  uint8_t      findBestSbt  ( const UnitArea& area, const uint32_t curPuSse );
290
  bool         saveBestSbt  ( const UnitArea& area, const uint32_t curPuSse, const uint8_t curPuSbt );
291
};
292
293
struct BestEncodingInfo
294
{ 
295
  CodingUnit      cu;
296
  TransformUnit   tu;
297
  EncTestMode     testMode;
298
  int             poc;
299
  Distortion      dist;
300
  double          costEDO;
301
};
302
303
class BestEncInfoCache
304
{
305
private:
306
  const PreCalcValues* m_pcv;
307
  BestEncodingInfo*    m_bestEncInfo[6][6][MAX_CU_SIZE >> MIN_CU_LOG2][MAX_CU_SIZE >> MIN_CU_LOG2];
308
  TCoeffSig*           m_pCoeff;
309
  BestEncodingInfo*    m_encInfoBuf;
310
  Mv*                  m_dmvrMvBuf;
311
  CodingStructure      m_dummyCS;
312
  XUCache              m_dummyCache;
313
314
protected:
315
  bool                 m_reuseCuResults;
316
  void create   ( const bool reuseCuResults, const ChromaFormat chFmt, int ctuSize );
317
  void destroy  ();
318
319
public:
320
19.6k
  BestEncInfoCache() : m_pcv( nullptr ), m_pCoeff( nullptr ), m_encInfoBuf( nullptr ), m_dmvrMvBuf( nullptr ), m_dummyCS( m_dummyCache, nullptr ) {}
321
19.6k
  ~BestEncInfoCache() {}
322
323
  void init             ( const Slice &slice );
324
  bool setCsFrom        (       CodingStructure& cs,       EncTestMode& testMode, const Partitioner& partitioner ) const;
325
  bool setFromCs        ( const CodingStructure& cs, const EncTestMode& testMode, const Partitioner& partitioner );
326
  bool isReusingCuValid ( const CodingStructure &cs, const Partitioner &partitioner, int qp );
327
};
328
329
//////////////////////////////////////////////////////////////////////////
330
// EncModeCtrl - allows and controls modes introduced by QTBT (inkl. multi-type-tree)
331
//                    - only 2Nx2N, no RQT, additional binary/triary CU splits
332
//////////////////////////////////////////////////////////////////////////
333
334
class EncModeCtrl: public CacheBlkInfoCtrl, public BestEncInfoCache
335
{
336
protected:
337
338
  const VVEncCfg*       m_pcEncCfg;
339
        RdCost*         m_pcRdCost;
340
  static_vector<ComprCUCtx, ( MAX_CU_DEPTH << 2 )> m_ComprCUCtxList;
341
  unsigned              m_skipThresholdE0023FastEnc;
342
  unsigned              m_tileIdx;
343
344
public:
345
  ComprCUCtx*           comprCUCtx;
346
347
19.6k
  ~EncModeCtrl    () { destroy(); }
348
349
  void init               ( const VVEncCfg& encCfg, RdCost *pRdCost );
350
  void destroy            ();
351
  void initCTUEncoding    ( const Slice &slice, int tileIdx );
352
  void initCULevel        ( Partitioner &partitioner, const CodingStructure& cs, int  MergeSimpleFlag );
353
  void finishCULevel      ( Partitioner &partitioner );
354
355
  bool tryMode            ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner );
356
  bool trySplit           ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner, const EncTestMode& lastTestmode );
357
  bool useModeResult      ( const EncTestMode& encTestmode, CodingStructure*& tempCS,  Partitioner& partitioner, const bool useEDO );
358
359
  void beforeSplit        ( Partitioner& partitioner );
360
};
361
362
} // namespace vvenc
363
364
//! \}
365