📄 ratectlquadratic.cpp
字号:
if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace)) &&(m_pcGenericRC->m_iFieldControl==1))
m_dReferenceMAD[0]=m_pdFCBUPFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit];
else
m_dReferenceMAD[0]=m_pdBUPFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit];
}
m_dMADPictureC1 = m_dPMADPictureC1;
m_dMADPictureC2 = m_dPMADPictureC2;
// compute the size of window
iWindowSize = (m_dCurrentFrameMAD > m_dPreviousFrameMAD)
? (int) ((float)(RC_MODEL_HISTORY-1) * m_dPreviousFrameMAD / m_dCurrentFrameMAD)
: (int) ((float)(RC_MODEL_HISTORY-1) * m_dCurrentFrameMAD / m_dPreviousFrameMAD);
iWindowSize = iClip3(1, (iNc-1), iWindowSize);
iWindowSize=imin(iWindowSize, imin(20, m_iMADWindowSize + 1));
// update the previous window size
m_iMADWindowSize=iWindowSize;
for (i = 0; i < (RC_MODEL_HISTORY-1); i++)
{
pbPictureRejected[i] = false;
}
//update the MAD for the previous frame
if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
m_dPreviousFrameMAD=m_dCurrentFrameMAD;
// initial MAD model estimator
MADModelEstimator (iWindowSize, pbPictureRejected);
// remove outlier
for (i = 0; i < iWindowSize; i++)
{
pdError[i] = m_dMADPictureC1 * m_dReferenceMAD[i] + m_dMADPictureC2 - m_dPictureMAD[i];
dStd += (pdError[i] * pdError[i]);
}
dThreshold = (iWindowSize == 2) ? 0 : sqrt (dStd / iWindowSize);
for (i = 0; i < iWindowSize; i++)
{
if (fabs(pdError[i]) > dThreshold)
pbPictureRejected[i] = true;
}
// always include the last data point
pbPictureRejected[0] = false;
// second MAD model estimator
MADModelEstimator (iWindowSize, pbPictureRejected);
}
}
/*!
*************************************************************************************
* \brief
* MAD mode estimator
*
*************************************************************************************
*/
void rc_quadratic::MADModelEstimator( int iWindowSize, bool *pbPictureRejected )
{
int iRealSize = iWindowSize;
int i;
double dOneSampleQ = 0.0;
double dA00 = 0.0, dA01 = 0.0, dA10 = 0.0, dA11 = 0.0, dB0 = 0.0, dB1 = 0.0;
double dMatrixValue;
bool bEstimateX2 = false;
for (i = 0; i < iWindowSize; i++)
{// find the number of samples which are not rejected
if (pbPictureRejected[i])
iRealSize--;
}
// default MAD model estimation results
m_dMADPictureC1 = m_dMADPictureC2 = 0.0;
for (i = 0; i < iWindowSize; i++)
{
if (!pbPictureRejected[i])
dOneSampleQ = m_dPictureMAD[i];
}
for (i = 0; i < iWindowSize; i++)
{// if all non-rejected MAD are the same, take 1st order model
if ((m_dPictureMAD[i] != dOneSampleQ) && !pbPictureRejected[i])
bEstimateX2 = true;
if (!pbPictureRejected[i])
m_dMADPictureC1 += m_dPictureMAD[i] / (m_dReferenceMAD[i]*iRealSize);
}
// take 2nd order model to estimate X1 and X2
if ((iRealSize >= 1) && bEstimateX2)
{
for (i = 0; i < iWindowSize; i++)
{
if (!pbPictureRejected[i])
{
dA00 = dA00 + 1.0;
dA01 += m_dReferenceMAD[i];
dA10 = dA01;
dA11 += m_dReferenceMAD[i] * m_dReferenceMAD[i];
dB0 += m_dPictureMAD[i];
dB1 += m_dPictureMAD[i] * m_dReferenceMAD[i];
}
}
// solve the equation of AX = B
dMatrixValue = dA00 * dA11 - dA01 * dA10;
if(fabs(dMatrixValue) > 0.000001)
{
m_dMADPictureC2 = (dB0 * dA11 - dB1 * dA01) / dMatrixValue;
m_dMADPictureC1 = (dB1 * dA00 - dB0 * dA10) / dMatrixValue;
}
else
{
m_dMADPictureC1 = dB0/dA01;
m_dMADPictureC2 = 0.0;
}
}
if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
{
m_dPMADPictureC1 = m_dMADPictureC1;
m_dPMADPictureC2 = m_dMADPictureC2;
}
}
/*!
*************************************************************************************
* \brief
* compute a quantization parameter for each frame
*
*************************************************************************************
*/
int rc_quadratic::updateQPRC1( int iTopField )
{
int iBits;
int iSumofBasicUnit;
int iMaxQpChange, iQp, iHp;
// frame layer rate control
if( m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs )
{
// fixed quantization parameter is used to coded I frame, the first P frame and the first B frame
// the quantization parameter is adjusted according the available channel bandwidth and
// the type of video
// top field
if((iTopField) || (m_pcGenericRC->m_iFieldControl==0))
{
if (m_pcJSVMParams->number == 0)
{
m_iQc = m_iMyInitialQp;
return m_iQc;
}
else if( m_iNumberofPPicture == 0 && (m_pcJSVMParams->number != 0))
{
m_iQc=m_iMyInitialQp;
if(m_pcGenericRC->m_iFieldControl==0)
updateQPNonPicAFF();
return m_iQc;
}
else
{
// adaptive field/frame coding
if( ( m_pcJSVMParams->PicInterlace == ADAPTIVE_CODING || m_pcJSVMParams->MbInterlace ) && m_pcGenericRC->m_iFieldControl == 0 )
updateQPInterlaceBU();
m_dX1 = m_dPX1;
m_dX2 = m_dPX2;
m_dMADPictureC1 = m_dPMADPictureC1;
m_dMADPictureC2 = m_dPMADPictureC2;
m_dPreviousPictureMAD = m_dPPictureMAD[0];
iMaxQpChange = m_iPMaxQpChange;
iQp = m_iPQp;
iHp = m_iPPreHeader;
// predict the MAD of current picture
m_dCurrentFrameMAD=m_dMADPictureC1*m_dPreviousPictureMAD + m_dMADPictureC2;
// compute the number of bits for the texture
if(m_iTarget < 0)
{
m_iQc=iQp+iMaxQpChange;
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // Clipping
}
else
{
iBits = m_iTarget-iHp;
iBits = imax(iBits, (int)(m_fBitRate/(m_fMINVALUE*m_fFrameRate)));
updateModelQPFrame( iBits );
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // clipping
m_iQc = iClip3(iQp-iMaxQpChange, iQp+iMaxQpChange, m_iQc); // control variation
}
if( m_pcGenericRC->m_iFieldControl == 0 )
updateQPNonPicAFF();
return m_iQc;
}
}
// bottom field
else
{
if( m_pcGenericRC->m_iNoGranularFieldRC == 0 )
updateBottomField();
return m_iQc;
}
}
// basic unit layer rate control
else
{
// top field of I frame
if (m_pcJSVMParams->number == 0)
{
m_iQc = m_iMyInitialQp;
return m_iQc;
}
else
{
if((m_pcGenericRC->m_iNumberofGOP==1)&&(m_iNumberofPPicture==0))
{
if((m_pcGenericRC->m_iFieldControl==0)||((m_pcGenericRC->m_iFieldControl==1) && (m_pcGenericRC->m_iNoGranularFieldRC==0)))
return updateFirstP( iTopField );
}
else
{
m_dX1=m_dPX1;
m_dX2=m_dPX2;
m_dMADPictureC1=m_dPMADPictureC1;
m_dMADPictureC2=m_dPMADPictureC2;
iQp=m_iPQp;
if(m_pcGenericRC->m_iFieldControl==0)
iSumofBasicUnit=m_iTotalNumberofBasicUnit;
else
iSumofBasicUnit=m_iTotalNumberofBasicUnit>>1;
// the average QP of the previous frame is used to coded the first basic unit of the current frame or field
if(m_iNumberofBasicUnit==iSumofBasicUnit)
return updateFirstBU( iTopField );
else
{
// compute the number of remaining bits
m_iTarget -= (m_pcGenericRC->m_iNumberofBasicUnitHeaderBits + m_pcGenericRC->m_iNumberofBasicUnitTextureBits);
m_pcGenericRC->m_iNumberofBasicUnitHeaderBits = 0;
m_pcGenericRC->m_iNumberofBasicUnitTextureBits = 0;
if(m_iTarget<0)
return updateNegativeTarget( iTopField, iQp );
else
{
// predict the MAD of current picture
predictCurrPicMAD();
// compute the total number of bits for the current basic unit
updateModelQPBU( iTopField, iQp );
m_iTotalFrameQP +=m_iQc;
m_iPQp=m_iQc;
m_iNumberofBasicUnit--;
if((m_iNumberofBasicUnit==0) && (m_pcJSVMParams->number != 0))
updateLastBU( iTopField );
return m_iQc;
}
}
}
}
}
return m_iQc;
}
/*!
*************************************************************************************
* \brief
* compute a quantization parameter for each frame
*
*************************************************************************************
*/
int rc_quadratic::updateQPRC2( int iTopField )
{
int iBits;
int iSumofBasicUnit;
int iMaxQpChange, iQp, iHp;
// frame layer rate control
if( m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs )
{
// fixed quantization parameter is used to coded I frame, the first P frame and the first B frame
// the quantization parameter is adjusted according the available channel bandwidth and
// the type of video
// top field
if((iTopField) || (m_pcGenericRC->m_iFieldControl==0))
{
if (m_pcJSVMParams->number == 0)
{
m_iQc = m_iMyInitialQp;
return m_iQc;
}
else if (m_pcJSVMParams->type==I_SLICE)
{
if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
updateQPInterlace();
m_iQc = m_iCurrLastQP; // Set QP to average qp of last P frame
return m_iQc;
}
else if(m_pcJSVMParams->type == B_SLICE)
{
int iPrevQP = imax(m_iPrevLastQP, m_iCurrLastQP);
if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
updateQPInterlace();
if (m_pcJSVMParams->HierarchicalCoding)
{
m_iQc = iPrevQP + m_pcJSVMParams->HierarchicalLevels - m_pcJSVMParams->CurrGopLevel + 1;
}
else
m_iQc = iPrevQP + 2 - m_pcJSVMParams->nal_reference_idc;
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // Clipping
return m_iQc;
}
else if( m_pcJSVMParams->type == P_SLICE && m_iNumberofPPicture == 0 )
{
m_iQc=m_iMyInitialQp;
if(m_pcGenericRC->m_iFieldControl==0)
updateQPNonPicAFF();
return m_iQc;
}
else
{
// adaptive field/frame coding
if( ( m_pcJSVMParams->PicInterlace == ADAPTIVE_CODING || m_pcJSVMParams->MbInterlace ) && m_pcGenericRC->m_iFieldControl == 0 )
updateQPInterlaceBU();
m_dX1 = m_dPX1;
m_dX2 = m_dPX2;
m_dMADPictureC1 = m_dPMADPictureC1;
m_dMADPictureC2 = m_dPMADPictureC2;
m_dPreviousPictureMAD = m_dPPictureMAD[0];
iMaxQpChange = m_iPMaxQpChange;
iQp = m_iPQp;
iHp = m_iPPreHeader;
// predict the MAD of current picture
m_dCurrentFrameMAD=m_dMADPictureC1*m_dPreviousPictureMAD + m_dMADPictureC2;
// compute the number of bits for the texture
if(m_iTarget < 0)
{
m_iQc=iQp+iMaxQpChange;
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // Clipping
}
else
{
iBits = m_iTarget-iHp;
iBits = imax(iBits, (int)(m_fBitRate/(m_fMINVALUE*m_fFrameRate)));
updateModelQPFrame( iBits );
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // clipping
m_iQc = iClip3(iQp-iMaxQpChange, iQp+iMaxQpChange, m_iQc); // control variation
}
if( m_pcGenericRC->m_iFieldControl == 0 )
updateQPNonPicAFF();
return m_iQc;
}
}
// bottom field
else
{
if( m_pcJSVMParams->type==P_SLICE && m_pcGenericRC->m_iNoGranularFieldRC == 0 )
updateBottomField();
return m_iQc;
}
}
// basic unit layer rate control
else
{
// top field of I frame
if (m_pcJSVMParams->number == 0)
{
m_iQc = m_iMyInitialQp;
return m_iQc;
}
else if (m_pcJSVMParams->type==I_SLICE)
{
// adaptive field/frame coding
if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
updateQPInterlace();
m_iQc = m_iPrevLastQP; // Set QP to average qp of last P frame
m_iPrevLastQP = m_iCurrLastQP;
m_iCurrLastQP = m_iPrevLastQP;
m_iPAveFrameQP = m_iCurrLastQP;
return m_iQc;
}
else if(m_pcJSVMParams->type == B_SLICE)
{
int iPrevQP = imax(m_iPrevLastQP, m_iCurrLastQP);
if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
updateQPInterlace();
if (m_pcJSVMParams->HierarchicalCoding)
{
m_iQc = iPrevQP + m_pcJSVMParams->HierarchicalLevels - m_pcJSVMParams->CurrGopLevel + 1;
}
else
m_iQc = iPrevQP + 2 - m_pcJSVMParams->nal_reference_idc;
m_iQc = iClip3(m_iRCMinQuant, m_iRCMaxQuant, m_iQc); // Clipping
return m_iQc;
}
else if( m_pcJSVMParams->type == P_SLICE )
{
if((m_pcGenericRC->m_iNumberofGOP==1)&&(m_iNumberofPPicture==0))
{
if((m_pcGenericRC->m_iFieldControl==0)||((m_pcGenericRC->m_iFieldControl==1) && (m_pcGenericRC->m_iNoGranularFieldRC==0)))
return updateFirstP( iTopField );
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -