/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 | | |