getpoc0,1,2,3,4,5,6.。。。
iGOPid
getpoc | 1 | 2 | 3 | 4 |
iGOPid | 0 | 1 | 2 | 3 |
poc | 1 | 2 | 3 | 0 |
depth | 2 | 1 | 2 | 0 |
QP | 44 | 45 | 44 | 38 |
QP计算过程:Int EncCfg::getQPForPicture()
qpbase为原始QP(22,27,32,37),由qpbase加gopEntry.m_QPoffset得到,再加上qpOffset得到最终QP。
拉姆达λ计算:
一般情况下为:
qp_temp=dQP-12;
lamba= dQPFactor*pow(2.0, qp_temp / 3.0);
反计算QP:
newqp=log(lamba / dQPFactor) / log(2.0)*3.0+12;
#if SHARP_LUMA_DELTA_QP
Double EncSlice::calculateLambda( const Slice* slice,
const Int GOPid, // entry in the GOP table
const Int depth, // slice GOP hierarchical depth.
const Double refQP, // initial slice-level QP
const Double dQP, // initial double-precision QP
Int &iQP ) // returned integer QP.
{
enum SliceType eSliceType = slice->getSliceType();
const Bool isField = slice->getPic()->fieldPic;
const Int NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
const Int SHIFT_QP = 12;
#if X0038_LAMBDA_FROM_QP_CAPABILITY
const Int temporalId=m_pcCfg->getGOPEntry(GOPid).m_temporalId;
const std::vector<Double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
#endif
#if FULL_NBIT
Int bitdepth_luma_qp_scale = 6 * (slice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
#else
Int bitdepth_luma_qp_scale = 0;
#endif
Double qp_temp = dQP + bitdepth_luma_qp_scale - SHIFT_QP;
// Case #1: I or P-slices (key-frame)
Double dQPFactor = m_pcCfg->getGOPEntry(GOPid).m_QPFactor;
if ( eSliceType==I_SLICE )
{
if (m_pcCfg->getIntraQpFactor()>=0.0 && m_pcCfg->getGOPEntry(GOPid).m_sliceType != I_SLICE)
{
dQPFactor=m_pcCfg->getIntraQpFactor();
}
else
{
#if X0038_LAMBDA_FROM_QP_CAPABILITY
if(m_pcCfg->getLambdaFromQPEnable())
{
dQPFactor=0.57;
}
else
{
#endif
Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
dQPFactor=0.57*dLambda_scale;
#if X0038_LAMBDA_FROM_QP_CAPABILITY
}
#endif
}
}
#if X0038_LAMBDA_FROM_QP_CAPABILITY
else if( m_pcCfg->getLambdaFromQPEnable() )
{
dQPFactor=0.57;
}
#endif
Double dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 ); //计算λ
#if X0038_LAMBDA_FROM_QP_CAPABILITY
if( !(m_pcCfg->getLambdaFromQPEnable()) && depth>0 )
#else
if ( depth>0 )
#endif
{
#if FULL_NBIT
Double qp_temp_ref_orig = refQP - SHIFT_QP;
dLambda *= Clip3( 2.00, 4.00, (qp_temp_ref_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
#else
Double qp_temp_ref = refQP + bitdepth_luma_qp_scale - SHIFT_QP;
dLambda *= Clip3( 2.00, 4.00, (qp_temp_ref / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
#endif
}
// if hadamard is used in ME process
if ( !m_pcCfg->getUseHADME() && slice->getSliceType( ) != I_SLICE )
{
dLambda *= 0.95;
}
#if X0038_LAMBDA_FROM_QP_CAPABILITY
Double lambdaModifier;
if( eSliceType != I_SLICE || intraLambdaModifiers.empty())
{
lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
}
else
{
lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
}
dLambda *= lambdaModifier;
#endif
iQP = max( -slice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
// NOTE: the lambda modifiers that are sometimes applied later might be best always applied in here.
return dLambda;
}
#endif