source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibDecoder/TDecBinCoderCABAC.cpp @ 1263

Last change on this file since 1263 was 1259, checked in by seregin, 9 years ago

port rev 4256

  • Property svn:eol-style set to native
File size: 10.4 KB
RevLine 
[313]1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
[1029]4 * granted under this license.
[313]5 *
[1259]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[313]7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TDecBinCoderCABAC.cpp
35    \brief    binary entropy decoder of CABAC
36*/
37
38#include "TDecBinCoderCABAC.h"
[1029]39#include "TLibCommon/Debug.h"
40#if RExt__DECODER_DEBUG_BIT_STATISTICS
41#include "TLibCommon/TComCodingStatistics.h"
42#endif
[313]43
44//! \ingroup TLibDecoder
45//! \{
46
47TDecBinCABAC::TDecBinCABAC()
48: m_pcTComBitstream( 0 )
49{
50}
51
52TDecBinCABAC::~TDecBinCABAC()
53{
54}
55
56Void
57TDecBinCABAC::init( TComInputBitstream* pcTComBitstream )
58{
59  m_pcTComBitstream = pcTComBitstream;
60}
61
62Void
63TDecBinCABAC::uninit()
64{
65  m_pcTComBitstream = 0;
66}
67
68Void
69TDecBinCABAC::start()
70{
71  assert( m_pcTComBitstream->getNumBitsUntilByteAligned() == 0 );
[1029]72#if RExt__DECODER_DEBUG_BIT_STATISTICS
73  TComCodingStatistics::UpdateCABACStat(STATS__CABAC_INITIALISATION, 512, 510, 0);
74#endif
[313]75  m_uiRange    = 510;
76  m_bitsNeeded = -8;
77  m_uiValue    = (m_pcTComBitstream->readByte() << 8);
78  m_uiValue   |= m_pcTComBitstream->readByte();
79}
80
81Void
82TDecBinCABAC::finish()
83{
84  UInt lastByte;
85
86  m_pcTComBitstream->peekPreviousByte( lastByte );
87  // Check for proper stop/alignment pattern
88  assert( ((lastByte << (8 + m_bitsNeeded)) & 0xff) == 0x80 );
89}
90
91/**
92 - Copy CABAC state.
93 .
94 \param pcTDecBinIf The source CABAC engine.
95 */
96Void
[1029]97TDecBinCABAC::copyState( const TDecBinIf* pcTDecBinIf )
[313]98{
[1029]99  const TDecBinCABAC* pcTDecBinCABAC = pcTDecBinIf->getTDecBinCABAC();
[313]100  m_uiRange   = pcTDecBinCABAC->m_uiRange;
101  m_uiValue   = pcTDecBinCABAC->m_uiValue;
102  m_bitsNeeded= pcTDecBinCABAC->m_bitsNeeded;
103}
104
105
[1029]106
107#if RExt__DECODER_DEBUG_BIT_STATISTICS
108Void TDecBinCABAC::decodeBin( UInt& ruiBin, ContextModel &rcCtxModel, const TComCodingStatisticsClassType &whichStat )
109#else
110Void TDecBinCABAC::decodeBin( UInt& ruiBin, ContextModel &rcCtxModel )
111#endif
[313]112{
[1029]113#ifdef DEBUG_CABAC_BINS
114  const UInt startingRange = m_uiRange;
115#endif
116
[313]117  UInt uiLPS = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) - 4 ];
118  m_uiRange -= uiLPS;
119  UInt scaledRange = m_uiRange << 7;
[1029]120
[313]121  if( m_uiValue < scaledRange )
122  {
123    // MPS path
124    ruiBin = rcCtxModel.getMps();
[1029]125#if RExt__DECODER_DEBUG_BIT_STATISTICS
126    TComCodingStatistics::UpdateCABACStat(whichStat, m_uiRange+uiLPS, m_uiRange, Int(ruiBin));
127#endif
[313]128    rcCtxModel.updateMPS();
[1029]129
130    if ( scaledRange < ( 256 << 7 ) )
[313]131    {
[1029]132      m_uiRange = scaledRange >> 6;
133      m_uiValue += m_uiValue;
134
135      if ( ++m_bitsNeeded == 0 )
136      {
137        m_bitsNeeded = -8;
138        m_uiValue += m_pcTComBitstream->readByte();
139      }
[313]140    }
141  }
142  else
143  {
144    // LPS path
[1029]145    ruiBin      = 1 - rcCtxModel.getMps();
146#if RExt__DECODER_DEBUG_BIT_STATISTICS
147    TComCodingStatistics::UpdateCABACStat(whichStat, m_uiRange+uiLPS, uiLPS, Int(ruiBin));
148#endif
[313]149    Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ];
150    m_uiValue   = ( m_uiValue - scaledRange ) << numBits;
151    m_uiRange   = uiLPS << numBits;
152    rcCtxModel.updateLPS();
[1029]153
[313]154    m_bitsNeeded += numBits;
[1029]155
[313]156    if ( m_bitsNeeded >= 0 )
157    {
158      m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
159      m_bitsNeeded -= 8;
160    }
161  }
[1029]162
163#ifdef DEBUG_CABAC_BINS
164  if ((g_debugCounter + debugCabacBinWindow) >= debugCabacBinTargetLine)
[1246]165  {
[1029]166    std::cout << g_debugCounter << ": coding bin value " << ruiBin << ", range = [" << startingRange << "->" << m_uiRange << "]\n";
[1246]167  }
[1029]168
169  if (g_debugCounter >= debugCabacBinTargetLine)
170  {
171    Char breakPointThis;
172    breakPointThis = 7;
173  }
[1246]174  if (g_debugCounter >= (debugCabacBinTargetLine + debugCabacBinWindow))
175  {
176    exit(0);
177  }
[1029]178  g_debugCounter++;
179#endif
[313]180}
181
[1029]182
183#if RExt__DECODER_DEBUG_BIT_STATISTICS
184Void TDecBinCABAC::decodeBinEP( UInt& ruiBin, const TComCodingStatisticsClassType &whichStat )
185#else
186Void TDecBinCABAC::decodeBinEP( UInt& ruiBin )
187#endif
[313]188{
[1029]189  if (m_uiRange == 256)
190  {
191#if RExt__DECODER_DEBUG_BIT_STATISTICS
192    decodeAlignedBinsEP(ruiBin, 1, whichStat);
193#else
194    decodeAlignedBinsEP(ruiBin, 1);
195#endif
196    return;
197  }
198
[313]199  m_uiValue += m_uiValue;
[1029]200
[313]201  if ( ++m_bitsNeeded >= 0 )
202  {
203    m_bitsNeeded = -8;
204    m_uiValue += m_pcTComBitstream->readByte();
205  }
[1029]206
[313]207  ruiBin = 0;
208  UInt scaledRange = m_uiRange << 7;
209  if ( m_uiValue >= scaledRange )
210  {
211    ruiBin = 1;
212    m_uiValue -= scaledRange;
213  }
[1029]214#if RExt__DECODER_DEBUG_BIT_STATISTICS
215  TComCodingStatistics::IncrementStatisticEP(whichStat, 1, Int(ruiBin));
216#endif
[313]217}
218
[1029]219#if RExt__DECODER_DEBUG_BIT_STATISTICS
220Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins, const TComCodingStatisticsClassType &whichStat )
221#else
[313]222Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins )
[1029]223#endif
[313]224{
[1029]225  if (m_uiRange == 256)
226  {
227#if RExt__DECODER_DEBUG_BIT_STATISTICS
228    decodeAlignedBinsEP(ruiBin, numBins, whichStat);
229#else
230    decodeAlignedBinsEP(ruiBin, numBins);
231#endif
232    return;
233  }
234
[313]235  UInt bins = 0;
[1029]236#if RExt__DECODER_DEBUG_BIT_STATISTICS
237  Int origNumBins=numBins;
238#endif
[313]239  while ( numBins > 8 )
240  {
241    m_uiValue = ( m_uiValue << 8 ) + ( m_pcTComBitstream->readByte() << ( 8 + m_bitsNeeded ) );
[1029]242
[313]243    UInt scaledRange = m_uiRange << 15;
244    for ( Int i = 0; i < 8; i++ )
245    {
246      bins += bins;
247      scaledRange >>= 1;
248      if ( m_uiValue >= scaledRange )
249      {
250        bins++;
251        m_uiValue -= scaledRange;
252      }
253    }
254    numBins -= 8;
255  }
[1029]256
[313]257  m_bitsNeeded += numBins;
258  m_uiValue <<= numBins;
[1029]259
[313]260  if ( m_bitsNeeded >= 0 )
261  {
262    m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
263    m_bitsNeeded -= 8;
264  }
[1029]265
[313]266  UInt scaledRange = m_uiRange << ( numBins + 7 );
267  for ( Int i = 0; i < numBins; i++ )
268  {
269    bins += bins;
270    scaledRange >>= 1;
271    if ( m_uiValue >= scaledRange )
272    {
273      bins++;
274      m_uiValue -= scaledRange;
275    }
276  }
[1029]277
[313]278  ruiBin = bins;
[1029]279#if RExt__DECODER_DEBUG_BIT_STATISTICS
280  TComCodingStatistics::IncrementStatisticEP(whichStat, origNumBins, Int(ruiBin));
281#endif
[313]282}
283
[1029]284Void TDecBinCABAC::align()
285{
286#if RExt__DECODER_DEBUG_BIT_STATISTICS
287  TComCodingStatistics::UpdateCABACStat(STATS__CABAC_EP_BIT_ALIGNMENT, m_uiRange, 256, 0);
288#endif
289  m_uiRange = 256;
290}
291
292#if RExt__DECODER_DEBUG_BIT_STATISTICS
293Void TDecBinCABAC::decodeAlignedBinsEP( UInt& ruiBins, Int numBins, const class TComCodingStatisticsClassType &whichStat )
294#else
295Void TDecBinCABAC::decodeAlignedBinsEP( UInt& ruiBins, Int numBins )
296#endif
297{
298  Int binsRemaining = numBins;
299  ruiBins = 0;
300
301  assert(m_uiRange == 256); //aligned decode only works when range = 256
302
303  while (binsRemaining > 0)
304  {
305    const UInt binsToRead = std::min<UInt>(binsRemaining, 8); //read bytes if able to take advantage of the system's byte-read function
306    const UInt binMask    = (1 << binsToRead) - 1;
307
308    //The MSB of m_uiValue is known to be 0 because range is 256. Therefore:
309    // > The comparison against the symbol range of 128 is simply a test on the next-most-significant bit
310    // > "Subtracting" the symbol range if the decoded bin is 1 simply involves clearing that bit.
311    //
312    //As a result, the required bins are simply the <binsToRead> next-most-significant bits of m_uiValue
313    //(m_uiValue is stored MSB-aligned in a 16-bit buffer - hence the shift of 15)
314    //
315    //   m_uiValue = |0|V|V|V|V|V|V|V|V|B|B|B|B|B|B|B|        (V = usable bit, B = potential buffered bit (buffer refills when m_bitsNeeded >= 0))
316    //
317    const UInt newBins = (m_uiValue >> (15 - binsToRead)) & binMask;
318
319    ruiBins   = (ruiBins   << binsToRead) | newBins;
320    m_uiValue = (m_uiValue << binsToRead) & 0x7FFF;
321
322    binsRemaining -= binsToRead;
323    m_bitsNeeded  += binsToRead;
324
325    if (m_bitsNeeded >= 0)
326    {
327      m_uiValue    |= m_pcTComBitstream->readByte() << m_bitsNeeded;
328      m_bitsNeeded -= 8;
329    }
330  }
331
332#if RExt__DECODER_DEBUG_BIT_STATISTICS
333  TComCodingStatistics::IncrementStatisticEP(whichStat, numBins, Int(ruiBins));
334#endif
335}
336
[313]337Void
338TDecBinCABAC::decodeBinTrm( UInt& ruiBin )
339{
340  m_uiRange -= 2;
341  UInt scaledRange = m_uiRange << 7;
342  if( m_uiValue >= scaledRange )
343  {
344    ruiBin = 1;
[1029]345#if RExt__DECODER_DEBUG_BIT_STATISTICS
346    TComCodingStatistics::UpdateCABACStat(STATS__CABAC_TRM_BITS, m_uiRange+2, 2, ruiBin);
347    TComCodingStatistics::IncrementStatisticEP(STATS__BYTE_ALIGNMENT_BITS, -m_bitsNeeded, 0);
348#endif
[313]349  }
350  else
351  {
352    ruiBin = 0;
[1029]353#if RExt__DECODER_DEBUG_BIT_STATISTICS
354    TComCodingStatistics::UpdateCABACStat(STATS__CABAC_TRM_BITS, m_uiRange+2, m_uiRange, ruiBin);
355#endif
[313]356    if ( scaledRange < ( 256 << 7 ) )
357    {
358      m_uiRange = scaledRange >> 6;
359      m_uiValue += m_uiValue;
[1029]360
[313]361      if ( ++m_bitsNeeded == 0 )
362      {
363        m_bitsNeeded = -8;
[1029]364        m_uiValue += m_pcTComBitstream->readByte();
[313]365      }
366    }
367  }
368}
369
370/** Read a PCM code.
371 * \param uiLength code bit-depth
372 * \param ruiCode pointer to PCM code value
373 * \returns Void
374 */
375Void  TDecBinCABAC::xReadPCMCode(UInt uiLength, UInt& ruiCode)
376{
377  assert ( uiLength > 0 );
378  m_pcTComBitstream->read (uiLength, ruiCode);
[1029]379#if RExt__DECODER_DEBUG_BIT_STATISTICS
380  TComCodingStatistics::IncrementStatisticEP(STATS__CABAC_PCM_CODE_BITS, uiLength, ruiCode);
381#endif
[313]382}
383//! \}
Note: See TracBrowser for help on using the repository browser.