Coverage Report

Created: 2026-08-13 07:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/CommonLib/RdCost.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     RdCost.h
43
    \brief    RD cost computation classes (header)
44
*/
45
46
#pragma once
47
48
#include "CommonDef.h"
49
#include "Mv.h"
50
#include "Unit.h"
51
#include "Slice.h"
52
53
#include <math.h>
54
55
//! \ingroup CommonLib
56
//! \{
57
58
namespace vvenc {
59
  
60
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_DIST
61
using namespace x86_simd;
62
#endif
63
#if defined(TARGET_SIMD_ARM)  && ENABLE_SIMD_OPT_DIST
64
using namespace arm_simd;
65
#endif
66
67
class DistParam;
68
69
// ====================================================================================================================
70
// Type definition
71
// ====================================================================================================================
72
73
// for function pointer
74
typedef Distortion( *FpDistFunc   )( const DistParam& );
75
typedef void      ( *FpDistFuncX5 )( const DistParam&, Distortion*, bool );
76
77
// ====================================================================================================================
78
// Class definition
79
// ====================================================================================================================
80
81
/// distortion parameter class
82
class DistParam
83
{
84
public:
85
  CPelBuf               org;
86
  CPelBuf               cur;
87
  FpDistFunc            distFunc  = nullptr;
88
  FpDistFuncX5          dmvrSadX5 = nullptr;
89
#if ENABLE_MEASURE_SEARCH_SPACE
90
  FpDistFunc            xDistFunc = nullptr;
91
#endif
92
  int                   bitDepth    = 0;
93
  int                   subShift    = 0;
94
  ComponentID           compID      = MAX_NUM_COMP;
95
  bool                  applyWeight = false;     // whether weighted prediction is used or not
96
  Distortion            maximumDistortionForEarlyExit = MAX_DISTORTION; /// During cost calculations, if distortion exceeds this value, cost calculations may early-terminate.
97
  const WPScalingParam* wpCur   = nullptr;           // weighted prediction scaling parameters for current ref
98
  const CPelBuf*        orgLuma = nullptr;
99
100
  const Pel*            mask        = nullptr;
101
  int                   maskStride  = 0;
102
  int                   stepX       = 0;
103
  int                   maskStride2 = 0;
104
105
44.6k
  DistParam() = default;
106
107
  DistParam( const CPelBuf& _org, const CPelBuf& _cur,  FpDistFunc _distFunc, int _bitDepth, int _subShift, ComponentID _compID )
108
3.01M
    : org(_org), cur(_cur), distFunc(_distFunc), bitDepth(_bitDepth), subShift(_subShift), compID(_compID)
109
3.01M
  {
110
3.01M
  }
111
};
112
113
/// RD cost computation class
114
class RdCost
115
{
116
public:
117
  Distortion ( *m_fxdWtdPredPtr )( const DistParam& dp, uint32_t fixedWeight );
118
119
  // for distortion
120
  FpDistFunc              m_afpDistortFunc[2][DF_TOTAL_FUNCTIONS]; // [eDFunc]
121
  FpDistFuncX5            m_afpDistortFuncX5[2]; // [eDFunc]
122
123
private:
124
  vvencCostMode           m_costMode;
125
  double                  m_distortionWeight[MAX_NUM_COMP]; // only chroma values are used.
126
  double                  m_dLambda;
127
  double                  m_dLambda_unadjusted; // TODO: check is necessary
128
  double                  m_DistScaleUnadjusted;
129
130
  std::vector<uint32_t>   m_lumaLevelToWeightPLUT;
131
132
  double                  m_chromaWeight;
133
  ChromaFormat            m_cf;
134
  double                  m_DistScale;
135
  double                  m_dLambdaMotionSAD;
136
137
  // for motion cost
138
  Mv                      m_mvPredictor;
139
  Mv                      m_bvPredictors[2];
140
  double                  m_motionLambda;
141
  int                     m_iCostScale;
142
  double                  m_dCostIBC;
143
public:
144
  RdCost();
145
  virtual ~RdCost();
146
147
  void          create( bool enableOpt = true );
148
149
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_DIST
150
  void          initRdCostX86();
151
  template <X86_VEXT vext>
152
  void          _initRdCostX86();
153
#endif
154
155
#if defined(TARGET_SIMD_ARM)  && ENABLE_SIMD_OPT_DIST
156
  void initRdCostARM();
157
  template<ARM_VEXT vext>
158
  void _initRdCostARM();
159
#endif   // TARGET_SIMD_ARM
160
161
24.1k
  void          setDistortionWeight ( const ComponentID compID, const double distortionWeight ) { m_distortionWeight[compID] = distortionWeight; }
162
  void          setLambda           ( double dLambda, const BitDepths &bitDepths );
163
19.2k
  void          setCostMode         ( vvencCostMode m )                      { m_costMode = m; }
164
165
0
  double        getLambda           ( bool unadj = false )              { return unadj ? m_dLambda_unadjusted : m_dLambda; }
166
0
  double        getChromaWeight     ()                                  { return ((m_distortionWeight[COMP_Cb] + m_distortionWeight[COMP_Cr]) / 2.0); }
167
  double        calcRdCost          ( uint64_t fracBits, Distortion distortion, bool useUnadjustedLambda = true ) const
168
2.69M
  {
169
2.69M
    return ( useUnadjustedLambda ? m_DistScaleUnadjusted : m_DistScale ) * double( distortion ) + double( fracBits );
170
2.69M
  }
171
172
  void          setDistParam        ( DistParam &rcDP, const CPelBuf& org, const Pel* piRefY , int iRefStride, int bitDepth, ComponentID compID, int subShiftMode = 0, int useHadamard = 0 );
173
  DistParam     setDistParam        ( const CPelBuf& org, const CPelBuf& cur, int bitDepth, DFunc dfunc );
174
  DistParam     setDistParam        ( const Pel* pOrg, const Pel* piRefY, int iOrgStride, int iRefStride, int bitDepth, ComponentID compID, int width, int height, int subShift, bool isDMVR = false );
175
  void          setDistParamGeo     ( DistParam &rcDP, const CPelBuf& org, const Pel *piRefY, int iRefStride, const Pel *mask, int iMaskStride, int stepX, int iMaskStride2, int bitDepth, ComponentID compID );
176
177
50.8k
  double        getMotionLambda     ()                      const { return m_dLambdaMotionSAD; }
178
0
  void          selectMotionLambda  ()                            { m_motionLambda = getMotionLambda(); }
179
91.0k
  void          setPredictor        ( const Mv& rcMv )            { m_mvPredictor = rcMv; }
180
48.1k
  void          setCostScale        ( int iCostScale )            { m_iCostScale = iCostScale; }
181
0
  Distortion    getCost             ( uint32_t b )          const { return Distortion( m_motionLambda * b ); }
182
  // for motion cost
183
  static uint32_t    xGetExpGolombNumberOfBits( int iVal )
184
182k
  {
185
182k
    CHECKD( iVal == std::numeric_limits<int>::min(), "Wrong value" );
186
187
#if ENABLE_SIMD_OPT && defined( TARGET_SIMD_X86 )
188
    // the proper Log2 is not restricted to 0...MAX_CU_SIZE
189
    return 1 + ( Log2( iVal <= 0 ? ( unsigned( -iVal ) << 1 ) + 1 : unsigned( iVal << 1 ) ) << 1 );
190
#else
191
182k
    unsigned uiLength2 = 1, uiTemp2 = ( iVal <= 0 ) ? ( unsigned( -iVal ) << 1 ) + 1 : unsigned( iVal << 1 );
192
193
190k
    while( uiTemp2 > MAX_CU_SIZE )
194
8.45k
    {
195
8.45k
      uiLength2 += ( MAX_CU_DEPTH << 1 );
196
8.45k
      uiTemp2  >>=   MAX_CU_DEPTH;
197
8.45k
    }
198
199
182k
    return uiLength2 + ( Log2(uiTemp2) << 1 );
200
182k
#endif
201
182k
  }
202
0
  Distortion     getCostOfVectorWithPredictor( const int x, const int y, const unsigned imvShift )  { return Distortion( m_motionLambda * getBitsOfVectorWithPredictor(x, y, imvShift )); }
203
91.0k
  uint32_t       getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift )  { return xGetExpGolombNumberOfBits(((x * (1 << m_iCostScale)) - m_mvPredictor.hor)>>imvShift) + xGetExpGolombNumberOfBits(((y * (1 << m_iCostScale)) - m_mvPredictor.ver)>>imvShift); }
204
205
  void           saveUnadjustedLambda ();
206
0
  void           setChromaFormat      ( ChromaFormat cf )   { m_cf = cf; }
207
  void           setPredictorsIBC     (Mv* pcMv)
208
25.4k
  {
209
76.2k
    for (int i = 0; i < 2; i++)
210
50.8k
    {
211
50.8k
      m_bvPredictors[i] = pcMv[i];
212
50.8k
    }
213
25.4k
  }
214
25.4k
  void           getMotionCostIBC(int add) { m_dCostIBC = m_dLambdaMotionSAD + add; }
215
  Distortion     getBvCostMultiplePredsIBC(int x, int y, bool useIMV);
216
  
217
  static Distortion xGetSAD8          ( const DistParam& pcDtParam );
218
  static Distortion xGetSAD16         ( const DistParam& pcDtParam ); // needs to be public for xGetSAD_MxN_SIMD ( NOTE: they are all public in vvenc )
219
  static void       xGetSAD16X5       ( const DistParam& pcDtParam, Distortion* cost, bool isCalCentrePos ); // needs to be public for xGetSADX5_16xN_SIMD ( NOTE: they are all public in vvenc )
220
221
  static Distortion xGetSSE           ( const DistParam& pcDtParam );
222
  static Distortion xGetSSE4          ( const DistParam& pcDtParam );
223
  static Distortion xGetSSE8          ( const DistParam& pcDtParam );
224
  static Distortion xGetSSE16         ( const DistParam& pcDtParam );
225
  static Distortion xGetSSE32         ( const DistParam& pcDtParam );
226
  static Distortion xGetSSE64         ( const DistParam& pcDtParam );
227
  static Distortion xGetSSE128        ( const DistParam& pcDtParam );
228
229
230
  static Distortion xGetSAD           ( const DistParam& pcDtParam );
231
  static Distortion xGetSAD4          ( const DistParam& pcDtParam );
232
  static Distortion xGetSAD32         ( const DistParam& pcDtParam );
233
  static Distortion xGetSAD64         ( const DistParam& pcDtParam );
234
  static Distortion xGetSAD128        ( const DistParam& pcDtParam );
235
  static Distortion xGetSADwMask      ( const DistParam &pcDtParam );
236
  
237
  static void       xGetSAD8X5        ( const DistParam& pcDtParam, Distortion* cost, bool isCalCentrePos );
238
  
239
  static Distortion xCalcHADs2x2      ( const Pel* piOrg, const Pel* piCur, int iStrideOrg, int iStrideCur );
240
  static Distortion xGetHAD2SADs      ( const DistParam& pcDtParam );
241
  template<bool fastHad>
242
  static Distortion xGetHADs          ( const DistParam& pcDtParam );
243
244
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_DIST
245
246
  template<X86_VEXT vext>
247
  static Distortion xGetSSE_SIMD    ( const DistParam& pcDtParam );
248
  template<int iWidth, X86_VEXT vext>
249
  static Distortion xGetSSE_NxN_SIMD( const DistParam& pcDtParam );
250
251
  template<X86_VEXT vext>
252
  static Distortion xGetSAD_SIMD    ( const DistParam& pcDtParam );
253
  template<int iWidth, X86_VEXT vext>
254
  static Distortion xGetSAD_NxN_SIMD( const DistParam& pcDtParam );
255
256
  template <X86_VEXT vext>
257
  static void xGetSADX5_8xN_SIMD    ( const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos );
258
  template <X86_VEXT vext>
259
  static void xGetSADX5_16xN_SIMD_X86   ( const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos );
260
261
  template<X86_VEXT vext, bool fastHad>
262
  static Distortion xGetHADs_SIMD   ( const DistParam& pcDtParam );
263
  template<X86_VEXT vext>
264
  static Distortion xGetHAD2SADs_SIMD( const DistParam &rcDtParam );
265
266
  template<X86_VEXT vext> 
267
  static Distortion xGetSADwMask_SIMD( const DistParam &pcDtParam );
268
#endif
269
270
  unsigned int   getBitsMultiplePredsIBC(int x, int y, bool useIMV);
271
272
  Distortion   getDistPart( const CPelBuf& org, const CPelBuf& cur, int bitDepth, const ComponentID compId, DFunc eDFunc );
273
274
  void initLumaLevelToWeightTable( int lumaBD );
275
};// END CLASS DEFINITION RdCost
276
277
} // namespace vvenc
278
279
//! \}
280