📄 ratectl.c
字号:
/**********************************************************************
* Software Copyright Licensing Disclaimer
*
* This software module was originally developed by contributors to the
* course of the development of ISO/IEC 14496-10 for reference purposes
* and its performance may not have been optimized. This software
* module is an implementation of one or more tools as specified by
* ISO/IEC 14496-10. ISO/IEC gives users free license to this software
* module or modifications thereof. Those intending to use this software
* module in products are advised that its use may infringe existing
* patents. ISO/IEC have no liability for use of this software module
* or modifications thereof. The original contributors retain full
* rights to modify and use the code for their own purposes, and to
* assign or donate the code to third-parties.
*
* This copyright notice must be included in all copies or derivative
* works. Copyright (c) ISO/IEC 2004.
**********************************************************************/
/*!
***************************************************************************
* \file ratectl.c
*
* \brief
* Rate Control algorithm
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Siwei Ma <swma@jdl.ac.cn>
* - Zhengguo LI<ezgli@lit.a-star.edu.sg>
*
* \date
* 16 Jan. 2003
**************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "ratectl.h"
const double THETA=1.3636;
const int Switch=0;
int Iprev_bits=0;
int Pprev_bits=0;
/* rate control variables */
int Xp = 0, Xb = 0;
static int R = 0,T_field = 0;
static int Np = 0, Nb = 0, bits_topfield = 0, Q = 0;
long T = 0,T1 = 0;
//HRD consideration
long UpperBound1 = 0, UpperBound2 = 0, LowerBound = 0;
double InitialDelayOffset = 0;
const double OMEGA=0.9;
double Wp = 0,Wb = 0;
int TotalPFrame = 0;
int DuantQp = 0;
int PDuantQp = 0;
FILE *BitRate = 0;
double DeltaP = 0;
// Initiate rate control parameters
void rc_init_seq()
{
double L1,L2,L3,bpp;
int qp;
int i;
Xp=0;
Xb=0;
bit_rate=input->bit_rate;
frame_rate = (float)(img->framerate *(input->successive_Bframe + 1)) / (float) (input->jumpd + 1);
PreviousBit_Rate=bit_rate;
/*compute the total number of MBs in a frame*/
img->Frame_Total_Number_MB=img->height*img->width/256;
if(input->basicunit>img->Frame_Total_Number_MB)
input->basicunit=img->Frame_Total_Number_MB;
if(input->basicunit<img->Frame_Total_Number_MB)
TotalNumberofBasicUnit=img->Frame_Total_Number_MB/input->basicunit;
MINVALUE=4.0;
/*initialize the parameters of fluid flow traffic model*/
BufferSize=bit_rate*2.56;
CurrentBufferFullness=0;
GOPTargetBufferLevel=CurrentBufferFullness;
/*HRD consideration*/
InitialDelayOffset=BufferSize*0.8;
/*initialize the previous window size*/
m_windowSize=0;
MADm_windowSize=0;
img->NumberofCodedBFrame=0;
img->NumberofCodedPFrame=0;
img->NumberofGOP=0;
/*remaining # of bits in GOP */
R = 0;
/*control parameter */
if(input->successive_Bframe>0)
{
GAMMAP=0.25;
BETAP=0.9;
}
else
{
GAMMAP=0.5;
BETAP=0.5;
}
/*quadratic rate-distortion model*/
PPreHeader=0;
Pm_X1=bit_rate*1.0;
Pm_X2=0.0;
/* linear prediction model for P picture*/
PMADPictureC1=1.0;
PMADPictureC2=0.0;
for(i=0;i<20;i++)
{
Pm_rgQp[i]=0;
Pm_rgRp[i]=0.0;
PPictureMAD[i]=0.0;
}
PPictureMAD[20]=0.0;
//Define the largest variation of quantization parameters
PDuantQp=2;
/*basic unit layer rate control*/
PAveHeaderBits1=0;
PAveHeaderBits3=0;
if(TotalNumberofBasicUnit>=9)
DDquant=1;
else
DDquant=2;
MBPerRow=input->img_width/16;
/*adaptive field/frame coding*/
img->FieldControl=0;
RC_MAX_QUANT = 51; // clipping
RC_MIN_QUANT = 0;//clipping
/*compute thei initial QP*/
bpp = 1.0*bit_rate /(frame_rate*img->width*img->height);
if (img->width == 176)
{
L1 = 0.1;
L2 = 0.3;
L3 = 0.6;
}else if (img->width == 352)
{
L1 = 0.2;
L2 = 0.6;
L3 = 1.2;
}else
{
L1 = 0.6;
L2 = 1.4;
L3 = 2.4;
}
if (input->SeinitialQP==0)
{
if(bpp<= L1)
qp = 35;
else
if(bpp<=L2)
qp = 25;
else
if(bpp<=L3)
qp = 20;
else
qp =10;
input->SeinitialQP = qp;
}
}
// Initiate one GOP
void rc_init_GOP(int np, int nb)
{
Boolean Overum=FALSE;
int OverBits;
int OverDuantQp;
int AllocatedBits;
int GOPDquant;
/*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(R<0)
Overum=TRUE;
OverBits=-R;
/*initialize the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
LowerBound=(long)(R+bit_rate/frame_rate);
UpperBound1=(long)(R+InitialDelayOffset);
/*compute the total number of bits for the current GOP*/
AllocatedBits = (int) floor((1 + np + nb) * bit_rate / frame_rate + 0.5);
R +=AllocatedBits;
Np = np;
Nb = nb;
OverDuantQp=(int)(8*OverBits/AllocatedBits+0.5);
GOPOverdue=FALSE;
/*field coding*/
img->IFLAG=1;
/*Compute InitialQp for each GOP*/
TotalPFrame=np;
img->NumberofGOP++;
if(img->NumberofGOP==1)
{
MyInitialQp=input->SeinitialQP;
PreviousQp2=MyInitialQp-1; //recent change -0;
QPLastGOP=MyInitialQp;
}
else
{
/*adaptive field/frame coding*/
if((input->PicInterlace==ADAPTIVE_CODING)\
||(input->MbInterlace))
{
if (img->FieldFrame == 1)
{
img->TotalQpforPPicture += FrameQPBuffer;
QPLastPFrame = FrameQPBuffer;
}
else
{
img->TotalQpforPPicture += FieldQPBuffer;
QPLastPFrame = FieldQPBuffer;
}
}
/*compute the average QP of P frames in the previous GOP*/
PAverageQp=(int)(1.0*img->TotalQpforPPicture/img->NumberofPPicture+0.5);
GOPDquant=(int)(0.5+1.0*(np+nb+1)/15);
if(GOPDquant>2)
GOPDquant=2;
PAverageQp-=GOPDquant;
if (PAverageQp > (QPLastPFrame - 2))
PAverageQp--;
PAverageQp = MAX(QPLastGOP-2, PAverageQp);
PAverageQp = MIN(QPLastGOP+2, PAverageQp);
PAverageQp = MIN(RC_MAX_QUANT, PAverageQp);
PAverageQp = MAX(RC_MIN_QUANT, PAverageQp);
MyInitialQp=PAverageQp;
QPLastGOP = MyInitialQp;
Pm_Qp=PAverageQp;
PAveFrameQP=PAverageQp;
PreviousQp1=PreviousQp2;
PreviousQp2=MyInitialQp-1;
}
img->TotalQpforPPicture=0;
img->NumberofPPicture=0;
NumberofBFrames=0;
}
void rc_init_pict(int fieldpic,int topfield,int targetcomputation)
{
int i;
/*compute the total number of basic units in a frame*/
if(input->MbInterlace)
TotalNumberofBasicUnit=img->Frame_Total_Number_MB/img->BasicUnit;
img->NumberofCodedMacroBlocks=0;
/*Normally, the bandwith 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(img->NumberofCodedPFrame==58)
bit_rate *=1.5;
else if(img->NumberofCodedPFrame==59)
PreviousBit_Rate=bit_rate;
}
/*predefine a target buffer level for each frame*/
if((fieldpic||topfield)&&targetcomputation)
{
switch (img->type)
{
case P_SLICE:
/*Since the available bandwidth may vary at any time, the total number of
bits is updated picture by picture*/
if(PreviousBit_Rate!=bit_rate)
R +=(int) floor((bit_rate-PreviousBit_Rate)*(Np+Nb)/frame_rate+0.5);
/* predefine the target buffer level for each picture.
frame layer rate control*/
if(img->BasicUnit==img->Frame_Total_Number_MB)
{
if(img->NumberofPPicture==1)
{
TargetBufferLevel=CurrentBufferFullness;
DeltaP=(CurrentBufferFullness-GOPTargetBufferLevel)/(TotalPFrame-1);
TargetBufferLevel -=DeltaP;
}
else if(img->NumberofPPicture>1)
TargetBufferLevel -=DeltaP;
}
/*basic unit layer rate control*/
else
{
if(img->NumberofCodedPFrame>0)
{
/*adaptive frame/filed coding*/
if(((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))\
&&(img->FieldControl==1))
{
for(i=0;i<TotalNumberofBasicUnit;i++)
FCBUPFMAD[i]=FCBUCFMAD[i];
}
else
{
for(i=0;i<TotalNumberofBasicUnit;i++)
BUPFMAD[i]=BUCFMAD[i];
}
}
if(img->NumberofGOP==1)
{
if(img->NumberofPPicture==1)
{
TargetBufferLevel=CurrentBufferFullness;
DeltaP=(CurrentBufferFullness-GOPTargetBufferLevel)/(TotalPFrame-1);
TargetBufferLevel -=DeltaP;
}
else if(img->NumberofPPicture>1)
TargetBufferLevel -=DeltaP;
}
else if(img->NumberofGOP>1)
{
if(img->NumberofPPicture==0)
{
TargetBufferLevel=CurrentBufferFullness;
DeltaP=(CurrentBufferFullness-GOPTargetBufferLevel)/TotalPFrame;
TargetBufferLevel -=DeltaP;
}
else if(img->NumberofPPicture>0)
TargetBufferLevel -=DeltaP;
}
}
if(img->NumberofCodedPFrame==1)
AWp=Wp;
if((img->NumberofCodedPFrame<8)&&(img->NumberofCodedPFrame>1))
AWp=Wp*(img->NumberofCodedPFrame-1)/img->NumberofCodedPFrame+\
AWp/img->NumberofCodedPFrame;
else if(img->NumberofCodedPFrame>1)
AWp=Wp/8+7*AWp/8;
//compute the average complexity of B frames
if(input->successive_Bframe>0)
{
//compute the target buffer level
TargetBufferLevel +=(AWp*(input->successive_Bframe+1)*bit_rate\
/(frame_rate*(AWp+AWb*input->successive_Bframe))-bit_rate/frame_rate);
}
break;
case B_SLICE:
/* update the total number of bits if the bandwidth is changed*/
if(PreviousBit_Rate!=bit_rate)
R +=(int) floor((bit_rate-PreviousBit_Rate)*(Np+Nb)/frame_rate+0.5);
if((img->NumberofCodedPFrame==1)&&(img->NumberofCodedBFrame==1))
{
AWp=Wp;
AWb=Wb;
}
else if(img->NumberofCodedBFrame>1)
{
//compute the average weight
if(img->NumberofCodedBFrame<8)
AWb=Wb*(img->NumberofCodedBFrame-1)/img->NumberofCodedBFrame+\
AWb/img->NumberofCodedBFrame;
else
AWb=Wb/8+7*AWb/8;
}
break;
}
/*Compute the target bit for each frame*/
if(img->type==P_SLICE)
{
/*frame layer rate control*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -