📄 ratectlquadratic.cpp
字号:
{
//compute the average weight
if(m_pcGenericRC->m_iNumberofCodedBFrame<8)
m_dAveWb = (m_dAveWb + m_dWb*(m_pcGenericRC->m_iNumberofCodedBFrame-1)) / m_pcGenericRC->m_iNumberofCodedBFrame;
else
m_dAveWb = (m_dWb + 7 * m_dAveWb) / 8;
}
}
// Compute the target bit for each frame
if( m_pcJSVMParams->type == P_SLICE || ( m_pcJSVMParams->number != 0 && m_pcJSVMParams->RCUpdateMode == RC_MODE_1 ) )
{
// frame layer rate control
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
{
if(m_iNumberofCodedPFrame>0)
{
m_iTarget = (int) floor( m_dWp * m_pcGenericRC->m_iRemainingBits / (m_iNp * m_dWp + m_iNb * m_dWb) + 0.5);
iTmpT = imax(0, (int) floor(m_fBitRate / m_fFrameRate - m_dGAMMAP * (m_pcGenericRC->m_i64CurrentBufferFullness-m_dTargetBufferLevel) + 0.5));
m_iTarget = (int) floor(m_dBETAP * (m_iTarget - iTmpT) + iTmpT + 0.5);
}
}
// basic unit layer rate control
else
{
if(((m_pcGenericRC->m_iNumberofGOP == 1)&&(m_iNumberofCodedPFrame>0))
|| (m_pcGenericRC->m_iNumberofGOP > 1))
{
m_iTarget = (int) (floor( m_dWp * m_pcGenericRC->m_iRemainingBits / (m_iNp * m_dWp + m_iNb * m_dWb) + 0.5));
iTmpT = imax(0, (int) (floor(m_fBitRate / m_fFrameRate - m_dGAMMAP * (m_pcGenericRC->m_i64CurrentBufferFullness-m_dTargetBufferLevel) + 0.5)));
m_iTarget = (int) (floor(m_dBETAP * (m_iTarget - iTmpT) + iTmpT + 0.5));
}
}
m_iTarget = (int)(fMult * m_iTarget);
// reserve some bits for smoothing
m_iTarget = (int)((1.0 - 0.0 * m_pcJSVMParams->successive_Bframe) * m_iTarget);
// HRD consideration
m_iTarget = iClip3(m_iLowerBound, m_iUpperBound2, m_iTarget);
if((iTopField) || (iFieldPic && ((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))))
m_iTargetField=m_iTarget;
}
}
if(iFieldPic || iTopField)
{
// frame layer rate control
m_pcGenericRC->m_iNumberofHeaderBits = 0;
m_pcGenericRC->m_iNumberofTextureBits = 0;
// basic unit layer rate control
if(m_pcJSVMParams->BasicUnit < m_pcJSVMParams->FrameSizeInMbs)
{
m_iTotalFrameQP = 0;
m_pcGenericRC->m_iNumberofBasicUnitHeaderBits = 0;
m_pcGenericRC->m_iNumberofBasicUnitTextureBits = 0;
m_pcGenericRC->m_i64TotalMADBasicUnit = 0;
if(m_pcGenericRC->m_iFieldControl==0)
m_iNumberofBasicUnit = m_iTotalNumberofBasicUnit;
else
m_iNumberofBasicUnit = m_iTotalNumberofBasicUnit >> 1;
}
}
if( ( m_pcJSVMParams->type==P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) ) && m_pcJSVMParams->BasicUnit < m_pcJSVMParams->FrameSizeInMbs && m_pcGenericRC->m_iFieldControl == 1 )
{
// top field at basic unit layer rate control
if(iTopField)
{
m_iBitsTopField=0;
m_iTarget=(int)(m_iTargetField*0.6);
}
// bottom field at basic unit layer rate control
else
{
m_iTarget=m_iTargetField-m_iBitsTopField;
m_pcGenericRC->m_iNumberofBasicUnitHeaderBits=0;
m_pcGenericRC->m_iNumberofBasicUnitTextureBits=0;
m_pcGenericRC->m_i64TotalMADBasicUnit=0;
m_iNumberofBasicUnit=m_iTotalNumberofBasicUnit >> 1;
}
}
}
/*!
*************************************************************************************
* \brief
* update one picture after frame/field encoding
*
* \param iNbits
* number of bits used for picture
*
*************************************************************************************
*/
void rc_quadratic::rc_update_pict( int iNbits )
{
int iDeltaBits = (iNbits - (int)floor(m_fBitRate / m_fFrameRate + 0.5F) );
m_pcGenericRC->m_iRemainingBits -= iNbits; // remaining # of bits in GOP
m_pcGenericRC->m_i64CurrentBufferFullness += iDeltaBits;
// update the lower bound and the upper bound for the target bits of each frame, HRD consideration
m_iLowerBound -= (int) iDeltaBits;
m_iUpperBound1 -= (int) iDeltaBits;
m_iUpperBound2 = (int)(m_fOMEGA * m_iUpperBound1);
return;
}
int rc_quadratic::updateComplexity( bool bIsUpdated, int iNbits )
{
double dAvemQc;
// frame layer rate control
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
return ((int) floor(iNbits * m_iQc + 0.5));
// basic unit layer rate control
else
{
if( bIsUpdated )
{
if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
{
dAvemQc = (double)m_iTotalFrameQP / (double)m_iTotalNumberofBasicUnit;
return ((int)floor(iNbits * dAvemQc + 0.5));
}
}
else if( m_pcJSVMParams->type == B_SLICE )
return ((int) floor(iNbits * m_iQc + 0.5));
}
return 0;
}
void rc_quadratic::updatePparams( int iComplexity )
{
m_iXp = iComplexity;
m_iNp--;
m_dWp = m_iXp;
m_iNumberofCodedPFrame++;
m_iNumberofPPicture++;
}
void rc_quadratic::updateBparams( int iComplexity )
{
m_iXb = iComplexity;
m_iNb--;
m_dWb = m_iXb / m_fTHETA;
m_iNumberofBFrames++;
m_pcGenericRC->m_iNumberofCodedBFrame++;
}
/*!
*************************************************************************************
* \brief
* update after frame encoding
*
* \param iNbits
* number of bits used for frame
*
*************************************************************************************
*/
void rc_quadratic::rc_update_pict_frame(int iNbits)
{
// update the iComplexity weight of I, P, B frame
int iComplexity = 0;
switch( m_pcJSVMParams->RCUpdateMode )
{
case RC_MODE_2:
default:
iComplexity = updateComplexity( (bool) (m_pcJSVMParams->type == P_SLICE), iNbits );
if ( m_pcJSVMParams->type == P_SLICE )
{
if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
updatePparams( iComplexity );
else
m_pcGenericRC->m_iNoGranularFieldRC = 0;
}
else if ( m_pcJSVMParams->type == B_SLICE )
updateBparams( iComplexity );
break;
case RC_MODE_1:
iComplexity = updateComplexity( (bool) (m_pcJSVMParams->number != 0), iNbits );
if ( m_pcJSVMParams->number != 0 )
{
if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
updatePparams( iComplexity );
else
m_pcGenericRC->m_iNoGranularFieldRC = 0;
}
break;
}
}
/*!
*************************************************************************************
* \brief
* update the parameters of quadratic R-D model
*
*************************************************************************************
*/
void rc_quadratic::updateRCModel( void )
{
int iWindowSize;
int i;
double dStd = 0.0, dThreshold;
int iNc = m_iNumberofCodedPFrame;
bool bMADModelFlag = false;
static bool pbRgRejected[RC_MODEL_HISTORY];
static double pdError [RC_MODEL_HISTORY];
if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
{
// frame layer rate control
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
{
m_dCurrentFrameMAD = m_pcGenericRC->ComputeFrameMAD();
iNc=m_iNumberofCodedPFrame;
}
// basic unit layer rate control
else
{
// compute the MAD of the current basic unit
m_dCurrentFrameMAD = (double) ((m_pcGenericRC->m_i64TotalMADBasicUnit >> 8)/m_pcJSVMParams->BasicUnit);
m_pcGenericRC->m_i64TotalMADBasicUnit=0;
// compute the average number of header bits
m_iCodedBasicUnit=m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit;
if(m_iCodedBasicUnit > 0)
{
m_iPAveHeaderBits1=(int)((double)(m_iPAveHeaderBits1*(m_iCodedBasicUnit-1)+
m_pcGenericRC->m_iNumberofBasicUnitHeaderBits)/m_iCodedBasicUnit+0.5);
if(m_iPAveHeaderBits3 == 0)
m_iPAveHeaderBits2 = m_iPAveHeaderBits1;
else
{
m_iPAveHeaderBits2 = (int)((double)(m_iPAveHeaderBits1 * m_iCodedBasicUnit+
m_iPAveHeaderBits3 * m_iNumberofBasicUnit)/m_iTotalNumberofBasicUnit+0.5);
}
}
// update the record of MADs for reference
if(((m_pcJSVMParams->PicInterlace == ADAPTIVE_CODING) || (m_pcJSVMParams->MbInterlace)) && (m_pcGenericRC->m_iFieldControl == 1))
m_pdFCBUCFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit]=m_dCurrentFrameMAD;
else
m_pdBUCFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit]=m_dCurrentFrameMAD;
if(m_iNumberofBasicUnit != 0)
iNc = m_iNumberofCodedPFrame * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;
else
iNc = (m_iNumberofCodedPFrame-1) * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;
}
if(iNc > 1)
bMADModelFlag=true;
m_iPPreHeader = m_pcGenericRC->m_iNumberofHeaderBits;
for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
{// update the history
m_dPRgQp[i] = m_dPRgQp[i - 1];
m_dRgQp[i] = m_dPRgQp[i];
m_dPRgRp[i] = m_dPRgRp[i - 1];
m_dRgRp[i] = m_dPRgRp[i];
}
m_dPRgQp[0] = m_pcGenericRC->QP2Qstep(m_iQc); //*1.0/m_dCurrentFrameMAD;
// frame layer rate control
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
m_dPRgRp[0] = m_pcGenericRC->m_iNumberofTextureBits*1.0/m_dCurrentFrameMAD;
// basic unit layer rate control
else
m_dPRgRp[0] = m_pcGenericRC->m_iNumberofBasicUnitTextureBits*1.0/m_dCurrentFrameMAD;
m_dRgQp[0] = m_dPRgQp[0];
m_dRgRp[0] = m_dPRgRp[0];
m_dX1 = m_dPX1;
m_dX2 = m_dPX2;
// compute the size of window
iWindowSize = (m_dCurrentFrameMAD>m_dPreviousFrameMAD)
? (int)(m_dPreviousFrameMAD/m_dCurrentFrameMAD * (RC_MODEL_HISTORY-1) )
: (int)(m_dCurrentFrameMAD/m_dPreviousFrameMAD *(RC_MODEL_HISTORY-1));
iWindowSize=iClip3(1, iNc, iWindowSize);
iWindowSize=imin(iWindowSize,m_iWindowSize+1);
iWindowSize=imin(iWindowSize,(RC_MODEL_HISTORY-1));
// update the previous window size
m_iWindowSize=iWindowSize;
for (i = 0; i < (RC_MODEL_HISTORY-1); i++)
{
pbRgRejected[i] = false;
}
// initial RD model estimator
RCModelEstimator (iWindowSize, pbRgRejected);
iWindowSize = m_iWindowSize;
// remove outlier
for (i = 0; i < (int) iWindowSize; i++)
{
pdError[i] = m_dX1 / m_dRgQp[i] + m_dX2 / (m_dRgQp[i] * m_dRgQp[i]) - m_dRgRp[i];
dStd += pdError[i] * pdError[i];
}
dThreshold = (iWindowSize == 2) ? 0 : sqrt (dStd / iWindowSize);
for (i = 0; i < (int) iWindowSize; i++)
{
if (fabs(pdError[i]) > dThreshold)
pbRgRejected[i] = true;
}
// always include the last data point
pbRgRejected[0] = false;
// second RD model estimator
RCModelEstimator (iWindowSize, pbRgRejected);
if( bMADModelFlag )
updateMADModel();
else if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
m_dPPictureMAD[0] = m_dCurrentFrameMAD;
}
}
/*!
*************************************************************************************
* \brief
* Model Estimator
*
*************************************************************************************
*/
void rc_quadratic::RCModelEstimator( int iWindowSize, bool *pbRgRejected )
{
int iRealSize = iWindowSize;
int i;
double dOneSampleQ = 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 (pbRgRejected[i])
iRealSize--;
}
// default RD model estimation results
m_dX1 = m_dX2 = 0.0;
for (i = 0; i < iWindowSize; i++)
{
if (!pbRgRejected[i])
dOneSampleQ = m_dRgQp[i];
}
for (i = 0; i < iWindowSize; i++)
{// if all non-rejected Q are the same, take 1st order model
if ((m_dRgQp[i] != dOneSampleQ) && !pbRgRejected[i])
bEstimateX2 = true;
if (!pbRgRejected[i])
m_dX1 += (m_dRgQp[i] * m_dRgRp[i]) / iRealSize;
}
// take 2nd order model to estimate X1 and X2
if ((iRealSize >= 1) && bEstimateX2)
{
for (i = 0; i < iWindowSize; i++)
{
if (!pbRgRejected[i])
{
dA00 = dA00 + 1.0;
dA01 += 1.0 / m_dRgQp[i];
dA10 = dA01;
dA11 += 1.0 / (m_dRgQp[i] * m_dRgQp[i]);
dB0 += m_dRgQp[i] * m_dRgRp[i];
dB1 += m_dRgRp[i];
}
}
// solve the equation of AX = B
dMatrixValue=dA00*dA11-dA01*dA10;
if(fabs(dMatrixValue) > 0.000001)
{
m_dX1 = (dB0 * dA11 - dB1 * dA01) / dMatrixValue;
m_dX2 = (dB1 * dA00 - dB0 * dA10) / dMatrixValue;
}
else
{
m_dX1 = dB0 / dA00;
m_dX2 = 0.0;
}
}
if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
{
m_dPX1 = m_dX1;
m_dPX2 = m_dX2;
}
}
/*!
*************************************************************************************
* \brief
* update the parameters of linear prediction model
*
*************************************************************************************
*/
void rc_quadratic::updateMADModel( void )
{
int iWindowSize;
int i;
double dStd = 0.0, dThreshold;
int iNc = m_iNumberofCodedPFrame;
static bool pbPictureRejected[RC_MODEL_HISTORY];
static double pdError [RC_MODEL_HISTORY];
if(m_iNumberofCodedPFrame>0)
{
// frame layer rate control
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
iNc = m_iNumberofCodedPFrame;
else // basic unit layer rate control
iNc = m_iNumberofCodedPFrame * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;
for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
{// update the history
m_dPPictureMAD[i] = m_dPPictureMAD[i - 1];
m_dPictureMAD[i] = m_dPPictureMAD[i];
m_dReferenceMAD[i] = m_dReferenceMAD[i-1];
}
m_dPPictureMAD[0] = m_dCurrentFrameMAD;
m_dPictureMAD[0] = m_dPPictureMAD[0];
if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
m_dReferenceMAD[0]=m_dPictureMAD[1];
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -