InterSearch.h 21.03 KiB
/* 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
* 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/CrossCompPrediction.h"
#include "CommonLib/TrQuant.h"
#include "CommonLib/Unit.h"
#include "CommonLib/UnitPartitioner.h"
#include "CommonLib/RdCost.h"
#include "CommonLib/AffineGradientSearch.h"
#include "CommonLib/IbcHashMap.h"
#include <unordered_map>
#include <vector>
//! \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;
};
class EncModeCtrl;
struct AffineMVInfo
{
Mv affMVs[2][33][3];
int x, y, w, h;
};
/// encoder search class
class InterSearch : public InterPrediction, CrossComponentPrediction, AffineGradientSearch
{
private:
EncModeCtrl *m_modeCtrl;
PelStorage m_tmpPredStorage [NUM_REF_PIC_LIST_01];
PelStorage m_tmpStorageLCU;
PelStorage m_tmpAffiStorage;
Pel* m_tmpAffiError;
int* m_tmpAffiDeri[2];
CodingStructure ****m_pSplitCS;
CodingStructure ****m_pFullCS;
CodingStructure **m_pSaveCS;
ClpRng m_lumaClpRng;
uint32_t m_estWeightIdxBits[GBI_NUM];
GBiMotionParam m_uniMotions;
bool m_affineModeSelected;
std::unordered_map< Position, std::unordered_map< Size, BlkRecord> > m_ctuRecord;
AffineMVInfo *m_affMVList;
int m_affMVListIdx;
int m_affMVListSize;
int m_affMVListMaxSize;
Distortion m_hevcCost;
protected:
// interface to option
EncCfg* m_pcEncCfg;
// interface to classes
TrQuant* m_pcTrQuant;
// 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;
CtxCache* m_CtxCache;
DistParam m_cDistParam;
// Misc.
Pel *m_pTempPel;
// AMVP cost computation
uint32_t m_auiMVPIdxCost [AMVP_MAX_NUM_CANDS+1][AMVP_MAX_NUM_CANDS+1]; //th array bounds
Mv m_integerMv2Nx2N [NUM_REF_PIC_LIST_01][MAX_NUM_REF];
bool m_isInitialized;
unsigned int m_numBVs, m_numBV16s;
Mv m_acBVs[IBC_NUM_CANDIDATES];
public:
InterSearch();
virtual ~InterSearch();
void init ( EncCfg* pcEncCfg,
TrQuant* pcTrQuant,
int iSearchRange,
int bipredSearchRange,
MESearchMethod motionEstimationSearchMethod,
const uint32_t maxCUWidth,
const uint32_t maxCUHeight,
const uint32_t maxTotalCUDepth,
RdCost* pcRdCost,
CABACWriter* CABACEstimator,
CtxCache* ctxCache
);
void destroy ();
void setTempBuffers (CodingStructure ****pSlitCS, CodingStructure ****pFullCS, CodingStructure **pSaveCS );
void resetCtuRecord () { m_ctuRecord.clear(); }
#if ENABLE_SPLIT_PARALLELISM
void copyState ( const InterSearch& other );
#endif
void setAffineModeSelected ( bool flag) { m_affineModeSelected = flag; }
void resetAffineMVList() { m_affMVListIdx = 0; m_affMVListSize = 0; }
void savePrevAffMVInfo(int idx, AffineMVInfo &tmpMVInfo, bool& isSaved)
{
if (m_affMVListSize > idx)
{
tmpMVInfo = m_affMVList[(m_affMVListIdx - 1 - idx + m_affMVListMaxSize) % m_affMVListMaxSize];
isSaved = true;
}
else
isSaved = false;
}
void addAffMVInfo(AffineMVInfo &tmpMVInfo)
{
int j = 0;
AffineMVInfo *prevInfo = nullptr;
for (; j < m_affMVListSize; j++)
{
prevInfo = m_affMVList + ((m_affMVListIdx - j - 1 + m_affMVListMaxSize) % (m_affMVListMaxSize));
if ((tmpMVInfo.x == prevInfo->x) && (tmpMVInfo.y == prevInfo->y) && (tmpMVInfo.w == prevInfo->w) && (tmpMVInfo.h == prevInfo->h))
{
break;
}
}
if (j < m_affMVListSize)
*prevInfo = tmpMVInfo;
else
{
m_affMVList[m_affMVListIdx] = tmpMVInfo;
m_affMVListIdx = (m_affMVListIdx + 1) % m_affMVListMaxSize;
m_affMVListSize = std::min(m_affMVListSize + 1, m_affMVListMaxSize);
}
}
protected:
/// sub-function for motion vector refinement used in fractional-pel accuracy
Distortion xPatternRefinement ( const CPelBuf* pcPatternKey, Mv baseRefMv, int iFrac, Mv& rcMvFrac, bool bAllowUseOfHadamard );
typedef struct
{
int left;
int right;
int top;
int bottom;
}SearchRange;
typedef struct
{
SearchRange searchRange;
const CPelBuf* pcPatternKey;
const Pel* piRefY;
int iRefStride;
int iBestX;
int iBestY;
uint32_t uiBestRound;
uint32_t uiBestDistance;
Distortion uiBestSad;
uint8_t ucPointNr;
int subShiftMode;
unsigned imvShift;
bool inCtuSearch;
bool zeroMV;
} IntTZSearchStruct;
// sub-functions for ME
inline void xTZSearchHelp ( IntTZSearchStruct& rcStruct, const int iSearchX, const int iSearchY, const uint8_t ucPointNr, const uint32_t uiDistance );
inline void xTZ2PointSearch ( IntTZSearchStruct& rcStruct );
inline void xTZ8PointSquareSearch ( IntTZSearchStruct& rcStruct, const int iStartX, const int iStartY, const int iDist );
inline void xTZ8PointDiamondSearch( IntTZSearchStruct& rcStruct, const int iStartX, const int iStartY, const int iDist, const bool bCheckCornersAtDist1 );
Distortion xGetInterPredictionError( PredictionUnit& pu, PelUnitBuf& origBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X );
public:
/// encoder estimation - inter prediction (non-skip)
void setModeCtrl( EncModeCtrl *modeCtrl ) { m_modeCtrl = modeCtrl;}
void predInterSearch(CodingUnit& cu, Partitioner& partitioner );
/// set ME search range
void setAdaptiveSearchRange ( int iDir, int iRefIdx, int iSearchRange) { CHECK(iDir >= MAX_NUM_REF_LIST_ADAPT_SR || iRefIdx>=int(MAX_IDX_ADAPT_SR), "Invalid index"); m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange; }
bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap);
void xIntraPatternSearch ( PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* cMvSrchRngLT, Mv* cMvSrchRngRB, Mv* pcMvPred);
void xSetIntraSearchRange ( PredictionUnit& pu, int iRoiWidth, int iRoiHeight, const int localSearchRangeX, const int localSearchRangeY, Mv& rcMvSrchRngLT, Mv& rcMvSrchRngRB);
void xIBCEstimation ( PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY);
void xIBCSearchMVCandUpdate ( Distortion uiSad, int x, int y, Distortion* uiSadBestCand, Mv* cMVCand);
int xIBCSearchMVChromaRefine( PredictionUnit& pu, int iRoiWidth, int iRoiHeight, int cuPelX, int cuPelY, Distortion* uiSadBestCand, Mv* cMVCand);
protected:
// -------------------------------------------------------------------------------------------------------------------
// Inter search (AMP)
// -------------------------------------------------------------------------------------------------------------------
void xEstimateMvPredAMVP ( PredictionUnit& pu,
PelUnitBuf& origBuf,
RefPicList eRefPicList,
int iRefIdx,
Mv& rcMvPred,
AMVPInfo& amvpInfo,
bool bFilled = false,
Distortion* puiDistBiP = NULL
);
void xCheckBestMVP ( RefPicList eRefPicList,
Mv cMv,
Mv& rcMvPred,
int& riMVPIdx,
AMVPInfo& amvpInfo,
uint32_t& ruiBits,
Distortion& ruiCost
,
const uint8_t imv
);
Distortion xGetTemplateCost ( const PredictionUnit& pu,
PelUnitBuf& origBuf,
PelUnitBuf& predBuf,
Mv cMvCand,
int iMVPIdx,
int iMVPNum,
RefPicList eRefPicList,
int iRefIdx
);
void xCopyAMVPInfo ( AMVPInfo* pSrc, AMVPInfo* pDst );
uint32_t xGetMvpIdxBits ( int iIdx, int iNum );
void xGetBlkBits ( bool bPSlice, int iPartIdx, uint32_t uiLastMode, uint32_t uiBlkBit[3]);
// -------------------------------------------------------------------------------------------------------------------
// motion estimation
// -------------------------------------------------------------------------------------------------------------------
void xMotionEstimation ( PredictionUnit& pu,
PelUnitBuf& origBuf,
RefPicList eRefPicList,
Mv& rcMvPred,
int iRefIdxPred,
Mv& rcMv,
int& riMVPIdx,
uint32_t& ruiBits,
Distortion& ruiCost,
const AMVPInfo& amvpInfo,
bool bBi = false
);
void xTZSearch ( const PredictionUnit& pu,
IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD,
const Mv* const pIntegerMv2Nx2NPred,
const bool bExtendedSettings,
const bool bFastSettings = false
);
void xTZSearchSelective ( const PredictionUnit& pu,
IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD,
const Mv* const pIntegerMv2Nx2NPred
);
void xSetSearchRange ( const PredictionUnit& pu,
const Mv& cMvPred,
const int iSrchRng,
SearchRange& sr
, IntTZSearchStruct & cStruct
);
void xPatternSearchFast ( const PredictionUnit& pu,
IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD,
const Mv* const pIntegerMv2Nx2NPred
);
void xPatternSearch ( IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD
);
void xPatternSearchIntRefine ( PredictionUnit& pu,
IntTZSearchStruct& cStruct,
Mv& rcMv,
Mv& rcMvPred,
int& riMVPIdx,
uint32_t& ruiBits,
Distortion& ruiCost,
const AMVPInfo& amvpInfo,
double fWeight
);
void xPatternSearchFracDIF ( const PredictionUnit& pu,
RefPicList eRefPicList,
int iRefIdx,
IntTZSearchStruct& cStruct,
const Mv& rcMvInt,
Mv& rcMvHalf,
Mv& rcMvQter,
Distortion& ruiCost
);
void xPredAffineInterSearch ( PredictionUnit& pu,
PelUnitBuf& origBuf,
int puIdx,
uint32_t& lastMode,
Distortion& affineCost,
Mv hevcMv[2][33]
, Mv mvAffine4Para[2][33][3]
, int refIdx4Para[2]
, uint8_t gbiIdx = GBI_DEFAULT
, bool enforceGBiPred = false
, uint32_t gbiIdxBits = 0
);
void xAffineMotionEstimation ( PredictionUnit& pu,
PelUnitBuf& origBuf,
RefPicList eRefPicList,
Mv acMvPred[3],
int iRefIdxPred,
Mv acMv[3],
uint32_t& ruiBits,
Distortion& ruiCost,
bool bBi = false
);
void xEstimateAffineAMVP ( PredictionUnit& pu,
AffineAMVPInfo& affineAMVPInfo,
PelUnitBuf& origBuf,
RefPicList eRefPicList,
int iRefIdx,
Mv acMvPred[3],
Distortion* puiDistBiP
);
Distortion xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx );
void xCopyAffineAMVPInfo ( AffineAMVPInfo& src, AffineAMVPInfo& dst );
void xCheckBestAffineMVP ( PredictionUnit &pu, AffineAMVPInfo &affineAMVPInfo, RefPicList eRefPicList, Mv acMv[3], Mv acMvPred[3], int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost );
#if JVET_M0444_SMVD
Distortion xGetSymmetricCost( PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eCurRefPicList, const MvField& cCurMvField, MvField& cTarMvField , int gbiIdx );
Distortion xSymmeticRefineMvSearch( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred
, RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion uiMinCost, int searchPattern, int nSearchStepShift, uint32_t uiMaxSearchRounds , int gbiIdx );
void xSymmetricMotionEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, Mv& rcMvCurPred, Mv& rcMvTarPred, RefPicList eRefPicList, MvField& rCurMvField, MvField& rTarMvField, Distortion& ruiCost, int gbiIdx );
#endif
bool xReadBufferedAffineUniMv ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost);
double xGetMEDistortionWeight ( uint8_t gbiIdx, RefPicList eRefPicList);
bool xReadBufferedUniMv ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost);
public:
void resetBufferedUniMotions () { m_uniMotions.reset(); }
uint32_t getWeightIdxBits ( uint8_t gbiIdx ) { return m_estWeightIdxBits[gbiIdx]; }
void initWeightIdxBits ();
#if JVET_M0444_SMVD
void symmvdCheckBestMvp(
PredictionUnit& pu,
PelUnitBuf& origBuf,
Mv curMv,
RefPicList curRefList,
AMVPInfo amvpInfo[2][33],
int32_t gbiIdx,
Mv cMvPredSym[2],
int32_t mvpIdxSym[2],
Distortion& bestCost,
bool skip = false
);
#endif
protected:
void xExtDIFUpSamplingH ( CPelBuf* pcPattern );
void xExtDIFUpSamplingQ ( CPelBuf* pcPatternKey, Mv halfPelRef );
// -------------------------------------------------------------------------------------------------------------------
// compute symbol bits
// -------------------------------------------------------------------------------------------------------------------
void setWpScalingDistParam ( int iRefIdx, RefPicList eRefPicListCur, Slice *slice );
private:
void xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, Mv &mv, int& idxMvPred, IbcHashMap& ibcHashMap);
public:
void encodeResAndCalcRdInterCU (CodingStructure &cs, Partitioner &partitioner, const bool &skipResidual
, const bool luma = true, const bool chroma = true
);
void xEncodeInterResidualQT (CodingStructure &cs, Partitioner &partitioner, const ComponentID &compID);
void xEstimateInterResidualQT (CodingStructure &cs, Partitioner &partitioner, Distortion *puiZeroDist = NULL
, const bool luma = true, const bool chroma = true
);
uint64_t xGetSymbolFracBitsInter (CodingStructure &cs, Partitioner &partitioner);
};// END CLASS DEFINITION EncSearch
//! \}
#endif // __ENCSEARCH__