HM符号率統計


HMは全てのフレームをエンコードした後、stdoutのデータフォーマットに出力する:
SUMMARY ——————————————————– Total Frames | Bitrate Y-PSNR U-PSNR V-PSNR YUV-PSNR 500 a 1722.4448 40.8944 43.4868 42.9115 41.4105 I Slices——————————————————– Total Frames | Bitrate Y-PSNR U-PSNR V-PSNR YUV-PSNR 1 i 5586.0000 42.8015 44.8098 44.9784 43.3934 P Slices——————————————————– Total Frames | Bitrate Y-PSNR U-PSNR V-PSNR YUV-PSNR 0 p -1.#IND -1.#IND -1.#IND -1.#IND -1.#IND B Slices——————————————————– Total Frames | Bitrate Y-PSNR U-PSNR V-PSNR YUV-PSNR 499 b 1714.7022 40.8906 43.4842 42.9074 41.4073 RVM: 0.000 Bytes written to file: 2155067 (1724.054 kbps) Total Time: 23008.202 sec.
上記の内容には、172.4448 kbpsと1724.54 kbpsの2つの平均符号率があります.前者はRBSPの符号率である.対応するビット統計コードは次のとおりです.
  //===== add PSNR =====
  // m_gcAnalyzeAll :SUMMARY---------------------------
  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
  TComSlice*  pcSlice = pcPic->getSlice(0);
  if (pcSlice->isIntra())
  { // m_gcAnalyzeI :I Slices--------------------------
    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
  }
  if (pcSlice->isInterP())
  { // m_gcAnalyzeP :P Slices--------------------------
    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
  }
  if (pcSlice->isInterB())
  { // m_gcAnalyzeB :B Slices--------------------------
    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
  }

VPS/SPS/PPSのRBSPに消費されるビットは、第1のIフレームに加算される.TEncGOP::xWriteParameterSetsは、VPS/SPS/PPSを符号化するために使用される.コードは次のとおりです.
Int TEncGOP::xWriteParameterSets (AccessUnit &accessUnit, TComSlice *slice)
{
  Int actualTotalBits = 0;

  actualTotalBits += xWriteVPS(accessUnit, m_pcEncTop->getVPS());
  actualTotalBits += xWriteSPS(accessUnit, slice->getSPS());
  actualTotalBits += xWritePPS(accessUnit, slice->getPPS());

  return actualTotalBits;
}

後者の符号率は、ファイルに書き込まれた平均符号率であり、上記の符号率よりも大きい.対応するビット統計コード:
Void TAppEncTop::rateStatsAccum(const AccessUnit& au, const std::vector& annexBsizes)
{ //  au size 4, VPS/SPS/PPS 4 NALU; au Slice NALU,size 1.
  AccessUnit::const_iterator it_au = au.begin();
  vector::const_iterator it_stats = annexBsizes.begin();

  for (; it_au != au.end(); it_au++, it_stats++)
  {
    switch ((*it_au)->m_nalUnitType)
    { // Slice NALU 
    case NAL_UNIT_CODED_SLICE_TRAIL_R:
    case NAL_UNIT_CODED_SLICE_TRAIL_N:
    case NAL_UNIT_CODED_SLICE_TSA_R:
    case NAL_UNIT_CODED_SLICE_TSA_N:
    case NAL_UNIT_CODED_SLICE_STSA_R:
    case NAL_UNIT_CODED_SLICE_STSA_N:
    case NAL_UNIT_CODED_SLICE_BLA_W_LP:
    case NAL_UNIT_CODED_SLICE_BLA_W_RADL:
    case NAL_UNIT_CODED_SLICE_BLA_N_LP:
    case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
    case NAL_UNIT_CODED_SLICE_IDR_N_LP:
    case NAL_UNIT_CODED_SLICE_CRA:
    case NAL_UNIT_CODED_SLICE_RADL_N:
    case NAL_UNIT_CODED_SLICE_RADL_R:
    case NAL_UNIT_CODED_SLICE_RASL_N:
    case NAL_UNIT_CODED_SLICE_RASL_R:
    case NAL_UNIT_VPS: // VPS NALU 
    case NAL_UNIT_SPS: // SPS NALU 
    case NAL_UNIT_PPS: // PPS NALU 
      m_essentialBytes += *it_stats;
      break;
    default:
      break;
    }

    m_totalBytes += *it_stats;
  }
}