[置顶] HEVC学习(二十四) —— 熵编码之五

本文介绍EncodeDecision过程,对应的代码及注释如下:

/**
 * \brief Encode bin
 *
 * \param binValue   bin value
 * \param rcCtxModel context model
 */
Void TEncBinCABAC::encodeBin( UInt binValue, ContextModel &rcCtxModel )
{
  {
    DTRACE_CABAC_VL( g_nSymbolCounter++ )
    DTRACE_CABAC_T( "\tstate=" )
    DTRACE_CABAC_V( ( rcCtxModel.getState() << 1 ) + rcCtxModel.getMps() )
    DTRACE_CABAC_T( "\tsymbol=" )
    DTRACE_CABAC_V( binValue )
    DTRACE_CABAC_T( "\n" )
  }
  m_uiBinsCoded += m_binCountIncrement;
  rcCtxModel.setBinsCoded( 1 );
  
  //! qCodRangeIdx = (codIRange >> 6) & 3;
  //! codIRangeLPS = rangeTabLPS[pStateIdx][qCodIRangeIdx];
  //! codIRange = codIRange - codIRangeLPS
  UInt  uiLPS   = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) & 3 ]; 
  m_uiRange    -= uiLPS;
  
  if( binValue != rcCtxModel.getMps() ) //!< binVal != valMPS,概率索引值将减小,即LPS的概率增大
  {
    Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ]; //!< RenormE
    m_uiLow     = ( m_uiLow + m_uiRange ) << numBits; //!< codILow = codILow + codIRange
    m_uiRange   = uiLPS << numBits;	//!< codIRange = codIRangeLPS
    rcCtxModel.updateLPS(); //!< pStateIdx = transIdxLPS[pStateIdx]
    
    m_bitsLeft -= numBits;
  }
  else //!< binVal == valMPS,概率索引值将增大,即LPS的概率减小
  {
    rcCtxModel.updateMPS(); //!< pStateIdx = transIdxLPS[pStateIdx]
    if ( m_uiRange >= 256 )
    {
      return;
    }
    
    m_uiLow <<= 1;
    m_uiRange <<= 1;
    m_bitsLeft--;
  }
  
  testAndWriteOut();
}

值得注意的是,HM中的归一化过程跟draft中的Figure 9-7、Figure 9-8不是一一对应关系,而是采用更为简洁的查表的方式进行,即代码中的sm_aucRenormTable:

const UChar TComCABACTables::sm_aucRenormTable[32] =
{
  6,  5,  4,  4,
  3,  3,  3,  3,
  2,  2,  2,  2,
  2,  2,  2,  2,
  1,  1,  1,  1,
  1,  1,  1,  1,
  1,  1,  1,  1,
  1,  1,  1,  1
};



 

 

你可能感兴趣的:(hm,HEVC,CABAC)