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/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
38.3k
  DistParam() = default;
106
107
  DistParam( const CPelBuf& _org, const CPelBuf& _cur,  FpDistFunc _distFunc, int _bitDepth, int _subShift, ComponentID _compID )
108
3.82M
    : org(_org), cur(_cur), distFunc(_distFunc), bitDepth(_bitDepth), subShift(_subShift), compID(_compID)
109
3.82M
  {
110
3.82M
  }
111
};
112
113
/// RD cost computation class
114
class RdCost
115
{
116
public:
117
  Distortion ( *m_fxdWtdPredPtr )( const DistParam& dp, uint32_t fixedWeight );
118
  // the bits of getBitsMultiplePredsIBC( x0 + i * xStep, y ) for i = 0 ... count - 1, with the given predictors
119
  void       ( *m_bvBitsLineIBC )( const Mv* predictors, const int x0, const int xStep, const int count, const int y, const bool useIMV, unsigned* bits );
120
121
  // for distortion
122
  FpDistFunc              m_afpDistortFunc[2][DF_TOTAL_FUNCTIONS]; // [eDFunc]
123
  FpDistFuncX5            m_afpDistortFuncX5[2]; // [eDFunc]
124
125
private:
126
  vvencCostMode           m_costMode;
127
  double                  m_distortionWeight[MAX_NUM_COMP]; // only chroma values are used.
128
  double                  m_dLambda;
129
  double                  m_dLambda_unadjusted; // TODO: check is necessary
130
  double                  m_DistScaleUnadjusted;
131
132
  std::vector<uint32_t>   m_lumaLevelToWeightPLUT;
133
134
  double                  m_chromaWeight;
135
  ChromaFormat            m_cf;
136
  double                  m_DistScale;
137
  double                  m_dLambdaMotionSAD;
138
139
  // for motion cost
140
  Mv                      m_mvPredictor;
141
  Mv                      m_bvPredictors[2];
142
  double                  m_motionLambda;
143
  int                     m_iCostScale;
144
  double                  m_dCostIBC;
145
public:
146
  RdCost();
147
  virtual ~RdCost();
148
149
  void          create( bool enableOpt = true );
150
151
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_DIST
152
  void          initRdCostX86();
153
  template <X86_VEXT vext>
154
  void          _initRdCostX86();
155
#endif
156
157
#if defined(TARGET_SIMD_ARM)  && ENABLE_SIMD_OPT_DIST
158
  void initRdCostARM();
159
  template<ARM_VEXT vext>
160
  void _initRdCostARM();
161
#endif   // TARGET_SIMD_ARM
162
163
23.5k
  void          setDistortionWeight ( const ComponentID compID, const double distortionWeight ) { m_distortionWeight[compID] = distortionWeight; }
164
  void          setLambda           ( double dLambda, const BitDepths &bitDepths );
165
5.97k
  void          setCostMode         ( vvencCostMode m )                      { m_costMode = m; }
166
167
0
  double        getLambda           ( bool unadj = false )              { return unadj ? m_dLambda_unadjusted : m_dLambda; }
168
0
  double        getChromaWeight     ()                                  { return ((m_distortionWeight[COMP_Cb] + m_distortionWeight[COMP_Cr]) / 2.0); }
169
  double        calcRdCost          ( uint64_t fracBits, Distortion distortion, bool useUnadjustedLambda = true ) const
170
3.42M
  {
171
3.42M
    return ( useUnadjustedLambda ? m_DistScaleUnadjusted : m_DistScale ) * double( distortion ) + double( fracBits );
172
3.42M
  }
173
174
  void          setDistParam        ( DistParam &rcDP, const CPelBuf& org, const Pel* piRefY , int iRefStride, int bitDepth, ComponentID compID, int subShiftMode = 0, int useHadamard = 0 );
175
  DistParam     setDistParam        ( const CPelBuf& org, const CPelBuf& cur, int bitDepth, DFunc dfunc );
176
  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 );
177
  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 );
178
179
64.8k
  double        getMotionLambda     ()                      const { return m_dLambdaMotionSAD; }
180
0
  void          selectMotionLambda  ()                            { m_motionLambda = getMotionLambda(); }
181
116k
  void          setPredictor        ( const Mv& rcMv )            { m_mvPredictor = rcMv; }
182
61.5k
  void          setCostScale        ( int iCostScale )            { m_iCostScale = iCostScale; }
183
0
  Distortion    getCost             ( uint32_t b )          const { return Distortion( m_motionLambda * b ); }
184
  // for motion cost
185
  static uint32_t    xGetExpGolombNumberOfBits( int iVal )
186
233k
  {
187
233k
    CHECKD( iVal == std::numeric_limits<int>::min(), "Wrong value" );
188
189
#if ENABLE_SIMD_OPT && defined( TARGET_SIMD_X86 )
190
    // the proper Log2 is not restricted to 0...MAX_CU_SIZE
191
    return 1 + ( Log2( iVal <= 0 ? ( unsigned( -iVal ) << 1 ) + 1 : unsigned( iVal << 1 ) ) << 1 );
192
#else
193
233k
    unsigned uiLength2 = 1, uiTemp2 = ( iVal <= 0 ) ? ( unsigned( -iVal ) << 1 ) + 1 : unsigned( iVal << 1 );
194
195
244k
    while( uiTemp2 > MAX_CU_SIZE )
196
11.3k
    {
197
11.3k
      uiLength2 += ( MAX_CU_DEPTH << 1 );
198
11.3k
      uiTemp2  >>=   MAX_CU_DEPTH;
199
11.3k
    }
200
201
233k
    return uiLength2 + ( Log2(uiTemp2) << 1 );
202
233k
#endif
203
233k
  }
