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

📄 ratectlquadratic.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      {
        m_dX1=m_dPX1;
        m_dX2=m_dPX2;
        m_dMADPictureC1=m_dPMADPictureC1;
        m_dMADPictureC2=m_dPMADPictureC2;

        iQp=m_iPQp;

        if(m_pcGenericRC->m_iFieldControl==0)
          iSumofBasicUnit=m_iTotalNumberofBasicUnit;
        else
          iSumofBasicUnit=m_iTotalNumberofBasicUnit>>1;

        // the average QP of the previous frame is used to coded the first basic unit of the current frame or field
        if(m_iNumberofBasicUnit==iSumofBasicUnit)
          return updateFirstBU( iTopField );
        else
        {
          // compute the number of remaining bits
          m_iTarget -= (m_pcGenericRC->m_iNumberofBasicUnitHeaderBits + m_pcGenericRC->m_iNumberofBasicUnitTextureBits);
          m_pcGenericRC->m_iNumberofBasicUnitHeaderBits  = 0;
          m_pcGenericRC->m_iNumberofBasicUnitTextureBits = 0;
          if(m_iTarget<0)
            return updateNegativeTarget( iTopField, iQp );
          else
          {
            // predict the MAD of current picture
            predictCurrPicMAD();

            // compute the total number of bits for the current basic unit
            updateModelQPBU( iTopField, iQp );

            m_iTotalFrameQP +=m_iQc;
            m_iPQp=m_iQc;
            m_iNumberofBasicUnit--;
            if((m_iNumberofBasicUnit==0) && m_pcJSVMParams->type == P_SLICE )
              updateLastBU( iTopField );

            return m_iQc;
          }
        }
      }
    }
  }
  return m_iQc;
}

void rc_quadratic::updateQPInterlace( void )
{
  if(m_pcGenericRC->m_iFieldControl==0)
  {
    // previous choice is frame coding
    if(m_pcGenericRC->m_iFieldFrame==1)
    {
      m_iPrevLastQP=m_iCurrLastQP;
      m_iCurrLastQP=m_iFrameQPBuffer;
    }
    // previous choice is field coding
    else
    {
      m_iPrevLastQP=m_iCurrLastQP;
      m_iCurrLastQP=m_iFieldQPBuffer;
    }
  }
}

void rc_quadratic::updateQPNonPicAFF( void )
{
  if(m_pcJSVMParams->frame_mbs_only_flag)
  {
    m_iTotalQpforPPicture +=m_iQc;
    m_iPrevLastQP=m_iCurrLastQP;
    m_iCurrLastQP=m_iQc;
    m_iPQp=m_iQc;
  }
  // adaptive field/frame coding
  else
    m_iFrameQPBuffer=m_iQc;
}

void rc_quadratic::updateBottomField( void )
{
  // field coding
  if(m_pcJSVMParams->PicInterlace==FIELD_CODING)
  {
    m_iTotalQpforPPicture +=m_iQc;
    m_iPrevLastQP=m_iCurrLastQP+1;
    m_iCurrLastQP=m_iQc;//+0 Recent change 13/1/2003
    m_iPQp=m_iQc;
  }
  // adaptive field/frame coding
  else
    m_iFieldQPBuffer=m_iQc;
}

int rc_quadratic::updateFirstP( int iTopField )
{
  // top field of the first P frame
  m_iQc=m_iMyInitialQp;
  m_pcGenericRC->m_iNumberofBasicUnitHeaderBits=0;
  m_pcGenericRC->m_iNumberofBasicUnitTextureBits=0;
  m_iNumberofBasicUnit--;
  // bottom field of the first P frame
  if((!iTopField)&&(m_iNumberofBasicUnit==0))
  {
    // frame coding or field coding
    if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
    {
      m_iTotalQpforPPicture +=m_iQc;
      m_iPrevLastQP=m_iCurrLastQP;
      m_iCurrLastQP=m_iQc;
      m_iPAveFrameQP=m_iQc;
      m_iPAveHeaderBits3=m_iPAveHeaderBits2;
    }
    // adaptive frame/field coding
    else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
    {
      if(m_pcGenericRC->m_iFieldControl==0)
      {
        m_iFrameQPBuffer=m_iQc;
        m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
      }
      else
      {
        m_iFieldQPBuffer=m_iQc;
        m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
      }
    }
  }
  m_iPQp=m_iQc;
  m_iTotalFrameQP +=m_iQc;
  return m_iQc;
}

int rc_quadratic::updateNegativeTarget( int iTopField, int iQp )
{
  int iPAverageQP;

  if(m_bGOPOverdue==true)
    m_iQc=iQp+2;
  else
    m_iQc=iQp+m_iDDquant;//2

  m_iQc = imin(m_iQc, m_iRCMaxQuant);  // clipping
  if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
    m_iQc = imin(m_iQc, m_iPAveFrameQP + 6);
  else
    m_iQc = imin(m_iQc, m_iPAveFrameQP + 3);

  m_iTotalFrameQP +=m_iQc;
  m_iNumberofBasicUnit--;
  if(m_iNumberofBasicUnit==0)
  {
    if((!iTopField)||(m_pcGenericRC->m_iFieldControl==0))
    {
      // frame coding or field coding
      if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
      {
        iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
        if (m_iNumberofPPicture == (m_pcJSVMParams->intra_period - 2))
          m_iQPLastPFrame = iPAverageQP;

        m_iTotalQpforPPicture +=iPAverageQP;
        if(m_bGOPOverdue==true)
        {
          m_iPrevLastQP=m_iCurrLastQP+1;
          m_iCurrLastQP=iPAverageQP;
        }
        else
        {
          if((m_iNumberofPPicture==0)&&(m_pcGenericRC->m_iNumberofGOP>1))
          {
            m_iPrevLastQP=m_iCurrLastQP;
            m_iCurrLastQP=iPAverageQP;
          }
          else if(m_iNumberofPPicture>0)
          {
            m_iPrevLastQP=m_iCurrLastQP+1;
            m_iCurrLastQP=iPAverageQP;
          }
        }
        m_iPAveFrameQP=iPAverageQP;
        m_iPAveHeaderBits3=m_iPAveHeaderBits2;
      }
      // adaptive field/frame coding
      else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
      {
        if(m_pcGenericRC->m_iFieldControl==0)
        {
          iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
          m_iFrameQPBuffer=iPAverageQP;
          m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
        }
        else
        {
          iPAverageQP=(int)((double)m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
          m_iFieldQPBuffer=iPAverageQP;
          m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
        }
      }
    }
  }
  if(m_bGOPOverdue==true)
    m_iPQp=m_iPAveFrameQP;
  else
    m_iPQp=m_iQc;

  return m_iQc;
}

int rc_quadratic::updateFirstBU( int iTopField )
{
  // adaptive field/frame coding
  if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))&&(m_pcGenericRC->m_iFieldControl==0))
  {
    // previous choice is frame coding
    if(m_pcGenericRC->m_iFieldFrame==1)
    {
      if(m_iNumberofPPicture>0)
        m_iTotalQpforPPicture +=m_iFrameQPBuffer;
      m_iPAveFrameQP=m_iFrameQPBuffer;
      m_iPAveHeaderBits3=m_iFrameAveHeaderBits;
    }
    // previous choice is field coding
    else
    {
      if(m_iNumberofPPicture>0)
        m_iTotalQpforPPicture +=m_iFieldQPBuffer;
      m_iPAveFrameQP=m_iFieldQPBuffer;
      m_iPAveHeaderBits3=m_iFieldAveHeaderBits;
    }
  }

  if(m_iTarget<=0)
  {
    m_iQc = m_iPAveFrameQP + 2;
    if(m_iQc > m_iRCMaxQuant)
      m_iQc = m_iRCMaxQuant;

    if(iTopField||(m_pcGenericRC->m_iFieldControl==0))
      m_bGOPOverdue=true;
  }
  else
  {
    m_iQc=m_iPAveFrameQP;
  }
  m_iTotalFrameQP +=m_iQc;
  m_iNumberofBasicUnit--;
  m_iPQp = m_iPAveFrameQP;

  return m_iQc;
}

void rc_quadratic::updateLastBU( int iTopField )
{
  int iPAverageQP;

  if((!iTopField)||(m_pcGenericRC->m_iFieldControl==0))
  {
    // frame coding or field coding
    if((m_pcJSVMParams->frame_mbs_only_flag)||(m_pcJSVMParams->PicInterlace==FIELD_CODING))
    {
      iPAverageQP=(int)((double)m_iTotalFrameQP/(double) m_iTotalNumberofBasicUnit+0.5);
      if (m_iNumberofPPicture == (m_pcJSVMParams->intra_period - 2))
        m_iQPLastPFrame = iPAverageQP;

      m_iTotalQpforPPicture +=iPAverageQP;
      m_iPrevLastQP=m_iCurrLastQP;
      m_iCurrLastQP=iPAverageQP;
      m_iPAveFrameQP=iPAverageQP;
      m_iPAveHeaderBits3=m_iPAveHeaderBits2;
    }
    else if((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))
    {
      if(m_pcGenericRC->m_iFieldControl==0)
      {
        iPAverageQP=(int)((double) m_iTotalFrameQP/(double)m_iTotalNumberofBasicUnit+0.5);
        m_iFrameQPBuffer=iPAverageQP;
        m_iFrameAveHeaderBits=m_iPAveHeaderBits2;
      }
      else
      {
        iPAverageQP=(int)((double) m_iTotalFrameQP/(double) m_iTotalNumberofBasicUnit+0.5);
        m_iFieldQPBuffer=iPAverageQP;
        m_iFieldAveHeaderBits=m_iPAveHeaderBits2;
      }
    }
  }
}

void rc_quadratic::predictCurrPicMAD( void )
{
  int i;
  if(((m_pcJSVMParams->PicInterlace==ADAPTIVE_CODING)||(m_pcJSVMParams->MbInterlace))&&(m_pcGenericRC->m_iFieldControl==1))
  {
    m_dCurrentFrameMAD=m_dMADPictureC1*m_pdFCBUPFMAD[m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit]+m_dMADPictureC2;
    m_dTotalBUMAD=0;
    for(i=m_iTotalNumberofBasicUnit-1; i>=(m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit);i--)
    {
      m_dCurrentBUMAD=m_dMADPictureC1*m_pdFCBUPFMAD[i]+m_dMADPictureC2;
      m_dTotalBUMAD +=m_dCurrentBUMAD*m_dCurrentBUMAD;
    }
  }
  else
  {
    m_dCurrentFrameMAD=m_dMADPictureC1*m_pdBUPFMAD[m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit]+m_dMADPictureC2;
    m_dTotalBUMAD=0;
    for(i=m_iTotalNumberofBasicUnit-1; i>=(m_iTotalNumberofBasicUnit-m_iNumberofBasicUnit);i--)
    {
      m_dCurrentBUMAD=m_dMADPictureC1*m_pdBUPFMAD[i]+m_dMADPictureC2;
      m_dTotalBUMAD +=m_dCurrentBUMAD*m_dCurrentBUMAD;
    }
  }
}

void rc_quadratic::updateModelQPBU( int iTopField, int iQp )
{
  double dTmp, dQstep;
  int iBits;
  // compute the total number of bits for the current basic unit
  iBits =(int)(m_iTarget * m_dCurrentFrameMAD * m_dCurrentFrameMAD / m_dTotalBUMAD);
  // compute the number of texture bits
  iBits -=m_iPAveHeaderBits2;

  iBits=imax(iBits,(int)(m_fBitRate/(m_fMINVALUE*m_fFrameRate*m_iTotalNumberofBasicUnit)));

  dTmp = m_dCurrentFrameMAD * m_dCurrentFrameMAD * m_dX1 * m_dX1 \
    + 4 * m_dX2 * m_dCurrentFrameMAD * iBits;
  if ((m_dX2 == 0.0) || (dTmp < 0) || ((sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD) <= 0.0))  // fall back 1st order mode
    dQstep = (float)(m_dX1 * m_dCurrentFrameMAD / (double) iBits);
  else // 2nd order mode
    dQstep = (float) ((2 * m_dX2 * m_dCurrentFrameMAD) / (sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD));

  m_iQc = m_pcGenericRC->Qstep2QP(dQstep);
  m_iQc = imin(iQp+m_iDDquant,  m_iQc); // control variation

  if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
    m_iQc = imin(m_iPAveFrameQP+6, m_iQc);
  else
    m_iQc = imin(m_iPAveFrameQP+3, m_iQc);

  m_iQc = iClip3(iQp-m_iDDquant, m_iRCMaxQuant, m_iQc); // clipping
  if( (unsigned int)(m_pcJSVMParams->basicunit) >= m_uiMBPerRow)
    m_iQc = imax(m_iPAveFrameQP-6, m_iQc);
  else
    m_iQc = imax(m_iPAveFrameQP-3, m_iQc);

  m_iQc = imax(m_iRCMinQuant, m_iQc);
}

