Newer
Older

Karsten Suehring
committed
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2010-2019, ITU/ISO/IEC

Karsten Suehring
committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file RdCost.h
\brief RD cost computation classes (header)
*/
#ifndef __RDCOST__
#define __RDCOST__
#include "CommonDef.h"
#include "Mv.h"
#include "Unit.h"
#include "Buffer.h"
#include "Slice.h"
#include "RdCostWeightPrediction.h"
#include <math.h>
//! \ingroup CommonLib
//! \{
class DistParam;
class EncCfg;
// ====================================================================================================================
// Type definition
// ====================================================================================================================
// for function pointer
typedef Distortion (*FpDistFunc) (const DistParam&);
// ====================================================================================================================
// Class definition
// ====================================================================================================================
/// distortion parameter class
class DistParam
{
public:
CPelBuf org;
CPelBuf cur;
#if WCG_EXT
CPelBuf orgLuma;
#endif
int step;
FpDistFunc distFunc;
int bitDepth;
bool useMR;
bool applyWeight; // whether weighted prediction is used or not
bool isBiPred;
const WPScalingParam *wpCur; // weighted prediction scaling parameters for current ref
ComponentID compID;
Distortion maximumDistortionForEarlyExit; /// During cost calculations, if distortion exceeds this value, cost calculations may early-terminate.
// (vertical) subsampling shift (for reducing complexity)
// - 0 = no subsampling, 1 = even rows, 2 = every 4th, etc.
int subShift;
int cShiftX;
int cShiftY;
DistParam() :
org(), cur(), step( 1 ), bitDepth( 0 ), useMR( false ), applyWeight( false ), isBiPred( false ), wpCur( nullptr ), compID( MAX_NUM_COMPONENT ), maximumDistortionForEarlyExit( std::numeric_limits<Distortion>::max() ), subShift( 0 )
, cShiftX(-1), cShiftY(-1)

Karsten Suehring
committed
};
/// RD cost computation class
class RdCost
{
private:
// for distortion
static FpDistFunc m_afpDistortFunc[DF_TOTAL_FUNCTIONS]; // [eDFunc]
CostMode m_costMode;
double m_distortionWeight[MAX_NUM_COMPONENT]; // only chroma values are used.
double m_dLambda;
#if WCG_EXT
double m_dLambda_unadjusted; // TODO: check is necessary
double m_DistScaleUnadjusted;
static std::vector<double> m_reshapeLumaLevelToWeightPLUT;
static std::vector<double> m_lumaLevelToWeightPLUT;
static uint32_t m_signalType;
static double m_chromaWeight;
static int m_lumaBD;
ChromaFormat m_cf;

Karsten Suehring
committed
#endif
double m_DistScale;
double m_dLambdaMotionSAD[2 /* 0=standard, 1=for transquant bypass when mixed-lossless cost evaluation enabled*/];
// for motion cost
Mv m_mvPredictor;

Karsten Suehring
committed
double m_motionLambda;
int m_iCostScale;

Karsten Suehring
committed
public:
RdCost();
virtual ~RdCost();
#if WCG_EXT
void setChromaFormat ( const ChromaFormat & _cf) { m_cf = _cf; }

Karsten Suehring
committed
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
double calcRdCost ( uint64_t fracBits, Distortion distortion, bool useUnadjustedLambda = true );
#else
double calcRdCost ( uint64_t fracBits, Distortion distortion );
#endif
void setDistortionWeight ( const ComponentID compID, const double distortionWeight ) { m_distortionWeight[compID] = distortionWeight; }
void setLambda ( double dLambda, const BitDepths &bitDepths );
#if WCG_EXT
double getLambda( bool unadj = false )
{ return unadj ? m_dLambda_unadjusted : m_dLambda; }
#else
double getLambda() { return m_dLambda; }
#endif
double getChromaWeight() { return ((m_distortionWeight[COMPONENT_Cb] + m_distortionWeight[COMPONENT_Cr]) / 2.0); }
void setCostMode(CostMode m) { m_costMode = m; }
// Distortion Functions
void init();
#ifdef TARGET_SIMD_X86
void initRdCostX86();
template <X86_VEXT vext>
void _initRdCostX86();
#endif
void setDistParam( DistParam &rcDP, const CPelBuf &org, const Pel* piRefY , int iRefStride, int bitDepth, ComponentID compID, int subShiftMode = 0, int step = 1, bool useHadamard = false );
void setDistParam( DistParam &rcDP, const CPelBuf &org, const CPelBuf &cur, int bitDepth, ComponentID compID, bool useHadamard = false );
void setDistParam( DistParam &rcDP, const Pel* pOrg, const Pel* piRefY, int iOrgStride, int iRefStride, int bitDepth, ComponentID compID, int width, int height, int subShiftMode = 0, int step = 1, bool useHadamard = false, bool bioApplied = false );

Karsten Suehring
committed
double getMotionLambda ( bool bIsTransquantBypass ) { return m_dLambdaMotionSAD[(bIsTransquantBypass && m_costMode==COST_MIXED_LOSSLESS_LOSSY_CODING)?1:0]; }
void selectMotionLambda ( bool bIsTransquantBypass ) { m_motionLambda = getMotionLambda( bIsTransquantBypass ); }
void setPredictor ( const Mv& rcMv )
{
m_mvPredictor = rcMv;
}
void setCostScale ( int iCostScale ) { m_iCostScale = iCostScale; }
Distortion getCost ( uint32_t b ) { return Distortion( m_motionLambda * b ); }
void getMotionCost(int add, bool isTransquantBypass) { m_dCost = m_dLambdaMotionSAD[(isTransquantBypass && m_costMode == COST_MIXED_LOSSLESS_LOSSY_CODING) ? 1 : 0] + add; }
void setPredictors(Mv* pcMv)
{
for (int i = 0; i<2; i++)
{
m_bvPredictors[i] = pcMv[i];
}
}
inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV)
{
return Distortion(m_dCost * getBitsMultiplePreds(x, y, useIMV));
}
unsigned int getBitsMultiplePreds(int x, int y, bool useIMV)
{
int rmvH[2];
int rmvV[2];
rmvH[0] = x - m_bvPredictors[0].getHor();
rmvH[1] = x - m_bvPredictors[1].getHor();
rmvV[0] = y - m_bvPredictors[0].getVer();
rmvV[1] = y - m_bvPredictors[1].getVer();
int absCand[2];
absCand[0] = abs(rmvH[0]) + abs(rmvV[0]);
absCand[1] = abs(rmvH[1]) + abs(rmvV[1]);
int rmvHQP[2];
int rmvVQP[2];
if (x % 4 == 0 && y % 4 == 0 && useIMV)
{
int imvShift = 2;
int offset = 1 << (imvShift - 1);

Karsten Suehring
committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
rmvHQP[0] = (x >> 2) - ((m_bvPredictors[0].getHor() + offset) >> 2);
rmvHQP[1] = (x >> 2) - ((m_bvPredictors[1].getHor() + offset) >> 2);
rmvVQP[0] = (y >> 2) - ((m_bvPredictors[0].getVer() + offset) >> 2);
rmvVQP[1] = (y >> 2) - ((m_bvPredictors[1].getVer() + offset) >> 2);
int absCandQP[2];
absCandQP[0] = abs(rmvHQP[0]) + abs(rmvVQP[0]);
absCandQP[1] = abs(rmvHQP[1]) + abs(rmvVQP[1]);
unsigned int candBits0QP, candBits1QP;
if (absCand[0] < absCand[1])
{
unsigned int candBits0 = getIComponentBits(rmvH[0]) + getIComponentBits(rmvV[0]);
if (absCandQP[0] < absCandQP[1])
{
candBits0QP = getIComponentBits(rmvHQP[0]) + getIComponentBits(rmvVQP[0]);
return candBits0QP <candBits0 ? candBits0QP : candBits0;
}
else
{
candBits1QP = getIComponentBits(rmvHQP[1]) + getIComponentBits(rmvVQP[1]);
return candBits1QP < candBits0 ? candBits1QP : candBits0;
}
}
else
{
unsigned int candBits1 = getIComponentBits(rmvH[1]) + getIComponentBits(rmvV[1]);
if (absCandQP[0] < absCandQP[1])
{
candBits0QP = getIComponentBits(rmvHQP[0]) + getIComponentBits(rmvVQP[0]);
return candBits0QP < candBits1 ? candBits0QP : candBits1;
}
else
{
candBits1QP = getIComponentBits(rmvHQP[1]) + getIComponentBits(rmvVQP[1]);
return candBits1QP < candBits1 ? candBits1QP : candBits1;
}
}
}
else
{
if (absCand[0] < absCand[1])
{
return getIComponentBits(rmvH[0]) + getIComponentBits(rmvV[0]);
}
else
{
return getIComponentBits(rmvH[1]) + getIComponentBits(rmvV[1]);
}
}
}
unsigned int getIComponentBits(int val)
{
if (!val) return 1;
unsigned int length = 1;
unsigned int temp = (val <= 0) ? (-val << 1) + 1 : (val << 1);
while (1 != temp)
{
temp >>= 1;
length += 2;
}
return length;
}

Karsten Suehring
committed
#if ENABLE_SPLIT_PARALLELISM
void copyState( const RdCost& other );
#endif
// for motion cost
static uint32_t xGetExpGolombNumberOfBits( int iVal )
{
CHECKD( iVal == std::numeric_limits<int>::min(), "Wrong value" );
unsigned uiLength2 = 1, uiTemp2 = ( iVal <= 0 ) ? ( unsigned( -iVal ) << 1 ) + 1 : unsigned( iVal << 1 );
while( uiTemp2 > MAX_CU_SIZE )
{
uiLength2 += ( MAX_CU_DEPTH << 1 );
uiTemp2 >>= MAX_CU_DEPTH;
}
return uiLength2 + ( floorLog2(uiTemp2) << 1 );

Karsten Suehring
committed
}
Distortion getCostOfVectorWithPredictor( const int x, const int y, const unsigned imvShift ) { return Distortion( m_motionLambda * getBitsOfVectorWithPredictor(x, y, imvShift )); }
uint32_t getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift ) { return xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor())>>imvShift) + xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer())>>imvShift); }
#if WCG_EXT
void saveUnadjustedLambda ();
void initLumaLevelToWeightTable ();
inline double getWPSNRLumaLevelWeight (int val) { return m_lumaLevelToWeightPLUT[val]; }
void initLumaLevelToWeightTableReshape();
void updateReshapeLumaLevelToWeightTableChromaMD (std::vector<Pel>& ILUT);
void restoreReshapeLumaLevelToWeightTable ();
inline double getWPSNRReshapeLumaLevelWeight (int val) { return m_reshapeLumaLevelToWeightPLUT[val]; }
void setReshapeInfo (uint32_t type, int lumaBD) { m_signalType = type; m_lumaBD = lumaBD; }
void updateReshapeLumaLevelToWeightTable (SliceReshapeInfo &sliceReshape, Pel *wtTable, double cwt);
inline std::vector<double>& getLumaLevelWeightTable () { return m_lumaLevelToWeightPLUT; }

Karsten Suehring
committed
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
private:
static Distortion xGetSSE ( const DistParam& pcDtParam );
static Distortion xGetSSE4 ( const DistParam& pcDtParam );
static Distortion xGetSSE8 ( const DistParam& pcDtParam );
static Distortion xGetSSE16 ( const DistParam& pcDtParam );
static Distortion xGetSSE32 ( const DistParam& pcDtParam );
static Distortion xGetSSE64 ( const DistParam& pcDtParam );
static Distortion xGetSSE16N ( const DistParam& pcDtParam );
#if WCG_EXT
static Distortion getWeightedMSE (int compIdx, const Pel org, const Pel cur, const uint32_t uiShift, const Pel orgLuma);
static Distortion xGetSSE_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE2_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE4_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE8_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE16_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE32_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE64_WTD ( const DistParam& pcDtParam );
static Distortion xGetSSE16N_WTD ( const DistParam& pcDtParam );
#endif
static Distortion xGetSAD ( const DistParam& pcDtParam );
static Distortion xGetSAD4 ( const DistParam& pcDtParam );
static Distortion xGetSAD8 ( const DistParam& pcDtParam );
static Distortion xGetSAD16 ( const DistParam& pcDtParam );
static Distortion xGetSAD32 ( const DistParam& pcDtParam );
static Distortion xGetSAD64 ( const DistParam& pcDtParam );
static Distortion xGetSAD16N ( const DistParam& pcDtParam );
static Distortion xGetSAD12 ( const DistParam& pcDtParam );
static Distortion xGetSAD24 ( const DistParam& pcDtParam );
static Distortion xGetSAD48 ( const DistParam& pcDtParam );
static Distortion xGetSAD_full ( const DistParam& pcDtParam );
static Distortion xGetMRSAD ( const DistParam& pcDtParam );
static Distortion xGetMRSAD4 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD8 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD16 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD32 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD64 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD16N ( const DistParam& pcDtParam );
static Distortion xGetMRSAD12 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD24 ( const DistParam& pcDtParam );
static Distortion xGetMRSAD48 ( const DistParam& pcDtParam );
static Distortion xGetMRHADs ( const DistParam& pcDtParam );
static Distortion xGetHADs ( const DistParam& pcDtParam );
static Distortion xCalcHADs2x2 ( const Pel *piOrg, const Pel *piCurr, int iStrideOrg, int iStrideCur, int iStep );
static Distortion xCalcHADs4x4 ( const Pel *piOrg, const Pel *piCurr, int iStrideOrg, int iStrideCur, int iStep );
static Distortion xCalcHADs8x8 ( const Pel *piOrg, const Pel *piCurr, int iStrideOrg, int iStrideCur, int iStep );
static Distortion xCalcHADs16x8 ( const Pel *piOrg, const Pel *piCur, int iStrideOrg, int iStrideCur );
static Distortion xCalcHADs8x16 ( const Pel *piOrg, const Pel *piCur, int iStrideOrg, int iStrideCur );
static Distortion xCalcHADs4x8 ( const Pel *piOrg, const Pel *piCur, int iStrideOrg, int iStrideCur );
static Distortion xCalcHADs8x4 ( const Pel *piOrg, const Pel *piCur, int iStrideOrg, int iStrideCur );
#ifdef TARGET_SIMD_X86
Adam Wieckowski
committed
template<X86_VEXT vext>

