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

📄 ratectlquadratic.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:

/*!
 ***************************************************************************
 * \file rc_quadratic.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>
 *     - Athanasios Leontaris <aleon@dolby.com>
 *
 * \date
 *   16 Jan. 2003
 *   18 Mar. 2007
 **************************************************************************
 */

#include "H264AVCEncoderLib.h"
#include "H264AVCCommonLib.h"
#include "RateCtlBase.h"
#include "RateCtlQuadratic.h"

using namespace h264;

jsvm_parameters *pcJSVMParams;
rc_generic      *pcGenericRC;
rc_quadratic    *pcQuadraticRC;

rc_quadratic::rc_quadratic( rc_generic *pcGenRC, jsvm_parameters *jsvm_params )
{
  m_pcGenericRC = pcGenRC;
  m_pcJSVMParams = jsvm_params;
  m_fTHETA = 1.3636F;
  m_fOMEGA = 0.9F;
  m_fMINVALUE = 4.0F;
}

rc_quadratic::~rc_quadratic( void )
{
  rc_free();
}

/*!
 *************************************************************************************
 * \brief
 *    Dynamically allocate memory needed for rate control
 *
 *************************************************************************************
 */
void rc_quadratic::rc_alloc( void )
{
  int iRcBufSize = m_pcJSVMParams->FrameSizeInMbs / m_pcJSVMParams->basicunit;

  m_dPreviousFrameMAD = 1.0;
  m_dCurrentFrameMAD = 1.0;
  m_i64PPrevBits = 0;
  m_i64IPrevBits = 0;
  m_iTarget = 0;
  m_iTargetField = 0;
  m_iLowerBound = 0;
  m_iUpperBound1 = INT_MAX;
  m_iUpperBound2 = INT_MAX;
  m_dWp = 0.0;
  m_dWb = 0.0;
  m_iPAveFrameQP   = m_pcJSVMParams->SetInitialQP;
  m_iQc            = m_iPAveFrameQP;
  m_iFieldQPBuffer = m_iPAveFrameQP;
  m_iFrameQPBuffer = m_iPAveFrameQP;
  m_iPAverageQp    = m_iPAveFrameQP;
  m_iMyInitialQp   = m_iPAveFrameQP;

  m_iRCMaxQuant = m_pcJSVMParams->RCMaxQP;
  m_iRCMinQuant = m_pcJSVMParams->RCMinQP; //-m_pcJSVMParams->bitdepth_luma_qp_scale;//clipping

  m_pdBUPFMAD = (double *) calloc ((iRcBufSize), sizeof (double));
  if (NULL == m_pdBUPFMAD)
  {
    fprintf(stderr, "rc_alloc: m_pdBUPFMAD");
    assert(0); // some compilers do not compile assert in release/Ox mode
    exit(1);
  }

  m_pdBUCFMAD = (double *) calloc ((iRcBufSize), sizeof (double));
  if (NULL == m_pdBUCFMAD)
  {
    fprintf(stderr, "rc_alloc: m_pdBUCFMAD");
    assert(0); // some compilers do not compile assert in release/Ox mode
    exit(1);
  }

  m_pdFCBUCFMAD = (double *) calloc ((iRcBufSize), sizeof (double));
  if (NULL == m_pdFCBUCFMAD)
  {
    fprintf(stderr, "rc_alloc: m_pdFCBUCFMAD");
    assert(0); // some compilers do not compile assert in release/Ox mode
    exit(1);
  }

  m_pdFCBUPFMAD = (double *) calloc ((iRcBufSize), sizeof (double));
  if (NULL == m_pdFCBUPFMAD)
  {
    fprintf(stderr, "rc_alloc: m_pdFCBUPFMAD");
    assert(0); // some compilers do not compile assert in release/Ox mode
    exit(1);
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Free memory needed for rate control
 *
 *************************************************************************************
*/
void rc_quadratic::rc_free( void )
{
  if (NULL != m_pdBUPFMAD)
  {
    free (m_pdBUPFMAD);
    m_pdBUPFMAD = NULL;
  }
  if (NULL != m_pdBUCFMAD)
  {
    free (m_pdBUCFMAD);
    m_pdBUCFMAD = NULL;
  }
  if (NULL != m_pdFCBUCFMAD)
  {
    free (m_pdFCBUCFMAD);
    m_pdFCBUCFMAD = NULL;
  }
  if (NULL != m_pdFCBUPFMAD)
  {
    free (m_pdFCBUPFMAD);
    m_pdFCBUPFMAD = NULL;
  }
}


/*!
 *************************************************************************************
 * \brief
 *    Initialize rate control parameters
 *
 *************************************************************************************
*/
void rc_quadratic::rc_init_seq( void )
{
  int i;

  m_iXp=0;
  m_iXb=0;

  m_fBitRate = (float) m_pcJSVMParams->bit_rate;
  m_fFrameRate = (m_pcJSVMParams->FrameRate *(float)(m_pcJSVMParams->successive_Bframe + 1)) / (float) (m_pcJSVMParams->jumpd + 1);
  m_fPrevBitRate = m_fBitRate;

  // compute the total number of MBs in a frame
  if(m_pcJSVMParams->basicunit > m_pcJSVMParams->FrameSizeInMbs)
    m_pcJSVMParams->basicunit = m_pcJSVMParams->FrameSizeInMbs;
  if(m_pcJSVMParams->basicunit < m_pcJSVMParams->FrameSizeInMbs)
    m_iTotalNumberofBasicUnit = m_pcJSVMParams->FrameSizeInMbs/m_pcJSVMParams->basicunit;
  else
    m_iTotalNumberofBasicUnit = 1;

  // initialize the parameters of fluid flow traffic model
  m_pcGenericRC->m_i64CurrentBufferFullness = 0;
  m_dGOPTargetBufferLevel = (double) m_pcGenericRC->m_i64CurrentBufferFullness;

  // initialize the previous window size
  m_iWindowSize    = 0;
  m_iMADWindowSize = 0;
  m_pcGenericRC->m_iNumberofCodedBFrame = 0;
  m_iNumberofCodedPFrame = 0;
  m_pcGenericRC->m_iNumberofGOP         = 0;
  // remaining # of bits in GOP
  m_pcGenericRC->m_iRemainingBits = 0;
  // control parameter
  if(m_pcJSVMParams->successive_Bframe>0)
  {
    m_dGAMMAP=0.25;
    m_dBETAP=0.9;
  }
  else
  {
    m_dGAMMAP=0.5;
    m_dBETAP=0.5;
  }

  // quadratic rate-distortion model
  m_iPPreHeader=0;

  m_dPX1 = m_fBitRate * 1.0;
  m_dPX2 = 0.0;
  // linear prediction model for P picture
  m_dPMADPictureC1 = 1.0;
  m_dPMADPictureC2 = 0.0;

  // Initialize values
  for(i=0;i<21;i++)
  {
    m_dPRgQp[i] = 0;
    m_dPRgRp[i] = 0.0;
    m_dPPictureMAD[i] = 0.0;
  }

  // basic unit layer rate control
  m_iPAveHeaderBits1 = 0;
  m_iPAveHeaderBits3 = 0;
  
  m_uiMBPerRow = m_pcJSVMParams->PicWidthInMbs;

  // adaptive field/frame coding
  m_pcGenericRC->m_iFieldControl=0;  
}

/*!
 *************************************************************************************
 * \brief
 *    Initialize one GOP
 *
 *************************************************************************************
*/
void rc_quadratic::rc_init_GOP( int iNp, int iNb )
{
  int iOverBits, iOverDuantQp;
  int iAllocatedBits, iGOPDquant;

  // 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.
  iOverBits=-m_pcGenericRC->m_iRemainingBits;

  // initialize the lower bound and the upper bound for the target bits of each frame, HRD consideration
  m_iLowerBound  = (int)(m_pcGenericRC->m_iRemainingBits + m_fBitRate / m_fFrameRate);
  m_iUpperBound1 = (int)(m_pcGenericRC->m_iRemainingBits + (m_fBitRate * 2.048));

  // compute the total number of bits for the current GOP
  iAllocatedBits = (int) floor((1 + iNp + iNb) * m_fBitRate / m_fFrameRate + 0.5);
  m_pcGenericRC->m_iRemainingBits += iAllocatedBits;
  m_iNp = iNp;
  m_iNb = iNb;

  iOverDuantQp=(int)(8 * iOverBits/iAllocatedBits+0.5);
  m_bGOPOverdue=false;

  // field coding
  if ( !m_pcJSVMParams->PicInterlace && m_pcJSVMParams->MbInterlace && m_pcJSVMParams->basicunit == m_pcJSVMParams->FrameSizeInMbs )
    m_pcGenericRC->m_iNoGranularFieldRC = 0;
  else
    m_pcGenericRC->m_iNoGranularFieldRC = 1;

  // Compute InitialQp for each GOP
  m_iTotalPFrame=iNp;
  m_pcGenericRC->m_iNumberofGOP++;
  if(m_pcGenericRC->m_iNumberofGOP==1)
  {
    m_iMyInitialQp = m_pcJSVMParams->SetInitialQP;
    m_iCurrLastQP = m_iMyInitialQp - 1; //recent change -0;
    m_iQPLastGOP   = m_iMyInitialQp;

    m_iPAveFrameQP   = m_iMyInitialQp;
    m_iQc          = m_iPAveFrameQP;
    m_iFieldQPBuffer = m_iPAveFrameQP;
    m_iFrameQPBuffer = m_iPAveFrameQP;
    m_iPAverageQp    = m_iPAveFrameQP;
  }
  else
  {
    // adaptive field/frame coding
    if( m_pcJSVMParams->PicInterlace == ADAPTIVE_CODING || m_pcJSVMParams->MbInterlace )
    {
      if (m_pcGenericRC->m_iFieldFrame == 1)
      {
        m_iTotalQpforPPicture += m_iFrameQPBuffer;
        m_iQPLastPFrame = m_iFrameQPBuffer;
      }
      else
      {
        m_iTotalQpforPPicture += m_iFieldQPBuffer;
        m_iQPLastPFrame = m_iFieldQPBuffer;
      }
    }
    // compute the average QP of P frames in the previous GOP
    m_iPAverageQp=(int)(1.0 * m_iTotalQpforPPicture / m_iNumberofPPicture+0.5);

    iGOPDquant=(int)((1.0*(iNp+iNb+1)/15.0) + 0.5);
    if(iGOPDquant>2)
      iGOPDquant=2;

    m_iPAverageQp -= iGOPDquant;

    if (m_iPAverageQp > (m_iQPLastPFrame - 2))
      m_iPAverageQp--;

    // QP is constrained by QP of previous QP
    m_iPAverageQp = iClip3(m_iQPLastGOP - 2, m_iQPLastGOP + 2, m_iPAverageQp);
    // Also clipped within range.
    m_iPAverageQp = iClip3(m_iRCMinQuant,  m_iRCMaxQuant,  m_iPAverageQp);

    m_iMyInitialQp = m_iPAverageQp;
    m_iPQp       = m_iPAverageQp;
    m_iPAveFrameQP = m_iPAverageQp;
    m_iQPLastGOP   = m_iMyInitialQp;
    m_iPrevLastQP = m_iCurrLastQP;
    m_iCurrLastQP = m_iMyInitialQp - 1;
  }

  m_iTotalQpforPPicture=0;
  m_iNumberofPPicture=0;
  m_iNumberofBFrames=0;
}


/*!
 *************************************************************************************
 * \brief
 *    Initialize one picture
 *
 *************************************************************************************
*/
void rc_quadratic::rc_init_pict( int iFieldPic, int iTopField, int iTargetComputation, float fMult )
{
  int iTmpT;

  // compute the total number of basic units in a frame
  if(m_pcJSVMParams->MbInterlace)
    m_iTotalNumberofBasicUnit = m_pcJSVMParams->FrameSizeInMbs / m_pcJSVMParams->BasicUnit;
  else
    m_iTotalNumberofBasicUnit = m_pcJSVMParams->FrameSizeInMbs / m_pcJSVMParams->basicunit;

  m_pcJSVMParams->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(m_pcJSVMParams->channel_type==1)
  {
    if(m_iNumberofCodedPFrame==58)
      m_fBitRate *= 1.5;
    else if(m_iNumberofCodedPFrame==59)
      m_fPrevBitRate = m_fBitRate;
  }

  // predefine a target buffer level for each frame
  if((iFieldPic||iTopField) && iTargetComputation)
  {
    if ( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number !=0)) )
    {
      // Since the available bandwidth may vary at any time, the total number of
      // bits is updated picture by picture
      if(m_fPrevBitRate!=m_fBitRate)
        m_pcGenericRC->m_iRemainingBits +=(int) floor((m_fBitRate-m_fPrevBitRate)*(m_iNp + m_iNb)/m_fFrameRate+0.5);

      // predefine the  target buffer level for each picture.
      // frame layer rate control
      if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
      {
        if(m_iNumberofPPicture==1)
        {
          m_dTargetBufferLevel = (double) m_pcGenericRC->m_i64CurrentBufferFullness;
          m_dDeltaP = (m_pcGenericRC->m_i64CurrentBufferFullness - m_dGOPTargetBufferLevel) / (m_iTotalPFrame-1);
          m_dTargetBufferLevel -= m_dDeltaP;
        }
        else if(m_iNumberofPPicture>1)
          m_dTargetBufferLevel -= m_dDeltaP;
      }
      // basic unit layer rate control
      else
      {
        if(m_iNumberofCodedPFrame>0)
        {
          // adaptive frame/field coding
          if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))&&(m_pcGenericRC->m_iFieldControl==1))
            memcpy((void *)m_pdFCBUPFMAD,(void *)m_pdFCBUCFMAD, m_iTotalNumberofBasicUnit * sizeof(double));
          else
            memcpy((void *)m_pdBUPFMAD,(void *)m_pdBUCFMAD, m_iTotalNumberofBasicUnit * sizeof(double));
        }

        if(m_pcGenericRC->m_iNumberofGOP==1)
        {
          if(m_iNumberofPPicture==1)
          {
            m_dTargetBufferLevel = (double) m_pcGenericRC->m_i64CurrentBufferFullness;
            m_dDeltaP = (m_pcGenericRC->m_i64CurrentBufferFullness - m_dGOPTargetBufferLevel)/(m_iTotalPFrame - 1);
            m_dTargetBufferLevel -= m_dDeltaP;
          }
          else if(m_iNumberofPPicture>1)
            m_dTargetBufferLevel -= m_dDeltaP;
        }
        else if(m_pcGenericRC->m_iNumberofGOP>1)
        {
          if(m_iNumberofPPicture==0)
          {
            m_dTargetBufferLevel = (double) m_pcGenericRC->m_i64CurrentBufferFullness;
            m_dDeltaP = (m_pcGenericRC->m_i64CurrentBufferFullness - m_dGOPTargetBufferLevel) / m_iTotalPFrame;
            m_dTargetBufferLevel -= m_dDeltaP;
          }
          else if(m_iNumberofPPicture>0)
            m_dTargetBufferLevel -= m_dDeltaP;
        }
      }

      if(m_iNumberofCodedPFrame==1)
        m_dAveWp = m_dWp;

      if((m_iNumberofCodedPFrame<8)&&(m_iNumberofCodedPFrame>1))
        m_dAveWp = (m_dAveWp + m_dWp * (m_iNumberofCodedPFrame-1))/m_iNumberofCodedPFrame;
      else if(m_iNumberofCodedPFrame>1)
        m_dAveWp = (m_dWp + 7 * m_dAveWp) / 8;

      // compute the average iComplexity of B frames
      if(m_pcJSVMParams->successive_Bframe>0)
      {
        // compute the target buffer level
        m_dTargetBufferLevel += (m_dAveWp * (m_pcJSVMParams->successive_Bframe + 1)*m_fBitRate\
          /(m_fFrameRate*(m_dAveWp+m_dAveWb*m_pcJSVMParams->successive_Bframe))-m_fBitRate/m_fFrameRate);
      }
    }
    else if ( m_pcJSVMParams->type == B_SLICE )
    {
      // update the total number of bits if the bandwidth is changed
      if(m_fPrevBitRate != m_fBitRate)
        m_pcGenericRC->m_iRemainingBits +=(int) floor((m_fBitRate-m_fPrevBitRate) * (m_iNp + m_iNb) / m_fFrameRate+0.5);
      if((m_iNumberofCodedPFrame==1)&&(m_pcGenericRC->m_iNumberofCodedBFrame==1))
      {
        m_dAveWp = m_dWp;
        m_dAveWb = m_dWb;
      }
      else if(m_pcGenericRC->m_iNumberofCodedBFrame > 1)

⌨️ 快捷键说明

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