📄 ratectlquadratic.cpp
字号:
{
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->type == P_SLICE )
updateLastBU( iTopField );
return m_iQc;
}
}
}
}
}
return m_iQc;
}
void rc_quadratic::updateQPInterlace( void )
{
if(m_pcGenericRC->m_iFieldControl==0)
{
// previous choice is frame coding
if(m_pcGenericRC->m_iFieldFrame==1)
{
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=m_iFrameQPBuffer;
}
// previous choice is field coding
else
{
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=m_iFieldQPBuffer;
}
}
}
void rc_quadratic::updateQPNonPicAFF( void )
{
if(m_pcJSVMParams->frame_mbs_only_flag)
{
m_iTotalQpforPPicture +=m_iQc;
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=m_iQc;
m_iPQp=m_iQc;
}
// adaptive field/frame coding
else
m_iFrameQPBuffer=m_iQc;
}
void rc_quadratic::updateBottomField( void )
{
// field coding
if(m_pcJSVMParams->PicInterlace==FIELD_CODING)
{
m_iTotalQpforPPicture +=m_iQc;
m_iPrevLastQP=m_iCurrLastQP+1;
m_iCurrLastQP=m_iQc;//+0 Recent change 13/1/2003
m_iPQp=m_iQc;
}
// adaptive field/frame coding
else
m_iFieldQPBuffer=m_iQc;
}
int rc_quadratic::updateFirstP( int iTopField )
{
// top field of the first P frame
m_iQc=m_iMyInitialQp;
m_pcGenericRC->m_iNumberofBasicUnitHeaderBits=0;
m_pcGenericRC->m_iNumberofBasicUnitTextureBits=0;
m_iNumberofBasicUnit--;
// bottom field of the first P frame
if((!iTopField)&&(m_iNumberofBasicUnit==0))
{
// frame coding or field coding
if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
{
m_iTotalQpforPPicture +=m_iQc;
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=m_iQc;
m_iPAveFrameQP=m_iQc;
m_iPAveHeaderBits3=m_iPAveHeaderBits2;
}
// adaptive frame/field coding
else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
{
if(m_pcGenericRC->m_iFieldControl==0)
{
m_iFrameQPBuffer=m_iQc;
m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
}
else
{
m_iFieldQPBuffer=m_iQc;
m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
}
}
}
m_iPQp=m_iQc;
m_iTotalFrameQP +=m_iQc;
return m_iQc;
}
int rc_quadratic::updateNegativeTarget( int iTopField, int iQp )
{
int iPAverageQP;
if(m_bGOPOverdue==true)
m_iQc=iQp+2;
else
m_iQc=iQp+m_iDDquant;//2
m_iQc = imin(m_iQc, m_iRCMaxQuant); // clipping
if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
m_iQc = imin(m_iQc, m_iPAveFrameQP + 6);
else
m_iQc = imin(m_iQc, m_iPAveFrameQP + 3);
m_iTotalFrameQP +=m_iQc;
m_iNumberofBasicUnit--;
if(m_iNumberofBasicUnit==0)
{
if((!iTopField)||(m_pcGenericRC->m_iFieldControl==0))
{
// frame coding or field coding
if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
{
iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
if (m_iNumberofPPicture == (m_pcJSVMParams->intra_period - 2))
m_iQPLastPFrame = iPAverageQP;
m_iTotalQpforPPicture +=iPAverageQP;
if(m_bGOPOverdue==true)
{
m_iPrevLastQP=m_iCurrLastQP+1;
m_iCurrLastQP=iPAverageQP;
}
else
{
if((m_iNumberofPPicture==0)&&(m_pcGenericRC->m_iNumberofGOP>1))
{
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=iPAverageQP;
}
else if(m_iNumberofPPicture>0)
{
m_iPrevLastQP=m_iCurrLastQP+1;
m_iCurrLastQP=iPAverageQP;
}
}
m_iPAveFrameQP=iPAverageQP;
m_iPAveHeaderBits3=m_iPAveHeaderBits2;
}
// adaptive field/frame coding
else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
{
if(m_pcGenericRC->m_iFieldControl==0)
{
iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
m_iFrameQPBuffer=iPAverageQP;
m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
}
else
{
iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
m_iFieldQPBuffer=iPAverageQP;
m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
}
}
}
}
if(m_bGOPOverdue==true)
m_iPQp=m_iPAveFrameQP;
else
m_iPQp=m_iQc;
return m_iQc;
}
int rc_quadratic::updateFirstBU( int iTopField )
{
// adaptive field/frame coding
if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))&&(m_pcGenericRC->m_iFieldControl==0))
{
// previous choice is frame coding
if(m_pcGenericRC->m_iFieldFrame==1)
{
if(m_iNumberofPPicture>0)
m_iTotalQpforPPicture +=m_iFrameQPBuffer;
m_iPAveFrameQP=m_iFrameQPBuffer;
m_iPAveHeaderBits3=m_iFrameAveHeaderBits;
}
// previous choice is field coding
else
{
if(m_iNumberofPPicture>0)
m_iTotalQpforPPicture +=m_iFieldQPBuffer;
m_iPAveFrameQP=m_iFieldQPBuffer;
m_iPAveHeaderBits3=m_iFieldAveHeaderBits;
}
}
if(m_iTarget<=0)
{
m_iQc = m_iPAveFrameQP + 2;
if(m_iQc > m_iRCMaxQuant)
m_iQc = m_iRCMaxQuant;
if(iTopField||(m_pcGenericRC->m_iFieldControl==0))
m_bGOPOverdue=true;
}
else
{
m_iQc=m_iPAveFrameQP;
}
m_iTotalFrameQP +=m_iQc;
m_iNumberofBasicUnit--;
m_iPQp = m_iPAveFrameQP;
return m_iQc;
}
void rc_quadratic::updateLastBU( int iTopField )
{
int iPAverageQP;
if((!iTopField)||(m_pcGenericRC->m_iFieldControl==0))
{
// frame coding or field coding
if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
{
iPAverageQP=(int)((double)m_iTotalFrameQP/(double) m_iTotalNumberofBasicUnit+0.5);
if (m_iNumberofPPicture == (m_pcJSVMParams->intra_period - 2))
m_iQPLastPFrame = iPAverageQP;
m_iTotalQpforPPicture +=iPAverageQP;
m_iPrevLastQP=m_iCurrLastQP;
m_iCurrLastQP=iPAverageQP;
m_iPAveFrameQP=iPAverageQP;
m_iPAveHeaderBits3=m_iPAveHeaderBits2;
}
else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
{
if(m_pcGenericRC->m_iFieldControl==0)
{
iPAverageQP=(int)((double) m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
m_iFrameQPBuffer=iPAverageQP;
m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
}
else
{
iPAverageQP=(int)((double) m_iTotalFrameQP/(double) m_iTotalNumberofBasicUnit+0.5);
m_iFieldQPBuffer=iPAverageQP;
m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
}
}
}
}
void rc_quadratic::predictCurrPicMAD( void )
{
int i;
if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))&&(m_pcGenericRC->m_iFieldControl==1))
{
m_dCurrentFrameMAD=m_dMADPictureC1*m_pdFCBUPFMAD[m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit]+m_dMADPictureC2;
m_dTotalBUMAD=0;
for(i=m_iTotalNumberofBasicUnit-1; i>=(m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit);i--)
{
m_dCurrentBUMAD=m_dMADPictureC1*m_pdFCBUPFMAD[i]+m_dMADPictureC2;
m_dTotalBUMAD +=m_dCurrentBUMAD*m_dCurrentBUMAD;
}
}
else
{
m_dCurrentFrameMAD=m_dMADPictureC1*m_pdBUPFMAD[m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit]+m_dMADPictureC2;
m_dTotalBUMAD=0;
for(i=m_iTotalNumberofBasicUnit-1; i>=(m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit);i--)
{
m_dCurrentBUMAD=m_dMADPictureC1*m_pdBUPFMAD[i]+m_dMADPictureC2;
m_dTotalBUMAD +=m_dCurrentBUMAD*m_dCurrentBUMAD;
}
}
}
void rc_quadratic::updateModelQPBU( int iTopField, int iQp )
{
double dTmp, dQstep;
int iBits;
// compute the total number of bits for the current basic unit
iBits =(int)(m_iTarget * m_dCurrentFrameMAD * m_dCurrentFrameMAD / m_dTotalBUMAD);
// compute the number of texture bits
iBits -=m_iPAveHeaderBits2;
iBits=imax(iBits,(int)(m_fBitRate/(m_fMINVALUE*m_fFrameRate*m_iTotalNumberofBasicUnit)));
dTmp = m_dCurrentFrameMAD * m_dCurrentFrameMAD * m_dX1 * m_dX1 \
+ 4 * m_dX2 * m_dCurrentFrameMAD * iBits;
if ((m_dX2 == 0.0) || (dTmp < 0) || ((sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD) <= 0.0)) // fall back 1st order mode
dQstep = (float)(m_dX1 * m_dCurrentFrameMAD / (double) iBits);
else // 2nd order mode
dQstep = (float) ((2 * m_dX2 * m_dCurrentFrameMAD) / (sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD));
m_iQc = m_pcGenericRC->Qstep2QP(dQstep);
m_iQc = imin(iQp+m_iDDquant, m_iQc); // control variation
if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
m_iQc = imin(m_iPAveFrameQP+6, m_iQc);
else
m_iQc = imin(m_iPAveFrameQP+3, m_iQc);
m_iQc = iClip3(iQp-m_iDDquant, m_iRCMaxQuant, m_iQc); // clipping
if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
m_iQc = imax(m_iPAveFrameQP-6, m_iQc);
else
m_iQc = imax(m_iPAveFrameQP-3, m_iQc);
m_iQc = imax(m_iRCMinQuant, m_iQc);
}
void rc_quadratic::updateQPInterlaceBU( void )
{
// previous choice is frame coding
if(m_pcGenericRC->m_iFieldFrame==1)
{
m_iTotalQpforPPicture +=m_iFrameQPBuffer;
m_iPQp=m_iFrameQPBuffer;
}
// previous choice is field coding
else
{
m_iTotalQpforPPicture +=m_iFieldQPBuffer;
m_iPQp=m_iFieldQPBuffer;
}
}
void rc_quadratic::updateModelQPFrame( int iBits )
{
double dTmp, dQstep;
dTmp = m_dCurrentFrameMAD * m_dX1 * m_dCurrentFrameMAD * m_dX1
+ 4 * m_dX2 * m_dCurrentFrameMAD * iBits;
if ((m_dX2 == 0.0) || (dTmp < 0) || ((sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD) <= 0.0)) // fall back 1st order mode
dQstep = (float) (m_dX1 * m_dCurrentFrameMAD / (double) iBits);
else // 2nd order mode
dQstep = (float) ((2 * m_dX2 * m_dCurrentFrameMAD) / (sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD));
m_iQc = m_pcGenericRC->Qstep2QP(dQstep);
}
void rc_quadratic::init( void )
{
m_fTHETA = 1.3636F;
m_fOMEGA = 0.9F;
m_i64IPrevBits = 0;
m_i64PPrevBits = 0;
m_pcJSVMParams->FrameSizeInMbs = (m_pcJSVMParams->height / MB_BLOCK_SIZE) *
(m_pcJSVMParams->width / MB_BLOCK_SIZE );
if ( m_pcJSVMParams->FrameSizeInMbs % m_pcJSVMParams->BasicUnit != 0 ) {
fprintf(stderr, "\nBasicUnit is required to be fraction of the total number of 16x16 MBs\n");
assert(0); // some compilers do not compile assert in release/Ox mode
exit(1);
}
m_pcJSVMParams->jumpd = m_pcJSVMParams->successive_Bframe;
m_pcJSVMParams->PicInterlace = FRAME_CODING;
m_pcJSVMParams->MbInterlace = 0;
m_pcJSVMParams->channel_type = 0;
m_pcJSVMParams->frame_mbs_only_flag = 1;
m_pcJSVMParams->intra_period = 0;
m_pcJSVMParams->NumberofCodedMacroBlocks = 0;
m_pcJSVMParams->current_mb_nr = 0;
m_pcGenericRC->m_iRemainingBits = 0;
m_iTargetField = 0; /* formerly static */
m_iNp = 0;
m_iNb = 0;
m_iBitsTopField = 0; /* formerly static */
if ( m_pcJSVMParams->frame_mbs_only_flag )
m_pcGenericRC->m_iTopFieldFlag = 0;
m_pcJSVMParams->qp = 30;
if ( m_pcJSVMParams->m_uiIntraPeriod != 1 )
m_pcJSVMParams->RCUpdateMode = RC_MODE_2;
else
m_pcJSVMParams->RCUpdateMode = RC_MODE_1;
m_pcJSVMParams->number = 0;
m_pcJSVMParams->PicWidthInMbs = m_pcJSVMParams->width / MB_BLOCK_SIZE;
m_pcJSVMParams->size = m_pcJSVMParams->width * m_pcJSVMParams->height;
if ( m_pcJSVMParams->successive_Bframe > 1 )
m_pcJSVMParams->HierarchicalCoding = 2;
else
m_pcJSVMParams->HierarchicalCoding = 0;
rc_alloc();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -