H.266中的熵编码总结

持续更新......

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

猜你喜欢

转载自blog.csdn.net/cxy19931018/article/details/80710192
今日推荐