H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng_liaojq2020的博客-优快云博客
VVC学习之五:帧内预测——67个模式预测信号生成 predIntraAng()_Aidoneus_y的博客-优快云博客
piPred:里面有W,H,Stride三个参数,建议在最边缘有填充的CTU时运行一下,看一下具体操作
void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu)
{
const ComponentID compID = MAP_CHROMA( compId );
const ChannelType channelType = toChannelType( compID );
const int iWidth = piPred.width;
const int iHeight = piPred.height;
CHECK(iWidth == 2, "Width of 2 is not supported");
CHECK(PU::isMIP(pu, toChannelType(compId)), "We should not get here for MIP.");
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" );
CHECK( floorLog2(iWidth) > 7, "Size not allowed" );
const int srcStride = m_refBufferStride[compID];
const int srcHStride = 2;
const CPelBuf & srcBuf = CPelBuf(getPredictorPtr(compID), srcStride, srcHStride);
const ClpRng& clpRng(pu.cu->cs->slice->clpRng(compID));//嵌位的范围
/************ 根据模式进入对应的操作 ************/
switch (uiDirMode)
{
case(PLANAR_IDX): xPredIntraPlanar(srcBuf, piPred); break;
case(DC_IDX): xPredIntraDc(srcBuf, piPred, channelType, false); break;
case(BDPCM_IDX): xPredIntraBDPCM(srcBuf, piPred, isLuma(compID) ? pu.cu->bdpcmMode : pu.cu->bdpcmModeChroma, clpRng); break;
default: xPredIntraAng(srcBuf, piPred, channelType, clpRng); break;
}
uiDirMode:亮度BDPCM模式?BDPCM_IDX:色度BDPCM模式?BDPCM_IDX:getFinalIntraMode()
getFinalIntraMode():如果是色度,进行预测模式转换:0~66.解析在最后
srcStride :从m_refBufferStride[compID],根据分量的不同,从参考像素步长缓冲区取出值。所以应该是左或上的参考像素的长度,值为当前区域的(宽或高)*2+1.因为有一个最左上像素。以块为64X64为例,srcStride =129
这里给出HEVC中的定义:
\param srcStride the stride of the reconstructed sample array
重建像素数组的步长,重建像素也被当成参考像素
还可以参考H.266/VVC代码学习:帧内预测之角度预测函数(predIntraAng、xPredIntraAng)_涵小呆的博客-优快云博客_vvc 帧内预测
H.266/VVC代码学习20:角度预测入口 / 特殊模式的PDPC技术(predIntraAng)_海洋之心。的博客-优快云博客
srcHStride:这个2代表有两条参考像素,上边和左边。如果用了MRL可能会有变化,srcBuf存了上边和左边参考像素的信息
srcBuf:存储了当前块预测要用的参考像素,第0行存的是上边的参考像素,第1行存的是左边的参考像素
ClpRng:clip range,应该是截取范围的意思
getPredictorPtr():ptr应该是pointer的意思。这个函数根据refFilterFlag的不同,返回滤波与未滤波的参考像素
/************ PDDC模式(当前仅对planar.DC模式) ************/
if (m_ipaParam.applyPDPC)
{
PelBuf dstBuf = piPred;
const int scale = ((floorLog2(iWidth) - 2 + floorLog2(iHeight) - 2 + 2) >> 2);//缩放
CHECK(scale < 0 || scale > 31, "PDPC: scale < 0 || scale > 31");
if (uiDirMode == PLANAR_IDX || uiDirMode == DC_IDX)
{
for (int y = 0; y < iHeight; y++)
{
const int wT = 32 >> std::min(31, ((y << 1) >> scale));//距离大于32,则权重就为0
const Pel left = srcBuf.at(y + 1, 1);
for (int x = 0; x < iWidth; x++)
{
const int wL = 32 >> std::min(31, ((x << 1) >> scale));
const Pel top = srcBuf.at(x + 1, 0);
const Pel val = dstBuf.at(x, y);
dstBuf.at(x, y) = val + ((wL * (left - val) + wT * (top - val) + 32) >> 6);
}
}
}
}
}
H.266/VVC技术学习:帧内预测之PDPC技术_涵小呆的博客-优快云博客
WT:当前测试像素与最上方参考像素的权重
WL:当前测试像素与最左方参考像素的权重。举例,x,y(0,0)时,WL=32,但x,y(10,0)时,WL=1,因为当前预测像素离左边参考像素过远,所以权重下降
注意:left,top读取的是srcBuf中的值,并不是整个块的dstBuf。所以这里也表示,srcBuf中第0列存的是上边的参考像素,第1列存的是左边的参考像素,有点像一个二维数组
注意:因为看了后面的xPredIntraPlanar()函数,有点对不上。所以推测srcBuf[0,0],srcBuf[0,0],都存的是同一个值,是两个参考像素共有的最左上角像素。在进行PDPC时,未计算最左上角像素的权重。
举例,当前预测像素(x,y)为(0,0),left为srcBuf.at(1, 1),即(-1,0),top为srcBuf.at(x + 1, 0),即(0,-1),刚好对应
VAL:当前预测像素(x,y)的像素值,注意,这里读取的是dstBuf
dstBuf.at(x, y):经过PDPC后的预测值(当前公式仅适用于planar,DC模式。其他的有变化)
1.2 getFinalIntraMode()函数解析
uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chType )
{
//当前测试模式
uint32_t uiIntraMode = pu.intraDir[chType];
//当前预测模式为70且为色度,由函数决定
if( uiIntraMode == DM_CHROMA_IDX && !isLuma( chType ) )
{
uiIntraMode = getCoLocatedIntraLumaMode(pu);
}
//若为422,色度,测试模式小于67.
//422的一个表做转换得出测试模式序号
if( pu.chromaFormat == CHROMA_422 && !isLuma( chType ) && uiIntraMode < NUM_LUMA_MODE ) // map directional, planar and dc
{
uiIntraMode = g_chroma422IntraAngleMappingTable[uiIntraMode];
}
return uiIntraMode;
}
H.266/VVC代码学习14:色度列表及DM模式代码(getFinalIntraMode、getIntraChromaCandModes)_海洋之心。的博客-优快云博客
DM_CHROMA_IDX:derived mode (DM),由亮度模式导出的色度模式号,DM_CHROMA_IDX =(NUM_LUMA_MODE + NUM_LMC_MODE)
getCoLocatedLumaPU():之后写,这个是用在色度预测里的
返回当前的预测模式序号