VTM碼率控制——代碼學習三

碼率分配

GOP碼率分配

TGOP=RpicAvg(Ncoded+SW)RcodedSW×NGOPT_{GOP} = \frac{R_{picAvg}\cdot (N_{coded} + SW) - R_{coded}}{SW} \times N_{GOP}

int EncRCGOP::xEstGOPTargetBits( EncRCSeq* encRCSeq, int GOPSize )
{
  int realInfluencePicture = min( g_RCSmoothWindowSize, encRCSeq->getFramesLeft() );
  int averageTargetBitsPerPic = (int)( encRCSeq->getTargetBits() / encRCSeq->getTotalFrames() );
  int currentTargetBitsPerPic = (int)( ( encRCSeq->getBitsLeft() - averageTargetBitsPerPic * (encRCSeq->getFramesLeft() - realInfluencePicture) ) / realInfluencePicture );
  int targetBits = currentTargetBitsPerPic * GOPSize;

  if ( targetBits < 200 )
  {
    targetBits = 200;   // at least allocate 200 bits for one GOP
  }

  return targetBits;
}

幀級碼率分配

Tpic=TGOPCodedGOPm=0NRPωpic_m×ωcurrPicT_{pic} = \frac{T_{GOP} - Coded_{GOP}}{ \sum_{m=0}^{N_{RP}} \omega_{pic\_m}} \times \omega_{currPic}

int EncRCPic::xEstPicTargetBits( EncRCSeq* encRCSeq, EncRCGOP* encRCGOP )
{
  int targetBits        = 0;
  int GOPbitsLeft       = encRCGOP->getBitsLeft();

  int i;
  int currPicPosition = encRCGOP->getNumPic()-encRCGOP->getPicLeft();
  int currPicRatio    = encRCSeq->getBitRatio( currPicPosition );
  int totalPicRatio   = 0;
  for ( i=currPicPosition; i<encRCGOP->getNumPic(); i++ )
  {
    totalPicRatio += encRCSeq->getBitRatio( i );
  }

  targetBits  = int( ((double)GOPbitsLeft) * currPicRatio / totalPicRatio );

  if ( targetBits < 100 )
  {
    targetBits = 100;   // at least allocate 100 bits for one picture
  }

  if ( m_encRCSeq->getFramesLeft() > 16 )
  {
    targetBits = int( g_RCWeightPicRargetBitInBuffer * targetBits + g_RCWeightPicTargetBitInGOP * m_encRCGOP->getTargetBitInGOP( currPicPosition ) );
  }

  return targetBits;
}

LCU碼率分配

TLCU=TcurrPicBitHCodedpicAllNotCodedLCUωLCU×ωcurrLCUT_{LCU} = \frac{T_{currPic} - Bit_{H}-Coded_{pic}}{\sum_{AllNotCodedLCU} \omega_{LCU}} \times \omega_{currLCU}

double EncRCPic::getLCUTargetBpp(bool isIRAP)
{
  int   LCUIdx    = getLCUCoded();
  double bpp      = -1.0;
  int avgBits     = 0;

  if (isIRAP)
  {
    int noOfLCUsLeft = m_numberOfLCU - LCUIdx + 1;
    int bitrateWindow = min(4,noOfLCUsLeft);
    double MAD      = getLCU(LCUIdx).m_costIntra;

    if (m_remainingCostIntra > 0.1 )
    {
      double weightedBitsLeft = (m_bitsLeft*bitrateWindow+(m_bitsLeft-getLCU(LCUIdx).m_targetBitsLeft)*noOfLCUsLeft)/(double)bitrateWindow;
      avgBits = int( MAD*weightedBitsLeft/m_remainingCostIntra );
    }
    else
    {
      avgBits = int( m_bitsLeft / m_LCULeft );
    }
    m_remainingCostIntra -= MAD;
  }
  else
  {
    double totalWeight = 0;
    for ( int i=LCUIdx; i<m_numberOfLCU; i++ )
    {
      totalWeight += m_LCUs[i].m_bitWeight;
    }
    int realInfluenceLCU = min( g_RCLCUSmoothWindowSize, getLCULeft() );
    avgBits = (int)( m_LCUs[LCUIdx].m_bitWeight - ( totalWeight - m_bitsLeft ) / realInfluenceLCU + 0.5 );
  }

  if ( avgBits < 1 )
  {
    avgBits = 1;
  }

  bpp = ( double )avgBits/( double )m_LCUs[ LCUIdx ].m_numberOfPixel;
  m_LCUs[ LCUIdx ].m_targetBits = avgBits;

  return bpp;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章