关于图像级别和单元级别的lambda和qp预测计算
这两个级别各两个参数的计算主要考虑的是计算和计算后的平滑参数的设置。都有现成的公式可以参考。同样用到的是HEVC提案JCTVC-K0103(码率控制提案)
(一)Double TEncRCPic::estimatePicLambda
Double TEncRCPic::estimatePicLambda( list<TEncRCPic*>& listPreviousPictures, SliceType eSliceType)//估计图片级别的lambda
{
Double alpha = m_encRCSeq->getPicPara( m_frameLevel ).m_alpha;
Double beta = m_encRCSeq->getPicPara( m_frameLevel ).m_beta;
Double bpp = (Double)m_targetBits/(Double)m_numberOfPixel;//前面求得的bpp用于这里来获得lambda
Double estLambda;
if (eSliceType == I_SLICE)//I片有自己的lambda算法
{
estLambda = calculateLambdaIntra(alpha, beta, pow(m_totalCostIntra/(Double)m_numberOfPixel, BETA1), bpp);
}
else
{
estLambda = alpha * pow( bpp, beta );//非I帧的计算公式,提案中常用的公式
}
/*到这里当前帧的lambda已经求得,但是还需要对数据进行处理才能正式用于编码当中,用约束条件进行约束,使其值有限定范围*/
//下面这段程序是对Lambda的平滑,保证前后帧之间的参数不变化太大。
Double lastLevelLambda = -1.0;//上一个级别???
Double lastPicLambda = -1.0;//上一帧的lambda
Double lastValidLambda = -1.0;
list<TEncRCPic*>::iterator it;
for ( it = listPreviousPictures.begin(); it != listPreviousPictures.end(); it++ )
{
if ( (*it)->getFrameLevel() == m_frameLevel )
{
lastLevelLambda = (*it)->getPicActualLambda();
}
lastPicLambda = (*it)->getPicActualLambda();
if ( lastPicLambda > 0.0 )
{
lastValidLambda = lastPicLambda;
}
}
if ( lastLevelLambda > 0.0 )
{
lastLevelLambda = Clip3( 0.1, 10000.0, lastLevelLambda );
estLambd