Commit c14437d3 authored by Xiang Li's avatar Xiang Li

Merge branch 'JVET-R0350' into 'master'

JVET-R0350: MIP for chroma in case of 4:4:4 format and single tree

See merge request jvet/VVCSoftware_VTM!1549
parents 3f33c612 325fd5ed
......@@ -217,6 +217,9 @@ void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, co
const int iWidth = piPred.width;
const int iHeight = piPred.height;
CHECK(iWidth == 2, "Width of 2 is not supported");
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
CHECK(PU::isMIP(pu, toChannelType(compId)), "We should not get here for MIP.");
#endif
const uint32_t uiDirMode = isLuma( compId ) && pu.cu->bdpcmMode ? BDPCM_IDX : !isLuma(compId) && pu.cu->bdpcmModeChroma ? BDPCM_IDX : PU::getFinalIntraMode(pu, channelType);
CHECK( floorLog2(iWidth) < 2 && pu.cs->pcv->noChroma2x2, "Size not allowed" );
......@@ -1836,24 +1839,62 @@ void IntraPrediction::initIntraMip( const PredictionUnit &pu, const CompArea &ar
// prepare input (boundary) data for prediction
CHECK( m_ipaParam.refFilterFlag, "ERROR: unfiltered refs expected for MIP" );
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
Pel *ptrSrc = getPredictorPtr(area.compID);
const int srcStride = m_refBufferStride[area.compID];
const int srcHStride = 2;
m_matrixIntraPred.prepareInputForPred(CPelBuf(ptrSrc, srcStride, srcHStride), area,
pu.cu->slice->getSPS()->getBitDepth(toChannelType(area.compID)), area.compID);
#else
Pel *ptrSrc = getPredictorPtr( COMPONENT_Y );
const int srcStride = m_refBufferStride[COMPONENT_Y];
const int srcHStride = 2;
m_matrixIntraPred.prepareInputForPred( CPelBuf( ptrSrc, srcStride, srcHStride ), area, pu.cu->slice->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ) );
#endif
}
void IntraPrediction::predIntraMip( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu )
{
#if !JVET_R0350_MIP_CHROMA_444_SINGLETREE
CHECK( compId != COMPONENT_Y, "Error: chroma not supported" );
#endif
CHECK( piPred.width > MIP_MAX_WIDTH || piPred.height > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" );
CHECK( piPred.width != (1 << floorLog2(piPred.width)) || piPred.height != (1 << floorLog2(piPred.height)), "Error: expecting blocks of size 2^M x 2^N" );
// generate mode-specific prediction
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
uint32_t modeIdx = MAX_NUM_MIP_MODE;
bool transposeFlag = false;
if (compId == COMPONENT_Y)
{
modeIdx = pu.intraDir[CHANNEL_TYPE_LUMA];
transposeFlag = pu.mipTransposedFlag;
}
else
{
const PredictionUnit &coLocatedLumaPU = PU::getCoLocatedLumaPU(pu);
CHECK(pu.intraDir[CHANNEL_TYPE_CHROMA] != DM_CHROMA_IDX, "Error: MIP is only supported for chroma with DM_CHROMA.");
CHECK(!coLocatedLumaPU.cu->mipFlag, "Error: Co-located luma CU should use MIP.");
modeIdx = coLocatedLumaPU.intraDir[CHANNEL_TYPE_LUMA];
transposeFlag = coLocatedLumaPU.mipTransposedFlag;
}
const int bitDepth = pu.cu->slice->getSPS()->getBitDepth(toChannelType(compId));
CHECK(modeIdx >= getNumModesMip(piPred), "Error: Wrong MIP mode index");
#else
const int bitDepth = pu.cu->slice->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA );
#endif
static_vector<int, MIP_MAX_WIDTH* MIP_MAX_HEIGHT> predMip( piPred.width * piPred.height );
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
m_matrixIntraPred.predBlock(predMip.data(), modeIdx, transposeFlag, bitDepth, compId);
#else
m_matrixIntraPred.predBlock( predMip.data(), pu.intraDir[CHANNEL_TYPE_LUMA], pu.mipTransposedFlag, bitDepth );
#endif
for( int y = 0; y < piPred.height; y++ )
{
......
......@@ -43,6 +43,9 @@
MatrixIntraPrediction::MatrixIntraPrediction():
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
m_component(MAX_NUM_COMPONENT),
#endif
m_reducedBoundary (MIP_MAX_INPUT_SIZE),
m_reducedBoundaryTransposed(MIP_MAX_INPUT_SIZE),
m_inputOffset ( 0 ),
......@@ -58,9 +61,16 @@ MatrixIntraPrediction::MatrixIntraPrediction():
{
}
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area &block, const int bitDepth,
const ComponentID compId)
{
m_component = compId;
#else
void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area& block, const int bitDepth)
{
#endif
// Step 1: Save block size and calculate dependent values
initPredBlockParams(block);
......@@ -114,8 +124,16 @@ void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area&
}
}
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
void MatrixIntraPrediction::predBlock(int *const result, const int modeIdx, const bool transpose, const int bitDepth,
const ComponentID compId)
{
CHECK(m_component != compId, "Boundary has not been prepared for this component.");
#else
void MatrixIntraPrediction::predBlock(int* const result, const int modeIdx, const bool transpose, const int bitDepth)
{
#endif
const bool needUpsampling = ( m_upsmpFactorHor > 1 ) || ( m_upsmpFactorVer > 1 );
const uint8_t* matrix = getMatrixData(modeIdx);
......
......@@ -50,10 +50,20 @@ class MatrixIntraPrediction
public:
MatrixIntraPrediction();
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
void prepareInputForPred(const CPelBuf &pSrc, const Area &block, const int bitDepth, const ComponentID compId);
void predBlock(int *const result, const int modeIdx, const bool transpose, const int bitDepth,
const ComponentID compId);
#else
void prepareInputForPred(const CPelBuf &pSrc, const Area& block, const int bitDepth);
void predBlock(int* const result, const int modeIdx, const bool transpose, const int bitDepth);
#endif
private:
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
ComponentID m_component;
#endif
static_vector<int, MIP_MAX_INPUT_SIZE> m_reducedBoundary; // downsampled boundary of a block
static_vector<int, MIP_MAX_INPUT_SIZE> m_reducedBoundaryTransposed; // downsampled, transposed boundary of a block
int m_inputOffset;
......
......@@ -81,6 +81,8 @@
#define JVET_R0156_ASPECT3_SPS_CLEANUP 1 // Condition sps_sublayer_dpb_params_flag on sps_ptl_dpb_hrd_params_present_flag, in addition to sps_max_sublayer_minus1, JVET-R0156 proposal 3, JVET-R0170, JVET-R0222 proposal 2
#define JVET_R0350_MIP_CHROMA_444_SINGLETREE 1 // JVET-R0350: MIP for chroma in case of 4:4:4 format and single tree
//########### place macros to be be kept below this line ###############
#define JVET_R0164_MEAN_SCALED_SATD 1 // JVET-R0164: Use a mean scaled version of SATD in encoder decisions
......
......@@ -553,9 +553,27 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType
bool PU::isMIP(const PredictionUnit &pu, const ChannelType &chType)
{
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
if (chType == CHANNEL_TYPE_LUMA)
{
// Default case if chType is omitted.
return pu.cu->mipFlag;
}
else
{
return isDMChromaMIP(pu) && (pu.intraDir[CHANNEL_TYPE_CHROMA] == DM_CHROMA_IDX);
}
#else
return (chType == CHANNEL_TYPE_LUMA && pu.cu->mipFlag);
#endif
}
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
bool PU::isDMChromaMIP(const PredictionUnit &pu)
{
return !pu.cu->isSepTree() && (pu.chromaFormat == CHROMA_444) && getCoLocatedLumaPU(pu).cu->mipFlag;
}
#endif
uint32_t PU::getIntraDirLuma( const PredictionUnit &pu )
{
......@@ -582,6 +600,14 @@ void PU::getIntraChromaCandModes( const PredictionUnit &pu, unsigned modeList[NU
modeList[6] = MDLM_T_IDX;
modeList[7] = DM_CHROMA_IDX;
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
// If Direct Mode is MIP, mode cannot be already in the list.
if (isDMChromaMIP(pu))
{
return;
}
#endif
const uint32_t lumaMode = getCoLocatedIntraLumaMode(pu);
for( int i = 0; i < 4; i++ )
{
......@@ -638,6 +664,23 @@ uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chT
return uiIntraMode;
}
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
const PredictionUnit &PU::getCoLocatedLumaPU(const PredictionUnit &pu)
{
Position topLeftPos = pu.blocks[pu.chType].lumaPos();
Position refPos = topLeftPos.offset(pu.blocks[pu.chType].lumaSize().width >> 1,
pu.blocks[pu.chType].lumaSize().height >> 1);
const PredictionUnit &lumaPU = pu.cu->isSepTree() ? *pu.cs->picture->cs->getPU(refPos, CHANNEL_TYPE_LUMA)
: *pu.cs->getPU(topLeftPos, CHANNEL_TYPE_LUMA);
return lumaPU;
}
uint32_t PU::getCoLocatedIntraLumaMode(const PredictionUnit &pu)
{
return PU::getIntraDirLuma(PU::getCoLocatedLumaPU(pu));
}
#else
uint32_t PU::getCoLocatedIntraLumaMode( const PredictionUnit &pu )
{
Position topLeftPos = pu.blocks[pu.chType].lumaPos();
......@@ -646,6 +689,7 @@ uint32_t PU::getCoLocatedIntraLumaMode( const PredictionUnit &pu )
return PU::getIntraDirLuma( lumaPU );
}
#endif
int PU::getWideAngIntraMode( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID )
{
......
......@@ -129,8 +129,14 @@ namespace PU
int getLMSymbolList(const PredictionUnit &pu, int *modeList);
int getIntraMPMs(const PredictionUnit &pu, unsigned *mpm, const ChannelType &channelType = CHANNEL_TYPE_LUMA);
bool isMIP (const PredictionUnit &pu, const ChannelType &chType = CHANNEL_TYPE_LUMA);
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
bool isDMChromaMIP (const PredictionUnit &pu);
#endif
uint32_t getIntraDirLuma (const PredictionUnit &pu);
void getIntraChromaCandModes (const PredictionUnit &pu, unsigned modeList[NUM_CHROMA_MODE]);
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
const PredictionUnit &getCoLocatedLumaPU(const PredictionUnit &pu);
#endif
uint32_t getFinalIntraMode (const PredictionUnit &pu, const ChannelType &chType);
uint32_t getCoLocatedIntraLumaMode (const PredictionUnit &pu);
int getWideAngIntraMode ( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID );
......
......@@ -4956,6 +4956,16 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
predIntraChromaLM( COMPONENT_Cb, piPredCb, pu, cbArea, predMode );
predIntraChromaLM( COMPONENT_Cr, piPredCr, pu, crArea, predMode );
}
#if JVET_R0350_MIP_CHROMA_444_SINGLETREE
else if (PU::isMIP(pu, CHANNEL_TYPE_CHROMA))
{
initIntraMip(pu, cbArea);
predIntraMip(COMPONENT_Cb, piPredCb, pu);
initIntraMip(pu, crArea);
predIntraMip(COMPONENT_Cr, piPredCr, pu);
}
#endif
else
{
predIntraAng( COMPONENT_Cb, piPredCb, pu);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment