HEVC函数解析-TEncEntropyIf的子类

来源:互联网 发布:免费源码加密 编辑:程序博客网 时间:2024/05/19 17:58

在TEncEntropy.hpp中,TEncEntropy被定义为抽样类,包含了各种code函数,申明为纯虚函数,这些函数具体的功能实现,由不同的派生子类定义。

  1. TEncCavlc子类
class TEncCavlc: public syntaxElementWriter, public TEncEntropyIf{    codeVPS();    codeSPS();    codeSliceHeader();}

具体的函数定义:

Void TEncCavlc::codePPS( const TComPPS* pcPPS ){#if ENC_DEC_TRACE  xTracePPSHeader ();#endif  WRITE_UVLC( pcPPS->getPPSId(),                             "pps_pic_parameter_set_id" );  WRITE_UVLC( pcPPS->getSPSId(),                             "pps_seq_parameter_set_id" );  WRITE_FLAG( pcPPS->getDependentSliceSegmentsEnabledFlag()    ? 1 : 0, "dependent_slice_segments_enabled_flag" );  WRITE_FLAG( pcPPS->getOutputFlagPresentFlag() ? 1 : 0,     "output_flag_present_flag" );  WRITE_CODE( pcPPS->getNumExtraSliceHeaderBits(), 3,        "num_extra_slice_header_bits");  WRITE_FLAG( pcPPS->getSignHideFlag(), "sign_data_hiding_flag" );  WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0,   "cabac_init_present_flag" );  WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1,     "num_ref_idx_l0_default_active_minus1");  WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1,     "num_ref_idx_l1_default_active_minus1");  }

可以看到在TEncCavlc的函数定义中,一直在重复调用宏函数WRITE_CODE(), WRITE_FLAG(),WRITE_UVLC()。这几个宏在父类syntaxElementWriter中定义:

**syntaxElementWriter.hpp**#define WRITE_CODE( value, length, name)     xWriteCode ( value, length )#define WRITE_UVLC( value,         name)     xWriteUvlc ( value )#define WRITE_SVLC( value,         name)     xWriteSvlc ( value )#define WRITE_FLAG( value,         name)     xWriteFlag ( value )class SyntaxElementWriter{protected:  TComBitIf*    m_pcBitIf; //指向抽象类的指针  SyntaxElementWriter()  :m_pcBitIf(NULL)  {};  virtual ~SyntaxElementWriter() {};  Void  setBitstream          ( TComBitIf* p )  { m_pcBitIf = p;  }  Void  xWriteCode            ( UInt uiCode, UInt uiLength );  Void  xWriteUvlc            ( UInt uiCode );  Void  xWriteSvlc            ( Int  iCode   );  Void  xWriteFlag            ( UInt uiCode );#if ENC_DEC_TRACE  Void  xWriteCodeTr          ( UInt value, UInt  length, const TChar *pSymbolName);  Void  xWriteUvlcTr          ( UInt value,               const TChar *pSymbolName);  Void  xWriteSvlcTr          ( Int  value,               const TChar *pSymbolName);  Void  xWriteFlagTr          ( UInt value,               const TChar *pSymbolName);#endif  Void xWriteRbspTrailingBits();  UInt  xConvertToUInt        ( Int iValue ) {  return ( iValue <= 0) ? -iValue<<1 : (iValue<<1)-1; }};

其中,xWriteCode(),xWriteUvlc(),xWriteSvlc(),xWriteFlag()是类syntaxElementWriter的成员函数

**syntaxElementWriter.cpp**Void SyntaxElementWriter::xWriteCode     ( UInt uiCode, UInt uiLength ){  assert ( uiLength > 0 );  m_pcBitIf->write( uiCode, uiLength );}Void SyntaxElementWriter::xWriteUvlc     ( UInt uiCode ){  UInt uiLength = 1;  UInt uiTemp = ++uiCode;  assert ( uiTemp );  while( 1 != uiTemp )  {    uiTemp >>= 1;    uiLength += 2;  }  // Take care of cases where uiLength > 32  m_pcBitIf->write( 0, uiLength >> 1);  m_pcBitIf->write( uiCode, (uiLength+1) >> 1);}

可见,syntaxElementWriter中xWrite()函数主要是调用了成员变量m_pcBitIf,这也是一个指向抽象类的指针。同样根据setBitStream()函数,用具体子类的指针或引用作为参数,对该指针变量进行赋值。
由此,得到了第二个抽象类:TComBitIf
抽象类在TComStream.hpp申明

class TComBitIf{public:  virtual Void        writeAlignOne         () {};  virtual Void        writeAlignZero        () {};  virtual Void        write                 ( UInt uiBits, UInt uiNumberOfBits )  = 0;  virtual Void        resetBits             ()                                    = 0;  virtual UInt        getNumberOfWrittenBits() const = 0;  virtual Int         getNumBitsUntilByteAligned() const = 0;  virtual ~TComBitIf() {}};

该抽象类多态派生出了两个类TComBitCounter和TComOutputBitStream

class TComBitCounter : public TComBitIf{protected:UInt m_uiBitCounter;public:TComBitCounter(){}Void write(UInt, UInt uiNumberOfBits) {m_uiBitCounter+=uiNumberOfBits;}Void resetBits() {m_uiBitCounter=0;}Uint getNumberOfWrittenBits()const {return m_uiBitCounter}Void getNumBitsUntilByteAligned()const {return (8-m_uiBitCounter)&0x7}};
TComOutputBitStream:public TComBitIf{std:vector<uint_8> m_fifo;UInt m_num_held_bits;   ///number of bits not flushed to bytestream.UChar m_held_bits; ///the bits held and not flushed to bytestream.public:Void write  (UInt uiBit, UInt uiNumberOfBits); //append uiNumberOfBit least significant bits of uiBits to the current bitstreamVoid writeAlignOne (); //insert one bits until the bitstream is byte-alignedVoid writeAlignZero(); //insert zero bits until the bitstream is byte-aligned//utility functionsUchar* getByteSteam() const;UInt getByteStreamLength();Void clear();/** 1. Return the number of bits that have been written since the last clear()   */  UInt getNumberOfWrittenBits() const { return UInt(m_fifo.size()) * 8 + m_num_held_bits; }  ...}

主要是write()函数,把uiBit这个值,写入uiNumberOfBits这么多个bit到比特流中去。
2. TEncSbac子类

原创粉丝点击