跨分支線性模型(Cross-component linear model,CCLM)預測中假設同一個編碼塊的色度像素值和對應的亮度像素值有線性關係,所以CCLM使用一個線性模型從亮度像素的重建值生成對應色度像素的預測值。
CCLM的參數α和β由相鄰的4個色度像素和對應的降採樣的亮度像素生成,假設當前塊尺寸是WxH,則W′和H′由下列步驟生成:
-
當使用LM模式時,W′=W,H′=H
-
當使用LM-A模式時,W′=W+H
-
當使用LM-L模式時,H′=H+W
上方相鄰的像素位置用S[0, -1]…S[W’-1, -1] 表示,左方相鄰的像素位置用S[-1, 0]…S[-1, H’-1]表示。則需要的4個像素的選取方式如下:
-
當使用LM模式且上方和左方相鄰的像素都可用時,S[W’/4, -1], S[3W’/4, -1], S[-1, H’/4], S[-1, 3H’/4]
-
當使用LM-A模式且只有上方相鄰的像素都可用時,S[W’/8, -1], S[3W’/8, -1], S[5W’/8, -1], S[7W’/8, -1]
-
當使用LM-L模式且只有左方相鄰的像素都可用時,S[-1, H’/8], S[-1, 3H’/8], S[-1, 5H’/8], S[-1, 7H’/8]
選擇的對應位置的4個亮度像素需要進行降採樣,並且經過4次比較找出2個較小值和兩個較大的值它們對應的色度值分別爲
則由下式可以計算得相關參數:
下圖展示了計算過程中需要使用的像素值
從上面公式可以看出α計算過程中出現了除法,爲了避免除法運算採用查表法計算α。同時爲了減少存儲表的空間,將diff值(最大值和最小值的差值)和α使用指數形式表示。其中diff可以表示爲一個4bit的底數和一個指數,所以1/diff的底數可以用一個16個元素的表表示爲
DivTable [ ] = { 0, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1, 1, 0 }
在LM-A模式中,只使用上方的參考像素計算線性模型參數,爲了獲得更多的參考像素需要將上方的參考像素擴展爲(W+H)。在LM-L模式中,只使用左方的參考像素計算線性模型參數,爲了獲得更多的參考像素需要將左方的參考像素擴展爲(H+W)。
對於非正方形塊,上方的參考像素擴展爲(W+W),左方的參考像素擴展爲(H+H)。
對於4:2:0的序列,提供了2種降採樣濾波器使亮度分量在水平和垂直方向進行2倍降採樣。可以在SPS中指定該參數,2種降採樣濾波器分別表示爲"type-0"和"type-2",分別如下:
注意:當上方的參考像素正好位於CTU邊界時,只使用1行亮度像素進行降採樣。
α和β也可以在解碼端計算得到,所以在傳輸碼流時不需要傳輸α和β相關的語法元素。
在VTM5中計算CCLM相關代碼如下:
if (leftAvailable || aboveAvailable)
{
int diff = maxLuma[0] - minLuma[0];
if (diff > 0)
{
int diffC = maxLuma[1] - minLuma[1];
int x = floorLog2( diff );
static const uint8_t DivSigTable[1 << 4] = {
// 4bit significands - 8 ( MSB is omitted ) //!<DivTable
0, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1, 1, 0
};
int normDiff = (diff << 4 >> x) & 15;
int v = DivSigTable[normDiff] | 8;
x += normDiff != 0;
int y = floorLog2( abs( diffC ) ) + 1;
int add = 1 << y >> 1;
a = (diffC * v + add) >> y;
iShift = 3 + x - y;
if ( iShift < 1 ) {
iShift = 1;
a = ( (a == 0)? 0: (a < 0)? -15 : 15 ); // a=Sign(a)*15
}
b = minLuma[1] - ((a * minLuma[0]) >> iShift);
}
else
{
a = 0;
b = minLuma[1];
iShift = 0;
}
}
else
{
a = 0;
b = 1 << (internalBitDepth - 1);
iShift = 0;
}
感興趣的請關注微信公衆號Video Coding