HEVC中编码每个CTU的码流跟踪

来源:互联网 发布:cst软件介绍 编辑:程序博客网 时间:2024/06/05 18:57

熵编码的重要类:TEncEntropy和TEncEntropyIf

TEncEntropyIf是纯熵编码的类,只有纯虚成员函数,没有数据成员。因此TEncEntropyIf是一个抽象类,等待被继承,纯虚函数在继承类中被定义。
**纯虚函数只有函数的名字而不具备函数的作用,留待派生中被定义。

...  virtual Void  codeVPS                 ( const TComVPS* pcVPS )                                      = 0;  virtual Void  codeSPS                 ( const TComSPS* pcSPS )                                      = 0;  virtual Void  codePPS                 ( const TComPPS* pcPPS )                                      = 0;  virtual Void  codeSliceHeader         ( TComSlice* pcSlice )                                  = 0;  ...

在TEncEntropy类中,包含唯一的一个数据成员: TEncEntropyIf* m_pcEntropyCoderIf;
这个类的定义如下:

/// entropy encoder classclass TEncEntropy{public:  Void    setEntropyCoder           ( TEncEntropyIf* e );  Void    setBitstream              ( TComBitIf* p )          { m_pcEntropyCoderIf->setBitstream(p);  }  Void    resetBits                 ()                        { m_pcEntropyCoderIf->resetBits();      }  UInt    getNumberOfWrittenBits    ()                        { return m_pcEntropyCoderIf->getNumberOfWrittenBits(); }  Void    resetEntropy              (const TComSlice *pSlice) { m_pcEntropyCoderIf->resetEntropy(pSlice);  }  SliceType determineCabacInitIdx   (const TComSlice *pSlice) { return m_pcEntropyCoderIf->determineCabacInitIdx(pSlice); }  Void    encodeSliceHeader         ( TComSlice* pcSlice );  Void    encodeTilesWPPEntryPoint( TComSlice* pSlice );  Void    encodeTerminatingBit      ( UInt uiIsLast );  Void    encodeSliceFinish         ();  TEncEntropyIf*      m_pcEntropyCoderIf;public:  Void encodeVPS               ( const TComVPS* pcVPS);  // SPS  Void encodeSPS               ( const TComSPS* pcSPS );  Void encodePPS               ( const TComPPS* pcPPS );  Void encodeSplitFlag         ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD = false );  Void encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodeSkipFlag          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodePUWise       ( TComDataCU* pcCU, UInt uiAbsPartIdx );  Void encodeInterDirPU   ( TComDataCU* pcSubCU, UInt uiAbsPartIdx  );  Void encodeRefFrmIdxPU  ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );  Void encodeMvdPU        ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );  Void encodeMVPIdxPU     ( TComDataCU* pcSubCU, UInt uiAbsPartIdx, RefPicList eRefList );  Void encodeMergeFlag    ( TComDataCU* pcCU, UInt uiAbsPartIdx );  Void encodeMergeIndex   ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodePredMode          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodePartSize          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD = false );  Void encodeIPCMInfo          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodePredInfo          ( TComDataCU* pcCU, UInt uiAbsPartIdx );  Void encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU = false );  Void encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx );  Void encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx );  Void encodeQtCbf             ( TComTU &rTu, const ComponentID compID, const Bool lowestLevel );  Void encodeQtCbfZero         ( TComTU &rTu, const ChannelType chType );  Void encodeQtRootCbfZero     ( );  Void encodeQtRootCbf         ( TComDataCU* pcCU, UInt uiAbsPartIdx );  Void encodeQP                ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodeChromaQpAdjustment ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );  Void encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID );private:  Void xEncodeTransform        ( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu );public:  Void encodeCoeff             ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& codeChromaQpAdj );  Void encodeCoeffNxN         ( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID );  Void estimateBit             ( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, ChannelType chType );  Void encodeSAOBlkParam(SAOBlkParam& saoBlkParam, const BitDepths &bitDepths, Bool* sliceEnabled, Bool leftMergeAvail, Bool aboveMergeAvail){m_pcEntropyCoderIf->codeSAOBlkParam(saoBlkParam, bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false);}  static Int countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize );};// END CLASS DEFINITION TEncEntropy

第一个Public下的函数基本是进行一些参数设置;而以encode-开头的函数,则是实现了熵编码写比特流的过程。注意到TEncEntropy类的这几个成员函数:

  Void    setBitstream              ( TComBitIf* p )          { m_pcEntropyCoderIf->setBitstream(p);  }  Void    resetBits                 ()                        { m_pcEntropyCoderIf->resetBits();      }  UInt    getNumberOfWrittenBits    ()                        { return m_pcEntropyCoderIf->getNumberOfWrittenBits(); }  Void    resetEntropy              (const TComSlice *pSlice) { m_pcEntropyCoderIf->resetEntropy(pSlice);  }  SliceType determineCabacInitIdx   (const TComSlice *pSlice) { return m_pcEntropyCoderIf->determineCabacInitIdx(pSlice); }

setBitstream(),resetBits(),getNumberOfWrittenBits(),resetEntropy(),determineCabacInitIdx()这几个功能的实现都是靠TEncEntropyIf来实现的。上面说到了TEncEntropyIf是一个抽象类,其成员函数不具有实际功能,这又是怎么回事呢?C++的类机制
这就不得提到另一个类: class TEncCavlc,这各类又多重继承了两个类:

class TEncCavlc : public SyntaxElementWriter, public TEncEntropyIf{Void setBitstream (TComBitIf * p) {m_pcBitIf = p;}Void resetBits () {m_pcBitIf->resetBits();}UInt getNumberOfWrittenBits() {return m_pcBitIf->getNumberOfWrittenBits();}}

而类TEncCavlc本身是没有数据成员的,所以m_pcBitIf是继承的SyntaxElementWriter这个类来的。

class SyntaxElementWriter{protected: TComBitIF * m_pcBitIf; ... Void setBitstream (TComBitIF* p) {m_pcBitIf = p};}

此处,需要了解这个类: TComBitIf, 它也是一个包含了纯虚函数的抽象类

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() {}};

虚函数的具体功能由派生子类定义

class TComOutputBitstream : public TComBitIf{std::vector<uint8_t> m_fifo;// 用于编码时写码流的接口  /**   * append uiNumberOfBits least significant bits of uiBits to   * the current bitstream   */  Void        write           ( UInt uiBits, UInt uiNumberOfBits );  /** insert one bits until the bitstream is byte-aligned */  Void        writeAlignOne   ();  /** insert zero bits until the bitstream is byte-aligned */  Void        writeAlignZero  ();  /** this function should never be called */  Void resetBits() { assert(0); }}

C++中多态功能,使得函数的调用跟具体的参数捆绑。定义一个基类,基类的成员函数定义为虚函数

virtual type fun (){    ...}

然后在由基类派生的不同子类中,覆盖函数的定义。在实际执行该函数功能时,由实际的指向子类的指针或引用作为传递参数,决定执行哪种子类对应的操作。

原创粉丝点击