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

📄 ratectl.c

📁 h.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
 *    Dynamically allocate memory needed for rate control
 *
 *************************************************************************************
*/
void rc_alloc()
{
  img->MADofMB = (double*) calloc (img->FrameSizeInMbs, sizeof (double));
  if (NULL==img->MADofMB)
  {
    no_mem_exit("rc_alloc: img->MADofMB");
  }
  
  BUPFMAD = (double*) calloc ((img->FrameSizeInMbs/input->basicunit), sizeof (double));
  if (NULL==BUPFMAD)
  {
    no_mem_exit("rc_alloc: img->BUPFMAD");
  }

  BUCFMAD = (double*) calloc ((img->FrameSizeInMbs/input->basicunit), sizeof (double));
  if (NULL==BUCFMAD)
  {
    no_mem_exit("rc_alloc: img->BUCFMAD");
  }

  FCBUCFMAD = (double*) calloc ((img->FrameSizeInMbs/input->basicunit), sizeof (double));
  if (NULL==FCBUCFMAD)
  {
    no_mem_exit("rc_alloc: img->FCBUCFMAD");
  }

  FCBUPFMAD = (double*) calloc ((img->FrameSizeInMbs/input->basicunit), sizeof (double));
  if (NULL==FCBUPFMAD)
  {
    no_mem_exit("rc_alloc: img->FCBUPFMAD");
  }

}

/*! 
 *************************************************************************************
 * \brief
 *    Free memory needed for rate control
 *
 *************************************************************************************
*/
void rc_free()
{
  if (NULL!=img->MADofMB)
  {
    free (img->MADofMB);
    img->MADofMB = NULL;
  }
  if (NULL!=BUPFMAD)
  {
    free (BUPFMAD);
    BUPFMAD = NULL;
  }
  if (NULL!=BUCFMAD)
  {
    free (BUCFMAD);
    BUCFMAD = NULL;
  }
  if (NULL!=FCBUCFMAD)
  {
    free (FCBUCFMAD);
    FCBUCFMAD = NULL;
  }
  if (NULL!=FCBUPFMAD)
  {
    free (FCBUPFMAD);
    FCBUPFMAD = NULL;
  }
}


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

⌨️ 快捷键说明

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