持续更新......
1.基于上下文的自适应上下文算术编码,有两种函数,一个是TEncBinCABAC类的encodeBin函数,一个是TEncBinCABACCounter类的encodeBin函数,前者可以把比特写进码流文件,后者只是计算熵编码的比特数(用于亮度预测模式中的MPM及其他)
Void TEncBinCABAC::encodeBin( UInt binValue, ContextModel &rcCtxModel )
{
#if !VCEG_AZ05_MULTI_PARAM_CABAC
m_uiBinsCoded += m_binCountIncrement;
rcCtxModel.setBinsCoded( 1 );
UInt uiCtxIdx = rcCtxModel.getIdx();
if(m_bUpdateStr && m_iCounter[uiCtxIdx] < CABAC_NUM_BINS)
{
m_pbCodedString[uiCtxIdx][m_iCounter[uiCtxIdx]] = (binValue==1? true:false);
m_iCounter[uiCtxIdx] ++;
}
#endif
UShort uiLPS = TComCABACTables::sm_aucLPSTable[rcCtxModel.getState()>>6][(m_uiRange>>2)-64];
m_uiRange -= uiLPS;
if( binValue == 0 )
{
rcCtxModel.updateLPS();
Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 2 ];
if (numBits)
{
m_uiLow = ( m_uiLow + m_uiRange ) << numBits;
m_uiRange = uiLPS << numBits;
m_bitsLeft -= numBits;
}
else
{
m_uiLow = m_uiLow + m_uiRange ;
m_uiRange = uiLPS ;
}
}
else
{
rcCtxModel.updateMPS();
if ( m_uiRange >= 256 )
{
return;
}
Int numBits = TComCABACTables::sm_aucRenormTable[ m_uiRange >> 2 ];
m_uiLow <<= numBits;
m_uiRange <<= numBits;
m_bitsLeft -= numBits;
}
testAndWriteOut();
}
Void TEncBinCABACCounter::encodeBin( UInt binValue, ContextModel &rcCtxModel )
{
#if DEBUG_ENCODER_SEARCH_BINS
const UInt64 startingFracBits = m_fracBits;
#endif
m_uiBinsCoded += m_binCountIncrement;
m_fracBits += rcCtxModel.getEntropyBits( binValue );
#if VCEG_AZ07_BAC_ADAPT_WDOW || VCEG_AZ05_MULTI_PARAM_CABAC
if( binValue == 0 )
{
rcCtxModel.updateLPS();
}
else
{
rcCtxModel.updateMPS();
}
#else
rcCtxModel.update( binValue );
#endif
#if DEBUG_ENCODER_SEARCH_BINS
if ((g_debugCounter + debugEncoderSearchBinWindow) >= debugEncoderSearchBinTargetLine)
{
std::cout << g_debugCounter << ": coding bin value " << binValue << ", fracBits = [" << startingFracBits << "->" << m_fracBits << "]\n";
}
if (g_debugCounter >= debugEncoderSearchBinTargetLine)
{
Char breakPointThis;
breakPointThis = 7;
}
if (g_debugCounter >= (debugEncoderSearchBinTargetLine + debugEncoderSearchBinWindow))
{
exit(0);
}
g_debugCounter++;
#endif
}
2.n比特的定长编码(4比特的定长编码用于亮度预测模式中的16种选择模式)
Void TEncBinCABAC::encodeBinsEP( UInt binValues, Int numBins )
{
m_uiBinsCoded += numBins & -m_binCountIncrement;
if (m_uiRange == 256)
{
encodeAlignedBinsEP(binValues, numBins);
return;
}
while ( numBins > 8 )
{
numBins -= 8;
UInt pattern = binValues >> numBins;
m_uiLow <<= 8;
m_uiLow += m_uiRange * pattern;
binValues -= pattern << numBins;
m_bitsLeft -= 8;
testAndWriteOut();
}
m_uiLow <<= numBins;
m_uiLow += m_uiRange * binValues;
m_bitsLeft -= numBins;
testAndWriteOut();
}
3.截断二元码(用于亮度预测模式中的45种非选择模式)
Void TEncSbac::xWriteTruncBinCode(UInt uiSymbol, UInt uiMaxSymbol)
{
UInt uiThresh;
if (uiMaxSymbol > 256)
{
UInt uiThreshVal = 1 << 8;
uiThresh = 8;
while (uiThreshVal <= uiMaxSymbol)
{
uiThresh++;
uiThreshVal <<= 1;
}
uiThresh--;
}
else
{
uiThresh = g_NonMPM[uiMaxSymbol];
}
UInt uiVal = 1 << uiThresh;
assert(uiVal <= uiMaxSymbol);
assert((uiVal << 1) > uiMaxSymbol);
assert(uiSymbol < uiMaxSymbol);
UInt b = uiMaxSymbol - uiVal;
assert(b < uiVal);
if (uiSymbol < uiVal - b)
{
m_pcBinIf->encodeBinsEP(uiSymbol, uiThresh);
}
else
{
uiSymbol += uiVal - b;
assert(uiSymbol < (uiVal << 1));
assert((uiSymbol >> 1) >= uiVal - b);
m_pcBinIf->encodeBinsEP(uiSymbol, uiThresh + 1);
}
}