204
0
  Distortion     getCostOfVectorWithPredictor( const int x, const int y, const unsigned imvShift )  { return Distortion( m_motionLambda * getBitsOfVectorWithPredictor(x, y, imvShift )); }
205
116k
  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); }
206
207
  void           saveUnadjustedLambda ();
208
0
  void           setChromaFormat      ( ChromaFormat cf )   { m_cf = cf; }
209
  void           setPredictorsIBC     (Mv* pcMv)
210
32.4k
  {
211
97.2k
    for (int i = 0; i < 2; i++)
212
64.8k
    {
213
64.8k
      m_bvPredictors[i] = pcMv[i];
214
64.8k
    }
215
32.4k
  }
216
32.4k
  void           getMotionCostIBC(int add) { m_dCostIBC = m_dLambdaMotionSAD + add; }
217
  Distortion     getBvCostMultiplePredsIBC(int x, int y, bool useIMV);
218
1.62M
  Distortion     getBvCostIBC         ( const unsigned bits ) const { return Distortion( m_dCostIBC * bits ); }
219
  // the bits of the block vectors ( x0 + i * xStep, y ), i = 0 ... count - 1, as getBitsMultiplePredsIBC
220
  void           getBvBitsRowIBC      ( const int x0, const int xStep, const int count, const int y, const bool useIMV, unsigned* bits ) const
221
22.9k
  {
222
22.9k
    m_bvBitsLineIBC( m_bvPredictors, x0, xStep, count, y, useIMV, bits );
223
22.9k
  }
224
  // the bits of the block vectors ( x, y0 + i * yStep ): the estimate is symmetric in the two components, so this is
225
  // the row of the transposed vectors
226
  void           getBvBitsColumnIBC   ( const int x, const int y0, const int yStep, const int count, const bool useIMV, unsigned* bits ) const
227
19.6k
  {
228
19.6k
    const Mv transposed[2] = { Mv( m_bvPredictors[0].ver, m_bvPredictors[0].hor ), Mv( m_bvPredictors[1].ver, m_bvPredictors[1].hor ) };
229
19.6k
    m_bvBitsLineIBC( transposed, y0, yStep, count, x, useIMV, bits );
230
19.6k
  }
231
  
232
  static Distortion xGetSAD8          ( const DistParam& pcDtParam );
233
  static Distortion xGetSAD16         ( const DistParam& pcDtParam ); // needs to be public for xGetSAD_MxN_SIMD ( NOTE: they are all public in vvenc )
234
  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 )
235
236
  static Distortion xGetSSE           ( const DistParam& pcDtParam );
237
  static Distortion xGetSSE4          ( const DistParam& pcDtParam );
238
  static Distortion xGetSSE8          ( const DistParam& pcDtParam );
239
  static Distortion xGetSSE16         ( const DistParam& pcDtParam );
240
  static Distortion xGetSSE32         ( const DistParam& pcDtParam );
241
  static Distortion xGetSSE64         ( const DistParam& pcDtParam );
242
  static Distortion xGetSSE128        ( const DistParam& pcDtParam );
243
244
245
  static Distortion xGetSAD           ( const DistParam& pcDtParam );
246
  static Distortion xGetSAD4          ( const DistParam& pcDtParam );
247
  static Distortion xGetSAD32         ( const DistParam& pcDtParam );
248
  static Distortion xGetSAD64         ( const DistParam& pcDtParam );
249
  static Distortion xGetSAD128        ( const DistParam& pcDtParam );
250
  static Distortion xGetSADwMask      ( const DistParam &pcDtParam );
251
  
252
  static void       xGetSAD8X5        ( const DistParam& pcDtParam, Distortion* cost, bool isCalCentrePos );
253
  
254
  static Distortion xCalcHADs2x2      ( const Pel* piOrg, const Pel* piCur, int iStrideOrg, int iStrideCur );
255
  static Distortion xGetHAD2SADs      ( const DistParam& pcDtParam );
256
  template<bool fastHad>
257
  static Distortion xGetHADs          ( const DistParam& pcDtParam );
258
259
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_DIST
260
261
  template<X86_VEXT vext>
262
  static Distortion xGetSSE_SIMD    ( const DistParam& pcDtParam );
263
  template<int iWidth, X86_VEXT vext>
264
  static Distortion xGetSSE_NxN_SIMD( const DistParam& pcDtParam );
265
266
  template<X86_VEXT vext>
267
  static Distortion xGetSAD_SIMD    ( const DistParam& pcDtParam );
268
  template<int iWidth, X86_VEXT vext>
269
  static Distortion xGetSAD_NxN_SIMD( const DistParam& pcDtParam );
270
271
  template <X86_VEXT vext>
272
  static void xGetSADX5_8xN_SIMD    ( const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos );
273
  template <X86_VEXT vext>
274
  static void xGetSADX5_16xN_SIMD_X86   ( const DistParam& rcDtParam, Distortion* cost, bool isCalCentrePos );
275
276
  template<X86_VEXT vext, bool fastHad>
277
  static Distortion xGetHADs_SIMD   ( const DistParam& pcDtParam );
278
  template<X86_VEXT vext>
279
  static Distortion xGetHAD2SADs_SIMD( const DistParam &rcDtParam );
280
281
  template<X86_VEXT vext> 
282
  static Distortion xGetSADwMask_SIMD( const DistParam &pcDtParam );
283
#endif
284
285
  unsigned int   getBitsMultiplePredsIBC(int x, int y, bool useIMV);
286
287
  Distortion   getDistPart( const CPelBuf& org, const CPelBuf& cur, int bitDepth, const ComponentID compId, DFunc eDFunc );
288
289
  void initLumaLevelToWeightTable( int lumaBD );
290
};// END CLASS DEFINITION RdCost
291
292
} // namespace vvenc
293
294
//! \}
295