📄 ratectl.c
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy for standardization procedure is available at
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors: Guoping Li, Siwei Ma, Jian Lou, Qiang Wang ,
* Jianwen Chen,Haiwu Zhao, Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
*
******************************************************************************
*/
/*!
***************************************************************************
* \file ratectl.c
*
* \brief
* Rate Control algorithm
*
* \major contributors:
* Siwei Ma <swma@jdl.ac.cn>
* Zhengguo LI<ezgli@lit.a-star.edu.sg>
*
* \date
* 16 Jan. 2003
**************************************************************************
*/
#include <stdio.h>
#include <math.h>
#include "global.h"
#include "ratectl.h"
#include "header.h"
const double THETA=1.3636;
const int Switch=0;
int Iprev_bits=0;
int Pprev_bits=0;
/* rate control variables */
int Xp, Xb;
static int R,T_field;
static int Np, Nb, bits_topfield, Q;
long T,T1;
//HRD consideration
long UpperBound1, UpperBound2, LowerBound;
double InitialDelayOffset;
const double OMEGA=0.9;
double Wp,Wb;
int TotalPFrame;
int DuantQp;
int PDuantQp;
FILE *BitRate;
double DeltaP;
// 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 =(int)((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=img->width/16;
/*adaptive field/frame coding*/
img->FieldControl=0;
RC_MAX_QUANT = 63; // 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
{
//Commented by qihuafei, 20070925
/*adaptive field/frame coding*/
/* if((input->InterlaceCodingOption==2))
{
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*/
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 INTER_IMG:
/*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)
{
//Commented by qihuafei, 20070925, start
/*adaptive frame/filed coding*/
/* if(((input->InterlaceCodingOption==2))\
&&(img->FieldControl==1))
{
for(i=0;i<TotalNumberofBasicUnit;i++)
FCBUPFMAD[i]=FCBUCFMAD[i];
}
else
{
*/ //Commented by qihuafei, 20070925, end
for(i=0;i<TotalNumberofBasicUnit;i++)
BUPFMAD[i]=BUCFMAD[i];
// } //Commented by qihuafei, 20070925
}
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_IMG:
/* 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -