- HEVC CCP回顾
- CCP是HEVC Range Extension标准中的技术,是基于线性模型 (Linear Mode, LM)的色度分量预测优化技术,其目的是降低颜色分量残差信号之间的数据相关性,且该技术仅作用于采样空间为 4:4:4的视频序列。
- RGB 颜色空间的视频序列,其颜色分量之间存在大量的数据冗余,一般通过将其转换为 YCbCr 颜色空间。但是,转换后的颜色分量之间仍存在一定的数据相关性。因此,一种基于线性模型的色度分量预测优化技术在 JCT-VC 会议中被提出。在该线性模型中,实际预测值 y 的计算方式为,y = a * x + b,其中, x 为根据预测得到的色度分量原始预测值, a、b为线性模型的参数, 且a为权重,b为预测偏移值。
- 参考文献:
A. Khairat, T. Nguyen, M. Siekmann, D. Marpe, and T. Wiegand, Adaptive Cross-Component Prediction for 4:4:4 High Efficiency Video Coding, IEEE International Conference on Image Processing (ICIP 2014), Paris, Oct 27-30, 2014.
T. Nguyen, A. Khairat, D. Marpe, M. Siekmann, and T. Wiegand, Extended Cross-Component Prediction in HEVC, Picture Coding Symposium, Cairns, Australia, 2015, pp. 164–168.
Cross-Component Prediction in HEVC Range Extensions与该paper对应的中文博客:HEVC帧内/帧间预测:Cross-Component Prediction (CCP)
- JVET中的CCP
- 扩展到Cr的预测由预测原始值与Cb的重构残差值预测得到(HEVC中都是chroma由Luma预测得到):predCr = predCr + a * resiCb
- chroma intra prediction mode增加了一种LM模式,用于从下采样的luma recontruct值来计算chroma分量的预测值:predC = a * recL + b
JEM中代码实现
- 详见宏
COM16_C806_LMCHROMA
- 采样空间限制
//仅对420格式使用
if (m_chromaFormatIDC != CHROMA_420)
{
if (m_useLMChroma)
{
printf("LMChroma must be off for non-420 chroma format input\n");
m_useLMChroma = false;
}
}
- 增加一种chroma预测的方式,即planar,dc,ver, hor + LM + DM,由5种扩展成6种
- SPS增加
cross_component_prediction_enabled_flag
- 关键函数
xIntraCodingTUBlock
//chroma is LM, then use downsampled luma & LM parameter for predictor
//if not use LM, and the component is Cr, and LM parameter a < 0, then use Cb resi & LM paramter for predictor
#if COM16_C806_LMCHROMA
if( uiChFinalMode == LM_CHROMA_IDX )
{
//get downsampled luma recontructed values
getLumaRecPixels( rTu, uiWidth, uiHeight );
predLMIntraChroma( rTu, compID, piPred, uiStride, uiWidth, uiHeight );
}
else
{
#endif
predIntraAng( compID, uiChFinalMode, piOrg, uiStride, piPred, uiStride, rTu, bUseFilteredPredictions );
#if COM16_C806_LMCHROMA
if( compID == COMPONENT_Cr && pcCU->getSlice()->getSPS()->getUseLMChroma() )
{
addCrossColorResi( rTu, compID, piPred, uiStride, uiWidth, uiHeight, pcResiYuv->getAddr( COMPONENT_Cb, uiAbsPartIdx ), pcResiYuv->getStride(COMPONENT_Cb) );
}
}
#endif
- LM参数的计算方式,见函数xGetLMParameters
//pred chroma from luma, in predLMIntraChroma()
if (iPredType == 0) //chroma from luma
{
iSrcStride = m_iLumaRecStride;
pSrcColor0 = m_pLumaRecBuffer + iSrcStride + 1;
pCurChroma0 = m_piYuvExt[compID][PRED_BUF_UNFILTERED];
iCurStride = 2 * uiWidth+ 1;
pCurChroma0 += iCurStride + 1;
}
else
//pred cr from cb, in addCrossColorResi
{
assert (compID == COMPONENT_Cr);
// pSrcColor0 = pcPattern->getAdiCbBuf( uiWidth, uiHeight, getPredicBuf() );
pSrcColor0 = m_piYuvExt[COMPONENT_Cb][PRED_BUF_UNFILTERED];
pCurChroma0 = m_piYuvExt[COMPONENT_Cr][PRED_BUF_UNFILTERED];
// pCurChroma0 = pcPattern->getAdiCrBuf( uiWidth, uiHeight, getPredicBuf() );
iSrcStride = 2 * uiWidth+ 1;
iCurStride = 2 * uiWidth+ 1;
pSrcColor0 += iSrcStride + 1;
pCurChroma0 += iCurStride + 1;
}
Int x = 0, y = 0, xx = 0, xy = 0;
Int i, j;
Int iCountShift = 0;
UInt uiInternalBitDepth = sps.getBitDepth(CHANNEL_TYPE_CHROMA);
Pel *pSrc = pSrcColor0 - iSrcStride;
Pel *pCur = pCurChroma0 - iCurStride;
//calculate sum of src, cur, src* src, src*cur
if (bAboveAvaillable)
{
for( j = 0; j < uiWidth; j++ )
{
x += pSrc[j];
y += pCur[j];
xx += pSrc[j] * pSrc[j];
xy += pSrc[j] * pCur[j];
}
}if (bLeftAvaillable)
{
pSrc = pSrcColor0 - 1;
pCur = pCurChroma0 - 1;for( i = 0; i < uiHeight; i++ )
{
x += pSrc[0];
y += pCur[0];
xx += pSrc[0] * pSrc[0];
xy += pSrc[0] * pCur[0];pSrc += iSrcStride;
pCur += iCurStride;
}
}if (bLeftAvaillable && bAboveAvaillable)
{
iCountShift = g_aucConvertToBit[ uiWidth ] + 3;
}
else if (bLeftAvaillable || bAboveAvaillable)
{
iCountShift = g_aucConvertToBit[ uiWidth ] + 2;
}
else
{
a = 0;
if (iPredType == 0)
{
b = 1 << (uiInternalBitDepth - 1);
}
else
{
b = 0;
}
iShift = 0;
return;
}Int iTempShift = uiInternalBitDepth + iCountShift - 15;
if( iTempShift > 0 )
{
x = ( x + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
y = ( y + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
iCountShift -= iTempShift;
}// LLS parameters estimation –>
xCalcLMParameters( x, y, xx, xy, iCountShift, iPredType, uiInternalBitDepth, a, b, iShift );
- lambda设置,见宏
COM16_C806_CR_FROM_CB_LAMBDA_ADJUSTMENT
//cb lambda * 15/16, cr lambda *16/15
if ( uiChFinalMode != LM_CHROMA_IDX && pcCU->getSlice()->getSPS()->getUseLMChroma() )
{
if (compID == COMPONENT_Cb)
{
m_pcTrQuant->setLambda ( m_pcTrQuant->getlambda() * 15/16);
}
else if (compID == COMPONENT_Cr)
{
m_pcTrQuant->setLambda ( m_pcTrQuant->getlambda() * 16/15);
}
}
- 详见宏