最近調試HEVC中碼率控制, 發現HM裏面一個重大bug

 

 

            最近調試HEVC中碼率控制, 發現裏面一個重大bug!

 

           碼率控制中有這麼一個函數:

Int TEncRCGOP::xEstGOPTargetBits( TEncRCSeq* 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; }

         主要就是控制目標碼率的範圍!
         H.265 碼率控制比H.264比較, 直觀上增加了一個參與計算的參數就是編碼幀數!也就是cfg裏面的參數FramesToBeEncoded。

         所以大家最好是變多少幀, 配置爲對少幀,  但有些情況是不知道要編碼多少幀, 有些同學就寫一個最大值, 比如 999999, 表面上看沒問題!

        但是編碼幾幀後就會發現!上面這段程序會進入  targetBits = 200 , 導致QP一直是51, 從而碼率控制失效, 設置不當還會導致 QP一直很小, 更是起不到碼率控制的作用!

        解決辦法:

        方法一1. 設置實際編碼幀數, 這樣控制最準, 當然不要導致Int currentTargetBitsPerPic = (Int)( ( encRCSeq->getBitsLeft() - averageTargetBitsPerPic * (encRCSeq->getFramesLeft() - realInfluencePicture) ) / realInfluencePicture );這裏溢出!

        方法2.  修改代碼, 防止溢出, 修改如下:

Int TEncRCGOP::xEstGOPTargetBits( TEncRCSeq* encRCSeq, Int GOPSize )
{
  Int realInfluencePicture = min( g_RCSmoothWindowSize, encRCSeq->getFramesLeft() );
  Int averageTargetBitsPerPic = (Int)( encRCSeq->getTargetBits() / encRCSeq->getTotalFrames() );
  Int currentTargetBitsPerPic = (Int)( ( encRCSeq->getBitsLeft() - (Int64)averageTargetBitsPerPic * (Int64)(encRCSeq->getFramesLeft() - realInfluencePicture) ) / realInfluencePicture );
  Int targetBits = currentTargetBitsPerPic * GOPSize;

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

  return targetBits;
}

       方法3:  修改代碼

      修改參與計算的幀數, 比如以2000幀爲單位做一次控制, 每2000幀重新配置下碼率控制!這樣來避免溢出!


 

 

   

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