/*
在進行幀內預測前,對PU的邊界參考像素進行填充及平滑濾波
過程:
1.得到tu的size即size*2
2.取reconYUV
3.對neighbor不可用參考像素進行填充
4.分別取topLeft、topLast、leftLast像素
5.進行平滑濾波
·若tusize爲32x32,且允許強平滑濾波,則使用強平滑濾波
1.計算閾值,並分別取topMiddle和leftMiddle像素值
2.若若上邊的 (最左邊+最右邊)-中間*2小於閾值,且左邊的 (最上邊+最下邊)-中間*2 小於 閾值,則使用強雙線性差值進行平滑濾波
·否則,進行常規平滑濾波
*/
void Predict::initAdiPattern(const CUData& cu, const CUGeom& cuGeom, uint32_t puAbsPartIdx, const IntraNeighbors& intraNeighbors, int dirMode)
{
//得到tu的像素size
int tuSize = 1 << intraNeighbors.log2TrSize;
//得到tu的像素的兩倍
int tuSize2 = tuSize << 1;
//取reconPic
PicYuv* reconPic = cu.m_encData->m_reconPic;
pixel* adiOrigin = reconPic->getLumaAddr(cu.m_cuAddr, cuGeom.absPartIdx + puAbsPartIdx);
intptr_t picStride = reconPic->m_stride;
//進行neighbor不可用參考像素進行填充,輸出到intraNeighbourBuf[0]中
fillReferenceSamples(adiOrigin, picStride, intraNeighbors, intraNeighbourBuf[0]);
pixel* refBuf = intraNeighbourBuf[0]; //unfiltered參考像素
pixel* fltBuf = intraNeighbourBuf[1]; //filtered參考像素
//取左上角像素、上邊的最右邊像素、左邊的最下邊像素
pixel topLeft = refBuf[0], topLast = refBuf[tuSize2], leftLast = refBuf[tuSize2 + tuSize2];
/* 若所有幀內預測方向都允許 && tuSize爲8/16/32之間一種,
或當前tuSize的當前預測方向允許平滑濾波,
則進行平滑濾波 */
if (dirMode == ALL_IDX ? (8 | 16 | 32) & tuSize : g_intraFilterFlags[dirMode] & tuSize)
{
// generate filtered intra prediction samples
//使用強幀內預測平滑 && tusize爲32x32pixel,則進行強平滑濾波
if (cu.m_slice->m_sps->bUseStrongIntraSmoothing && tuSize == 32)
{
//計算閾值
const int threshold = 1 << (X265_DEPTH - 5);
//取上邊的中間像素,左邊的中間像素
pixel topMiddle = refBuf[32], leftMiddle = refBuf[tuSize2 + 32];
/* 若上邊的 (最左邊+最右邊)-中間*2 小於 閾值,
且左邊的 (最上邊+最下邊)-中間*2 小於 閾值,
則使用強雙線性差值進行平滑濾波 */
if (abs(topLeft + topLast - (topMiddle << 1)) < threshold &&
abs(topLeft + leftLast - (leftMiddle << 1)) < threshold)
{
// "strong" bilinear interpolation 使用強雙線性插值
const int shift = 5 + 1;
int init = (topLeft << shift) + tuSize;
int deltaL, deltaR;
//Δleft = 左邊最下邊-左邊最上邊,Δtop = 上邊最右邊-上邊最左邊
deltaL = leftLast - topLeft; deltaR = topLast - topLeft;
//最左上角,即左邊最上,上邊最左,像素不進行平滑濾波,直接輸出
fltBuf[0] = topLeft;
//遍歷2倍size長度邊界參考像素
for (int i = 1; i < tuSize2; i++)
{
//左邊平滑濾波,輸出到fltBuf中
fltBuf[i + tuSize2] = (pixel)((init + deltaL * i) >> shift); // Left Filtering
//上邊平滑濾波,輸出到fltBuf中
fltBuf[i] = (pixel)((init + deltaR * i) >> shift); // Above Filtering
}
//上邊最下不進行平滑濾波
fltBuf[tuSize2] = topLast;
//左邊最下不進行平滑濾波
fltBuf[tuSize2 + tuSize2] = leftLast;
return;
}
}
//對參考像素refBuf進行常規的平滑過濾,輸出到fltBuf中
primitives.cu[intraNeighbors.log2TrSize - 2].intra_filter(refBuf, fltBuf);
}
}
Predict::initAdiPattern()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.