HEVC幀間位元速率控制
1. 首先呼叫initPicPara以及initLCUPara兩個函式對影象級和CTU級的alpha和beta進行初始化。
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後不會更新每個LCU的alpha和beta值,也就是說,第一個P幀中的LCU仍使用初始的alpha和beta。
對於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級的alpha和beta。更新後的alpha和beta用於framelevel相同的下一個幀的位置相同的LCU進行第二步m_bitWeight和第三步②estLambda的計算。
5: 編完一幀後進入updateAfterPict更新幀級的alpha和beta。更新後的alpha和beta被framelevel相同的下一個幀使用。