本文介绍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 };