Ignore:
Timestamp:
11 May 2012, 21:20:17 (12 years ago)
Author:
hschwarz
Message:

updated trunk (move to HM6.1)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp

    r5 r56  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license.
    5  *
    6  * Copyright (c) 2010-2011, ISO/IEC
     4 * granted under this license. 
     5 *
     6 * Copyright (c) 2010-2012, ITU/ISO/IEC
    77 * All rights reserved.
    88 *
     
    1515 *    this list of conditions and the following disclaimer in the documentation
    1616 *    and/or other materials provided with the distribution.
    17  *  * Neither the name of the ISO/IEC nor the names of its contributors may
     17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
    1818 *    be used to endorse or promote products derived from this software without
    1919 *    specific prior written permission.
     
    3232 */
    3333
    34 
    35 
    3634/** \file     TEncBinCoderCABAC.cpp
    3735    \brief    binary entropy encoder of CABAC
     
    3937
    4038#include "TEncBinCoderCABAC.h"
     39#include "TLibCommon/TComRom.h"
     40
     41
     42//! \ingroup TLibEncoder
     43//! \{
    4144
    4245
    4346TEncBinCABAC::TEncBinCABAC()
    4447: m_pcTComBitIf( 0 )
    45 , m_bBinCountingEnabled(0)
     48, m_binCountIncrement( 0 )
     49#if FAST_BIT_EST
     50, m_fracBits( 0 )
     51#endif
    4652{
    4753}
     
    5157}
    5258
    53 Void
    54 TEncBinCABAC::init( TComBitIf* pcTComBitIf )
     59Void TEncBinCABAC::init( TComBitIf* pcTComBitIf )
    5560{
    5661  m_pcTComBitIf = pcTComBitIf;
    5762}
    5863
    59 Void
    60 TEncBinCABAC::uninit()
     64Void TEncBinCABAC::uninit()
    6165{
    6266  m_pcTComBitIf = 0;
    6367}
    6468
    65 Void
    66 TEncBinCABAC::start()
    67 {
    68   m_uiLow           = 0;
    69   m_uiRange         = 510;
    70   m_uiBitsToFollow  = 0;
    71   m_uiByte          = 0;
    72   m_uiBitsLeft      = 9;
    73 }
    74 
    75 Void
    76 TEncBinCABAC::finish()
    77 {
    78   xWriteBitAndBitsToFollow( ( m_uiLow >> 9 ) & 1 );
    79   xWriteBit               ( ( m_uiLow >> 8 ) & 1 );
    80   // xWriteBit               ( 1 ); // stop bit, already written in TEncGOP::compressGOP
    81   if( 8 - m_uiBitsLeft != 0 )
    82   {
    83     m_pcTComBitIf->write  ( m_uiByte, 8 - m_uiBitsLeft );
    84   }
    85 }
    86 
    87 Void
    88 TEncBinCABAC::copyState( TEncBinIf* pcTEncBinIf )
     69Void TEncBinCABAC::start()
     70{
     71  m_uiLow            = 0;
     72  m_uiRange          = 510;
     73  m_bitsLeft         = 23;
     74  m_numBufferedBytes = 0;
     75  m_bufferedByte     = 0xff;
     76}
     77
     78Void TEncBinCABAC::finish()
     79{
     80  if ( m_uiLow >> ( 32 - m_bitsLeft ) )
     81  {
     82    //assert( m_numBufferedBytes > 0 );
     83    //assert( m_bufferedByte != 0xff );
     84    m_pcTComBitIf->write( m_bufferedByte + 1, 8 );
     85    while ( m_numBufferedBytes > 1 )
     86    {
     87      m_pcTComBitIf->write( 0x00, 8 );
     88      m_numBufferedBytes--;
     89    }
     90    m_uiLow -= 1 << ( 32 - m_bitsLeft );
     91  }
     92  else
     93  {
     94    if ( m_numBufferedBytes > 0 )
     95    {
     96      m_pcTComBitIf->write( m_bufferedByte, 8 );
     97    }
     98    while ( m_numBufferedBytes > 1 )
     99    {
     100      m_pcTComBitIf->write( 0xff, 8 );
     101      m_numBufferedBytes--;
     102    }   
     103  }
     104  m_pcTComBitIf->write( m_uiLow >> 8, 24 - m_bitsLeft );
     105}
     106
     107#if OL_FLUSH
     108Void TEncBinCABAC::flush()
     109{
     110  encodeBinTrm(1);
     111  finish();
     112  m_pcTComBitIf->write(1, 1);
     113#if OL_FLUSH_ALIGN
     114  m_pcTComBitIf->writeAlignZero();
     115#endif
     116
     117  start();
     118}
     119#endif
     120
     121/** Reset BAC register and counter values.
     122 * \returns Void
     123 */
     124Void TEncBinCABAC::resetBac()
     125{
     126  start();
     127}
     128
     129#if BURST_IPCM
     130/** Encode # of subsequent IPCM blocks.
     131 * \param numSubseqIPCM
     132 * \returns Void
     133 */
     134Void TEncBinCABAC::encodeNumSubseqIPCM( Int numSubseqIPCM )
     135{
     136  finish();
     137  m_pcTComBitIf->write( 1, 1 ); // stop bit
     138
     139  m_pcTComBitIf->write( numSubseqIPCM ? 1 : 0, 1);
     140
     141  if ( numSubseqIPCM > 0)
     142  {
     143    Bool bCodeLast = ( 3 > numSubseqIPCM );
     144
     145    while( --numSubseqIPCM )
     146    {
     147      m_pcTComBitIf->write( 1, 1 );
     148    }
     149    if( bCodeLast )
     150    {
     151      m_pcTComBitIf->write( 0, 1 );
     152    }
     153  }
     154}
     155#endif
     156
     157/** Encode PCM alignment zero bits.
     158 * \returns Void
     159 */
     160Void TEncBinCABAC::encodePCMAlignBits()
     161{
     162#if !BURST_IPCM
     163  finish();
     164  m_pcTComBitIf->write( 1, 1 ); // stop bit
     165#endif
     166  m_pcTComBitIf->writeAlignZero(); // pcm align zero
     167}
     168
     169/** Write a PCM code.
     170 * \param uiCode code value
     171 * \param uiLength code bit-depth
     172 * \returns Void
     173 */
     174Void TEncBinCABAC::xWritePCMCode(UInt uiCode, UInt uiLength)
     175{
     176  m_pcTComBitIf->write(uiCode, uiLength);
     177}
     178
     179Void TEncBinCABAC::copyState( TEncBinIf* pcTEncBinIf )
    89180{
    90181  TEncBinCABAC* pcTEncBinCABAC = pcTEncBinIf->getTEncBinCABAC();
    91182  m_uiLow           = pcTEncBinCABAC->m_uiLow;
    92183  m_uiRange         = pcTEncBinCABAC->m_uiRange;
    93   m_uiBitsToFollow  = pcTEncBinCABAC->m_uiBitsToFollow;
    94   m_uiByte          = pcTEncBinCABAC->m_uiByte;
    95   m_uiBitsLeft      = pcTEncBinCABAC->m_uiBitsLeft;
    96 }
    97 
    98 Void 
    99 TEncBinCABAC::resetBits()
    100 {
    101   m_uiLow          &= 255;
    102   m_uiBitsToFollow  = 0;
    103   m_uiByte          = 0;
    104   m_uiBitsLeft      = 9;
    105 }
    106 
    107 UInt
    108 TEncBinCABAC::getNumWrittenBits()
    109 {
    110   return m_pcTComBitIf->getNumberOfWrittenBits() + 8 + m_uiBitsToFollow - m_uiBitsLeft + 1;
    111 }
    112 
    113 Void
    114 TEncBinCABAC::encodeBin( UInt uiBin, ContextModel &rcCtxModel )
    115 {
    116   {
    117     DTRACE_CABAC_V( g_nSymbolCounter++ )
     184  m_bitsLeft        = pcTEncBinCABAC->m_bitsLeft;
     185  m_bufferedByte    = pcTEncBinCABAC->m_bufferedByte;
     186  m_numBufferedBytes = pcTEncBinCABAC->m_numBufferedBytes;
     187#if FAST_BIT_EST
     188  m_fracBits = pcTEncBinCABAC->m_fracBits;
     189#endif
     190}
     191
     192Void TEncBinCABAC::resetBits()
     193{
     194  m_uiLow            = 0;
     195  m_bitsLeft         = 23;
     196  m_numBufferedBytes = 0;
     197  m_bufferedByte     = 0xff;
     198  if ( m_binCountIncrement )
     199  {
     200    m_uiBinsCoded = 0;
     201  }
     202#if FAST_BIT_EST
     203  m_fracBits &= 32767;
     204#endif
     205}
     206
     207UInt TEncBinCABAC::getNumWrittenBits()
     208{
     209  return m_pcTComBitIf->getNumberOfWrittenBits() + 8 * m_numBufferedBytes + 23 - m_bitsLeft;
     210}
     211
     212/**
     213 * \brief Encode bin
     214 *
     215 * \param binValue   bin value
     216 * \param rcCtxModel context model
     217 */
     218Void TEncBinCABAC::encodeBin( UInt binValue, ContextModel &rcCtxModel )
     219{
     220  {
     221    DTRACE_CABAC_VL( g_nSymbolCounter++ )
    118222    DTRACE_CABAC_T( "\tstate=" )
    119223    DTRACE_CABAC_V( ( rcCtxModel.getState() << 1 ) + rcCtxModel.getMps() )
    120224    DTRACE_CABAC_T( "\tsymbol=" )
    121     DTRACE_CABAC_V( uiBin )
     225    DTRACE_CABAC_V( binValue )
    122226    DTRACE_CABAC_T( "\n" )
    123227  }
    124   if (m_bBinCountingEnabled)
    125   {
    126     m_uiBinsCoded++;
    127   }
     228  m_uiBinsCoded += m_binCountIncrement;
     229#if CABAC_INIT_FLAG
     230  rcCtxModel.setBinsCoded( 1 );
     231#endif
     232 
    128233  UInt  uiLPS   = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) & 3 ];
    129234  m_uiRange    -= uiLPS;
    130   if( uiBin != rcCtxModel.getMps() )
    131   {
    132     m_uiLow    += m_uiRange;
    133     m_uiRange   = uiLPS;
     235 
     236  if( binValue != rcCtxModel.getMps() )
     237  {
     238    Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ];
     239    m_uiLow     = ( m_uiLow + m_uiRange ) << numBits;
     240    m_uiRange   = uiLPS << numBits;
    134241    rcCtxModel.updateLPS();
     242   
     243    m_bitsLeft -= numBits;
    135244  }
    136245  else
    137246  {
    138247    rcCtxModel.updateMPS();
    139   }
    140   while( m_uiRange < 256 )
    141   {
    142     if( m_uiLow >= 512 )
    143     {
    144       xWriteBitAndBitsToFollow( 1 );
    145       m_uiLow -= 512;
    146     }
    147     else if( m_uiLow < 256 )
    148     {
    149       xWriteBitAndBitsToFollow( 0 );
    150     }
    151     else
    152     {
    153       m_uiBitsToFollow++;
    154       m_uiLow         -= 256;
    155     }
     248    if ( m_uiRange >= 256 )
     249    {
     250      return;
     251    }
     252   
     253    m_uiLow <<= 1;
     254    m_uiRange <<= 1;
     255    m_bitsLeft--;
     256  }
     257 
     258  testAndWriteOut();
     259}
     260
     261/**
     262 * \brief Encode equiprobable bin
     263 *
     264 * \param binValue bin value
     265 */
     266Void TEncBinCABAC::encodeBinEP( UInt binValue )
     267{
     268  {
     269    DTRACE_CABAC_VL( g_nSymbolCounter++ )
     270    DTRACE_CABAC_T( "\tEPsymbol=" )
     271    DTRACE_CABAC_V( binValue )
     272    DTRACE_CABAC_T( "\n" )
     273  }
     274  m_uiBinsCoded += m_binCountIncrement;
     275  m_uiLow <<= 1;
     276  if( binValue )
     277  {
     278    m_uiLow += m_uiRange;
     279  }
     280  m_bitsLeft--;
     281 
     282  testAndWriteOut();
     283}
     284
     285/**
     286 * \brief Encode equiprobable bins
     287 *
     288 * \param binValues bin values
     289 * \param numBins number of bins
     290 */
     291Void TEncBinCABAC::encodeBinsEP( UInt binValues, Int numBins )
     292{
     293  m_uiBinsCoded += numBins & -m_binCountIncrement;
     294 
     295  for ( Int i = 0; i < numBins; i++ )
     296  {
     297    DTRACE_CABAC_VL( g_nSymbolCounter++ )
     298    DTRACE_CABAC_T( "\tEPsymbol=" )
     299    DTRACE_CABAC_V( ( binValues >> ( numBins - 1 - i ) ) & 1 )
     300    DTRACE_CABAC_T( "\n" )
     301  }
     302 
     303  while ( numBins > 8 )
     304  {
     305    numBins -= 8;
     306    UInt pattern = binValues >> numBins;
     307    m_uiLow <<= 8;
     308    m_uiLow += m_uiRange * pattern;
     309    binValues -= pattern << numBins;
     310    m_bitsLeft -= 8;
     311   
     312    testAndWriteOut();
     313  }
     314 
     315  m_uiLow <<= numBins;
     316  m_uiLow += m_uiRange * binValues;
     317  m_bitsLeft -= numBins;
     318 
     319  testAndWriteOut();
     320}
     321
     322/**
     323 * \brief Encode terminating bin
     324 *
     325 * \param binValue bin value
     326 */
     327Void TEncBinCABAC::encodeBinTrm( UInt binValue )
     328{
     329  m_uiBinsCoded += m_binCountIncrement;
     330  m_uiRange -= 2;
     331  if( binValue )
     332  {
     333    m_uiLow  += m_uiRange;
     334    m_uiLow <<= 7;
     335    m_uiRange = 2 << 7;
     336    m_bitsLeft -= 7;
     337  }
     338  else if ( m_uiRange >= 256 )
     339  {
     340    return;
     341  }
     342  else
     343  {
    156344    m_uiLow   <<= 1;
    157345    m_uiRange <<= 1;
    158   }
    159 }
    160 
    161 Void
    162 TEncBinCABAC::encodeBinEP( UInt uiBin )
    163 {
    164   {
    165     DTRACE_CABAC_V( g_nSymbolCounter++ )
    166     DTRACE_CABAC_T( "\tEPsymbol=" )
    167     DTRACE_CABAC_V( uiBin )
    168     DTRACE_CABAC_T( "\n" )
    169   }
    170   if (m_bBinCountingEnabled)
    171   {
    172     m_uiBinsCoded++;
    173   }
    174   m_uiLow <<= 1;
    175   if( uiBin )
    176   {
    177     m_uiLow += m_uiRange;
    178   }
    179   if( m_uiLow >= 1024 )
    180   {
    181     xWriteBitAndBitsToFollow( 1 );
    182     m_uiLow -= 1024;
    183   }
    184   else if( m_uiLow < 512 )
    185   {
    186     xWriteBitAndBitsToFollow( 0 );
     346    m_bitsLeft--;   
     347  }
     348 
     349  testAndWriteOut();
     350}
     351
     352Void TEncBinCABAC::testAndWriteOut()
     353{
     354  if ( m_bitsLeft < 12 )
     355  {
     356    writeOut();
     357  }
     358}
     359
     360/**
     361 * \brief Move bits from register into bitstream
     362 */
     363Void TEncBinCABAC::writeOut()
     364{
     365  UInt leadByte = m_uiLow >> (24 - m_bitsLeft);
     366  m_bitsLeft += 8;
     367  m_uiLow &= 0xffffffffu >> m_bitsLeft;
     368 
     369  if ( leadByte == 0xff )
     370  {
     371    m_numBufferedBytes++;
    187372  }
    188373  else
    189374  {
    190     m_uiBitsToFollow++;
    191     m_uiLow         -= 512;
    192   }
    193 }
    194 
    195 Void
    196 TEncBinCABAC::encodeBinTrm( UInt uiBin )
    197 {
    198   if (m_bBinCountingEnabled)
    199   {
    200     m_uiBinsCoded++;
    201   }
    202   m_uiRange -= 2;
    203   if( uiBin )
    204   {
    205     m_uiLow  += m_uiRange;
    206     m_uiRange = 2;
    207   }
    208   while( m_uiRange < 256 )
    209   {
    210     if( m_uiLow >= 512 )
    211     {
    212       xWriteBitAndBitsToFollow( 1 );
    213       m_uiLow -= 512;
    214     }
    215     else if( m_uiLow < 256 )
    216     {
    217       xWriteBitAndBitsToFollow( 0 );
     375    if ( m_numBufferedBytes > 0 )
     376    {
     377      UInt carry = leadByte >> 8;
     378      UInt byte = m_bufferedByte + carry;
     379      m_bufferedByte = leadByte & 0xff;
     380      m_pcTComBitIf->write( byte, 8 );
     381     
     382      byte = ( 0xff + carry ) & 0xff;
     383      while ( m_numBufferedBytes > 1 )
     384      {
     385        m_pcTComBitIf->write( byte, 8 );
     386        m_numBufferedBytes--;
     387      }
    218388    }
    219389    else
    220390    {
    221       m_uiBitsToFollow++;
    222       m_uiLow         -= 256;
    223     }
    224     m_uiLow   <<= 1;
    225     m_uiRange <<= 1;
    226   }
    227 }
    228 
    229 Void 
    230 TEncBinCABAC::xWriteBit( UInt uiBit )
    231 {
    232   m_uiByte += m_uiByte + uiBit;
    233   if( ! --m_uiBitsLeft )
    234   {
    235     m_pcTComBitIf->write( m_uiByte, 8 );
    236     m_uiBitsLeft  = 8;
    237     m_uiByte      = 0;
    238   }
    239 }
    240 
    241 Void 
    242 TEncBinCABAC::xWriteBitAndBitsToFollow( UInt uiBit )
    243 {
    244   xWriteBit( uiBit );
    245   uiBit = 1 - uiBit;
    246   while( m_uiBitsToFollow > 0 )
    247   {
    248     m_uiBitsToFollow--;
    249     xWriteBit( uiBit );
    250   }
    251 }
     391      m_numBufferedBytes = 1;
     392      m_bufferedByte = leadByte;
     393    }     
     394  }   
     395}
     396
     397/** flush bits when CABAC termination
     398  * \param [in] bEnd true means this flushing happens at the end of RBSP. No need to encode stop bit
     399  */
     400Void TEncBinCABAC::encodeFlush(Bool bEnd)
     401{
     402  m_uiRange = 2;
     403
     404  m_uiLow  += 2;
     405  m_uiLow <<= 7;
     406  m_uiRange = 2 << 7;
     407  m_bitsLeft -= 7;
     408  testAndWriteOut();
     409  finish();
     410
     411  if(!bEnd)
     412  {
     413    m_pcTComBitIf->write( 1, 1 ); // stop bit
     414  }
     415}
     416
     417//! \}
Note: See TracChangeset for help on using the changeset viewer.