Commit 35a88f87 authored by Xiaozhong Xu's avatar Xiaozhong Xu Committed by Frank Bossen

L0293_CPR mode

parent a5bbac4b
......@@ -111,6 +111,7 @@ LMChroma : 1 # use CCLM only
DepQuant : 1
IMV : 2
ALF : 1
CPR : 0 # turned off in CTC
# Fast tools
PBIntraFast : 1
......
......@@ -128,6 +128,7 @@ DepQuant : 1
IMV : 2
ALF : 1
MHIntra : 1
CPR : 0 # turned off in CTC
# Fast tools
PBIntraFast : 1
......
......@@ -131,6 +131,7 @@ GBi : 1
GBiFast : 1
MHIntra : 1
Triangle : 1
CPR : 0 # turned off in CTC
# Fast tools
PBIntraFast : 1
......
......@@ -146,6 +146,7 @@ GBiFast : 1
BIO : 1
MHIntra : 1
Triangle : 1
CPR : 0 # turned off in CTC
# Fast tools
PBIntraFast : 1
......
......@@ -269,6 +269,17 @@ void EncApp::xInitLibCfg()
#if JVET_L0124_L0208_TRIANGLE
m_cEncLib.setUseTriangle ( m_Triangle );
#endif
#if JVET_L0293_CPR
m_cEncLib.setCPRMode ( m_CPRMode );
m_cEncLib.setCPRLocalSearchRangeX ( m_CPRLocalSearchRangeX );
m_cEncLib.setCPRLocalSearchRangeY ( m_CPRLocalSearchRangeY );
m_cEncLib.setCPRHashSearch ( m_CPRHashSearch );
m_cEncLib.setCPRHashSearchMaxCand ( m_CPRHashSearchMaxCand );
m_cEncLib.setCPRHashSearchRange4SmallBlk ( m_CPRHashSearchRange4SmallBlk );
m_cEncLib.setCPRFastMethod ( m_CPRFastMethod );
#endif
// ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here
m_cEncLib.setMaxCUWidth ( m_QTBT ? m_uiCTUSize : m_uiMaxCUWidth );
......
......@@ -874,6 +874,17 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
#if JVET_L0124_L0208_TRIANGLE
("Triangle", m_Triangle, false, "Enable triangular shape motion vector prediction (0:off, 1:on)")
#endif
#if JVET_L0293_CPR
( "CPR", m_CPRMode, 0u, "CPRMode (0x1:enabled, 0x0:disabled) [default: disabled]")
( "CPRLocalSearchRangeX", m_CPRLocalSearchRangeX, 128u, "Search range of CPR local search in x direction")
( "CPRLocalSearchRangeY", m_CPRLocalSearchRangeY, 128u, "Search range of CPR local search in y direction")
( "CPRHashSearch", m_CPRHashSearch, 1u, "Hash based CPR search")
( "CPRHashSearchMaxCand", m_CPRHashSearchMaxCand, 256u, "Max candidates for hash based CPR search")
( "CPRHashSearchRange4SmallBlk", m_CPRHashSearchRange4SmallBlk, 256u, "Small block search range in based CPR search")
( "CPRFastMethod", m_CPRFastMethod, 6u, "Fast methods for CPR")
#endif
// ADD_NEW_TOOL : (encoder app) add parsing parameters here
("LCTUFast", m_useFastLCTU, false, "Fast methods for large CTU")
......@@ -1964,6 +1975,9 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara( m_DisableMotionCompression, "Disable motion data compression only allowed with NEXT profile" );
xConfirmPara( m_MTT, "Multi type tree is only allowed with NEXT profile" );
xConfirmPara( m_ImvMode, "IMV is only allowed with NEXT profile" );
#if JVET_L0293_CPR
xConfirmPara(m_CPRMode, "CPR Mode only allowed with NEXT profile");
#endif
xConfirmPara( m_useFastLCTU, "Fast large CTU can only be applied when encoding with NEXT profile" );
xConfirmPara( m_EMT, "EMT only allowed with NEXT profile" );
xConfirmPara( m_FastEMT, "EMT only allowed with NEXT profile" );
......@@ -3208,6 +3222,9 @@ void EncAppCfg::xPrintParameter()
msg( VERBOSE, "Triangle:%d ", m_Triangle );
#endif
}
#if JVET_L0293_CPR
msg(VERBOSE, "CPR:%d ", m_CPRMode);
#endif
// ADD_NEW_TOOL (add some output indicating the usage of tools)
msg( VERBOSE, "\nFAST TOOL CFG: " );
......
......@@ -246,6 +246,18 @@ protected:
#if JVET_L0124_L0208_TRIANGLE
bool m_Triangle;
#endif
#if JVET_L0293_CPR
unsigned m_CPRMode;
unsigned m_CPRLocalSearchRangeX;
unsigned m_CPRLocalSearchRangeY;
unsigned m_CPRHashSearch;
unsigned m_CPRHashSearchMaxCand;
unsigned m_CPRHashSearchRange4SmallBlk;
unsigned m_CPRFastMethod;
#endif
// ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here
unsigned m_uiMaxCUWidth; ///< max. CU width in pixel
......
......@@ -749,7 +749,11 @@ void CodingStructure::useSubStructure( const CodingStructure& subStruct, const C
if( cpyResi ) picture->getResiBuf( clippedArea ).copyFrom( subResiBuf );
if( cpyReco ) picture->getRecoBuf( clippedArea ).copyFrom( subRecoBuf );
#if JVET_L0293_CPR
if (!subStruct.m_isTuEnc && (!slice->isIntra() && subStruct.chType != CHANNEL_TYPE_CHROMA))
#else
if( !subStruct.m_isTuEnc && !slice->isIntra() )
#endif
{
// copy motion buffer
MotionBuf ownMB = getMotionBuf ( clippedArea );
......@@ -1302,3 +1306,38 @@ const TransformUnit* CodingStructure::getTURestricted( const Position &pos, cons
}
}
#if JVET_L0293_CPR
CprLumaCoverage CodingStructure::getCprLumaCoverage(const CompArea& chromaArea) const
{
CHECK(chType != CHANNEL_TYPE_CHROMA, "Error");
const unsigned int unitAreaSubBlock = MIN_PU_SIZE * MIN_PU_SIZE;
CompArea lumaArea = CompArea(COMPONENT_Y, chromaArea.chromaFormat, chromaArea.lumaPos(), recalcSize(chromaArea.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, chromaArea.size()));
lumaArea = clipArea(lumaArea, picture->block(COMPONENT_Y));
const unsigned int fullArea = lumaArea.area();
unsigned int cprArea = 0;
for (SizeType y = 0; y < lumaArea.height; y += MIN_PU_SIZE)
{
for (SizeType x = 0; x < lumaArea.width; x += MIN_PU_SIZE)
{
Position pos = lumaArea.offset(x, y);
if (picture->cs->getMotionInfo(pos).isInter) // need to change if inter slice allows dualtree
{
cprArea += unitAreaSubBlock;
}
}
}
CprLumaCoverage coverage = CPR_LUMA_COVERAGE_FULL;
if (cprArea == 0)
{
coverage = CPR_LUMA_COVERAGE_NONE;
}
else if (cprArea < fullArea)
{
coverage = CPR_LUMA_COVERAGE_PARTIAL;
}
return coverage;
}
#endif
\ No newline at end of file
......@@ -58,6 +58,15 @@ enum PictureType
PIC_ORG_RESI,
NUM_PIC_TYPES
};
#if JVET_L0293_CPR
enum CprLumaCoverage
{
CPR_LUMA_COVERAGE_FULL = 0,
CPR_LUMA_COVERAGE_PARTIAL,
CPR_LUMA_COVERAGE_NONE,
NUM_CPR_LUMA_COVERAGE,
};
#endif
extern XUCache g_globalUnitCache;
// ---------------------------------------------------------------------------
......@@ -76,6 +85,9 @@ public:
Slice *slice;
UnitScale unitScale[MAX_NUM_COMPONENT];
#if JVET_L0293_CPR
ChannelType chType;
#endif
int baseQP;
int prevQP[MAX_NUM_CHANNEL_TYPE];
......@@ -146,6 +158,9 @@ public:
cCUTraverser traverseCUs(const UnitArea& _unit, const ChannelType _chType) const;
cPUTraverser traversePUs(const UnitArea& _unit, const ChannelType _chType) const;
cTUTraverser traverseTUs(const UnitArea& _unit, const ChannelType _chType) const;
#if JVET_L0293_CPR
CprLumaCoverage getCprLumaCoverage(const CompArea& chromaArea) const;
#endif
// ---------------------------------------------------------------------------
// encoding search utilities
// ---------------------------------------------------------------------------
......
......@@ -114,6 +114,28 @@ struct UnitScale
Size scale( const Size &size ) const { return { size.width >> posx, size.height >> posy }; }
Area scale( const Area &_area ) const { return Area( scale( _area.pos() ), scale( _area.size() ) ); }
};
#if JVET_L0293_CPR
namespace std
{
template <>
struct hash<Position> : public unary_function<Position, uint64_t>
{
uint64_t operator()(const Position& value) const
{
return (((uint64_t)value.x << 32) + value.y);
}
};
template <>
struct hash<Size> : public unary_function<Size, uint64_t>
{
uint64_t operator()(const Size& value) const
{
return (((uint64_t)value.width << 32) + value.height);
}
};
}
#endif
inline size_t rsAddr(const Position &pos, const uint32_t stride, const UnitScale &unitScale )
{
return (size_t)(stride >> unitScale.posx) * (size_t)(pos.y >> unitScale.posy) + (size_t)(pos.x >> unitScale.posx);
......
......@@ -435,6 +435,15 @@ static const int TRIANGLE_MAX_NUM_SATD_CANDS = 3;
static const int TRIANGLE_MIN_SIZE = 8 * 8;
#endif
#if JVET_L0293_CPR
static const int CPR_MAX_CAND_SIZE = 16; // max block size for cpr search
static const int CPR_NUM_CANDIDATES = 64; ///< Maximum number of candidates to store/test
static const int CHROMA_REFINEMENT_CANDIDATES = 8; /// 8 candidates BV to choose from
static const int CPR_FAST_METHOD_NOINTRA_CPRCBF0 = 0x01;
static const int CPR_FAST_METHOD_BUFFERBV = 0X02;
static const int CPR_FAST_METHOD_ADAPTIVE_SEARCHRANGE = 0X04;
#endif
// ====================================================================================================================
// Macro functions
// ====================================================================================================================
......
......@@ -397,7 +397,14 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx )
pu.mvpIdx [REF_PIC_LIST_1] = NOT_VALID;
pu.mvpNum [REF_PIC_LIST_0] = NOT_VALID;
pu.mvpNum [REF_PIC_LIST_1] = NOT_VALID;
#if JVET_L0293_CPR
if (interDirNeighbours[candIdx] == 1 && pu.cs->slice->getRefPic(REF_PIC_LIST_0, mvFieldNeighbours[candIdx << 1].refIdx)->getPOC() == pu.cs->slice->getPOC())
{
pu.cu->cpr = true;
pu.bv = pu.mv[REF_PIC_LIST_0];
pu.bv >>= (2 + VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE); // used for only integer resolution
}
#endif
#if JVET_L0646_GBI
pu.cu->GBiIdx = ( interDirNeighbours[candIdx] == 3 ) ? GBiIdx[candIdx] : GBI_DEFAULT;
#endif
......
This diff is collapsed.
/* 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-2018, 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 CprHashMap.h
\brief CPR hash map encoder class (header)
*/
#ifndef __CPRHASHMAP__
#define __CPRHASHMAP__
// Include files
#include "CommonLib/CommonDef.h"
#include "CommonLib/IntraPrediction.h"
#include "CommonLib/InterPrediction.h"
#include "CommonLib/TrQuant.h"
#include "CommonLib/Unit.h"
#include "CommonLib/UnitPartitioner.h"
#include <unordered_map>
#include <vector>
//! \ingroup EncoderLib
//! \{
// ====================================================================================================================
// Class definition
// ====================================================================================================================
class CprHashMap
{
private:
int m_picWidth;
int m_picHeight;
unsigned int** m_pos2Hash;
std::unordered_map<unsigned int, std::vector<Position>> m_hash2Pos;
unsigned int xxCalcBlockHash(const Pel* pel, const int stride, const int width, const int height, unsigned int crc);
template<ChromaFormat chromaFormat>
void xxBuildPicHashMap(const PelUnitBuf& pic);
static uint32_t xxComputeCrc32c16bit(uint32_t crc, const Pel pel);
public:
uint32_t (*m_computeCrc32c) (uint32_t crc, const Pel pel);
CprHashMap();
virtual ~CprHashMap();
void init(const int picWidth, const int picHeight);
void destroy();
void rebuildPicHashMap(const PelUnitBuf& pic);
bool cprHashMatch(const Area& lumaArea, std::vector<Position>& cand, const CodingStructure& cs, const int maxCand, const int searchRange4SmallBlk);
int getHashHitRatio(const Area& lumaArea);
#ifdef TARGET_SIMD_X86
void initCprHashMapX86();
template <X86_VEXT vext>
void _initCprHashMapX86();
#endif
};
//! \}
#endif // __CPRHASHMAP__
......@@ -371,18 +371,63 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R
#endif
}
#if JVET_L0293_CPR
void InterPrediction::xChromaMC(PredictionUnit &pu, PelUnitBuf& pcYuvPred)
{
// separated tree, chroma
const CompArea lumaArea = CompArea(COMPONENT_Y, pu.chromaFormat, pu.Cb().lumaPos(), recalcSize(pu.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, pu.Cb().size()));
PredictionUnit subPu;
subPu.cs = pu.cs;
subPu.cu = pu.cu;
Picture * refPic = pu.cu->slice->getPic();
for (int y = lumaArea.y; y < lumaArea.y + lumaArea.height; y += MIN_PU_SIZE)
{
for (int x = lumaArea.x; x < lumaArea.x + lumaArea.width; x += MIN_PU_SIZE)
{
const MotionInfo &curMi = pu.cs->picture->cs->getMotionInfo(Position{ x, y });
subPu.UnitArea::operator=(UnitArea(pu.chromaFormat, Area(x, y, MIN_PU_SIZE, MIN_PU_SIZE)));
PelUnitBuf subPredBuf = pcYuvPred.subBuf(UnitAreaRelative(pu, subPu));
xPredInterBlk(COMPONENT_Cb, subPu, refPic, curMi.mv[0], subPredBuf, false, pu.cu->slice->clpRng(COMPONENT_Cb)
#if JVET_L0256_BIO
, false
#endif
, true
);
xPredInterBlk(COMPONENT_Cr, subPu, refPic, curMi.mv[0], subPredBuf, false, pu.cu->slice->clpRng(COMPONENT_Cr)
#if JVET_L0256_BIO
, false
#endif
, true
);
}
}
}
#endif
void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList& eRefPicList, PelUnitBuf& pcYuvPred, const bool& bi
#if JVET_L0256_BIO
,const bool& bioApplied /*=false*/
#endif
#if JVET_L0293_CPR
, const bool luma, const bool chroma
#endif
)
{
const SPS &sps = *pu.cs->sps;
int iRefIdx = pu.refIdx[eRefPicList];
Mv mv[3];
#if JVET_L0293_CPR
bool isCPR = false;
if (pu.cs->slice->getRefPic(eRefPicList, iRefIdx)->getPOC() == pu.cs->slice->getPOC())
{
isCPR = true;
}
#endif
if( pu.cu->affine )
{
CHECK( iRefIdx < 0, "iRefIdx incorrect." );
......@@ -409,6 +454,12 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList&
for( uint32_t comp = COMPONENT_Y; comp < pcYuvPred.bufs.size() && comp <= m_maxCompIDToPred; comp++ )
{
const ComponentID compID = ComponentID( comp );
#if JVET_L0293_CPR
if (compID == COMPONENT_Y && !luma)
continue;
if (compID != COMPONENT_Y && !chroma)
continue;
#endif
if ( pu.cu->affine )
{
#if JVET_L0256_BIO
......@@ -419,10 +470,16 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList&
else
{
xPredInterBlk( compID, pu, pu.cu->slice->getRefPic( eRefPicList, iRefIdx ), mv[0], pcYuvPred, bi, pu.cu->slice->clpRng( compID )
#if JVET_L0256_BIO
,bioApplied
#endif
);
#if JVET_L0293_CPR
, isCPR
#endif
);
}
}
}
......@@ -530,10 +587,15 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
}
void InterPrediction::xPredInterBlk ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv& _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng
#if JVET_L0256_BIO
,const bool& bioApplied /*=false*/
#endif
)
#if JVET_L0293_CPR
, bool isCPR /*=false*/
#endif
)
{
JVET_J0090_SET_REF_PICTURE( refPic, compID );
const ChromaFormat chFmt = pu.chromaFormat;
......@@ -556,7 +618,12 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio
int xFrac = _mv.hor & ((1 << shiftHor) - 1);
int yFrac = _mv.ver & ((1 << shiftVer) - 1);
#if JVET_L0293_CPR
if (isCPR)
{
xFrac = yFrac = 0;
}
#endif
xFrac <<= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE - iAddPrecShift;
yFrac <<= VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE - iAddPrecShift;
#if !REMOVE_MV_ADAPT_PREC
......@@ -653,7 +720,11 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio
{
Mv mvTemp = _mv[0];
clipMv( mvTemp, pu.cu->lumaPos(), *pu.cs->sps );
xPredInterBlk( compID, pu, refPic, mvTemp, dstPic, bi, clpRng );
xPredInterBlk( compID, pu, refPic, mvTemp, dstPic, bi, clpRng
#if JVET_L0293_CPR
, false
#endif
);
return;
}
......@@ -1110,8 +1181,32 @@ void InterPrediction::xWeightedAverage( const PredictionUnit& pu, const CPelUnit
}
void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBuf, const RefPicList &eRefPicList
#if JVET_L0293_CPR
, const bool luma, const bool chroma
#endif
)
{
#if JVET_L0293_CPR
// dual tree handling for CPR as the only ref
if (!luma || !chroma)
{
if (!luma && chroma)
{
xChromaMC(pu, predBuf);
return;
}
else // (luma && !chroma)
{
xPredInterUni(pu, eRefPicList, predBuf, false
#if JVET_L0256_BIO
, false
#endif
, luma, chroma);
return;
}
}
// else, go with regular MC below
#endif
CodingStructure &cs = *pu.cs;
const PPS &pps = *cs.pps;
const SliceType sliceType = cs.slice->getSliceType();
......@@ -1130,7 +1225,11 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
}
else
{
#if JVET_L0293_CPR
if (pu.mergeType != MRG_TYPE_DEFAULT_N && pu.mergeType != MRG_TYPE_CPR)
#else
if( pu.mergeType != MRG_TYPE_DEFAULT_N )
#endif
{
xSubPuMC( pu, predBuf, eRefPicList );
}
......@@ -1147,20 +1246,33 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
}
void InterPrediction::motionCompensation( CodingUnit &cu, const RefPicList &eRefPicList
#if JVET_L0293_CPR
, const bool luma, const bool chroma
#endif
)
{
for( auto &pu : CU::traversePUs( cu ) )
{
PelUnitBuf predBuf = cu.cs->getPredBuf( pu );
motionCompensation( pu, predBuf, eRefPicList );
motionCompensation( pu, predBuf, eRefPicList
#if JVET_L0293_CPR
, luma, chroma
#endif
);
}
}
void InterPrediction::motionCompensation( PredictionUnit &pu, const RefPicList &eRefPicList /*= REF_PIC_LIST_X*/
#if JVET_L0293_CPR
, const bool luma, const bool chroma
#endif
)
{
PelUnitBuf predBuf = pu.cs->getPredBuf( pu );
motionCompensation( pu, predBuf, eRefPicList
#if JVET_L0293_CPR
, luma, chroma
#endif
);
}
......
......@@ -115,12 +115,20 @@ protected:
#if JVET_L0256_BIO
,const bool& bioApplied = false
#endif
#if JVET_L0293_CPR
, const bool luma = true, const bool chroma = true
#endif
);
void xPredInterBi ( PredictionUnit& pu, PelUnitBuf &pcYuvPred );
void xPredInterBlk ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv& _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng
#if JVET_L0256_BIO
,const bool& bioApplied = false
#endif
#if JVET_L0293_CPR
, bool isCPR = false
#endif
);
#if JVET_L0256_BIO
......@@ -141,7 +149,9 @@ protected:
MotionInfo m_SubPuMiBuf[(MAX_CU_SIZE * MAX_CU_SIZE) >> (MIN_CU_LOG2 << 1)];
#if JVET_L0293_CPR
void xChromaMC(PredictionUnit &pu, PelUnitBuf& pcYuvPred);
#endif
public:
InterPrediction();
virtual ~InterPrediction();
......@@ -150,10 +160,19 @@ public:
// inter
void motionCompensation (PredictionUnit &pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X
#if JVET_L0293_CPR
, const bool luma = true, const bool chroma = true
#endif
);
void motionCompensation (PredictionUnit &pu, const RefPicList &eRefPicList = REF_PIC_LIST_X
#if JVET_L0293_CPR
, const bool luma = true, const bool chroma = true
#endif
);
void motionCompensation (CodingUnit &cu, const RefPicList &eRefPicList = REF_PIC_LIST_X
#if JVET_L0293_CPR
, const bool luma = true, const bool chroma = true
#endif
);
#if JVET_L0124_L0208_TRIANGLE
......
......@@ -442,7 +442,13 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
const Slice& sliceQ = *cu.slice;
const Position& cuPosLuma = cu.lumaPos();
#if JVET_L0293_CPR
int shiftHor = cu.Y().valid() ? 0 : ::getComponentScaleX(COMPONENT_Cb, cu.firstPU->chromaFormat);
int shiftVer = cu.Y().valid() ? 0 : ::getComponentScaleY(COMPONENT_Cb, cu.firstPU->chromaFormat);
const Position& posQ = Position{ localPos.x >> shiftHor, localPos.y >> shiftVer };
#else
const Position& posQ = localPos;
#endif
const Position posP = ( edgeDir == EDGE_VER ) ? posQ.offset( -1, 0 ) : posQ.offset( 0, -1 );
const bool sameCU = posP.x >= cuPosLuma.x && posP.y >= cuPosLuma.y;
......
......@@ -106,6 +106,9 @@ struct MotionInfo
Mv mv [ NUM_REF_PIC_LIST_01 ];
int16_t refIdx [ NUM_REF_PIC_LIST_01 ];
#if JVET_L0293_CPR
Mv bv;
#endif
MotionInfo() : isInter( false ), interDir( 0 ), sliceIdx( 0 ), refIdx{ NOT_VALID, NOT_VALID } { }
// ensure that MotionInfo(0) produces '\x000....' bit pattern - needed to work with AreaBuf - don't use this constructor for anything else
MotionInfo( int i ) : isInter( i != 0 ), interDir( 0 ), sliceIdx( 0 ), refIdx{ 0, 0 } { CHECKD( i != 0, "The argument for this constructor has to be '0'" ); }
......
......@@ -273,6 +273,19 @@ public:
}
#endif
};// END CLASS DEFINITION MV
#if JVET_L0293_CPR
namespace std
{
template <>
struct hash<Mv> : public unary_function<Mv, uint64_t>
{
uint64_t operator()(const Mv& value) const
{
return (((uint64_t)value.hor << 32) + value.ver);
}
};
};
#endif
void roundMV( Mv& rcMv, unsigned imvShift );
void clipMv ( Mv& rcMv, const struct Position& pos, const class SPS& sps );
......
......@@ -916,9 +916,11 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co
const int iQBits = QUANT_SHIFT + cQP.per + iTransformShift;
// QBits will be OK for any internal bit depth as the reduction in transform shift is balanced by an increase in Qp_per due to QpBDOffset
#if JVET_L0293_CPR
const int iAdd = int64_t(bUseHalfRoundingPoint ? 256 : (tu.cs->slice->isIRAP() ? 171 : 85)) << int64_t(iQBits - 9);
#else
const int iAdd = int64_t(bUseHalfRoundingPoint ? 256 : (tu.cs->slice->getSliceType() == I_SLICE ? 171 : 85)) << int64_t(iQBits - 9);
#endif
TCoeff transformedCoefficient;
// transform-skip
......
......@@ -115,10 +115,16 @@ private:
// for motion cost
Mv m_mvPredictor;
#if JVET_L0293_CPR
Mv m_bvPredictors[2];
#endif
double m_motionLambda;
int m_iCostScale;
bool m_useQtbt;
#if JVET_L0293_CPR
double m_dCost; // for cpr
#endif
public:
RdCost();