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

📄 ratectl.c

📁 H.264视频编码器(ITU的264编码参考软件)
💻 C
📖 第 1 页 / 共 4 页
字号:

/*!
 ***************************************************************************
 * \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 <stdlib.h>
#include <math.h>
#include <assert.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, Xb;
static int R,T_field;
static int Np, Nb, bits_topfield;
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;

/*! 
 *************************************************************************************
 * \brief
 *    Initialize 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 = (img->framerate *(float)(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 the 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;
  }
}

/*! 
 *************************************************************************************
 * \brief
 *    Initialize 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; 
}


/*! 
 *************************************************************************************
 * \brief
 *    Initialize one picture
 *
 *************************************************************************************
*/
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 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(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 */
      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)

⌨️ 快捷键说明

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