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