📄 rc_quadratic.c
字号:
denom += (float)input->RCISliceBitRatio - 1.0F;
}
// set bit targets for each type of frame
generic_RC->RCPSliceBits = (int) floor( numer / denom + 0.5F );
generic_RC->RCISliceBits = (input->intra_period) ? (int)(input->RCISliceBitRatio * generic_RC->RCPSliceBits + 0.5) : 0;
for ( level = 0; level < levels; level++ )
{
generic_RC->RCBSliceBits[level] = (int)floor(input->RCBSliceBitRatio[level] * generic_RC->RCPSliceBits + 0.5);
}
generic_RC->NIslice = (input->intra_period) ? ((input->no_frames - 1) / input->intra_period) : 0;
generic_RC->NPslice = input->no_frames - 1 - generic_RC->NIslice;
}
break;
default:
break;
}
/* check if the last GOP over uses its budget. If yes, the initial QP of the I frame in
the coming GOP will be increased.*/
if(generic_RC->RemainingBits<0)
Overum=TRUE;
OverBits=-(int)(generic_RC->RemainingBits);
/*initialize the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
prc->LowerBound = (int)(generic_RC->RemainingBits + prc->bit_rate / prc->frame_rate);
prc->UpperBound1 = (int)(generic_RC->RemainingBits + (prc->bit_rate * 2.048));
/*compute the total number of bits for the current GOP*/
AllocatedBits = (int) floor((1 + np + nb) * prc->bit_rate / prc->frame_rate + 0.5);
generic_RC->RemainingBits += AllocatedBits;
prc->Np = np;
prc->Nb = nb;
OverDuantQp=(int)(8 * OverBits/AllocatedBits+0.5);
prc->GOPOverdue=FALSE;
/*field coding*/
//generic_RC->NoGranularFieldRC = ( input->PicInterlace || !input->MbInterlace || input->basicunit != img->FrameSizeInMbs );
if ( !input->PicInterlace && input->MbInterlace && input->basicunit == img->FrameSizeInMbs )
generic_RC->NoGranularFieldRC = 0;
else
generic_RC->NoGranularFieldRC = 1;
/*Compute InitialQp for each GOP*/
prc->TotalPFrame=np;
generic_RC->NumberofGOP++;
if(generic_RC->NumberofGOP==1)
{
prc->MyInitialQp = input->SeinitialQP;
prc->CurrLastQP = prc->MyInitialQp - 1; //recent change -0;
prc->QPLastGOP = prc->MyInitialQp;
prc->PAveFrameQP = prc->MyInitialQp;
prc->m_Qc = prc->PAveFrameQP;
prc->FieldQPBuffer = prc->PAveFrameQP;
prc->FrameQPBuffer = prc->PAveFrameQP;
prc->PAverageQp = prc->PAveFrameQP;
}
else
{
/*adaptive field/frame coding*/
if( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace )
{
if (generic_RC->FieldFrame == 1)
{
prc->TotalQpforPPicture += prc->FrameQPBuffer;
prc->QPLastPFrame = prc->FrameQPBuffer;
}
else
{
prc->TotalQpforPPicture += prc->FieldQPBuffer;
prc->QPLastPFrame = prc->FieldQPBuffer;
}
}
/*compute the average QP of P frames in the previous GOP*/
prc->PAverageQp=(int)(1.0 * prc->TotalQpforPPicture / prc->NumberofPPicture+0.5);
GOPDquant=(int)((1.0*(np+nb+1)/15.0) + 0.5);
if(GOPDquant>2)
GOPDquant=2;
prc->PAverageQp -= GOPDquant;
if (prc->PAverageQp > (prc->QPLastPFrame - 2))
prc->PAverageQp--;
// QP is constrained by QP of previous QP
prc->PAverageQp = iClip3(prc->QPLastGOP - 2, prc->QPLastGOP + 2, prc->PAverageQp);
// Also clipped within range.
prc->PAverageQp = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->PAverageQp);
prc->MyInitialQp = prc->PAverageQp;
prc->Pm_Qp = prc->PAverageQp;
prc->PAveFrameQP = prc->PAverageQp;
prc->QPLastGOP = prc->MyInitialQp;
prc->PrevLastQP = prc->CurrLastQP;
prc->CurrLastQP = prc->MyInitialQp - 1;
}
prc->TotalQpforPPicture=0;
prc->NumberofPPicture=0;
prc->NumberofBFrames=0;
}
/*!
*************************************************************************************
* \brief
* Initialize one picture
*
*************************************************************************************
*/
void rc_init_pict(rc_quadratic *prc, int fieldpic,int topfield,int targetcomputation, float mult)
{
int tmp_T;
/* compute the total number of basic units in a frame */
if(input->MbInterlace)
prc->TotalNumberofBasicUnit = img->FrameSizeInMbs / img->BasicUnit;
else
prc->TotalNumberofBasicUnit = img->FrameSizeInMbs / input->basicunit;
img->NumberofCodedMacroBlocks = 0;
/* Normally, the bandwidth for the VBR case is estimated by
a congestion control algorithm. A bandwidth curve can be predefined if we only want to
test the proposed algorithm */
if(input->channel_type==1)
{
if(prc->NumberofCodedPFrame==58)
prc->bit_rate *= 1.5;
else if(prc->NumberofCodedPFrame==59)
prc->PrevBitRate = prc->bit_rate;
}
/* predefine a target buffer level for each frame */
if((fieldpic||topfield) && targetcomputation)
{
if ( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number !=0)) )
{
/* Since the available bandwidth may vary at any time, the total number of
bits is updated picture by picture*/
if(prc->PrevBitRate!=prc->bit_rate)
generic_RC->RemainingBits +=(int) floor((prc->bit_rate-prc->PrevBitRate)*(prc->Np + prc->Nb)/prc->frame_rate+0.5);
/* predefine the target buffer level for each picture.
frame layer rate control */
if(img->BasicUnit == img->FrameSizeInMbs)
{
if(prc->NumberofPPicture==1)
{
prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel) / (prc->TotalPFrame-1);
prc->TargetBufferLevel -= prc->DeltaP;
}
else if(prc->NumberofPPicture>1)
prc->TargetBufferLevel -= prc->DeltaP;
}
/* basic unit layer rate control */
else
{
if(prc->NumberofCodedPFrame>0)
{
/* adaptive frame/field coding */
if(((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))&&(generic_RC->FieldControl==1))
memcpy((void *)prc->FCBUPFMAD,(void *)prc->FCBUCFMAD, prc->TotalNumberofBasicUnit * sizeof(double));
else
memcpy((void *)prc->BUPFMAD,(void *)prc->BUCFMAD, prc->TotalNumberofBasicUnit * sizeof(double));
}
if(generic_RC->NumberofGOP==1)
{
if(prc->NumberofPPicture==1)
{
prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel)/(prc->TotalPFrame - 1);
prc->TargetBufferLevel -= prc->DeltaP;
}
else if(prc->NumberofPPicture>1)
prc->TargetBufferLevel -= prc->DeltaP;
}
else if(generic_RC->NumberofGOP>1)
{
if(prc->NumberofPPicture==0)
{
prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel) / prc->TotalPFrame;
prc->TargetBufferLevel -= prc->DeltaP;
}
else if(prc->NumberofPPicture>0)
prc->TargetBufferLevel -= prc->DeltaP;
}
}
if(prc->NumberofCodedPFrame==1)
prc->AveWp = prc->Wp;
if((prc->NumberofCodedPFrame<8)&&(prc->NumberofCodedPFrame>1))
prc->AveWp = (prc->AveWp + prc->Wp * (prc->NumberofCodedPFrame-1))/prc->NumberofCodedPFrame;
else if(prc->NumberofCodedPFrame>1)
prc->AveWp = (prc->Wp + 7 * prc->AveWp) / 8;
// compute the average complexity of B frames
if(input->successive_Bframe>0)
{
// compute the target buffer level
prc->TargetBufferLevel += (prc->AveWp * (input->successive_Bframe + 1)*prc->bit_rate\
/(prc->frame_rate*(prc->AveWp+prc->AveWb*input->successive_Bframe))-prc->bit_rate/prc->frame_rate);
}
}
else if ( img->type == B_SLICE )
{
/* update the total number of bits if the bandwidth is changed*/
if(prc->PrevBitRate != prc->bit_rate)
generic_RC->RemainingBits +=(int) floor((prc->bit_rate-prc->PrevBitRate) * (prc->Np + prc->Nb) / prc->frame_rate+0.5);
if((prc->NumberofCodedPFrame==1)&&(generic_RC->NumberofCodedBFrame==1))
{
prc->AveWp = prc->Wp;
prc->AveWb = prc->Wb;
}
else if(generic_RC->NumberofCodedBFrame > 1)
{
//compute the average weight
if(generic_RC->NumberofCodedBFrame<8)
prc->AveWb = (prc->AveWb + prc->Wb*(generic_RC->NumberofCodedBFrame-1)) / generic_RC->NumberofCodedBFrame;
else
prc->AveWb = (prc->Wb + 7 * prc->AveWb) / 8;
}
}
/* Compute the target bit for each frame */
if( img->type == P_SLICE || ( (img->number != 0) && (input->RCUpdateMode == RC_MODE_1 || input->RCUpdateMode == RC_MODE_3 ) ) )
{
/* frame layer rate control */
if(img->BasicUnit == img->FrameSizeInMbs || (input->RCUpdateMode == RC_MODE_3) )
{
if(prc->NumberofCodedPFrame>0)
{
if (input->RCUpdateMode == RC_MODE_3)
{
int level_idx = (img->type == B_SLICE && input->HierarchicalCoding) ? (generic_RC->temporal_levels - 1 - gop_structure[img->b_frame_to_code-1].hierarchy_layer) : 0;
int bitrate = (img->type == B_SLICE) ? generic_RC->RCBSliceBits[ level_idx ]
: ( img->type == P_SLICE ? generic_RC->RCPSliceBits : generic_RC->RCISliceBits );
int level, denom = generic_RC->NIslice * generic_RC->RCISliceBits + generic_RC->NPslice * generic_RC->RCPSliceBits;
if ( input->HierarchicalCoding )
{
for ( level = 0; level < generic_RC->temporal_levels; level++ )
denom += generic_RC->hierNb[ level ] * generic_RC->RCBSliceBits[ level ];
}
else
{
denom += generic_RC->hierNb[0] * generic_RC->RCBSliceBits[0];
}
// target due to remaining bits
prc->Target = (int) floor( (float)(1.0 * bitrate * generic_RC->RemainingBits) / (float)denom + 0.5F );
// target given original taget rate and buffer considerations
tmp_T = imax(0, (int) floor( (double)bitrate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5) );
// translate Target rate from B or I "domain" to P domain since the P RC model is going to be used to select the QP
// for hierarchical coding adjust the target QP to account for different temporal levels
switch( img->type )
{
case B_SLICE:
prc->Target = (int) floor( (float)prc->Target / input->RCBoverPRatio + 0.5F);
break;
case I_SLICE:
prc->Target = (int) floor( (float)prc->Target / (input->RCIoverPRatio * 4.0) + 0.5F); // 4x accounts for the fact that header bits reduce the percentage of texture
break;
case P_SLICE:
default:
break;
}
}
else
{
prc->Target = (int) floor( prc->Wp * generic_RC->RemainingBits / (prc->Np * prc->Wp + prc->Nb * prc->Wb) + 0.5);
tmp_T = imax(0, (int) floor(prc->bit_rate / prc->frame_rate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5));
prc->Target = (int) floor(prc->BETAP * (prc->Target - tmp_T) + tmp_T + 0.5);
}
}
}
/* basic unit layer rate control */
else
{
if(((generic_RC->NumberofGOP == 1)&&(prc->NumberofCodedPFrame>0))
|| (generic_RC->NumberofGOP > 1))
{
prc->Target = (int) (floor( prc->Wp * generic_RC->RemainingBits / (prc->Np * prc->Wp + prc->Nb * prc->Wb) + 0.5));
tmp_T = imax(0, (int) (floor(prc->bit_rate / prc->frame_rate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5)));
prc->Target = (int) (floor(prc->BETAP * (prc->Target - tmp_T) + tmp_T + 0.5));
}
}
prc->Target = (int)(mult * prc->Target);
/* reserve some bits for smoothing */
prc->Target = (int)((1.0 - 0.0 * input->successive_Bframe) * prc->Target);
/* HRD consideration */
if ( input->RCUpdateMode != RC_MODE_3 || img->type == P_SLICE )
prc->Target = iClip3(prc->LowerBound, prc->UpperBound2, prc->Target);
if((topfield) || (fieldpic && ((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))))
prc->TargetField=prc->Target;
}
}
if(fieldpic || topfield)
{
/* frame layer rate control */
generic_RC->NumberofHeaderBits = 0;
generic_RC->NumberofTextureBits = 0;
/* basic unit layer rate control */
if(img->BasicUnit < img->FrameSizeInMbs)
{
prc->TotalFrameQP = 0;
generic_RC->NumberofBasicUnitHeaderBits = 0;
generic_RC->NumberofBasicUnitTextureBits = 0;
generic_RC->TotalMADBasicUnit = 0;
if(generic_RC->FieldControl==0)
prc->NumberofBasicUnit = prc->TotalNumberofBasicUnit;
else
prc->NumberofBasicUnit = prc->TotalNumberofBasicUnit >> 1;
}
}
if( ( img->type==P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) ) && img->BasicUnit < img->FrameSizeInMbs && generic_RC->FieldControl == 1 )
{
/* top field at basic unit layer rate control */
if(topfield)
{
prc->bits_topfield=0;
prc->Target=(int)(prc->TargetField*0.6);
}
/* bottom field at basic unit layer rate control */
else
{
prc->Target=prc->TargetField-prc->bits_topfield;
generic_RC->NumberofBasicUnitHeaderBits=0;
generic_RC->NumberofBasicUnitTextureBits=0;
generic_RC->TotalMADBasicUnit=0;
prc->NumberofBasicUnit=prc->TotalNumberofBasicUnit >> 1;
}
}
}
/*!
*************************************************************************************
* \brief
* update one picture after frame/field encoding
*
* \param nbits
* number of bits used for picture
*
*************************************************************************************
*/
void rc_update_pict(rc_quadratic *prc, int nbits)
{
int delta_bits = (nbits - (int)floor(prc->bit_rate / prc->frame_rate + 0.5F) );
generic_RC->RemainingBits -= nbits; /* remaining # of bits in GOP */
generic_RC->CurrentBufferFullness += delta_bits;
/*update the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
prc->LowerBound -= (int) delta_bits;
prc->UpperBound1 -= (int) delta_bits;
prc->UpperBound2 = (int)(OMEGA * prc->UpperBound1);
return;
}
int updateComplexity( rc_quadratic *prc, Boolean is_updated, int nbits )
{
double Avem_Qc;
/* frame layer rate control */
if(img->BasicUnit == img->FrameSizeInMbs)
return ((int) floor(nbits * prc->m_Qc + 0.5));
/* basic unit layer rate control */
else
{
if( is_updated )
{
if( generic_RC->NoGranularFieldRC == 0 || generic_RC->FieldControl == 0 )
{
Avem_Qc = (double)prc->TotalFrameQP / (double)prc->TotalNumberofBasicUnit;
return ((int)floor(nbits * Avem_Qc + 0.5));
}
}
else if( img->type == B_SLICE )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -