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

📄 ratectlquadratic.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      {
        //compute the average weight
        if(m_pcGenericRC->m_iNumberofCodedBFrame<8)
          m_dAveWb = (m_dAveWb + m_dWb*(m_pcGenericRC->m_iNumberofCodedBFrame-1)) / m_pcGenericRC->m_iNumberofCodedBFrame;
        else
          m_dAveWb = (m_dWb + 7 * m_dAveWb) / 8;
      }
    }
    // Compute the target bit for each frame
    if( m_pcJSVMParams->type == P_SLICE || ( m_pcJSVMParams->number != 0 && m_pcJSVMParams->RCUpdateMode == RC_MODE_1 ) )
    {
      // frame layer rate control
      if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
      {
        if(m_iNumberofCodedPFrame>0)
        {
          m_iTarget = (int) floor( m_dWp * m_pcGenericRC->m_iRemainingBits / (m_iNp * m_dWp + m_iNb * m_dWb) + 0.5);
          iTmpT  = imax(0, (int) floor(m_fBitRate / m_fFrameRate - m_dGAMMAP * (m_pcGenericRC->m_i64CurrentBufferFullness-m_dTargetBufferLevel) + 0.5));
          m_iTarget = (int) floor(m_dBETAP * (m_iTarget - iTmpT) + iTmpT + 0.5);
        }
      }
      // basic unit layer rate control
      else
      {
        if(((m_pcGenericRC->m_iNumberofGOP == 1)&&(m_iNumberofCodedPFrame>0))
          || (m_pcGenericRC->m_iNumberofGOP > 1))
        {
          m_iTarget = (int) (floor( m_dWp * m_pcGenericRC->m_iRemainingBits / (m_iNp * m_dWp + m_iNb * m_dWb) + 0.5));
          iTmpT  = imax(0, (int) (floor(m_fBitRate / m_fFrameRate - m_dGAMMAP * (m_pcGenericRC->m_i64CurrentBufferFullness-m_dTargetBufferLevel) + 0.5)));
          m_iTarget = (int) (floor(m_dBETAP * (m_iTarget - iTmpT) + iTmpT + 0.5));
        }
      }
      m_iTarget = (int)(fMult * m_iTarget);

      // reserve some bits for smoothing
      m_iTarget = (int)((1.0 - 0.0 * m_pcJSVMParams->successive_Bframe) * m_iTarget);

      // HRD consideration
      m_iTarget = iClip3(m_iLowerBound, m_iUpperBound2, m_iTarget);
      if((iTopField) || (iFieldPic && ((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))))
        m_iTargetField=m_iTarget;
    }
  }

  if(iFieldPic || iTopField)
  {
    // frame layer rate control
    m_pcGenericRC->m_iNumberofHeaderBits  = 0;
    m_pcGenericRC->m_iNumberofTextureBits = 0;

    // basic unit layer rate control
    if(m_pcJSVMParams->BasicUnit < m_pcJSVMParams->FrameSizeInMbs)
    {
      m_iTotalFrameQP = 0;
      m_pcGenericRC->m_iNumberofBasicUnitHeaderBits  = 0;
      m_pcGenericRC->m_iNumberofBasicUnitTextureBits = 0;
      m_pcGenericRC->m_i64TotalMADBasicUnit = 0;
      if(m_pcGenericRC->m_iFieldControl==0)
        m_iNumberofBasicUnit = m_iTotalNumberofBasicUnit;
      else
        m_iNumberofBasicUnit = m_iTotalNumberofBasicUnit >> 1;
    }
  }

  if( ( m_pcJSVMParams->type==P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) ) && m_pcJSVMParams->BasicUnit < m_pcJSVMParams->FrameSizeInMbs && m_pcGenericRC->m_iFieldControl == 1 )
  {
    // top field at basic unit layer rate control
    if(iTopField)
    {
      m_iBitsTopField=0;
      m_iTarget=(int)(m_iTargetField*0.6);
    }
    // bottom field at basic unit layer rate control
    else
    {
      m_iTarget=m_iTargetField-m_iBitsTopField;
      m_pcGenericRC->m_iNumberofBasicUnitHeaderBits=0;
      m_pcGenericRC->m_iNumberofBasicUnitTextureBits=0;
      m_pcGenericRC->m_i64TotalMADBasicUnit=0;
      m_iNumberofBasicUnit=m_iTotalNumberofBasicUnit >> 1;
    }
  }
}

/*!
 *************************************************************************************
 * \brief
 *    update one picture after frame/field encoding
 *
 * \param iNbits
 *    number of bits used for picture
 *
 *************************************************************************************
*/
void rc_quadratic::rc_update_pict( int iNbits )
{
  int iDeltaBits = (iNbits - (int)floor(m_fBitRate / m_fFrameRate + 0.5F) );
  m_pcGenericRC->m_iRemainingBits -= iNbits; // remaining # of bits in GOP
  m_pcGenericRC->m_i64CurrentBufferFullness += iDeltaBits;

  // update the lower bound and the upper bound for the target bits of each frame, HRD consideration
  m_iLowerBound  -= (int) iDeltaBits;
  m_iUpperBound1 -= (int) iDeltaBits;
  m_iUpperBound2  = (int)(m_fOMEGA * m_iUpperBound1);

  return;
}

int rc_quadratic::updateComplexity( bool bIsUpdated, int iNbits )
{
  double dAvemQc;

  // frame layer rate control
  if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
    return ((int) floor(iNbits * m_iQc + 0.5));
  // basic unit layer rate control
  else
  {
    if( bIsUpdated )
    {
      if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
      {
        dAvemQc = (double)m_iTotalFrameQP / (double)m_iTotalNumberofBasicUnit;
        return ((int)floor(iNbits * dAvemQc + 0.5));
      }
    }
    else if( m_pcJSVMParams->type == B_SLICE )
      return ((int) floor(iNbits * m_iQc + 0.5));
  }
  return 0;
}

void rc_quadratic::updatePparams( int iComplexity )
{
  m_iXp = iComplexity;
  m_iNp--;
  m_dWp = m_iXp;
  m_iNumberofCodedPFrame++;
  m_iNumberofPPicture++;
}

void rc_quadratic::updateBparams( int iComplexity )
{
  m_iXb = iComplexity;
  m_iNb--;
  m_dWb = m_iXb / m_fTHETA;     
  m_iNumberofBFrames++;
  m_pcGenericRC->m_iNumberofCodedBFrame++;
}

/*! 
 *************************************************************************************
 * \brief
 *    update after frame encoding
 *
 * \param iNbits
 *    number of bits used for frame
 *
 *************************************************************************************
*/
void rc_quadratic::rc_update_pict_frame(int iNbits)
{
  // update the iComplexity weight of I, P, B frame
  int iComplexity = 0;

  switch( m_pcJSVMParams->RCUpdateMode )
  {
  case RC_MODE_2:
  default:
    iComplexity = updateComplexity( (bool) (m_pcJSVMParams->type == P_SLICE), iNbits );
    if ( m_pcJSVMParams->type == P_SLICE )
    {
      if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
        updatePparams( iComplexity );
      else
        m_pcGenericRC->m_iNoGranularFieldRC = 0;
    }
    else if ( m_pcJSVMParams->type == B_SLICE )
      updateBparams( iComplexity );
    break;
  case RC_MODE_1:
    iComplexity = updateComplexity( (bool) (m_pcJSVMParams->number != 0), iNbits );
    if ( m_pcJSVMParams->number != 0 )
    {
      if( m_pcGenericRC->m_iNoGranularFieldRC == 0 || m_pcGenericRC->m_iFieldControl == 0 )
        updatePparams( iComplexity );
      else
        m_pcGenericRC->m_iNoGranularFieldRC = 0;
    }
    break;
  }   
}

/*!
 *************************************************************************************
 * \brief
 *    update the parameters of quadratic R-D model
 *
 *************************************************************************************
*/
void rc_quadratic::updateRCModel( void )
{
  int iWindowSize;
  int i;
  double dStd = 0.0, dThreshold;
  int iNc = m_iNumberofCodedPFrame;
  bool bMADModelFlag = false;
  static bool pbRgRejected[RC_MODEL_HISTORY];
  static double  pdError     [RC_MODEL_HISTORY];

  if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
  {
    // frame layer rate control
    if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
    {
      m_dCurrentFrameMAD = m_pcGenericRC->ComputeFrameMAD();
      iNc=m_iNumberofCodedPFrame;
    }
    // basic unit layer rate control
    else
    {
      // compute the MAD of the current basic unit
      m_dCurrentFrameMAD = (double) ((m_pcGenericRC->m_i64TotalMADBasicUnit >> 8)/m_pcJSVMParams->BasicUnit);
      m_pcGenericRC->m_i64TotalMADBasicUnit=0;

      // compute the average number of header bits
      m_iCodedBasicUnit=m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit;
      if(m_iCodedBasicUnit > 0)
      {
        m_iPAveHeaderBits1=(int)((double)(m_iPAveHeaderBits1*(m_iCodedBasicUnit-1)+
          m_pcGenericRC->m_iNumberofBasicUnitHeaderBits)/m_iCodedBasicUnit+0.5);
        if(m_iPAveHeaderBits3 == 0)
          m_iPAveHeaderBits2 = m_iPAveHeaderBits1;
        else
        {
          m_iPAveHeaderBits2 = (int)((double)(m_iPAveHeaderBits1 * m_iCodedBasicUnit+
            m_iPAveHeaderBits3 * m_iNumberofBasicUnit)/m_iTotalNumberofBasicUnit+0.5);
        }
      }
      // update the record of MADs for reference
      if(((m_pcJSVMParams->PicInterlace == ADAPTIVE_CODING) || (m_pcJSVMParams->MbInterlace)) && (m_pcGenericRC->m_iFieldControl == 1))
        m_pdFCBUCFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit]=m_dCurrentFrameMAD;
      else
        m_pdBUCFMAD[m_iTotalNumberofBasicUnit-1-m_iNumberofBasicUnit]=m_dCurrentFrameMAD;

      if(m_iNumberofBasicUnit != 0)
        iNc = m_iNumberofCodedPFrame * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;
      else
        iNc = (m_iNumberofCodedPFrame-1) * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;
    }

    if(iNc > 1)
      bMADModelFlag=true;

    m_iPPreHeader = m_pcGenericRC->m_iNumberofHeaderBits;
    for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
    {// update the history
      m_dPRgQp[i] = m_dPRgQp[i - 1];
      m_dRgQp[i]  = m_dPRgQp[i];
      m_dPRgRp[i] = m_dPRgRp[i - 1];
      m_dRgRp[i]  = m_dPRgRp[i];
    }
    m_dPRgQp[0] = m_pcGenericRC->QP2Qstep(m_iQc); //*1.0/m_dCurrentFrameMAD;
    // frame layer rate control
    if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
      m_dPRgRp[0] = m_pcGenericRC->m_iNumberofTextureBits*1.0/m_dCurrentFrameMAD;
    // basic unit layer rate control
    else
      m_dPRgRp[0] = m_pcGenericRC->m_iNumberofBasicUnitTextureBits*1.0/m_dCurrentFrameMAD;

    m_dRgQp[0] = m_dPRgQp[0];
    m_dRgRp[0] = m_dPRgRp[0];
    m_dX1 = m_dPX1;
    m_dX2 = m_dPX2;

    // compute the size of window
    iWindowSize = (m_dCurrentFrameMAD>m_dPreviousFrameMAD)
      ? (int)(m_dPreviousFrameMAD/m_dCurrentFrameMAD * (RC_MODEL_HISTORY-1) )
      : (int)(m_dCurrentFrameMAD/m_dPreviousFrameMAD *(RC_MODEL_HISTORY-1));
    iWindowSize=iClip3(1, iNc, iWindowSize);
    iWindowSize=imin(iWindowSize,m_iWindowSize+1);
    iWindowSize=imin(iWindowSize,(RC_MODEL_HISTORY-1));

    // update the previous window size
    m_iWindowSize=iWindowSize;

    for (i = 0; i < (RC_MODEL_HISTORY-1); i++)
    {
      pbRgRejected[i] = false;
    }

    // initial RD model estimator
    RCModelEstimator (iWindowSize, pbRgRejected);

    iWindowSize = m_iWindowSize;
    // remove outlier

    for (i = 0; i < (int) iWindowSize; i++)
    {
      pdError[i] = m_dX1 / m_dRgQp[i] + m_dX2 / (m_dRgQp[i] * m_dRgQp[i]) - m_dRgRp[i];
      dStd += pdError[i] * pdError[i];
    }
    dThreshold = (iWindowSize == 2) ? 0 : sqrt (dStd / iWindowSize);
    for (i = 0; i < (int) iWindowSize; i++)
    {
      if (fabs(pdError[i]) > dThreshold)
        pbRgRejected[i] = true;
    }
    // always include the last data point
    pbRgRejected[0] = false;

    // second RD model estimator
    RCModelEstimator (iWindowSize, pbRgRejected);

    if( bMADModelFlag )
      updateMADModel();
    else if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
      m_dPPictureMAD[0] = m_dCurrentFrameMAD;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Model Estimator
 *
 *************************************************************************************
*/
void rc_quadratic::RCModelEstimator( int iWindowSize, bool *pbRgRejected )
{
  int iRealSize = iWindowSize;
  int i;
  double dOneSampleQ = 0;
  double dA00 = 0.0, dA01 = 0.0, dA10 = 0.0, dA11 = 0.0, dB0 = 0.0, dB1 = 0.0;
  double dMatrixValue;
  bool bEstimateX2 = false;

  for (i = 0; i < iWindowSize; i++)
  {// find the number of samples which are not rejected
    if (pbRgRejected[i])
      iRealSize--;
  }

  // default RD model estimation results
  m_dX1 = m_dX2 = 0.0;

  for (i = 0; i < iWindowSize; i++)
  {
    if (!pbRgRejected[i])
      dOneSampleQ = m_dRgQp[i];
  }
  for (i = 0; i < iWindowSize; i++)
  {// if all non-rejected Q are the same, take 1st order model
    if ((m_dRgQp[i] != dOneSampleQ) && !pbRgRejected[i])
      bEstimateX2 = true;
    if (!pbRgRejected[i])
      m_dX1 += (m_dRgQp[i] * m_dRgRp[i]) / iRealSize;
  }

  // take 2nd order model to estimate X1 and X2
  if ((iRealSize >= 1) && bEstimateX2)
  {
    for (i = 0; i < iWindowSize; i++)
    {
      if (!pbRgRejected[i])
      {
        dA00  = dA00 + 1.0;
        dA01 += 1.0 / m_dRgQp[i];
        dA10  = dA01;
        dA11 += 1.0 / (m_dRgQp[i] * m_dRgQp[i]);
        dB0  += m_dRgQp[i] * m_dRgRp[i];
        dB1  += m_dRgRp[i];
      }
    }
    // solve the equation of AX = B
    dMatrixValue=dA00*dA11-dA01*dA10;
    if(fabs(dMatrixValue) > 0.000001)
    {
      m_dX1 = (dB0 * dA11 - dB1 * dA01) / dMatrixValue;
      m_dX2 = (dB1 * dA00 - dB0 * dA10) / dMatrixValue;
    }
    else
    {
      m_dX1 = dB0 / dA00;
      m_dX2 = 0.0;
    }
  }

  if( m_pcJSVMParams->type == P_SLICE || (m_pcJSVMParams->RCUpdateMode == RC_MODE_1 && (m_pcJSVMParams->number != 0)) )
  {
    m_dPX1 = m_dX1;
    m_dPX2 = m_dX2;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    update the parameters of linear prediction model
 *
 *************************************************************************************
*/
void rc_quadratic::updateMADModel( void )
{
  int    iWindowSize;
  int    i;
  double dStd = 0.0, dThreshold;
  int    iNc = m_iNumberofCodedPFrame;
  static bool pbPictureRejected[RC_MODEL_HISTORY];
  static double  pdError          [RC_MODEL_HISTORY];

  if(m_iNumberofCodedPFrame>0)
  {
    // frame layer rate control
    if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
      iNc = m_iNumberofCodedPFrame;
    else // basic unit layer rate control
      iNc = m_iNumberofCodedPFrame * m_iTotalNumberofBasicUnit + m_iCodedBasicUnit;

    for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
    {// update the history
      m_dPPictureMAD[i]  = m_dPPictureMAD[i - 1];
      m_dPictureMAD[i]   = m_dPPictureMAD[i];
      m_dReferenceMAD[i] = m_dReferenceMAD[i-1];
    }
    m_dPPictureMAD[0] = m_dCurrentFrameMAD;
    m_dPictureMAD[0]  = m_dPPictureMAD[0];

    if(m_pcJSVMParams->BasicUnit == m_pcJSVMParams->FrameSizeInMbs)
      m_dReferenceMAD[0]=m_dPictureMAD[1];
    else
    {

⌨️ 快捷键说明

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