Commit cc0c138b authored by Karsten Suehring's avatar Karsten Suehring
Browse files

Temporal MCTS encoding constraints and decoder checks (JCTVC-AC0038)

parent 84ddcf73
......@@ -91,6 +91,9 @@ Bool TAppDecCfg::parseCfg( Int argc, TChar* argv[] )
#endif
("OutputDecodedSEIMessagesFilename", m_outputDecodedSEIMessagesFilename, string(""), "When non empty, output decoded SEI messages to the indicated file. If file is '-', then output to stdout\n")
("ClipOutputVideoToRec709Range", m_bClipOutputVideoToRec709Range, false, "If true then clip output video to the Rec. 709 Range on saving")
#if MCTS_ENC_CHECK
("TMCTSCheck", m_tmctsCheck, false, "If enabled, the decoder checks for violations of mc_exact_sample_value_match_flag in Temporal MCTS ")
#endif
;
po::setDefaults(opts);
......
......@@ -73,6 +73,9 @@ protected:
#endif
std::string m_outputDecodedSEIMessagesFilename; ///< filename to output decoded SEI messages to. If '-', then use stdout. If empty, do not output details.
Bool m_bClipOutputVideoToRec709Range; ///< If true, clip the output video to the Rec 709 range on saving.
#if MCTS_ENC_CHECK
Bool m_tmctsCheck;
#endif
public:
TAppDecCfg()
......@@ -92,6 +95,9 @@ public:
#endif
, m_outputDecodedSEIMessagesFilename()
, m_bClipOutputVideoToRec709Range(false)
#if MCTS_ENC_CHECK
, m_tmctsCheck(false)
#endif
{
for (UInt channelTypeIndex = 0; channelTypeIndex < MAX_NUM_CHANNEL_TYPE; channelTypeIndex++)
{
......
......@@ -291,6 +291,9 @@ Void TAppDecTop::xInitDecLib()
// initialize decoder class
m_cTDecTop.init();
m_cTDecTop.setDecodedPictureHashSEIEnabled(m_decodedPictureHashSEIEnabled);
#if MCTS_ENC_CHECK
m_cTDecTop.setTMctsCheckEnabled(m_tmctsCheck);
#endif
#if O0043_BEST_EFFORT_DECODING
m_cTDecTop.setForceDecodeBitDepth(m_forceDecodeBitDepth);
#endif
......
......@@ -1075,6 +1075,9 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
("SEISOPDescription", m_SOPDescriptionSEIEnabled, false, "Control generation of SOP description SEI messages")
("SEIScalableNesting", m_scalableNestingSEIEnabled, false, "Control generation of scalable nesting SEI messages")
("SEITempMotionConstrainedTileSets", m_tmctsSEIEnabled, false, "Control generation of temporal motion constrained tile sets SEI message")
#if MCTS_ENC_CHECK
("SEITMCTSTileConstraint", m_tmctsSEITileConstraint, false, "Constrain motion vectors at tile boundaries")
#endif
("SEITimeCodeEnabled", m_timeCodeSEIEnabled, false, "Control generation of time code information SEI message")
("SEITimeCodeNumClockTs", m_timeCodeSEINumTs, 0, "Number of clock time sets [0..3]")
("SEITimeCodeTimeStampFlag", cfg_timeCodeSeiTimeStampFlag, cfg_timeCodeSeiTimeStampFlag, "Time stamp flag associated to each time set")
......@@ -2541,6 +2544,14 @@ Void TAppEncCfg::xCheckParameter()
m_tmctsSEIEnabled = false;
}
#if MCTS_ENC_CHECK
if ((m_tmctsSEIEnabled) && (m_tmctsSEITileConstraint) && (m_bLFCrossTileBoundaryFlag) )
{
printf("Warning: Constrained Encoding for Temporal Motion Constrained Tile Sets is enabled. Disabling filtering across tile boundaries!\n");
m_bLFCrossTileBoundaryFlag = false;
}
#endif
if(m_timeCodeSEIEnabled)
{
xConfirmPara(m_timeCodeSEINumTs > MAX_TIMECODE_SEI_SETS, "Number of time sets cannot exceed 3");
......
......@@ -330,6 +330,9 @@ protected:
Bool m_SOPDescriptionSEIEnabled;
Bool m_scalableNestingSEIEnabled;
Bool m_tmctsSEIEnabled;
#if MCTS_ENC_CHECK
Bool m_tmctsSEITileConstraint;
#endif
Bool m_timeCodeSEIEnabled;
Int m_timeCodeSEINumTs;
TComSEITimeSet m_timeSetArray[MAX_TIMECODE_SEI_SETS];
......
......@@ -333,6 +333,9 @@ Void TAppEncTop::xInitLibCfg()
m_cTEncTop.setSOPDescriptionSEIEnabled ( m_SOPDescriptionSEIEnabled );
m_cTEncTop.setScalableNestingSEIEnabled ( m_scalableNestingSEIEnabled );
m_cTEncTop.setTMCTSSEIEnabled ( m_tmctsSEIEnabled );
#if MCTS_ENC_CHECK
m_cTEncTop.setTMCTSSEITileConstraint ( m_tmctsSEITileConstraint );
#endif
m_cTEncTop.setTimeCodeSEIEnabled ( m_timeCodeSEIEnabled );
m_cTEncTop.setNumberOfTimeSets ( m_timeCodeSEINumTs );
for(Int i = 0; i < m_timeCodeSEINumTs; i++)
......
......@@ -649,14 +649,14 @@ public:
//definition according to P1005_v1;
class SEITempMotionConstrainedTileSets: public SEI
{
struct TileSetData
class TileSetData
{
protected:
std::vector<Int> m_top_left_tile_index; //[tileSetIdx][tileIdx];
std::vector<Int> m_bottom_right_tile_index;
public:
Int m_mcts_id;
Int m_mcts_id;
Bool m_display_tile_set_flag;
Int m_num_tile_rects_in_set; //_minus1;
Bool m_exact_sample_value_match_flag;
......
......@@ -2139,7 +2139,11 @@ Bool TComDataCU::hasEqualMotion( UInt uiAbsPartIdx, const TComDataCU* pcCandCU,
}
//! Construct a list of merging candidates
#if MCTS_ENC_CHECK
Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, UInt &numSpatialMergeCandidates, Int mrgCandIdx ) const
#else
Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMvFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx ) const
#endif
{
UInt uiAbsPartAddr = m_absZIdxInCtu + uiAbsPartIdx;
Bool abCandIsInter[ MRG_MAX_NUM_CANDS ];
......@@ -2183,6 +2187,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
}
if ( mrgCandIdx == iCount )
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount + 1;
#endif
return;
}
iCount ++;
......@@ -2191,6 +2198,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
return;
}
// above
......@@ -2215,6 +2225,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
}
if ( mrgCandIdx == iCount )
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount + 1;
#endif
return;
}
iCount ++;
......@@ -2222,6 +2235,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
return;
}
......@@ -2246,6 +2262,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
}
if ( mrgCandIdx == iCount )
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount + 1;
#endif
return;
}
iCount ++;
......@@ -2253,6 +2272,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
return;
}
......@@ -2277,6 +2299,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
}
if ( mrgCandIdx == iCount )
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount + 1;
#endif
return;
}
iCount ++;
......@@ -2284,6 +2309,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
return;
}
......@@ -2311,6 +2339,9 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
}
if ( mrgCandIdx == iCount )
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount + 1;
#endif
return;
}
iCount ++;
......@@ -2319,9 +2350,14 @@ Void TComDataCU::getInterMergeCandidates( UInt uiAbsPartIdx, UInt uiPUIdx, TComM
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
return;
}
#if MCTS_ENC_CHECK
numSpatialMergeCandidates = iCount;
#endif
if ( getSlice()->getEnableTMVPFlag() )
{
//>> MTK colocated-RightBottom
......@@ -2580,6 +2616,9 @@ Void TComDataCU::fillMvpCand ( const UInt partIdx, const UInt partAddr, const Re
pInfo->iN = 0;
if (refIdx < 0)
{
#if MCTS_ENC_CHECK
pInfo->numSpatialMVPCandidates = 0;
#endif
return;
}
......@@ -2651,7 +2690,9 @@ Void TComDataCU::fillMvpCand ( const UInt partIdx, const UInt partAddr, const Re
pInfo->iN = 1;
}
}
#if MCTS_ENC_CHECK
pInfo->numSpatialMVPCandidates = pInfo->iN;
#endif
if (pInfo->iN < AMVP_MAX_NUM_CANDS && getSlice()->getEnableTMVPFlag() )
{
// Get Temporal Motion Predictor
......@@ -3165,4 +3206,17 @@ UInt TComDataCU::getCoefScanIdx(const UInt uiAbsPartIdx, const UInt uiWidth, con
}
}
#if MCTS_ENC_CHECK
Bool TComDataCU::isLastColumnCTUInTile() const
{
UInt currentTileIdx = this->getPic()->getPicSym()->getTileIdxMap(this->getCtuRsAddr());
TComTile *pCurrentTile = m_pcPic->getPicSym()->getTComTile(currentTileIdx);
UInt frameWidthInCtus = m_pcPic->getPicSym()->getFrameWidthInCtus();
UInt rightEdgeCTUPosInCurrentTile = pCurrentTile->getRightEdgePosInCtus();
UInt ctuXPosInCtus = this->getCtuRsAddr() % frameWidthInCtus;
return (rightEdgeCTUPosInCurrentTile == ctuXPosInCtus);
}
#endif
//! \}
......@@ -137,6 +137,9 @@ private:
SChar* m_apiMVPIdx[NUM_REF_PIC_LIST_01]; ///< array of motion vector predictor candidates
SChar* m_apiMVPNum[NUM_REF_PIC_LIST_01]; ///< array of number of possible motion vectors predictors
Bool* m_pbIPCMFlag; ///< array of intra_pcm flags
#if MCTS_ENC_CHECK
Bool m_tMctsMvpIsValid;
#endif
// -------------------------------------------------------------------------------------------------------------------
// misc. variables
......@@ -210,6 +213,12 @@ public:
Void setDepthSubParts ( UInt uiDepth, UInt uiAbsPartIdx );
#if MCTS_ENC_CHECK
Void setTMctsMvpIsValid(Bool b) { m_tMctsMvpIsValid = b; }
Bool getTMctsMvpIsValid() { return m_tMctsMvpIsValid; }
Bool isLastColumnCTUInTile() const;
#endif
// -------------------------------------------------------------------------------------------------------------------
// member functions for CU data
// -------------------------------------------------------------------------------------------------------------------
......@@ -425,7 +434,11 @@ public:
Void deriveLeftBottomIdx ( UInt uiPartIdx, UInt& ruiPartIdxLB ) const;
Bool hasEqualMotion ( UInt uiAbsPartIdx, const TComDataCU* pcCandCU, UInt uiCandAbsPartIdx ) const;
#if MCTS_ENC_CHECK
Void getInterMergeCandidates ( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, UInt& numSpatialMergeCandidates , Int mrgCandIdx = -1) const;
#else
Void getInterMergeCandidates ( UInt uiAbsPartIdx, UInt uiPUIdx, TComMvField* pcMFieldNeighbours, UChar* puhInterDirNeighbours, Int& numValidMergeCand, Int mrgCandIdx = -1 ) const;
#endif
Void deriveLeftRightTopIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLT, UInt& ruiPartIdxRT ) const;
Void deriveLeftBottomIdxGeneral ( UInt uiAbsPartIdx, UInt uiPartIdx, UInt& ruiPartIdxLB ) const;
......
......@@ -55,6 +55,9 @@ typedef struct _AMVPInfo
{
TComMv m_acMvCand[ AMVP_MAX_NUM_CANDS ]; ///< array of motion vector predictor candidates
Int iN; ///< number of motion vector predictor candidates
#if MCTS_ENC_CHECK
UInt numSpatialMVPCandidates;
#endif
} AMVPInfo;
// ====================================================================================================================
......
......@@ -77,19 +77,43 @@ Int isBelowLeftAvailable ( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiP
// Public member functions (TComPattern)
// ====================================================================================================================
#if MCTS_ENC_CHECK
Void TComPattern::initPattern(Pel* piY,
Int roiWidth,
Int roiHeight,
Int stride,
Int bitDepthLuma,
Int roiPosX,
Int roiPosY)
#else
Void TComPattern::initPattern (Pel* piY,
Int roiWidth,
Int roiHeight,
Int stride,
Int bitDepthLuma)
#endif
{
m_piROIOrigin = piY;
m_roiWidth = roiWidth;
m_roiHeight = roiHeight;
m_patternStride = stride;
m_bitDepth = bitDepthLuma;
#if MCTS_ENC_CHECK
m_roiPosX = roiPosX;
m_roiPosY = roiPosY;
#endif
}
#if MCTS_ENC_CHECK
Void TComPattern::setTileBorders(Int tileLeftTopPelPosX, Int tileLeftTopPelPosY, Int tileRightBottomPelPosX, Int tileRightBottomPelPosY)
{
m_tileLeftTopPelPosX = tileLeftTopPelPosX;
m_tileLeftTopPelPosY = tileLeftTopPelPosY;
m_tileRightBottomPelPosX = tileRightBottomPelPosX;
m_tileRightBottomPelPosY = tileRightBottomPelPosY;
}
#endif
// TODO: move this function to TComPrediction.cpp.
Void TComPrediction::initIntraPatternChType( TComTU &rTu, const ComponentID compID, const Bool bFilterRefSamples DEBUG_STRING_FN_DECLARE(sDebug))
......
......@@ -61,12 +61,30 @@ private:
Int m_patternStride;
Int m_bitDepth;
#if MCTS_ENC_CHECK
Int m_roiPosX;
Int m_roiPosY;
Int m_tileLeftTopPelPosX;
Int m_tileLeftTopPelPosY;
Int m_tileRightBottomPelPosX;
Int m_tileRightBottomPelPosY;
#endif
public:
// ROI & pattern information, (ROI = &pattern[AboveOffset][LeftOffset])
Int getROIYWidth() const { return m_roiWidth; }
Int getROIYHeight() const { return m_roiHeight; }
Int getPatternLStride() const { return m_patternStride; }
Int getBitDepthY() const { return m_bitDepth; }
#if MCTS_ENC_CHECK
Int getROIYPosX() const { return m_roiPosX; }
Int getROIYPosY() const { return m_roiPosY; }
Int getTileLeftTopPelPosX() const { return m_tileLeftTopPelPosX; }
Int getTileLeftTopPelPosY() const { return m_tileLeftTopPelPosY; }
Int getTileRightBottomPelPosX() const { return m_tileRightBottomPelPosX; }
Int getTileRightBottomPelPosY() const { return m_tileRightBottomPelPosY; }
#endif
__inline Pel* getROIY()
{
......@@ -83,6 +101,14 @@ public:
, m_roiHeight(0)
, m_patternStride(0)
, m_bitDepth(0)
#if MCTS_ENC_CHECK
, m_roiPosX(0)
, m_roiPosY(0)
, m_tileLeftTopPelPosX(0)
, m_tileLeftTopPelPosY(0)
, m_tileRightBottomPelPosX(0)
, m_tileRightBottomPelPosY(0)
#endif
{};
......@@ -91,7 +117,12 @@ public:
// -------------------------------------------------------------------------------------------------------------------
/// set parameters from Pel buffers for accessing neighbouring pixels
Void initPattern( Pel* piY, Int roiWidth, Int roiHeight, Int stride, Int bitDepthLuma );
#if MCTS_ENC_CHECK
Void initPattern(Pel* piY, Int roiWidth, Int roiHeight, Int stride, Int bitDepthLuma, Int roiPosX, Int roiPosY);
Void setTileBorders(Int tileLeftTopPelPosX, Int tileLeftTopPelPosY, Int tileRightBottomPelPosX, Int tileRightBottomPelPosY);
#else
Void initPattern(Pel* piY, Int roiWidth, Int roiHeight, Int stride, Int bitDepthLuma);
#endif
};
//! \}
......
......@@ -599,4 +599,22 @@ TComTile::TComTile()
TComTile::~TComTile()
{
}
#if MCTS_ENC_CHECK
Void getTilePosition(const TComDataCU* const pcCU, UInt &tileXPosInCtus, UInt &tileYPosInCtus, UInt &tileWidthtInCtus, UInt &tileHeightInCtus)
{
const UInt currentTileIdx = pcCU->getPic()->getPicSym()->getTileIdxMap(pcCU->getCtuRsAddr());
const TComTile *pCurrentTile = pcCU->getPic()->getPicSym()->getTComTile(currentTileIdx);
const UInt frameWidthInCtus = pcCU->getPic()->getPicSym()->getFrameWidthInCtus();
const UInt firstCtuRsAddrOfTile = pcCU->getPic()->getPicSym()->getTComTile(pcCU->getPic()->getPicSym()->getTileIdxMap(pcCU->getCtuRsAddr()))->getFirstCtuRsAddr();
tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
tileYPosInCtus = firstCtuRsAddrOfTile / frameWidthInCtus;
tileWidthtInCtus = pCurrentTile->getTileWidthInCtus();
tileHeightInCtus = pCurrentTile->getTileHeightInCtus();
}
#endif
//! \}
......@@ -195,5 +195,9 @@ protected:
//! \}
#if MCTS_ENC_CHECK
Void getTilePosition(const TComDataCU* const pcCU, UInt &tileXPosInCtus, UInt &tileYPosInCtus, UInt &tileWidthtInCtus, UInt &tileHeightInCtus);
#endif
#endif // __TCOMPICSYM__
......@@ -824,4 +824,273 @@ Bool TComPrediction::UseDPCMForFirstPassIntraEstimation(TComTU &rTu, const UInt
(uiDirMode==HOR_IDX || uiDirMode==VER_IDX);
}
#if MCTS_ENC_CHECK
Void getRefPUPartPos(TComDataCU* pcCU, TComMv& cMv, Int uiPartIdx, Int& ruiPredXLeft, Int& ruiPredYTop, Int& ruiPredXRight, Int& ruiPredYBottom, Int iWidth, Int iHeight)
{
ruiPredXLeft = pcCU->getCUPelX();
ruiPredYTop = pcCU->getCUPelY();
switch (pcCU->getPartitionSize(0))
{
case SIZE_2NxN:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + (iHeight << 1);
ruiPredYTop += iHeight;
}
break;
case SIZE_Nx2N:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
ruiPredXRight = ruiPredXLeft + (iWidth << 1);
ruiPredYBottom = ruiPredYTop + iHeight;
ruiPredXLeft += iWidth;
}
break;
case SIZE_NxN:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else if (uiPartIdx == 1)
{
ruiPredXRight = ruiPredXLeft + (iWidth << 1);
ruiPredYBottom = ruiPredYTop + iHeight;
ruiPredXLeft += iWidth;
}
else if (uiPartIdx == 2)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + (iHeight << 1);
ruiPredYTop += iHeight;
}
else if (uiPartIdx == 3)
{
ruiPredXRight = ruiPredXLeft + (iWidth << 1);
ruiPredYBottom = ruiPredYTop + (iHeight << 1);
ruiPredXLeft += iWidth;
ruiPredYTop += iHeight;
}
break;
case SIZE_2NxnU:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + pcCU->getHeight(0);
ruiPredYTop += (iHeight / 3);
}
break;
case SIZE_2NxnD:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
Int oriHeight = iHeight << 2;
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + oriHeight;
ruiPredYTop += (oriHeight >> 2) + (oriHeight >> 1);
}
break;
case SIZE_nLx2N:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
ruiPredXRight = ruiPredXLeft + pcCU->getWidth(0);
ruiPredYBottom = ruiPredYTop + iHeight;
ruiPredXLeft += (iWidth / 3);
}
break;
case SIZE_nRx2N:
if (uiPartIdx == 0)
{
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
}
else
{
Int oriWidth = (iWidth << 2);
ruiPredXRight = ruiPredXLeft + oriWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
ruiPredXLeft += (oriWidth >> 2) + (oriWidth >> 1);
}
break;
default:
ruiPredXRight = ruiPredXLeft + iWidth;
ruiPredYBottom = ruiPredYTop + iHeight;
break;
}
ruiPredXLeft += (cMv.getHor() >> 2);
ruiPredYTop += (cMv.getVer() >> 2);
ruiPredXRight += (cMv.getHor() >> 2) - 1;
ruiPredYBottom += (cMv.getVer() >> 2) - 1;
}
Bool checkMVPRange(TComMv& cMv, UInt ctuLength, UInt tileXPosInCtus, UInt tileYPosInCtus, UInt tileWidthtInCtus, UInt tileHeightInCtus, Int PredXLeft, Int PredXRight, Int PredYTop, Int PredYBottom, ChromaFormat chromaFormat)
{
// filter length of sub-sample generation filter to be considered
const UInt LumaLTSampleOffset = 3;
const UInt LumaRBSampleOffset = 4;
const UInt CromaLTSampleoffset = 1;
const UInt CromaRBSampleoffset = 2;
// tile position in full pels
const Int leftTopPelPosX = ctuLength * tileXPosInCtus;
const Int leftTopPelPosY = ctuLength * tileYPosInCtus;
const Int rightBottomPelPosX = ((tileWidthtInCtus + tileXPosInCtus) * ctuLength) - 1;
const Int rightBottomPelPosY = ((tileHeightInCtus + tileYPosInCtus) * ctuLength) - 1;
// Luma MV range check
const Bool isFullPelHorLuma = (cMv.getHor() % 4 == 0);
const Bool isFullPelVerLuma = (cMv.getVer() % 4 == 0);
const Int lRangeXLeft = leftTopPelPosX + (isFullPelHorLuma ? 0 : LumaLTSampleOffset);
const Int lRangeYTop = leftTopPelPosY + (isFullPelVerLuma ? 0 : LumaLTSampleOffset);
const Int lRangeXRight = rightBottomPelPosX - (isFullPelHorLuma ? 0 : LumaRBSampleOffset);
const Int lRangeYBottom = rightBottomPelPosY - (isFullPelVerLuma ? 0 : LumaRBSampleOffset);
if (!(PredXLeft >= lRangeXLeft && PredXLeft <= lRangeXRight) || !(PredXRight >= lRangeXLeft && PredXRight <= lRangeXRight))
{
return false;
}
else if (!(PredYTop >= lRangeYTop && PredYTop <= lRangeYBottom) || !(PredYBottom >= lRangeYTop && PredYBottom <= lRangeYBottom))
{
return false;
}
if ((chromaFormat != CHROMA_444) && (chromaFormat != CHROMA_400))