HEVC熵解碼程式碼分析—類結構(1)

來源:互聯網
上載者:User

標籤:hevc   熵解碼   類結構   

最近開始做HEVC了,其中熵解碼作為最底層的部分,因為和h264差不多,難度係數不是很大,主要是一些查表的操作

具體的實現原理就不細說了,主要從代碼來進行解釋

首先分析HM工程當中的熵解碼的部分作為引導,因為最終要在DSP上進行運行,之後會重寫為C代碼,流程性更強


程式碼分析

首先介紹熵解碼中比較重要的幾個結構體和設計到的函數

一進入main函數,最主要的就是對應的解碼類TAppDecTop

int main(int argc, char* argv[]){  TAppDecTop  cTAppDecTop;

TAppDecTop類中主要是create和destroy相關的成員函數,真正重要的解碼類還在 TDecTop當中,開啟TDecTop類,會看到一些比較重要的模組的類

  TComPrediction          m_cPrediction;  TComTrQuant             m_cTrQuant;  TDecGop                 m_cGopDecoder;  TDecSlice               m_cSliceDecoder;  TDecCu                  m_cCuDecoder;  TDecEntropy             m_cEntropyDecoder;  TDecCavlc               m_cCavlcDecoder;  TDecSbac                m_cSbacDecoder;  TDecBinCABAC            m_cBinCABAC;  SEIReader               m_seiReader;  TComLoopFilter          m_cLoopFilter;  TComSampleAdaptiveOffset m_cSAO;

很明顯有幾個和熵解碼有關係:

TDecEntropy             m_cEntropyDecoder;看一下成員函數

  Void init (TComPrediction* p) {m_pcPrediction = p;}  Void decodePUWise       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU );  Void decodeInterDirPU   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx );  Void decodeRefFrmIdxPU  ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );  Void decodeMvdPU        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );  Void decodeMVPIdxPU     ( TComDataCU* pcSubCU, UInt uiPartAddr, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList );  Void    setEntropyDecoder           ( TDecEntropyIf* p );  Void    setBitstream                ( TComInputBitstream* p ) { m_pcEntropyDecoderIf->setBitstream(p);                    }  Void    resetEntropy                ( TComSlice* p)           { m_pcEntropyDecoderIf->resetEntropy(p);                    }  Void    decodeVPS                   ( TComVPS* pcVPS ) { m_pcEntropyDecoderIf->parseVPS(pcVPS); }  Void    decodeSPS                   ( TComSPS* pcSPS ) { m_pcEntropyDecoderIf->parseSPS(pcSPS); }  Void    decodePPS                   ( TComPPS* pcPPS ) { m_pcEntropyDecoderIf->parsePPS(pcPPS); }
可以看出來,就是一些解碼模組對應的功能函數

但是這裡有一個比較需要注意的地方就是這個函數裡面對應的解碼,不僅會用到熵解碼的相關方法,還會有CAVLC的解碼方法,那麼怎麼區分呢

這裡一個C++相關的知識就有了,C++類的多態的實現

TDecEntropyIf*  m_pcEntropyDecoderIf;

class TDecEntropyIf{public:  //  Virtual list for SBAC/CAVLC  virtual Void  resetEntropy          ( TComSlice* pcSlice )     = 0;  virtual Void  setBitstream          ( TComInputBitstream* p )  = 0;  virtual Void  parseVPS                  ( TComVPS* pcVPS )     = 0;  virtual Void  parseSPS                  ( TComSPS* pcSPS )     = 0;  virtual Void  parsePPS                  ( TComPPS* pcPPS )     = 0;  virtual Void parseSliceHeader          ( TComSlice* pcSlice, ParameterSetManagerDecoder *parameterSetManager)       = 0;  virtual Void parseTerminatingBit       ( UInt& ruilsLast )                                     = 0;  virtual Void parseRemainingBytes( Bool noTrailingBytesExpected ) = 0;  virtual Void parseMVPIdx        ( Int& riMVPIdx ) = 0;public:  virtual Void parseSkipFlag      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseSplitFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parsePLTModeFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parsePLTModeSyntax        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiNumComp) = 0;  virtual Void parsePLTSharingModeFlag   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseScanRotationModeFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseMergeFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPUIdx ) = 0;  virtual Void parseMergeIndex    ( TComDataCU* pcCU, UInt& ruiMergeIndex ) = 0;  virtual Void parsePartSize      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parsePartSizeIntraBC( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parsePredMode      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseIntraDirLumaAng( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseIntraBCFlag   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth ) = 0;  virtual Void parseIntraBC       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth ) = 0;  virtual Void parseIntraBCBvd    ( TComDataCU* pcCU, UInt uiAbsPartAddr, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList ) = 0;  virtual Void parseInterDir      ( TComDataCU* pcCU, UInt& ruiInterDir, UInt uiAbsPartIdx ) = 0;  virtual Void parseRefFrmIdx     ( TComDataCU* pcCU, Int& riRefFrmIdx, RefPicList eRefList ) = 0;  virtual Void parseMvd           ( TComDataCU* pcCU, UInt uiAbsPartAddr, UInt uiPartIdx, UInt uiDepth, RefPicList eRefList ) = 0;  virtual Void parseCrossComponentPrediction ( class TComTU &rTu, ComponentID compID ) = 0;  virtual Void parseTransformSubdivFlag( UInt& ruiSubdivFlag, UInt uiLog2TransformBlockSize ) = 0;  virtual Void parseQtCbf         ( TComTU &rTu, const ComponentID compID, const Bool lowestLevel ) = 0;  virtual Void parseColourTransformFlag( UInt uiAbsPartIdx, Bool& uiFlag ) = 0;  virtual Void parseQtRootCbf     ( UInt uiAbsPartIdx, UInt& uiQtRootCbf ) = 0;  virtual Void parseDeltaQP       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseChromaQpAdjustment( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;  virtual Void parseIPCMInfo     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth) = 0;  virtual Void parseCoeffNxN( class TComTU &rTu, ComponentID compID  ) = 0;  virtual Void parseTransformSkipFlags ( class TComTU &rTu, ComponentID component ) = 0;  virtual Void parseExplicitRdpcmMode ( TComTU &rTu, ComponentID compID ) = 0;  virtual ~TDecEntropyIf() {}};

這個類裡面都是虛成員函數,是通過具體傳入這個類的繼承類的情況選擇相應的解碼方法。

Void    setEntropyDecoder           ( TDecEntropyIf* p );

比如

class TDecSbac : public TDecEntropyIf

class TDecCavlc : public SyntaxElementParser, public TDecEntropyIf

這樣上層的類就基本上差不多了

和熵解碼最相關的兩個類:

