1. 程式人生 > >HEVC的幀內預測(1)

HEVC的幀內預測(1)

HEVC的幀內預測(intra prediction),即intra塊的預測過程,為intra塊解碼提供預測值(predSamples[ x ][ y ])。

首先要確定當前塊和鄰塊的關係。

1.z-scan order block availability

z-scan order block availability,就是在Z順序掃描下的availability。

首先介紹計算MinTbAddrZs的方法

陣列MinTbAddrZs表示以最小塊(minimum blocks)為單位的z-scan 順序地址,最小塊的尺寸由變數Log2MinTrafoSize決定。

由以下公式得到:


看著是不是很頭疼?有沒有想死的感覺?

其中:CtbLog2SizeY為ctb(coding tree block)的尺寸對數,MinTbLog2SizeY為最小的Tb(transform block變換塊)的尺寸對數。ctbAddrRs為當前ctb的raster掃描地址,CtbAddrRsToTs[ ctbAddrRs ]就是將ctbAddrRs轉化為了Ts(tiles)掃描地址(詳見HEVC標準中的影象分割(1))。

其實這公式表達的意思就是當前以最小塊為單位的座標(x,y)的地址,此地址的定址順序在CTB內部為z-scan,在跨越CTB時為tile掃描順序。

舉個例子,如圖:


在圖(1)中,黃色塊代表當前的ctb,粗黑線標出了tile的邊界,小方塊代表ctb,黃色塊代表(x,y)所在的ctb,即當前ctb,虛線箭頭就是ts掃描的方向。則根據公式,當前ctb的ts掃描地址為24。

圖(2)中,大的黃色塊代表當前ctb,陰影塊代表(x,y)所在的tb,假設CtbLog2SizeY = 4,MinTbLog2SizeY = 3,一個ctb中包含4個tb。(x,y)在當前ctb的地址為2。

所以MinTbAddrZs  = 24 + 2 = 26嗎?錯!!!

因為前面掃描過的ctb都有4個tb,所以MinTbAddrZs  = 24*4 + 2 = 98.

當前塊左上角畫素座標(xCurr, yCurr),由以上MinTbAddrZs步驟計算出其最小塊地址minBlockAddrCurr。

再計算左上角座標為(xNbY, yNbY)的相鄰塊的最小塊地址,minBlockAddrN

當相鄰塊位於影象範圍外時,minBlockAddrN為-1,否則根據MinTbAddrZs方法進行計算。

如果有一個或者多個下列條件為真時,availableN 為FALSE

 1. minBlockAddrN 小於0

 2. minBlockAddrN 比 minBlockAddrCurr大

 3. 相鄰塊所在的slice segment對應的SliceAddrRs和當前塊所在的slice segment對應的SliceAddrRs不同。

 4. 相鄰塊和當前塊處於不同的tile。

否則, availableN為TRUE。


在intraSplitFlag為1時,要把當前的色度塊分成4個塊進行處理。

2.幀內預測模式計算

HEVC的幀內預測有34中模式,比H264的幀內預測更加精細。如下圖的對比
H.264的intra預測模式
HEVC的intra預測模式

引入HEVC的幀內預測模式值與名稱的對應

0:INTRA_PLANAR

1:INTRA_DC

2~34:INTRA_ANGULAR2~INTRA_ANGULAR34

幀內預測模式的值可以下步驟得出:

1. 用A表示當前塊左邊鄰塊,B表示當前快上邊鄰塊。

2.計算備選幀內預測模式(candIntraPredModeX,X可以為A或者B),有下列步驟:

if(availableX==false)
{
   candIntraPredModeX = INTRA_DC;
}
else if((CuPredMode[ xNbX][ yNbX ]!=INTRA)||( pcm_flag[ xNbX ][ yNbX ]==1))
{
   candIntraPredModeX = INTRA_DC;
}
else if(B位於另外一個coding tree unit)
{
   candIntraPredModeX = INTRA_DC;
}
else
{
   candIntraPredModeX= IntraPredModeY[ xNbX ][ yNbX ]
}

其中,availableX表示鄰塊的是否可用,由第1部分介紹的過程得出。

CuPredMode[ xNbX ][ yNbX ]指相鄰塊的預測模式,可為INTRA(1)或INTER(0)。

pcm_flag[ xNbX ][ yNbX ]指相鄰塊的pcm標誌。

IntraPredModeY[ xNbX ][ yNbX ]指相鄰塊的幀內預測模式(範圍:0~34)。

3. 備選模式表(candModeList[ x ], x = 0~2)的計算過程如下:

if (candIntraPredModeB==candIntraPredModeA)
{
  if(candIntraPredModeA<2)
  {
     candModeList[0]=0, candModeList[1]=1,candModeList[2]=26;
  }
  else
  {
    candModeList[0] = candIntraPredModeA 
    candModeList[1] = 2 + ( ( candIntraPredModeA + 29 ) % 32 )
    candModeList[2] = 2 + ( ( candIntraPredModeA −2 + 1 ) % 32 )
   }
}
else
{
   candModeList[0] = candIntraPredModeA
   candModeList[1] = candIntraPredModeB
   if((candModeList[0]!=0)&&( candModeList[1]!=0))
      candModeList[2] =0;
   elseif((candModeList[0]!=1)&&( candModeList[ 1 ]!=1))
      candModeList[2] =1;
   else
      candModeList[2] =26;
}

完成此步驟後,得到備選模式表candModeList[x ]。

4.當前幀的亮度幀內預測解碼模式(IntraPredModeY[ xPb ][ yPb ]),由以下步驟得出:

if(prev_intra_luma_pred_flag[ xPb ][ yPb ] ==1)
{
   IntraPredModeY[ xPb ][ yPb ] = candModeList[ mpm_idx ]
}
else
{
   if(candModeList[ 0 ]>candModeList[ 1 ])
     Swap( candModeList[ 0 ], candModeList[ 1 ] )  
   if(candModeList[ 0 ]>candModeList[ 2 ])
     Swap( candModeList[ 0 ], candModeList[ 2 ] )  
   if(candModeList[ 1 ]>candModeList[ 2 ])
     Swap( candModeList[ 1 ], candModeList[ 2 ] )  
   IntraPredModeY[ xPb ][ yPb ] =rem_intra_luma_pred_mode[ xPb ][ yPb ];
   for(i=0;i<2;i++)
   {
      if(IntraPredModeY[ xPb ][ yPb ] >= candModeList[ i ])
        IntraPredModeY[ xPb ][ yPb ]++;
   }
}
其中,prev_intra_luma_pred_flag,mpm_idx和rem_intra_luma_pred_mode都是coding_uint中的語法元素,可由cabac解碼得到。

至此,得到亮度的幀內預測模式(IntraPredModeY)。