void rc_quadratic::updateQPInterlaceBU( void )
{
  // previous choice is frame coding
  if(m_pcGenericRC->m_iFieldFrame==1)
  {
    m_iTotalQpforPPicture +=m_iFrameQPBuffer;
    m_iPQp=m_iFrameQPBuffer;
  }
  // previous choice is field coding
  else
  {
    m_iTotalQpforPPicture +=m_iFieldQPBuffer;
    m_iPQp=m_iFieldQPBuffer;
  }
}

void rc_quadratic::updateModelQPFrame( int iBits )
{
  double dTmp, dQstep;

  dTmp = m_dCurrentFrameMAD * m_dX1 * m_dCurrentFrameMAD * m_dX1
    + 4 * m_dX2 * m_dCurrentFrameMAD * iBits;
  if ((m_dX2 == 0.0) || (dTmp < 0) || ((sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD) <= 0.0)) // fall back 1st order mode
    dQstep = (float) (m_dX1 * m_dCurrentFrameMAD / (double) iBits);
  else // 2nd order mode
    dQstep = (float) ((2 * m_dX2 * m_dCurrentFrameMAD) / (sqrt (dTmp) - m_dX1 * m_dCurrentFrameMAD));

  m_iQc = m_pcGenericRC->Qstep2QP(dQstep);
}

void rc_quadratic::init( void )
{
  m_fTHETA = 1.3636F;
	m_fOMEGA = 0.9F;

  m_i64IPrevBits = 0;
	m_i64PPrevBits = 0;

  m_pcJSVMParams->FrameSizeInMbs = (m_pcJSVMParams->height / MB_BLOCK_SIZE) * 
    (m_pcJSVMParams->width / MB_BLOCK_SIZE );
  if ( m_pcJSVMParams->FrameSizeInMbs % m_pcJSVMParams->BasicUnit != 0 ) {
    fprintf(stderr, "\nBasicUnit is required to be fraction of the total number of 16x16 MBs\n");
    assert(0); // some compilers do not compile assert in release/Ox mode
    exit(1);
  }
  
	m_pcJSVMParams->jumpd = m_pcJSVMParams->successive_Bframe;
	m_pcJSVMParams->PicInterlace = FRAME_CODING;
	m_pcJSVMParams->MbInterlace = 0;
	m_pcJSVMParams->channel_type = 0;
	m_pcJSVMParams->frame_mbs_only_flag = 1;
	m_pcJSVMParams->intra_period = 0;
	m_pcJSVMParams->NumberofCodedMacroBlocks = 0;
	m_pcJSVMParams->current_mb_nr = 0;
  m_pcGenericRC->m_iRemainingBits = 0;
  m_iTargetField = 0; /* formerly static */
  m_iNp = 0;
	m_iNb = 0;
	m_iBitsTopField = 0; /* formerly static */

  if ( m_pcJSVMParams->frame_mbs_only_flag )
    m_pcGenericRC->m_iTopFieldFlag = 0;

  m_pcJSVMParams->qp = 30;
  if ( m_pcJSVMParams->m_uiIntraPeriod != 1 )
    m_pcJSVMParams->RCUpdateMode = RC_MODE_2;
  else
    m_pcJSVMParams->RCUpdateMode = RC_MODE_1;
  m_pcJSVMParams->number = 0;
  m_pcJSVMParams->PicWidthInMbs = m_pcJSVMParams->width / MB_BLOCK_SIZE;
  m_pcJSVMParams->size = m_pcJSVMParams->width * m_pcJSVMParams->height;
  if ( m_pcJSVMParams->successive_Bframe > 1 )
    m_pcJSVMParams->HierarchicalCoding = 2;
  else 
    m_pcJSVMParams->HierarchicalCoding = 0;

  rc_alloc();  
}


⌨️ 快捷键说明

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