📄 rc_quadratic.c
字号:
int n_realSize = n_windowSize;
int i;
double oneSampleQ = 0.0;
double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0;
double MatrixValue;
Boolean estimateX2 = FALSE;
for (i = 0; i < n_windowSize; i++)
{// find the number of samples which are not rejected
if (PictureRejected[i])
n_realSize--;
}
// default MAD model estimation results
prc->MADPictureC1 = prc->MADPictureC2 = 0.0;
for (i = 0; i < n_windowSize; i++)
{
if (!PictureRejected[i])
oneSampleQ = prc->PictureMAD[i];
}
for (i = 0; i < n_windowSize; i++)
{// if all non-rejected MAD are the same, take 1st order model
if ((prc->PictureMAD[i] != oneSampleQ) && !PictureRejected[i])
estimateX2 = TRUE;
if (!PictureRejected[i])
prc->MADPictureC1 += prc->PictureMAD[i] / (prc->ReferenceMAD[i]*n_realSize);
}
// take 2nd order model to estimate X1 and X2
if ((n_realSize >= 1) && estimateX2)
{
for (i = 0; i < n_windowSize; i++)
{
if (!PictureRejected[i])
{
a00 = a00 + 1.0;
a01 += prc->ReferenceMAD[i];
a10 = a01;
a11 += prc->ReferenceMAD[i] * prc->ReferenceMAD[i];
b0 += prc->PictureMAD[i];
b1 += prc->PictureMAD[i] * prc->ReferenceMAD[i];
}
}
// solve the equation of AX = B
MatrixValue = a00 * a11 - a01 * a10;
if(fabs(MatrixValue) > 0.000001)
{
prc->MADPictureC2 = (b0 * a11 - b1 * a01) / MatrixValue;
prc->MADPictureC1 = (b1 * a00 - b0 * a10) / MatrixValue;
}
else
{
prc->MADPictureC1 = b0/a01;
prc->MADPictureC2 = 0.0;
}
}
if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
{
prc->PMADPictureC1 = prc->MADPictureC1;
prc->PMADPictureC2 = prc->MADPictureC2;
}
}
/*!
*************************************************************************************
* \brief
* compute a quantization parameter for each frame (RC_MODE_0)
*
*************************************************************************************
*/
int updateQPRC0(rc_quadratic *prc, int topfield)
{
int m_Bits;
int BFrameNumber;
int StepSize;
int SumofBasicUnit;
int MaxQpChange, m_Qp, m_Hp;
/* frame layer rate control */
if( img->BasicUnit == img->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((topfield) || (generic_RC->FieldControl==0))
{
if (img->type==I_SLICE)
{
prc->m_Qc = prc->MyInitialQp;
return prc->m_Qc;
}
else if(img->type == B_SLICE)
{
if(input->successive_Bframe==1)
{
if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
updateQPInterlace( prc );
prc->m_Qc = imin(prc->PrevLastQP, prc->CurrLastQP) + 2;
prc->m_Qc = imax(prc->m_Qc, imax(prc->PrevLastQP, prc->CurrLastQP));
prc->m_Qc = imax(prc->m_Qc, prc->CurrLastQP + 1);
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
else
{
BFrameNumber = (prc->NumberofBFrames + 1) % input->successive_Bframe;
if(BFrameNumber==0)
BFrameNumber = input->successive_Bframe;
/*adaptive field/frame coding*/
if(BFrameNumber==1)
{
if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
updateQPInterlace( prc );
}
if((prc->CurrLastQP-prc->PrevLastQP)<=(-2*input->successive_Bframe-3))
StepSize=-3;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-2))
StepSize=-2;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-1))
StepSize=-1;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe))
StepSize=0;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe+1))
StepSize=1;
else
StepSize=2;
prc->m_Qc = prc->PrevLastQP + StepSize;
prc->m_Qc += iClip3( -2 * (BFrameNumber - 1), 2*(BFrameNumber-1),
(BFrameNumber-1)*(prc->CurrLastQP-prc->PrevLastQP)/(input->successive_Bframe-1));
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
return prc->m_Qc;
}
else if( img->type == P_SLICE && prc->NumberofPPicture == 0 )
{
prc->m_Qc=prc->MyInitialQp;
if(generic_RC->FieldControl==0)
updateQPNonPicAFF( prc );
return prc->m_Qc;
}
else
{
/*adaptive field/frame coding*/
if( ( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace ) && generic_RC->FieldControl == 0 )
updateQPInterlaceBU( prc );
prc->m_X1 = prc->Pm_X1;
prc->m_X2 = prc->Pm_X2;
prc->MADPictureC1 = prc->PMADPictureC1;
prc->MADPictureC2 = prc->PMADPictureC2;
prc->PreviousPictureMAD = prc->PPictureMAD[0];
MaxQpChange = prc->PMaxQpChange;
m_Qp = prc->Pm_Qp;
m_Hp = prc->PPreHeader;
/* predict the MAD of current picture*/
prc->CurrentFrameMAD = prc->MADPictureC1*prc->PreviousPictureMAD + prc->MADPictureC2;
/*compute the number of bits for the texture*/
if(prc->Target < 0)
{
prc->m_Qc=m_Qp+MaxQpChange;
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
else
{
m_Bits = prc->Target-m_Hp;
m_Bits = imax(m_Bits, (int)(prc->bit_rate/(MINVALUE*prc->frame_rate)));
updateModelQPFrame( prc, m_Bits );
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // clipping
prc->m_Qc = iClip3(m_Qp-MaxQpChange, m_Qp+MaxQpChange, prc->m_Qc); // control variation
}
if( generic_RC->FieldControl == 0 )
updateQPNonPicAFF( prc );
return prc->m_Qc;
}
}
/*bottom field*/
else
{
if( img->type == P_SLICE && generic_RC->NoGranularFieldRC == 0 )
updateBottomField( prc );
return prc->m_Qc;
}
}
/*basic unit layer rate control*/
else
{
/*top field of I frame*/
if (img->type == I_SLICE)
{
prc->m_Qc = prc->MyInitialQp;
return prc->m_Qc;
}
else if( img->type == B_SLICE )
{
/*top field of B frame*/
if((topfield)||(generic_RC->FieldControl==0))
{
if(input->successive_Bframe==1)
{
/*adaptive field/frame coding*/
if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
updateQPInterlace( prc );
if(prc->PrevLastQP==prc->CurrLastQP)
prc->m_Qc=prc->PrevLastQP+2;
else
prc->m_Qc=(prc->PrevLastQP+prc->CurrLastQP)/2+1;
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
else
{
BFrameNumber=(prc->NumberofBFrames+1)%input->successive_Bframe;
if(BFrameNumber==0)
BFrameNumber=input->successive_Bframe;
/*adaptive field/frame coding*/
if(BFrameNumber==1)
{
if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
updateQPInterlace( prc );
}
if((prc->CurrLastQP-prc->PrevLastQP)<=(-2*input->successive_Bframe-3))
StepSize=-3;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-2))
StepSize=-2;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-1))
StepSize=-1;
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe))
StepSize=0;//0
else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe+1))
StepSize=1;//1
else
StepSize=2;//2
prc->m_Qc=prc->PrevLastQP+StepSize;
prc->m_Qc +=
iClip3( -2*(BFrameNumber-1), 2*(BFrameNumber-1), (BFrameNumber-1)*(prc->CurrLastQP-prc->PrevLastQP)/(input->successive_Bframe-1) );
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
return prc->m_Qc;
}
/*bottom field of B frame*/
else
{
return prc->m_Qc;
}
}
else if( img->type == P_SLICE )
{
if( (generic_RC->NumberofGOP == 1) && (prc->NumberofPPicture == 0) )
{
if((generic_RC->FieldControl==0)||((generic_RC->FieldControl==1) && (generic_RC->NoGranularFieldRC==0)))
return updateFirstP( prc, topfield );
}
else
{
prc->m_X1=prc->Pm_X1;
prc->m_X2=prc->Pm_X2;
prc->MADPictureC1=prc->PMADPictureC1;
prc->MADPictureC2=prc->PMADPictureC2;
m_Qp=prc->Pm_Qp;
if(generic_RC->FieldControl==0)
SumofBasicUnit=prc->TotalNumberofBasicUnit;
else
SumofBasicUnit=prc->TotalNumberofBasicUnit>>1;
/*the average QP of the previous frame is used to coded the first basic unit of the current frame or field*/
if(prc->NumberofBasicUnit==SumofBasicUnit)
return updateFirstBU( prc, topfield );
else
{
/*compute the number of remaining bits*/
prc->Target -= (generic_RC->NumberofBasicUnitHeaderBits + generic_RC->NumberofBasicUnitTextureBits);
generic_RC->NumberofBasicUnitHeaderBits = 0;
generic_RC->NumberofBasicUnitTextureBits = 0;
if(prc->Target<0)
return updateNegativeTarget( prc, topfield, m_Qp );
else
{
/*predict the MAD of current picture*/
predictCurrPicMAD( prc );
/*compute the total number of bits for the current basic unit*/
updateModelQPBU( prc, topfield, m_Qp );
prc->TotalFrameQP +=prc->m_Qc;
prc->Pm_Qp=prc->m_Qc;
prc->NumberofBasicUnit--;
if( prc->NumberofBasicUnit == 0 && img->type == P_SLICE )
updateLastBU( prc, topfield );
return prc->m_Qc;
}
}
}
}
}
return prc->m_Qc;
}
/*!
*************************************************************************************
* \brief
* compute a quantization parameter for each frame
*
*************************************************************************************
*/
int updateQPRC1(rc_quadratic *prc, int topfield)
{
int m_Bits;
int SumofBasicUnit;
int MaxQpChange, m_Qp, m_Hp;
/* frame layer rate control */
if( img->BasicUnit == img->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 vide */
/*top field*/
if((topfield) || (generic_RC->FieldControl==0))
{
if (img->number == 0)
{
prc->m_Qc = prc->MyInitialQp;
return prc->m_Qc;
}
else if( prc->NumberofPPicture == 0 && (img->number != 0))
{
prc->m_Qc=prc->MyInitialQp;
if(generic_RC->FieldControl==0)
updateQPNonPicAFF( prc );
return prc->m_Qc;
}
else
{
/*adaptive field/frame coding*/
if( ( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace ) && generic_RC->FieldControl == 0 )
updateQPInterlaceBU( prc );
prc->m_X1 = prc->Pm_X1;
prc->m_X2 = prc->Pm_X2;
prc->MADPictureC1 = prc->PMADPictureC1;
prc->MADPictureC2 = prc->PMADPictureC2;
prc->PreviousPictureMAD = prc->PPictureMAD[0];
MaxQpChange = prc->PMaxQpChange;
m_Qp = prc->Pm_Qp;
m_Hp = prc->PPreHeader;
/* predict the MAD of current picture*/
prc->CurrentFrameMAD=prc->MADPictureC1*prc->PreviousPictureMAD + prc->MADPictureC2;
/*compute the number of bits for the texture*/
if(prc->Target < 0)
{
prc->m_Qc=m_Qp+MaxQpChange;
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
}
else
{
m_Bits = prc->Target-m_Hp;
m_Bits = imax(m_Bits, (int)(prc->bit_rate/(MINVALUE*prc->frame_rate)));
updateModelQPFrame( prc, m_Bits );
prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // clipping
prc->m_Qc = iClip3(m_Qp-MaxQpChange, m_Qp+MaxQpChange, prc->m_Qc); // control variation
}
if( generic_RC->FieldControl == 0 )
updateQPNonPicAFF( prc );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -