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.
*

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
* 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 InterSearch.h
\brief inter search class (header)
*/
#ifndef __INTERSEARCH__
#define __INTERSEARCH__
// Include files
#include "CABACWriter.h"
#include "EncCfg.h"
#include "CommonLib/MotionInfo.h"
#include "CommonLib/InterPrediction.h"
#include "CommonLib/TrQuant.h"
#include "CommonLib/Unit.h"
#include "CommonLib/UnitPartitioner.h"
#include "CommonLib/RdCost.h"
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
#include "CommonLib/AffineGradientSearch.h"

Karsten Suehring
committed
//! \ingroup EncoderLib
//! \{
// ====================================================================================================================
// Class definition
// ====================================================================================================================
static const uint32_t MAX_NUM_REF_LIST_ADAPT_SR = 2;
static const uint32_t MAX_IDX_ADAPT_SR = 33;
static const uint32_t NUM_MV_PREDICTORS = 3;
struct BlkRecord
{
std::unordered_map<Mv, Distortion> bvRecord;
};

Karsten Suehring
committed
class EncModeCtrl;
struct AffineMVInfo
{
Mv affMVs[2][33][3];
int x, y, w, h;
};
struct BlkUniMvInfo
{
Mv uniMvs[2][33];
int x, y, w, h;
};
typedef struct
{
Mv acMvAffine4Para[2][3];
Mv acMvAffine6Para[2][3];
int16_t affine4ParaRefIdx[2];
int16_t affine6ParaRefIdx[2];
Distortion hevcCost[3];
Distortion affineCost[3];
bool affine4ParaAvail;
bool affine6ParaAvail;
} EncAffineMotion;
#if MERGE_ENC_OPT
struct ModeInfo
{
uint32_t mergeCand;
bool isRegularMerge;
bool isMMVD;
bool isCIIP;
#if CIIP_PDPC
bool isCiipPDPC;
#if JVET_AG0135_AFFINE_CIIP
bool isCiipAffine;
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
int intraMode;
#endif
bool isAffine;
#if AFFINE_MMVD
bool isAffineMmvd;
#endif
#if TM_MRG
bool isTMMrg;
#if JVET_AG0276_LIC_FLAG_SIGNALING
bool isTMMrgOppositeLic;
bool isOppositeLic;
bool isAffOppositeLic;
#endif
#if JVET_X0049_ADAPT_DMVR
bool isBMMrg;
uint8_t bmDir;
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
bool isAffBMMrg;
uint8_t affBMDir;
#endif
#if JVET_AA0070_RRIBC
int rribcFlipType;
#endif
bool isGeo;
uint8_t geoSplitDir;
uint8_t geoMergeIdx0;
uint8_t geoMergeIdx1;
#if ENABLE_OBMC
bool isOBMC;
#endif
ModeInfo() : mergeCand(0), isRegularMerge(false), isMMVD(false)
, isCIIP(false)
#if CIIP_PDPC
, isCiipPDPC(false)
#if JVET_AG0135_AFFINE_CIIP
, isCiipAffine(false)
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
, intraMode(0)
#endif
, isAffine(false)
#if AFFINE_MMVD
, isAffineMmvd(false)
#endif
#if TM_MRG
, isTMMrg(false)
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
, isTMMrgOppositeLic(false)
, isOppositeLic(false)
, isAffOppositeLic(false)
#endif
#if JVET_X0049_ADAPT_DMVR
, isBMMrg(false)
, bmDir(0)
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
, isAffBMMrg(false)
, affBMDir(0)
#endif
#if JVET_AA0070_RRIBC
, rribcFlipType(0)
#endif
, isGeo(false), geoSplitDir(0), geoMergeIdx0(0), geoMergeIdx1(0)
#if ENABLE_OBMC
, isOBMC(false)
#endif
{}
ModeInfo(const uint32_t mergeCand, const bool isRegularMerge, const bool isMMVD, const bool isCIIP
#if CIIP_PDPC
, const bool isCiipPDPC
#if JVET_AG0135_AFFINE_CIIP
, const bool isCiipAffine
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
, const int intraMode
#endif
, const bool isAffine
#if ENABLE_OBMC
, const bool isOBMC = false
#endif
#if AFFINE_MMVD
, const bool isAffineMmvd = false
#endif
#if TM_MRG
, const bool isTMMrg = false
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
, const bool isTMMrgOppositeLic = false
, const bool isOppositeLic = false
, const bool isAffOppositeLic = false
#endif
) :
mergeCand(mergeCand), isRegularMerge(isRegularMerge), isMMVD(isMMVD), isCIIP(isCIIP)
#if CIIP_PDPC
, isCiipPDPC(isCiipPDPC)
#if JVET_AG0135_AFFINE_CIIP
, isCiipAffine(isCiipAffine)
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
, intraMode(intraMode)
#endif
, isAffine(isAffine)
#if AFFINE_MMVD
, isAffineMmvd(isAffineMmvd)
#endif
#if TM_MRG
, isTMMrg(isTMMrg)
#endif
#if JVET_AG0276_LIC_FLAG_SIGNALING
, isTMMrgOppositeLic(isTMMrgOppositeLic)
, isOppositeLic(isOppositeLic)
, isAffOppositeLic(isAffOppositeLic)
#endif
#if JVET_X0049_ADAPT_DMVR
, isBMMrg( false )
, bmDir( 0 )
#endif
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
, isAffBMMrg(false)
, affBMDir(0)
#endif
, isGeo(false), geoSplitDir(0), geoMergeIdx0(0), geoMergeIdx1(0)
#if ENABLE_OBMC
, isOBMC(false)
#endif
{}
ModeInfo(const CodingUnit cu, const PredictionUnit pu)
{
#if AFFINE_MMVD
Mehdi Salehifar
committed
#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
mergeCand = pu.afMmvdFlag ? pu.afMmvdMergeIdx : pu.mergeIdx;
Chun-Chi Chen
committed
#if JVET_AA0132_CONFIGURABLE_TM_TOOLS
mergeCand = !pu.cs->sps->getUseTMMMVD() && pu.afMmvdFlag ? pu.afMmvdBaseIdx * ECM3_AF_MMVD_MAX_REFINE_NUM + pu.afMmvdStep * ECM3_AF_MMVD_OFFSET_DIR + pu.afMmvdDir : mergeCand;
#endif
Mehdi Salehifar
committed
#else
mergeCand = pu.afMmvdFlag ? pu.afMmvdBaseIdx * AF_MMVD_MAX_REFINE_NUM + pu.afMmvdStep * AF_MMVD_OFFSET_DIR + pu.afMmvdDir : pu.mergeIdx;
Mehdi Salehifar
committed
#endif
#else
mergeCand = pu.mergeIdx;
#endif
isRegularMerge = pu.regularMergeFlag;
isMMVD = pu.mmvdMergeFlag || cu.mmvdSkip;
isCIIP = pu.ciipFlag;
#if CIIP_PDPC
isCiipPDPC = pu.ciipPDPC;
#if JVET_AG0135_AFFINE_CIIP
isCiipAffine = pu.ciipAffine;
#endif
#if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION
intraMode = pu.intraDir[0];
#endif
isAffine = cu.affine;
#if AFFINE_MMVD
isAffineMmvd = pu.afMmvdFlag;
#endif
#if TM_MRG
isTMMrg = pu.tmMergeFlag;
#if JVET_AG0276_LIC_FLAG_SIGNALING
isTMMrgOppositeLic = pu.tmMergeFlagOppositeLic;
isOppositeLic = pu.mergeOppositeLic;
isAffOppositeLic = pu.affineOppositeLic;
#endif
#if JVET_X0049_ADAPT_DMVR
isBMMrg = pu.bmMergeFlag;
bmDir = pu.bmDir;
#if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
isAffBMMrg = pu.affBMMergeFlag;
affBMDir = pu.affBMDir;
#endif
#if JVET_AA0070_RRIBC
rribcFlipType = cu.rribcFlipType;
#endif
isGeo = cu.geoFlag;
geoSplitDir = pu.geoSplitDir;
geoMergeIdx0 = pu.geoMergeIdx0;
geoMergeIdx1 = pu.geoMergeIdx1;
#if ENABLE_OBMC
isOBMC = cu.obmcFlag;
#endif
#if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING
CHECK(cu.geoBlendFlag && (pu.geoMergeIdx0 != pu.mergeIdx || pu.geoMergeIdx0 != mergeCand),"ModeInfo() failed.");
#if JVET_AC0112_IBC_CIIP
struct ModeIbcInfo
{
#if JVET_AC0112_IBC_GPM
uint32_t mergeCand;
bool isCIIP;
int dirIdx;
bool isIbcGpm;
int mergeIdx0;
int mergeIdx1;
int splitDir;
int bldIdx;
int combIdx;
#if JVET_AE0169_BIPREDICTIVE_IBC
ModeIbcInfo() : mergeCand(0), isCIIP(false), dirIdx(0), isIbcGpm(false), mergeIdx0(MAX_UCHAR), mergeIdx1(MAX_UCHAR), splitDir(0), bldIdx(0), combIdx(0)
#else
ModeIbcInfo() : mergeCand(0), isCIIP(false), dirIdx(0), isIbcGpm(false), mergeIdx0(0), mergeIdx1(0), splitDir(0), bldIdx(0), combIdx(0)
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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
{}
ModeIbcInfo(const uint32_t mergeCand, const bool isCIIP, const int dirIdx, const bool isIbcGpm, const int mergeIdx0, const int mergeIdx1, const int splitDir, const int bldIdx, const int combIdx
) :
mergeCand(mergeCand), isCIIP(isCIIP), dirIdx(dirIdx), isIbcGpm(isIbcGpm), mergeIdx0(mergeIdx0), mergeIdx1(mergeIdx1), splitDir(splitDir), bldIdx(bldIdx), combIdx(combIdx)
{}
ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu)
{
mergeCand = pu.mergeIdx;
isCIIP = pu.ibcCiipFlag;
dirIdx = pu.ibcCiipIntraIdx;
isIbcGpm = pu.ibcGpmFlag;
mergeIdx0 = pu.ibcGpmMergeIdx0;
mergeIdx1 = pu.ibcGpmMergeIdx1;
splitDir = pu.ibcGpmSplitDir;
bldIdx = pu.ibcGpmBldIdx;
}
#else
uint32_t mergeCand;
bool isCIIP;
int dirIdx;
ModeIbcInfo() : mergeCand(0), isCIIP(false), dirIdx(0)
{}
ModeIbcInfo(const uint32_t mergeCand, const bool isCIIP, const int dirIdx
) :
mergeCand(mergeCand), isCIIP(isCIIP), dirIdx(dirIdx)
{}
ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu)
{
mergeCand = pu.mergeIdx;
isCIIP = pu.ibcCiipFlag;
dirIdx = pu.ibcCiipIntraIdx;
}
#endif
};
#endif
#if JVET_AC0112_IBC_GPM && !JVET_AC0112_IBC_CIIP
struct ModeIbcInfo
{
uint32_t mergeCand;
bool isIbcGpm;
int mergeIdx0;
int mergeIdx1;
int splitDir;
int bldIdx;
int combIdx;
ModeIbcInfo() : mergeCand(0), isIbcGpm(false), mergeIdx0(0), mergeIdx1(0), splitDir(0), bldIdx(0), combIdx(0)
{}
ModeIbcInfo(const uint32_t mergeCand, const bool isIbcGpm, const int mergeIdx0, const int mergeIdx1, const int splitDir, const int bldIdx, const int combIdx
) :
mergeCand(mergeCand), isIbcGpm(isIbcGpm), mergeIdx0(mergeIdx0), mergeIdx1(mergeIdx1), splitDir(splitDir), bldIdx(bldIdx), combIdx(combIdx)
{}
ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu)
{
mergeCand = pu.mergeIdx;
isIbcGpm = pu.ibcGpmFlag;
mergeIdx0 = pu.ibcGpmMergeIdx0;
mergeIdx1 = pu.ibcGpmMergeIdx1;
splitDir = pu.ibcGpmSplitDir;
bldIdx = pu.ibcGpmBldIdx;
}
};
#endif
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
#if INTER_LIC
class EncFastLICCtrl
{
double m_amvpRdBeforeLIC[NUM_IMV_MODES];
public:
EncFastLICCtrl() { init(); }
void init()
{
m_amvpRdBeforeLIC[IMV_OFF ] = std::numeric_limits<double>::max();
m_amvpRdBeforeLIC[IMV_FPEL] = std::numeric_limits<double>::max();
m_amvpRdBeforeLIC[IMV_4PEL] = std::numeric_limits<double>::max();
m_amvpRdBeforeLIC[IMV_HPEL] = std::numeric_limits<double>::max();
}
bool skipRDCheckForLIC( bool isLIC
, int imv, double curBestRd
, uint32_t cuNumPel
)
{
bool skipLIC = false;
if (isLIC)
{
skipLIC |= skipLicBasedOnBestAmvpRDBeforeLIC(imv, curBestRd);
skipLIC |= (cuNumPel < LIC_MIN_CU_PIXELS);
}
return skipLIC;
}
public:
void setBestAmvpRDBeforeLIC(const CodingUnit& cu, double curCuRdCost)
{
m_amvpRdBeforeLIC[cu.imv] = !cu.firstPU->mergeFlag && cu.predMode != MODE_IBC && !cu.licFlag ? std::min(curCuRdCost, m_amvpRdBeforeLIC[cu.imv]) : m_amvpRdBeforeLIC[cu.imv];
}
private:
bool skipLicBasedOnBestAmvpRDBeforeLIC(uint8_t curCuimvIdx, double curBestRdCost)
{
return m_amvpRdBeforeLIC[curCuimvIdx] != std::numeric_limits<double>::max()
&& m_amvpRdBeforeLIC[curCuimvIdx] > curBestRdCost * LIC_AMVP_SKIP_TH;
}
};
#endif
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
template <int N>
struct SrchCostBv
{
static const int maxSize = N;
static const int capacity = (N) + 1;
uint32_t cnt;
bool enableFracIBC; // Just to make sure cfg-off results and macro-off results will match
bool enableMultiCandSrch; // True: search best fracBv among best N integer BVs; False: search best fracBv among best integer BVs and best fracBv of previous round
Distortion costList [capacity];
Mv mvList [capacity];
#if JVET_AE0169_BIPREDICTIVE_IBC
int mergeIdxList[capacity];
#endif
uint8_t imvList [capacity];
uint8_t mvpIdxList[capacity];
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
int bvTypeList[capacity];
#endif
#if JVET_AA0070_RRIBC && JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
bool bvFlipList[capacity];
#endif
#if JVET_AE0159_FIBC
bool bvFilter[capacity];
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
bool skipLicSrch[capacity];
int bvLicIdx[capacity];
#endif
SrchCostBv()
: cnt (0)
, enableFracIBC (false)
, enableMultiCandSrch (false)
{
mvList[maxSize].setZero();
}
void init(bool resetHistoryMv = false, bool _enableFracIBC = false)
{
cnt = 0;
enableFracIBC = _enableFracIBC;
enableMultiCandSrch = _enableFracIBC;
if (resetHistoryMv)
{
mvList[maxSize].setZero();
#if JVET_AE0159_FIBC
bvFilter[maxSize] = false;
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
bvLicIdx[maxSize] = 0;
skipLicSrch[maxSize] = false;
}
}
void cutoff(double ratio)
{
if (N >= 2)
{
if (cnt >= 2)
{
double th = ratio * (double)costList[0];
for (int i = 1; i < cnt; ++i)
{
if ((double)costList[i] > th)
{
cnt = i;
return;
}
}
}
}
}
int find(int mvx, int mvy
#if JVET_AE0169_BIPREDICTIVE_IBC
, int mergeIdx
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
, int bvType
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
, bool bvFlip
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
, int bvLic
#endif
)
{
for (int i = 0; i < (int)cnt; ++i)
{
if (mvList[i].getHor() == mvx && mvList[i].getVer() == mvy
#if JVET_AE0169_BIPREDICTIVE_IBC
&& mergeIdxList[i] == mergeIdx
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
&& bvTypeList[i] == bvType
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
&& bvFlipList[i] == bvFlip
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
&& bvLicIdx[i] == bvLic
#endif
)
{
return i;
}
}
return NOT_VALID;
}
void replaceAt(uint32_t idxSrc, uint32_t idxDst)
{
if (idxSrc != idxDst)
{
costList [idxDst] = costList [idxSrc];
mvList [idxDst] = mvList [idxSrc];
#if JVET_AE0169_BIPREDICTIVE_IBC
mergeIdxList[idxDst] = mergeIdxList[idxSrc];
#endif
imvList [idxDst] = imvList [idxSrc];
mvpIdxList[idxDst] = mvpIdxList[idxSrc];
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
bvTypeList[idxDst] = bvTypeList[idxSrc];
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
bvFlipList[idxDst] = bvFlipList[idxSrc];
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
bvLicIdx[idxDst] = bvLicIdx[idxSrc];
skipLicSrch[idxDst] = skipLicSrch[idxSrc];
#endif
#if JVET_AE0159_FIBC
bvFilter[idxDst] = bvFilter[idxSrc];
#endif
}
}
int insert(Distortion cost, int mvx, int mvy
#if JVET_AE0169_BIPREDICTIVE_IBC
, int mergeIdx
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
, int bvType = 0
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
, bool bvFlip = true
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
, int bvLic = 0
#endif
)
{
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
// Ignore 1-D BV's
if (bvType != 0)
{
return NOT_VALID;
}
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
bvFlip = bvType == 0 ? false : bvFlip;
#endif
// Find insertion index
int insertIdx = NOT_VALID;
for (int i = 0; i < (int)cnt; ++i)
{
if (cost <= costList[i])
{
if (cost == costList[i])
{
if (mvList[i].getHor() == mvx && mvList[i].getVer() == mvy
#if JVET_AE0169_BIPREDICTIVE_IBC
&& mergeIdxList[i] == mergeIdx
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
&& bvTypeList[i] == bvType
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
&& bvFlipList[i] == bvFlip
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
&& bvLicIdx[i] == bvLic
#endif
)
{
return NOT_VALID;
}
}
else
{
insertIdx = i;
break;
}
}
}
// Do insertion
auto setAt = [&](uint32_t idx)
{
costList[idx] = cost;
mvList[idx].set(mvx, mvy);
#if JVET_AE0169_BIPREDICTIVE_IBC
mergeIdxList[idx] = mergeIdx;
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
bvTypeList[idx] = bvType;
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
bvFlipList[idx] = bvFlip;
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
bvLicIdx[idx] = bvLic;
#endif
#if JVET_AE0159_FIBC
bvFilter[idx] = false;
#endif
};
auto replaceNext = [&](uint32_t idx)
{
costList[idx + 1] = costList[idx];
mvList[idx + 1].set(mvList[idx].getHor(), mvList[idx].getVer());
#if JVET_AE0169_BIPREDICTIVE_IBC
mergeIdxList[idx + 1] = mergeIdxList[idx];
#endif
#if JVET_AA0070_RRIBC || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
bvTypeList[idx + 1] = bvTypeList[idx];
#endif
#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV && JVET_AA0070_RRIBC
bvFlipList[idx + 1] = bvFlipList[idx];
#endif
#if JVET_AE0078_IBC_LIC_EXTENSION
bvLicIdx[idx + 1] = bvLicIdx[idx];
#endif
#if JVET_AE0159_FIBC
bvFilter[idx + 1] = bvFilter[idx];
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
#endif
};
if (insertIdx != NOT_VALID)
{
for (int i = (cnt < N ? cnt - 1 : N - 2); i >= insertIdx; --i)
{
replaceNext(i);
}
setAt(insertIdx);
if (cnt < N)
{
++cnt;
}
return insertIdx;
}
else if (cnt < N)
{
insertIdx = cnt;
setAt(insertIdx);
++cnt;
return insertIdx;
}
else
{
return NOT_VALID;
}
}
};
typedef SrchCostBv<4> SrchCostIntBv;
#endif

Karsten Suehring
committed
/// encoder search class

Karsten Suehring
committed
class InterSearch : public InterPrediction, AffineGradientSearch

Karsten Suehring
committed
{
private:
EncModeCtrl *m_modeCtrl;
PelStorage m_tmpPredStorage [NUM_REF_PIC_LIST_01];
PelStorage m_tmpStorageLCU;
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
PelStorage m_tmpStorageCUflipH;
PelStorage m_tmpStorageCUflipV;
public:
SrchCostIntBv m_bestSrchCostIntBv;
#if JVET_AE0159_FIBC || JVET_AE0078_IBC_LIC_EXTENSION
SrchCostIntBv m_bestSrchCostIbcFilter;
#endif
private:
#endif

Karsten Suehring
committed
PelStorage m_tmpAffiStorage;
Pel* m_tmpAffiError;

Karsten Suehring
committed
int* m_tmpAffiDeri[2];
#if JVET_AC0112_IBC_CIIP
PelStorage m_ibcCiipBuffer;
#endif
#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC
#if JVET_AA0070_RRIBC
AMVPInfo m_amvpInfo[3];
AMVPInfo m_amvpInfo4Pel[3];
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
AMVPInfo m_amvpInfoHPel[3];
AMVPInfo m_amvpInfoQPel[3];
#endif
#else
AMVPInfo m_amvpInfo;
AMVPInfo m_amvpInfo4Pel;
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
AMVPInfo m_amvpInfoHPel;
AMVPInfo m_amvpInfoQPel;
#endif
#if JVET_AE0169_BIPREDICTIVE_IBC
Pel** m_amvpMergeBuffer;
MergeCtx m_amvpMergeCtx;
#endif

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
int m_mhpMrgTempBufSet;
PelUnitBuf m_mhpMrgTempBuf[GEO_MAX_NUM_UNI_CANDS];
PelUnitBuf m_mhpMrgTempBufLic[GEO_MAX_NUM_UNI_CANDS];
#else
bool m_mhpMrgTempBufSet;
PelUnitBuf m_mhpMrgTempBuf[GEO_MAX_NUM_UNI_CANDS];

Xiaoyu Xiu
committed
#endif
PelUnitBuf m_mhpTempBuf[GEO_MAX_TRY_WEIGHTED_SAD];
int m_mhpTempBufCounter;
#endif

Karsten Suehring
committed
CodingStructure ****m_pSplitCS;
CodingStructure ****m_pFullCS;
CodingStructure **m_pSaveCS;
ClpRng m_lumaClpRng;
uint32_t m_estWeightIdxBits[BCW_NUM];
BcwMotionParam m_uniMotions;

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
bool m_doAffineLic;
#if TM_AMVP
bool updateMvNeeded;
bool updateL1ZeroFlagMvNeeded;
bool updateSMVDMvNeeded;
bool isBDOFNotNeeded;
AMVPInfo *amvpCand0;
AMVPInfo *amvpCand1;
AMVPInfo *amvpCand0Lic;
AMVPInfo *amvpCand1Lic;
int mvpIdx0;
int mvpIdx1;
#endif
#endif
std::unordered_map< Position, std::unordered_map< Size, BlkRecord> > m_ctuRecord;
#if JVET_AA0070_RRIBC
Distortion minCostProj;
#endif
AffineMVInfo *m_affMVList;
int m_affMVListIdx;
int m_affMVListSize;
int m_affMVListMaxSize;
BlkUniMvInfo* m_uniMvList;
int m_uniMvListIdx;
int m_uniMvListSize;
int m_uniMvListMaxSize;
#if INTER_LIC
BlkUniMvInfo* m_uniMvListLIC;
int m_uniMvListIdxLIC;
int m_uniMvListSizeLIC;
#endif
#if JVET_AG0098_AMVP_WITH_SBTMVP
bool* m_amvpSbTmvpBufValid;
MotionInfo* m_amvpSbTmvpMotionBuf;
Position m_amvpSbTmvpBufTLPos;
EncAffineMotion m_affineMotion;
Pekka Astola
committed
#if JVET_AE0059_INTER_CCCM
Pel **m_interCccmStorage;
#endif
#if JVET_AF0073_INTER_CCP_MERGE
Pel **m_interCcpMergeStorage;
#endif
#if JVET_AE0169_BIPREDICTIVE_IBC
Distortion m_bestBvpSADHADCost;
#endif

Karsten Suehring
committed
protected:
// interface to option
EncCfg* m_pcEncCfg;
// interface to classes
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
TrQuant* m_pcTrQuant;
protected:
#else
EncReshape* m_pcReshape;
#endif

Karsten Suehring
committed
// ME parameters
int m_iSearchRange;
int m_bipredSearchRange; // Search range for bi-prediction
MESearchMethod m_motionEstimationSearchMethod;
int m_aaiAdaptSR [MAX_NUM_REF_LIST_ADAPT_SR][MAX_IDX_ADAPT_SR];
// RD computation
CABACWriter* m_CABACEstimator;

Karsten Suehring
committed
DistParam m_cDistParam;
#if JVET_AA0133_INTER_MTS_OPT
double m_globalBestLumaCost;
double m_bestDCT2PassLumaCost;
#endif
RefPicList m_currRefPicList;
int m_currRefPicIndex;
int m_numHashMVStoreds[NUM_REF_PIC_LIST_01][MAX_NUM_REF];
Mv m_hashMVStoreds[NUM_REF_PIC_LIST_01][MAX_NUM_REF][5];

Karsten Suehring
committed
// Misc.
Pel *m_pTempPel;
// AMVP cost computation
#if JVET_Y0129_MVD_SIGNAL_AMVP_MERGE_MODE
uint32_t m_auiMVPIdxCost [AMVP_MAX_NUM_CANDS+1][AMVP_MAX_NUM_CANDS+1+1]; //th array bounds
#else

Karsten Suehring
committed
uint32_t m_auiMVPIdxCost [AMVP_MAX_NUM_CANDS+1][AMVP_MAX_NUM_CANDS+1]; //th array bounds
#endif

Karsten Suehring
committed
Mv m_integerMv2Nx2N [NUM_REF_PIC_LIST_01][MAX_NUM_REF];
bool m_isInitialized;
Mv m_acBVs[2 * IBC_NUM_CANDIDATES];
unsigned int m_numBVs;
bool m_useCompositeRef;
Distortion m_estMinDistSbt[NUMBER_SBT_MODE + 1]; // estimated minimum SSE value of the PU if using a SBT mode
uint8_t m_sbtRdoOrder[NUMBER_SBT_MODE]; // order of SBT mode in RDO
bool m_skipSbtAll; // to skip all SBT modes for the current PU
uint8_t m_histBestSbt; // historical best SBT mode for PU of certain SSE values
uint8_t m_histBestMtsIdx; // historical best MTS idx for PU of certain SSE values
#if JVET_AF0073_INTER_CCP_MERGE
bool m_isInterCcpModelReady;
int m_validNum;
CCPModelCandidate m_interCcpMergeList[MAX_CCP_CAND_LIST_SIZE];
#endif
#if JVET_X0083_BM_AMVP_MERGE_MODE
public:
Distortion m_amvpOnlyCost;
#endif

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
void initMHPTmpBuffer(PelStorage* mergeTmpBuffer, PelStorage* mergeTmpBuffer2, int maxNumMergeCandidates,
#else
void initMHPTmpBuffer(PelStorage* mergeTmpBuffer, int maxNumMergeCandidates,

Xiaoyu Xiu
committed
#endif
PelStorage* mhpTmpBuffer, int maxNumStoredMhpCandidates,
const UnitArea localUnitArea)
{

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
m_mhpMrgTempBufSet = 0;
#else

Xiaoyu Xiu
committed
#endif
for (uint8_t mergeCand = 0; mergeCand < maxNumMergeCandidates; mergeCand++)
{
m_mhpMrgTempBuf[mergeCand] = mergeTmpBuffer[mergeCand].getBuf(localUnitArea);

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
m_mhpMrgTempBufLic[mergeCand] = mergeTmpBuffer2[mergeCand].getBuf(localUnitArea);
#endif
}
for (uint8_t i = 0; i < maxNumStoredMhpCandidates; i++)
{
m_mhpTempBuf[i] = mhpTmpBuffer[i].getBuf(localUnitArea);
}
m_mhpTempBufCounter = 0;
}

Xiaoyu Xiu
committed
#if JVET_AD0213_LIC_IMP
void setGeoTmpBuffer(int setId)
{
m_mhpMrgTempBufSet = setId;
}
void setGeoTmpBuffer(MergeCtx geoMrgCtx, int setId)
{
m_mhpMrgTempBufSet = setId;
m_geoMrgCtx = geoMrgCtx;
}
#else
void setGeoTmpBuffer()
{
m_mhpMrgTempBufSet = true;
}
void setGeoTmpBuffer(MergeCtx geoMrgCtx)
{
m_mhpMrgTempBufSet = true;
m_geoMrgCtx = geoMrgCtx;
}

Xiaoyu Xiu
committed
#endif
#if JVET_AI0183_MVP_EXTENSION
MotionInfo m_subPuMiBuf[SUB_BUFFER_SIZE][(MAX_CU_SIZE * MAX_CU_SIZE) >> (MIN_CU_LOG2 << 1)];
#endif

Karsten Suehring
committed
InterSearch();
virtual ~InterSearch();
void init ( EncCfg* pcEncCfg,
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
TrQuant* pcTrQuant,
int iSearchRange,
int bipredSearchRange,
MESearchMethod motionEstimationSearchMethod,

Karsten Suehring
committed
const uint32_t maxCUWidth,
const uint32_t maxCUHeight,
const uint32_t maxTotalCUDepth,
RdCost* pcRdCost,
CABACWriter* CABACEstimator,
CtxCache* ctxCache
#if JVET_Z0153_IBC_EXT_REF
, const uint32_t curPicWidthY
#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
, const uint32_t curPicHeightY
#endif

Karsten Suehring
committed
);
void destroy ();
void calcMinDistSbt ( CodingStructure &cs, const CodingUnit& cu, const uint8_t sbtAllowed );
uint8_t skipSbtByRDCost ( int width, int height, int mtDepth, uint8_t sbtIdx, uint8_t sbtPos, double bestCost, Distortion distSbtOff, double costSbtOff, bool rootCbfSbtOff );
bool getSkipSbtAll () { return m_skipSbtAll; }
void setSkipSbtAll ( bool skipAll ) { m_skipSbtAll = skipAll; }
uint8_t getSbtRdoOrder ( uint8_t idx ) { assert( m_sbtRdoOrder[idx] < NUMBER_SBT_MODE ); assert( (uint32_t)( m_estMinDistSbt[m_sbtRdoOrder[idx]] >> 2 ) < ( MAX_UINT >> 1 ) ); return m_sbtRdoOrder[idx]; }
Distortion getEstDistSbt ( uint8_t sbtMode) { return m_estMinDistSbt[sbtMode]; }
void initTuAnalyzer () { m_estMinDistSbt[NUMBER_SBT_MODE] = std::numeric_limits<uint64_t>::max(); m_skipSbtAll = false; }