Karsten Suehring
committed
static Distortion xGetSSE_SIMD ( const DistParam& pcDtParam );
Adam Wieckowski
committed
template<int iWidth, X86_VEXT vext>

Karsten Suehring
committed
static Distortion xGetSSE_NxN_SIMD( const DistParam& pcDtParam );
Adam Wieckowski
committed
template<X86_VEXT vext>

Karsten Suehring
committed
static Distortion xGetSAD_SIMD ( const DistParam& pcDtParam );
Adam Wieckowski
committed
template<int iWidth, X86_VEXT vext>

Karsten Suehring
committed
static Distortion xGetSAD_NxN_SIMD( const DistParam& pcDtParam );
Adam Wieckowski
committed
template<X86_VEXT vext>
static Distortion xGetSAD_IBD_SIMD( const DistParam& pcDtParam );

Karsten Suehring
committed
Adam Wieckowski
committed
template<X86_VEXT vext>

Karsten Suehring
committed
static Distortion xGetHADs_SIMD ( const DistParam& pcDtParam );
#endif
public:
#if WCG_EXT
Distortion getDistPart( const CPelBuf &org, const CPelBuf &cur, int bitDepth, const ComponentID compID, DFunc eDFunc, const CPelBuf *orgLuma = NULL );
#else
Distortion getDistPart( const CPelBuf &org, const CPelBuf &cur, int bitDepth, const ComponentID compID, DFunc eDFunc );
#endif
};// END CLASS DEFINITION RdCost
//! \}
#endif // __RDCOST__