⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ratectl.c

📁 h.264标准和jm
💻 C
📖 第 1 页 / 共 3 页
字号:
 /*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose.  In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/

/*!
 ***************************************************************************
 * \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"


const double THETA=1.3636;
const int Switch=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 = (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->InterlaceCodingOption==1)\
			||(input->InterlaceCodingOption==3))
		{
			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->InterlaceCodingOption==3)
		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->InterlaceCodingOption==1)||(input->InterlaceCodingOption==3))\
							&&(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*/
			if(img->BasicUnit==img->Frame_Total_Number_MB)
			{
				if(img->NumberofCodedPFrame>0)
				{
					T = (long) floor(Wp*R/(Np*Wp+Nb*Wb) + 0.5);
								
					T1 = (long) floor(bit_rate/frame_rate-GAMMAP*(CurrentBufferFullness-TargetBufferLevel)+0.5);
					T1=MAX(0,T1);
					T = (long)(floor(BETAP*T+(1.0-BETAP)*T1+0.5));
				}
			 }
			/*basic unit layer rate control*/
			else
			{
				if((img->NumberofGOP==1)&&(img->NumberofCodedPFrame>0))
				{
					T = (int) floor(Wp*R/(Np*Wp+Nb*Wb) + 0.5);
					T1 = (int) floor(bit_rate/frame_rate-GAMMAP*(CurrentBufferFullness-TargetBufferLevel)+0.5);
					T1=MAX(0,T1);
					T = (int)(floor(BETAP*T+(1.0-BETAP)*T1+0.5));
				}
				else if(img->NumberofGOP>1)
				{
					T = (long) floor(Wp*R/(Np*Wp+Nb*Wb) + 0.5);
					T1 = (long) floor(bit_rate/frame_rate-GAMMAP*(CurrentBufferFullness-TargetBufferLevel)+0.5);
					T1 = MAX(0,T1);
					T = (long)(floor(BETAP*T+(1.0-BETAP)*T1+0.5));
				}
			}

			/*reserve some bits for smoothing*/

			T=(long)((1.0-0.0*input->successive_Bframe)*T);
			/*HRD consideration*/
			T = MAX(T, (long) LowerBound);
    		T = MIN(T, (long) UpperBound2);

			if((topfield)||(fieldpic&&((input->InterlaceCodingOption==1)\
				||(input->InterlaceCodingOption==3))))
				T_field=T;
		}
	}

	if(fieldpic||topfield)
	{
		/*frame layer rate control*/
		img->NumberofHeaderBits=0;
		img->NumberofTextureBits=0;

		/*basic unit layer rate control*/
		if(img->BasicUnit<img->Frame_Total_Number_MB)
		{
			TotalFrameQP=0;
			img->NumberofBasicUnitHeaderBits=0;
			img->NumberofBasicUnitTextureBits=0;
			img->TotalMADBasicUnit=0;
			if(img->FieldControl==0)
				NumberofBasicUnit=TotalNumberofBasicUnit;
			else
				NumberofBasicUnit=TotalNumberofBasicUnit/2;
		}
	}
		
	if((img->type==P_SLICE)&&(img->BasicUnit<img->Frame_Total_Number_MB)\
		&&(img->FieldControl==1))
	{
	/*top filed at basic unit layer rate control*/
		if(topfield)
		{
			bits_topfield=0;
			T=(long)(T_field*0.6);
		}
  /*bottom filed at basic unit layer rate control*/
		else
		{
			T=T_field-bits_topfield;
			img->NumberofBasicUnitHeaderBits=0;
			img->NumberofBasicUnitTextureBits=0;
			img->TotalMADBasicUnit=0;
			NumberofBasicUnit=TotalNumberofBasicUnit/2;
		}
	}
}

//calculate MAD for the current macroblock 
double calc_MAD()
{
	int k,l;
   	int s = 0;
	double MAD;

	for (k = 0; k < 16; k++)
		for (l = 0; l < 16; l++)
			s+= abs(diffy[k][l]);
	
	MAD=s*1.0/256;
	return MAD;
}

// update one picture after frame/field encoding
void rc_update_pict(int nbits)
{
	R-= nbits; /* remaining # of bits in GOP */
	CurrentBufferFullness += nbits - bit_rate/frame_rate;

	/*update the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
	LowerBound  +=(long)(bit_rate/frame_rate-nbits);
	UpperBound1 +=(long)(bit_rate/frame_rate-nbits);
	UpperBound2 = (long)(OMEGA*UpperBound1);
	
	return;
}

// update after frame encoding
void rc_update_pict_frame(int nbits)
{

/*update the
complexity weight of I, P, B frame*/
	int Avem_Qc;
	int X;
		
/*frame layer rate control*/
	if(img->BasicUnit==img->Frame_Total_Number_MB)
		X = (int) floor(nbits*m_Qc+ 0.5);
/*basic unit layer rate control*/
	else
	{
		if(img->type==P_SLICE)
		{
			if(((img->IFLAG==0)&&(img->FieldControl==1))\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -