1.术语
- IPP:Inter plane prediction
- CCP:Cross component predition
-
CCLM:Cross-component linear model prediction
-
CfL:Chroma from luma
2.背景
因为原来发的paper是基于RGB编码,看过相关性的paper;也就在那段时间,range extension software引入了CCP。
最早是RGB编码中的inter plane prediction,由Woo-Shik Kim搞出来的。265时代,被引入HEVC range extension,技术命名为cross component prediction,至此主要还是支持444 format;到了266、av1时代,JEM和BMS,改名为cross-component linear model prediction,增加了下采样对YUV420 format的支持,而AV1中叫chroma from luma,由Mozilla贡献;后面的提案又引入的5种enhanced linear model,在最近的会议中,enhanced linear model并没有被接受,仅保留CCLM。
但换汤不换药,最根源的思想还是在去除分量间的相关性。
E0077:enhanced linear model
K0190:only keep CCLM
3.算法详解
4.代码
预测流程
//! 预测流程
//! 调用1:编码:模式预测
//! 调用2:编码:实际编码
//! 调用3:解码:重构
...
//===== get prediction signal =====
#if COM16_C806_LMCHROMA
if( uiChFinalMode == LM_CHROMA_IDX )///< 使用cclm mode
{
predLMIntraChroma(rTu, compID, piPred, uiStride, uiWidth, uiHeight);
}
else ///< 使用正常intra mode
{
#endif
predIntraAng( compID, uiChFinalMode, piOrg, uiStride, piPred, uiStride, rTu, bUseFilteredPredictions );
#if COM16_C806_LMCHROMA
if( compID == COMPONENT_Cr && pcCU->getSlice()->getSPS()->getUseLMChroma() )
{ ///< Cb-to-Cr
addCrossColorResi( rTu, compID, piPred, uiStride, uiWidth, uiHeight, pcResiYuv->getAddr( COMPONENT_Cb, uiAbsPartIdx ), pcResiYuv->getStride(COMPONENT_Cb) );
}
}
#endif
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
预测流程之Luma-to-Chroma
Void TComPrediction::predLMIntraChroma( TComTU& rTu, const ComponentID compID, Pel* pPred, UInt uiPredStride, UInt uiCWidth, UInt uiCHeight )
{
// LLS parameters estimation -->
Int a, b, iShift;
xGetLMParameters( rTu, compID, uiCWidth, uiCHeight, 0, a, b, iShift );
// get prediction -->
Int iLumaStride = m_iLumaRecStride;
Pel *pLuma = m_pLumaRecBuffer + iLumaStride + 1;
for( Int i = 0; i < uiCHeight; i++ )
{
for( Int j = 0; j < uiCWidth; j++ )
{
pPred[j] = Clip3(0, maxV, ( ( a * pLuma[j] ) >> iShift ) + b );
}
pPred += uiPredStride;
pLuma += iLumaStride;
}
// <-- end of get prediction
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
预测流程之Cb-to-Cr
//! Cb residual predict Cr residual
Void TComPrediction::addCrossColorResi( TComTU& rTu, const ComponentID compID, Pel* piPred, UInt uiPredStride, UInt uiWidth, UInt uiHeight, Pel* piResi, UInt uiResiStride )
{
Int a, b, iShift;
xGetLMParameters( rTu, compID, uiWidth, uiHeight, 1, a, b, iShift ); ///< cb-to-cr lambda
Int offset = 1 << (iShift - 1);
if (a >= 0)
{
return;
}
Pel* pPred = piPred; ///< [out]Cr resi pred
Pel* pResi = piResi; ///< [in]Cb resi
for( UInt uiY = 0; uiY < uiHeight; uiY++ )
{
for( UInt uiX = 0; uiX < uiWidth; uiX++ )
{
pPred[ uiX ] = Clip3(0, maxV, pPred[ uiX ] + (( pResi[ uiX ] * a + offset) >> iShift ) );
}
pPred += uiPredStride;
pResi += uiResiStride;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
预测之线性模型参数推算
//! 生成线性模型的参数
Void TComPrediction::xCalcLMParameters( Int x, Int y, Int xx, Int xy, Int iCountShift, Int iPredType, Int bitDepth, Int &a, Int &b, Int &iShift );
- 1
- 2
-
Chroma from Luma
-
Cr from Cb
whereλ=∑(Cb(n)?Cb(n))>>9λ=∑(Cb(n)?Cb(n))>>9
熵编码
Void TEncSbac::codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
{
UInt uiIntraDirChroma = pcCU->getIntraDir( CHANNEL_TYPE_CHROMA, uiAbsPartIdx );
if( uiIntraDirChroma == DM_CHROMA_IDX )
{
m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, 0 ) ); ///< dm
}
#if COM16_C806_LMCHROMA
else if( uiIntraDirChroma == LM_CHROMA_IDX && pcCU->getSlice()->getSPS()->getUseLMChroma() )
{
m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, 0 ) );
m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, 1 ) ); ///< cclm
}
#endif
else
{
m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, 0 ) );
#if COM16_C806_LMCHROMA
if (pcCU->getSlice()->getSPS()->getUseLMChroma())
{
m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, 1 )); ///< intra pred mode
}
#endif
UInt uiAllowedChromaDir[ NUM_CHROMA_MODE ];
pcCU->getAllowedChromaDir( uiAbsPartIdx, uiAllowedChromaDir );
#if COM16_C806_LMCHROMA
for( Int i = 0; i < NUM_CHROMA_MODE - 2; i++ )
#endif
{
if( uiIntraDirChroma == uiAllowedChromaDir[i] )
{
uiIntraDirChroma = i;
break;
}
}
m_pcBinIf->encodeBinsEP( uiIntraDirChroma, 2 );
}
return;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 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
熵解码
Void TDecSbac::parseIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
{
UInt uiSymbol;
m_pcTDecBinIf->decodeBin( uiSymbol, m_cCUChromaPredSCModel.get( 0, 0, 0 ) RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(ctype) );
if( uiSymbol == 0 ) ///< dm
{
uiSymbol = DM_CHROMA_IDX;
}
else
{
#if COM16_C806_LMCHROMA
if( pcCU->getSlice()->getSPS()->getUseLMChroma() )
{
m_pcTDecBinIf->decodeBin( uiSymbol, m_cCUChromaPredSCModel.get( 0, 0, 1 ) RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(ctype) );
}
else
{
uiSymbol = 1;
}
if( uiSymbol == 0 ) ///< cclm
{
uiSymbol = LM_CHROMA_IDX;
}
else ///< intra pred mode
{
#endif
UInt uiIPredMode;
m_pcTDecBinIf->decodeBinsEP( uiIPredMode, 2 RExt__DECODER_DEBUG_BIT_STATISTICS_PASS_OPT_ARG(ctype) );
UInt uiAllowedChromaDir[ NUM_CHROMA_MODE ];
pcCU->getAllowedChromaDir( uiAbsPartIdx, uiAllowedChromaDir );
uiSymbol = uiAllowedChromaDir[ uiIPredMode ];
#if COM16_C806_LMCHROMA
}
#endif
}
pcCU->setIntraDirSubParts( CHANNEL_TYPE_CHROMA, uiSymbol, uiAbsPartIdx, uiDepth );
}