  TDecSbac                m_cSbacDecoder;  TDecBinCABAC            m_cBinCABAC;

其中 TDecSbac                m_cSbacDecoder 是包含了一個slice當中解模組的所有功能函數,其中包括

  Void load                       ( const TDecSbac* pSrc );  Void loadContexts               ( const TDecSbac* pSrc );  Void xCopyFrom                  ( const TDecSbac* pSrc );  Void xCopyContextsFrom          ( const TDecSbac* pSrc );  Void  resetEntropy (TComSlice* pSlice );  Void  setBitstream              ( TComInputBitstream* p  ) { m_pcBitstream = p; m_pcTDecBinIf->init( p ); }  Void  parseVPS                  ( TComVPS* /*pcVPS*/ ) {}  Void  parseSPS                  ( TComSPS* /*pcSPS*/ ) {}  Void  parsePPS                  ( TComPPS* /*pcPPS*/ ) {}  Void  parseSliceHeader          ( TComSlice* /*pcSlice*/, ParameterSetManagerDecoder* /*parameterSetManager*/) {}  Void  parseTerminatingBit       ( UInt& ruiBit );  Void  parseRemainingBytes       ( Bool noTrailingBytesExpected);  Void  parseMVPIdx               ( Int& riMVPIdx          );  Void  parseSaoMaxUvlc           ( UInt& val, UInt maxSymbol );  Void  parseSaoMerge             ( UInt&  ruiVal   );  Void  parseSaoTypeIdx           ( UInt&  ruiVal  );  Void  parseSaoUflc              ( UInt uiLength, UInt& ruiVal     );  Void parseSAOBlkParam           (SAOBlkParam& saoBlkParam, Bool* sliceEnabled, Bool leftMergeAvail, Bool aboveMergeAvail);  Void parseSaoSign               (UInt& val);

碼流的擷取,底層熵解碼一個bit,根據bit資料反二值化等操作,最終解出文法元素相應的值


TDecBinCABAC類就是熵解碼中最底層,從碼流中解碼出相應的1個bit資料的函數

也就是最底層的算術解碼

  Void  decodeBin         ( UInt& ruiBin, ContextModel& rcCtxModel );  Void  decodeBinEP       ( UInt& ruiBin                           );  Void  decodeBinsEP      ( UInt& ruiBin, Int numBins              );  Void  decodeAlignedBinsEP( UInt& ruiBins, Int numBins             );#endif  Void  align             ();  Void  decodeBinTrm      ( UInt& ruiBin                           );  Void  xReadPCMCode      ( UInt uiLength, UInt& ruiCode );  Void  copyState         ( const TDecBinIf* pcTDecBinIf );  TDecBinCABAC* getTDecBinCABAC()             { return this; }  const TDecBinCABAC* getTDecBinCABAC() const { return this; }private:  TComInputBitstream* m_pcTComBitstream;  UInt                m_uiRange;  UInt                m_uiValue;  Int                 m_bitsNeeded;};

總結一下:

在HM中和熵解碼有關的類結構基本上羅列出來就是:

TAppDecTop

       TDecTop

                TDecEntropy

                TDecSbac

                TDecBinCABAC


HEVC熵解碼程式碼分析—類結構(1)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.