POC計算

視頻編碼中由於B幀的存在使得視頻的播放順序和編碼順序不一樣。解碼後的視頻需要按播放順序排列播放,POC(picture order count)就是視頻幀按播放順序的標識號。

POC的作用主要有:幀的唯一標識符、用於merge模式下生成運動信息、解碼端一致性檢查。

每一個編碼的幀都有一個POC,可以用變量PicOrderCntVal表示,取值範圍爲-2^31~2^31-1,所以POC值需要31比特表示,爲了節省比特,碼流中只傳輸POC的低有效位(LSB),而高有效位(MSB)可以由前面幀計算得到。

POC計算過程如下:

噹噹前幀不是NoRaslOutputFlag=1的IRAP圖像時,變量prevPicOrderCntLsbprevPicOrderCntMsb 可由下面步驟求得:

  1. prevTid0Pic是時域層爲0(TemporalId=0)且按解碼順序離當前圖像最近的非RASL、RADL或SLNR(sub-layer non-reference picture)圖像。

  2. prevPicOrderCntLsb等於prevTid0Pic的 slice_pic_order_cnt_lsb。

  3. prevPicOrderCntMsb等於prevTid0Pic的PicOrderCntMsb。

當前圖像的PicOrderCntMsb的計算過程如下:

  1. 如果當前圖像是IRAP圖像,且NoRaslOutputFlag=1,則PicOrderCntMsb=0。

  2. 否則,PicOrderCntMsb按下面步驟生成:

if( ( slice_pic_order_cnt_lsb < prevPicOrderCntLsb ) &&
( ( prevPicOrderCntLsb − slice_pic_order_cnt_lsb ) >= ( MaxPicOrderCntLsb / 2 ) ) )
PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb
else if( (slice_pic_order_cnt_lsb > prevPicOrderCntLsb ) &&
( ( slice_pic_order_cnt_lsb − prevPicOrderCntLsb ) > ( MaxPicOrderCntLsb / 2 ) ) )
PicOrderCntMsb = prevPicOrderCntMsb − MaxPicOrderCntLsb
else
PicOrderCntMsb = prevPicOrderCntMsb

最終POC的計算如下:

PicOrderCntVal = PicOrderCntMsb + slice_pic_order_cnt_lsb

注意:對所有IDR圖像PicOrderCntVal=0。

HM中相關代碼如下:

  if( pcSlice->getIdrPicFlag() )
    {//!<IDR圖像POC=0
      pcSlice->setPOC(0);
      TComReferencePictureSet* rps = pcSlice->getLocalRPS();
      (*rps)=TComReferencePictureSet();
      pcSlice->setRPS(rps);
    }
    else
    {
      READ_CODE(sps->getBitsForPOC(), uiCode, "slice_pic_order_cnt_lsb");
      Int iPOClsb = uiCode;
      Int iPrevPOC = prevTid0POC;
      Int iMaxPOClsb = 1<< sps->getBitsForPOC();
      Int iPrevPOClsb = iPrevPOC & (iMaxPOClsb - 1);
      Int iPrevPOCmsb = iPrevPOC-iPrevPOClsb;
      Int iPOCmsb;
      if( ( iPOClsb  <  iPrevPOClsb ) && ( ( iPrevPOClsb - iPOClsb )  >=  ( iMaxPOClsb / 2 ) ) )
      {
        iPOCmsb = iPrevPOCmsb + iMaxPOClsb;
      }
      else if( (iPOClsb  >  iPrevPOClsb )  && ( (iPOClsb - iPrevPOClsb )  >  ( iMaxPOClsb / 2 ) ) )
      {
        iPOCmsb = iPrevPOCmsb - iMaxPOClsb;
      }
      else
      {
        iPOCmsb = iPrevPOCmsb;
      }
      if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP )
      {
        // For BLA picture types, POCmsb is set to 0.
        iPOCmsb = 0;
      }
      pcSlice->setPOC              (iPOCmsb+iPOClsb);

感興趣的請關注微信公衆號Video Coding

 

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