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