上一篇文章主要讨论了RC的总体框架,本文开始分析具体的代码实现细节。分析的顺序按照总体框架来,即初始化-->更新。
(1)m_cRateCtrl.init()
#if M0036_RC_IMPROVEMENT
Void TEncRateCtrl::init( Int totalFrames, Int targetBitrate, Int frameRate, Int GOPSize, Int picWidth, Int picHeight, Int LCUWidth, Int LCUHeight, Int keepHierBits, Bool useLCUSeparateModel, GOPEntry GOPList[MAX_GOP] )
#else
Void TEncRateCtrl::init( Int totalFrames, Int targetBitrate, Int frameRate, Int GOPSize, Int picWidth, Int picHeight, Int LCUWidth, Int LCUHeight, Bool keepHierBits, Bool useLCUSeparateModel, GOPEntry GOPList[MAX_GOP] )
#endif
{
destroy();
Bool isLowdelay = true;
for ( Int i=0; i<GOPSize-1; i++ )
{
if ( GOPList[i].m_POC > GOPList[i+1].m_POC ) //!< 判断是否为lowdelay配置
{
isLowdelay = false;
break;
}
}
Int numberOfLevel = 1;
#if M0036_RC_IMPROVEMENT
Int adaptiveBit = 0;
if ( keepHierBits > 0 )
#else
if ( keepHierBits ) //!< hierarchical structure
#endif
{
numberOfLevel = Int( log((Double)GOPSize)/log(2.0) + 0.5 ) + 1;
}
if ( !isLowdelay && GOPSize == 8 )
{
numberOfLevel = Int( log((Double)GOPSize)/log(2.0) + 0.5 ) + 1;
}
numberOfLevel++; // intra picture
numberOfLevel++; // non-reference picture
Int* bitsRatio; //!< 每一幅picture的权值
bitsRatio = new Int[ GOPSize ];
for ( Int i=0; i<GOPSize; i++ )
{
bitsRatio[i] = 10;
if ( !GOPList[i].m_refPic )
{
bitsRatio[i] = 2;
}
}
#if M0036_RC_IMPROVEMENT
if ( keepHierBits > 0 )
#else
if ( keepHierBits )
#endif
{
Double bpp = (Double)( targetBitrate / (Double)( frameRate*picWidth*picHeight ) ); //!< K0103 式子(3)
if ( GOPSize == 4 && isLowdelay ) //!< K0103 Table 1
{
if ( bpp > 0.2 )
{
bitsRatio[0] = 2;
bitsRatio[1] = 3;
bitsRatio[2] = 2;
bitsRatio[3] = 6;
}
else if( bpp > 0.1 )
{
bitsRatio[0] = 2;
bitsRatio[1] = 3;
bitsRatio[2] = 2;
bitsRatio[3] = 10;
}
else if ( bpp > 0.05 )
{
bitsRatio[0] = 2;
bitsRatio[1] = 3;
bitsRatio[2] = 2;
bitsRatio[3] = 12;
}
else
{
bitsRatio[0] = 2;
bitsRatio[1] = 3;
bitsRatio[2] = 2;
bitsRatio[3] = 14;
}
#if M0036_RC_IMPROVEMENT
if ( keepHierBits == 2 )
{
adaptiveBit = 1;
}
#endif
}
else if ( GOPSize == 8 && !isLowdelay ) //!< K0103 Table 2
{
if ( bpp > 0.2 )
{
bitsRatio[0] = 15;
bitsRatio[1] = 5;
bitsRatio[2] = 4;
bitsRatio[3] = 1;
bitsRatio