1. 程式人生 > >HEVC幀間位元速率控制

HEVC幀間位元速率控制

1. 首先呼叫initPicPara以及initLCUPara兩個函式對影象級和CTU級的alphabeta進行初始化。

initPicPara:framelevel=0 則 alpha=6.7542,beta=1.786

           否則    alpha=3.2003,beta=-1.367

initLCUPara:將一幀內的每個LCU按照對應幀的alpha和beta初始化。

     即framelevel=0時,該幀內所有LCU alpha=6.7542,beta=1.786

         否則,    該幀內所有LCU alpha=3.2003,beta=-1.367

2. 通過estimatePicLambda

函式估計一幀影象的estLambda(該值會在多處使用)。再計算m_bitWeight

  m_bitWeight = m_LCUs[i].m_numberOfPixel *pow( estLambda/alphaLCU, 1.0/betaLCU );

其中,alphaLCU和betaLCU是LCU級的alpha和beta。

 for ( Int i=0; i<m_numberOfLCU; i++ )
  {
    Double BUTargetBits = m_targetBits * m_LCUs[i].m_bitWeight / totalWeight;
    m_LCUs[i].m_bitWeight = BUTargetBits;
  }

再根據estLambda通過estimatePicQP函式計算estPicQP。

3. I幀碼控這裡不詳細闡述,只是在編完每個LCU後不會更新每個LCUalphabeta值,也就是說,第一個P幀中的LCU仍使用初始的alphabeta

  對於P幀中的每個LCU:

  ①進入getLCUTargetBpp計算bpp:

 for ( Int i=LCUIdx; i<m_numberOfLCU; i++ )

    {

      totalWeight += m_LCUs[i].m_bitWeight;

     }

Int realInfluenceLCU =min( g_RCLCUSmoothWindowSize, getLCULeft() );

 avgBits = (Int)( m_LCUs[LCUIdx].m_bitWeight - ( totalWeight - m_bitsLeft ) / realInfluenceLCU + 0.5 );

( 其中m_bitWeight代表:為每個LCU分配的初始目標bit數。上式中為何會有減號後一項?這是因為HM會根據上一個LCU實際所用bits數來更新下一個LCU的目標bits(動態調整),目的是使該幀實際編碼bit與目標bit儘可能接近。(若目標剩餘位元totalWeight > 實際剩餘位元m_bitsLeft,則應該減少下一個LCU的目標bits。否則若還按照m_bitWeight分配目標bits,則會導致總bits數分完後還有剩餘LCU未編碼。)realInfluenceLCU是平滑視窗,即平滑位元波動。+0.5達到向上取整的目的。

下面是在位元速率為3.5M時,p幀的幾個CTU各個值:

第10個:m_bitWeight: 84.8472  totalWeight - m_bitsLeft: 285.84  avgBits:13

第11個:m_bitWeight: 137.799  totalWeight - m_bitsLeft: 258.992  avgBits:73

第12個:m_bitWeight: 151.531  totalWeight - m_bitsLeft: 342.193  avgBits:66

第13個:m_bitWeight: 150.398  totalWeight - m_bitsLeft: 612.662  avgBits:-2

第14個:m_bitWeight: 121.049  totalWeight - m_bitsLeft: 896.264  avgBits:-102

第15個:m_bitWeight: 117.018  totalWeight - m_bitsLeft: 954.215   avgBits:-121

可以看出:一般情況totalWeight - m_bitsLeft會大於m_bitWeight,因此需要平滑視窗來防止所有CTU的avgBits取得負值。realInfluenceLCU取值為4應為經驗值。

 if ( avgBits < 1 )  avgBits = 1;

 bpp = ( Double )avgBits/( Double )m_LCUs[ LCUIdx ].m_numberOfPixel;

得到bpp後,通過getLCUEstLambda函式計算lambda

 estLambda = alpha *pow( bpp, beta ); 再通過 clipNeighbourLambda(上一個CTU實際編碼lambda)和clipPicLambda(即第二步求出的影象級estLambda)限定該CTU級的estLambda得到應用於編碼的lambda。

③得到編碼lambda後,進入getLCUEstQP計算QP

  estQP = Int( 4.2005 *log( lambda ) + 13.7122 + 0.5 );再通過 clipNeighbourQP(上一個CTU實際編碼QP)和clipPicQP(即第二步求出的影象級estpicQP)限定該CTU級的estQP得到應用於編碼的QP。

4: 進入updateAfterCTU更新CTU級的alphabeta。更新後的alphabeta用於framelevel相同的下一個幀的位置相同的LCU進行第二步m_bitWeight和第三步②estLambda的計算。

5: 編完一幀後進入updateAfterPict更新幀級的alphabeta更新後的alphabetaframelevel相同的下一使用。