Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
0
{
94
0
  idx1 = Log2( area.width  )-2;
95
0
  idx2 = Log2( area.height )-2;
96
0
  idx3 = (area.x & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
97
0
  idx4 = (area.y & pcv.maxCUSizeMask) >> MIN_CU_LOG2;
98
0
}
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&)
Unexecuted instantiation: EncModeCtrl.cpp:vvenc::getAreaIdxNew(vvenc::Area const&, vvenc::PreCalcValues const&, unsigned int&, unsigned int&, unsigned int&, unsigned int&)
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
0
    : 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
0
    : 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
0
{
121
0
  switch( encTestmode.type )
122
0
  {
123
0
  case ETM_SPLIT_QT     :
124
0
  case ETM_SPLIT_BT_H   :
125
0
  case ETM_SPLIT_BT_V   :
126
0
  case ETM_SPLIT_TT_H   :
127
0
  case ETM_SPLIT_TT_V   :
128
0
    return true;
129
0
  default:
130
0
    return false;
131
0
  }
132
0
}
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
0
{
141
0
  return (   encTestmode.type == ETM_INTER_ME
142
0
          || encTestmode.type == ETM_INTER_IMV
143
0
          || encTestmode.type == ETM_MERGE_SKIP
144
0
         );
145
0
}
146
147
inline PartSplit getPartSplit( const EncTestMode& encTestmode )
148
0
{
149
0
  switch( encTestmode.type )
150
0
  {
151
0
  case ETM_SPLIT_QT     : return CU_QUAD_SPLIT;
152
0
  case ETM_SPLIT_BT_H   : return CU_HORZ_SPLIT;
153
0
  case ETM_SPLIT_BT_V   : return CU_VERT_SPLIT;
154
0
  case ETM_SPLIT_TT_H   : return CU_TRIH_SPLIT;
155
0
  case ETM_SPLIT_TT_V   : return CU_TRIV_SPLIT;
156
0
  default:                return CU_DONT_SPLIT;
157
0
  }
158
0
}
159
160
//////////////////////////////////////////////////////////////////////////
161
// EncModeCtrl controls if specific modes should be tested
162
//////////////////////////////////////////////////////////////////////////
163
164
struct ComprCUCtx
165
{
166
  ComprCUCtx()
167
0
  {
168
0
  }
169
170
  ComprCUCtx( const CodingStructure& cs, const uint32_t _minDepth, const uint32_t _maxDepth )
171
0
    : minDepth      ( _minDepth  )
172
0
    , maxDepth      ( _maxDepth  )
173
0
    , bestCS        ( nullptr    )
174
0
    , bestCU        ( nullptr    )
175
0
    , bestTU        ( nullptr    )
176
0
    , bestMode      ()
177
0
    , bestCostBeforeSplit   (MAX_DOUBLE)
178
0
    , bestCostVertSplit     (MAX_DOUBLE)
179
0
    , bestCostHorzSplit     (MAX_DOUBLE)
180
0
    , bestCostNoImv         (MAX_DOUBLE *.5)
181
0
    , grad_horVal           (0)
182
0
    , grad_verVal           (0)
183
0
    , grad_dupVal           (0)
184
0
    , grad_dowVal           (0)
185
0
    , interHad              (MAX_DISTORTION)
186
0
    , maxQtSubDepth         (0)
187
0
    , isReusingCu           (false)
188
0
    , qtBeforeBt            (false)
189
0
    , doTriHorzSplit        (false)
190
0
    , doTriVertSplit        (false)
191
0
    , didQuadSplit          (false)
192
0
    , didHorzSplit          (false)
193
0
    , didVertSplit          (false)
194
0
    , doHorChromaSplit      (false)
195
0
    , doVerChromaSplit      (false)
196
0
    , doQtChromaSplit       (false)
197
0
    , isBestNoSplitSkip     (false)
198
0
    , intraWasTested        (false)
199
0
    , relatedCuIsValid      (false)
200
0
    , isIntra               (false)
201
0
    , nonSkipWasTested      (false)
202
0
    , bestNsPredMode        (EncTestMode())
203
0
  {
204
0
  }
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
0
  CacheBlkInfoCtrl() : m_codedCUInfoBuf( nullptr ) {}
284
0
  ~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
0
  BestEncInfoCache() : m_pcv( nullptr ), m_pCoeff( nullptr ), m_encInfoBuf( nullptr ), m_dmvrMvBuf( nullptr ), m_dummyCS( m_dummyCache, nullptr ) {}
321
0
  ~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
0
  ~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