initIntraPatternChType函数在帧内预测的过程中会被调用,完成当前块帧内预测参考像素模板的初始化工作。
initIntraPatternChType用来准备好帧内预测过程中需要用到的当前pu左侧和上侧的参考像素。
获取当前pu的参考模板像素,存入m_piYuvExt,之后对参考像素滤波,存入m_piYuvExt,这些过程其实和书上说的过程是差不多的。
相比于VTM1,由于MRL模式,xFillReferenceSamples函数中参考模板像素的获取以及补全具体操作发生了一点改变。
void IntraPrediction::initIntraPatternChType(const CodingUnit &cu, const CompArea &area, const bool bFilterRefSamples)
{
const CodingStructure& cs = *cu.cs;
Pel *refBufUnfiltered = m_piYuvExt[area.compID][PRED_BUF_UNFILTERED]; //获取到的未滤波参考像素
Pel *refBufFiltered = m_piYuvExt[area.compID][PRED_BUF_FILTERED]; //滤波后的参考像素
//注意,refBufUnfiltered和refBufFiltered的像素指针,所指都在左上第一个参考像素位置
setReferenceArrayLengths(area); //设置当前块左侧和上侧参考像素的长度
// ----- Step 1: unfiltered reference samples ------ //由重建像素获取当前pu的参考模板像素
xFillReferenceSamples( cs.picture->getRecoBuf( area ), refBufUnfiltered, area, cu ); //获取当前pu的参考像素
// ----- Step 2: filtered reference samples -----
if( bFilterRefSamples ) //参考像素是否滤波
{
xFilterReferenceSamples( refBufUnfiltered, refBufFiltered, area, *cs.sps //对获取到的没有滤波的参考像素进行滤波
#if JVET_L0283_MULTI_REF_LINE
, cu.firstPU->multiRefIdx
#endif
);
}
}
xFillReferenceSamples函数填充帧内预测过程中左侧和上侧的参考像素模板。
参考像素模板为当前pu的左侧、左下、上侧、右上、左上的像素信息,其中左下和右上的参考像素模板长度分别为pu.width和pu.hight,即左和上的参考像素长度,都为width+height。左上的那个参考像素,可以看做归并到上面的参考像素,长度为unitWidth,函数中有体现。
由于宏JVET_L0283_MULTI_REF_LINE开启,所以删掉了一些无用代码。
函数本身流程相比于VTM1中基本没有变化。
由于MRL模式,参考模板像素的获取以及补全具体操作发生了一点改变。
void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu )
{
const ChannelType chType = toChannelType( area.compID );
const CodingStructure &cs = *cu.cs;
const SPS &sps = *cs.sps;
const PreCalcValues &pcv = *cs.pcv;
#if JVET_L0283_MULTI_REF_LINE
const int multiRefIdx = (area.compID == COMPONENT_Y) ? cu.firstPU->multiRefIdx : 0;
#endif //MRL模式的multiRefIdx
const int tuWidth = area.width;
const int tuHeight = area.height;
const int predSize = m_topRefLength; //2*width
const int predHSize = m_leftRefLength; //2*height
#if JVET_L0283_MULTI_REF_LINE
#if JVET_L0279_WAIP_CLEANUP
int whRatio = std::max(1, tuWidth / tuHeight);
int hwRatio = std::max(1, tuHeight / tuWidth);
const int predStride = predSize + 1 + (whRatio + 1) * multiRefIdx; //参考像素的stride
#else
const int predStride = predSize + 1 + 5 * multiRefIdx;
#endif
#else
const int predStride = predSize + 1;
#endif
const bool noShift = pcv.noChroma2x2 && area.width == 4; // don't shift on the lowest level (chroma not-split)
const int unitWidth = pcv.minCUWidth >> (noShift ? 0 : getComponentScaleX( area.compID, sps.getChromaFormatIdc() ));//VTM处理的最小块大小
const int unitHeight = pcv.minCUHeight >> (noShift ? 0 : getComponentScaleY( area.compID, sps.getChromaFormatIdc() ));//亮度4x4,色度2x2
const int totalAboveUnits = (predSize + (un