source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibDecoder/TDecBinCoderCABAC.cpp @ 1311

Last change on this file since 1311 was 916, checked in by seregin, 10 years ago

initial porting

  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
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
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
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"
39#include "TLibCommon/Debug.h"
40#if RExt__DECODER_DEBUG_BIT_STATISTICS
41#include "TLibCommon/TComCodingStatistics.h"
42#endif
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 );
72#if RExt__DECODER_DEBUG_BIT_STATISTICS
73  TComCodingStatistics::UpdateCABACStat(STATS__CABAC_INITIALISATION, 512, 510, 0);
74#endif
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
97TDecBinCABAC::copyState( const TDecBinIf* pcTDecBinIf )
98{
99  const TDecBinCABAC* pcTDecBinCABAC = pcTDecBinIf->getTDecBinCABAC();
100  m_uiRange   = pcTDecBinCABAC->m_uiRange;
101  m_uiValue   = pcTDecBinCABAC->m_uiValue;
102  m_bitsNeeded= pcTDecBinCABAC->m_bitsNeeded;
103}
104
105
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
112{
113#ifdef DEBUG_CABAC_BINS
114  const UInt startingRange = m_uiRange;
115#endif
116
117  UInt uiLPS = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) - 4 ];
118  m_uiRange -= uiLPS;
119  UInt scaledRange = m_uiRange << 7;
120
121  if( m_uiValue < scaledRange )
122  {
123    // MPS path
124    ruiBin = rcCtxModel.getMps();
125#if RExt__DECODER_DEBUG_BIT_STATISTICS
126    TComCodingStatistics::UpdateCABACStat(whichStat, m_uiRange+uiLPS, m_uiRange, Int(ruiBin));
127#endif
128    rcCtxModel.updateMPS();
129
130    if ( scaledRange < ( 256 << 7 ) )
131    {
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      }
140    }
141  }
142  else
143  {
144    // LPS path
145    ruiBin      = 1 - rcCtxModel.getMps();
146#if RExt__DECODER_DEBUG_BIT_STATISTICS
147    TComCodingStatistics::UpdateCABACStat(whichStat, m_uiRange+uiLPS, uiLPS, Int(ruiBin));
148#endif
149    Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ];
150    m_uiValue   = ( m_uiValue - scaledRange ) << numBits;
151    m_uiRange   = uiLPS << numBits;
152    rcCtxModel.updateLPS();
153
154    m_bitsNeeded += numBits;
155
156    if ( m_bitsNeeded >= 0 )
157    {
158      m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
159      m_bitsNeeded -= 8;
160    }
161  }
162
163#ifdef DEBUG_CABAC_BINS
164  if ((g_debugCounter + debugCabacBinWindow) >= debugCabacBinTargetLine)
165    std::cout << g_debugCounter << ": coding bin value " << ruiBin << ", range = [" << startingRange << "->" << m_uiRange << "]\n";
166
167  if (g_debugCounter >= debugCabacBinTargetLine)
168  {
169    Char breakPointThis;
170    breakPointThis = 7;
171  }
172  if (g_debugCounter >= (debugCabacBinTargetLine + debugCabacBinWindow)) exit(0);
173  g_debugCounter++;
174#endif
175}
176
177
178#if RExt__DECODER_DEBUG_BIT_STATISTICS
179Void TDecBinCABAC::decodeBinEP( UInt& ruiBin, const TComCodingStatisticsClassType &whichStat )
180#else
181Void TDecBinCABAC::decodeBinEP( UInt& ruiBin )
182#endif
183{
184  if (m_uiRange == 256)
185  {
186#if RExt__DECODER_DEBUG_BIT_STATISTICS
187    decodeAlignedBinsEP(ruiBin, 1, whichStat);
188#else
189    decodeAlignedBinsEP(ruiBin, 1);
190#endif
191    return;
192  }
193
194  m_uiValue += m_uiValue;
195
196  if ( ++m_bitsNeeded >= 0 )
197  {
198    m_bitsNeeded = -8;
199    m_uiValue += m_pcTComBitstream->readByte();
200  }
201
202  ruiBin = 0;
203  UInt scaledRange = m_uiRange << 7;
204  if ( m_uiValue >= scaledRange )
205  {
206    ruiBin = 1;
207    m_uiValue -= scaledRange;
208  }
209#if RExt__DECODER_DEBUG_BIT_STATISTICS
210  TComCodingStatistics::IncrementStatisticEP(whichStat, 1, Int(ruiBin));
211#endif
212}
213
214#if RExt__DECODER_DEBUG_BIT_STATISTICS
215Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins, const TComCodingStatisticsClassType &whichStat )
216#else
217Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins )
218#endif
219{
220  if (m_uiRange == 256)
221  {
222#if RExt__DECODER_DEBUG_BIT_STATISTICS
223    decodeAlignedBinsEP(ruiBin, numBins, whichStat);
224#else
225    decodeAlignedBinsEP(ruiBin, numBins);
226#endif
227    return;
228  }
229
230  UInt bins = 0;
231#if RExt__DECODER_DEBUG_BIT_STATISTICS
232  Int origNumBins=numBins;
233#endif
234  while ( numBins > 8 )
235  {
236    m_uiValue = ( m_uiValue << 8 ) + ( m_pcTComBitstream->readByte() << ( 8 + m_bitsNeeded ) );
237
238    UInt scaledRange = m_uiRange << 15;
239    for ( Int i = 0; i < 8; i++ )
240    {
241      bins += bins;
242      scaledRange >>= 1;
243      if ( m_uiValue >= scaledRange )
244      {
245        bins++;
246        m_uiValue -= scaledRange;
247      }
248    }
249    numBins -= 8;
250  }
251
252  m_bitsNeeded += numBins;
253  m_uiValue <<= numBins;
254
255  if ( m_bitsNeeded >= 0 )
256  {
257    m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
258    m_bitsNeeded -= 8;
259  }
260
261  UInt scaledRange = m_uiRange << ( numBins + 7 );
262  for ( Int i = 0; i < numBins; i++ )
263  {
264    bins += bins;
265    scaledRange >>= 1;
266    if ( m_uiValue >= scaledRange )
267    {
268      bins++;
269      m_uiValue -= scaledRange;
270    }
271  }
272
273  ruiBin = bins;
274#if RExt__DECODER_DEBUG_BIT_STATISTICS
275  TComCodingStatistics::IncrementStatisticEP(whichStat, origNumBins, Int(ruiBin));
276#endif
277}
278
279Void TDecBinCABAC::align()
280{
281#if RExt__DECODER_DEBUG_BIT_STATISTICS
282  TComCodingStatistics::UpdateCABACStat(STATS__CABAC_EP_BIT_ALIGNMENT, m_uiRange, 256, 0);
283#endif
284  m_uiRange = 256;
285}
286
287#if RExt__DECODER_DEBUG_BIT_STATISTICS
288Void TDecBinCABAC::decodeAlignedBinsEP( UInt& ruiBins, Int numBins, const class TComCodingStatisticsClassType &whichStat )
289#else
290Void TDecBinCABAC::decodeAlignedBinsEP( UInt& ruiBins, Int numBins )
291#endif
292{
293  Int binsRemaining = numBins;
294  ruiBins = 0;
295
296  assert(m_uiRange == 256); //aligned decode only works when range = 256
297
298  while (binsRemaining > 0)
299  {
300    const UInt binsToRead = std::min<UInt>(binsRemaining, 8); //read bytes if able to take advantage of the system's byte-read function
301    const UInt binMask    = (1 << binsToRead) - 1;
302
303    //The MSB of m_uiValue is known to be 0 because range is 256. Therefore:
304    // > The comparison against the symbol range of 128 is simply a test on the next-most-significant bit
305    // > "Subtracting" the symbol range if the decoded bin is 1 simply involves clearing that bit.
306    //
307    //As a result, the required bins are simply the <binsToRead> next-most-significant bits of m_uiValue
308    //(m_uiValue is stored MSB-aligned in a 16-bit buffer - hence the shift of 15)
309    //
310    //   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))
311    //
312    const UInt newBins = (m_uiValue >> (15 - binsToRead)) & binMask;
313
314    ruiBins   = (ruiBins   << binsToRead) | newBins;
315    m_uiValue = (m_uiValue << binsToRead) & 0x7FFF;
316
317    binsRemaining -= binsToRead;
318    m_bitsNeeded  += binsToRead;
319
320    if (m_bitsNeeded >= 0)
321    {
322      m_uiValue    |= m_pcTComBitstream->readByte() << m_bitsNeeded;
323      m_bitsNeeded -= 8;
324    }
325  }
326
327#if RExt__DECODER_DEBUG_BIT_STATISTICS
328  TComCodingStatistics::IncrementStatisticEP(whichStat, numBins, Int(ruiBins));
329#endif
330}
331
332Void
333TDecBinCABAC::decodeBinTrm( UInt& ruiBin )
334{
335  m_uiRange -= 2;
336  UInt scaledRange = m_uiRange << 7;
337  if( m_uiValue >= scaledRange )
338  {
339    ruiBin = 1;
340#if RExt__DECODER_DEBUG_BIT_STATISTICS
341    TComCodingStatistics::UpdateCABACStat(STATS__CABAC_TRM_BITS, m_uiRange+2, 2, ruiBin);
342    TComCodingStatistics::IncrementStatisticEP(STATS__BYTE_ALIGNMENT_BITS, -m_bitsNeeded, 0);
343#endif
344  }
345  else
346  {
347    ruiBin = 0;
348#if RExt__DECODER_DEBUG_BIT_STATISTICS
349    TComCodingStatistics::UpdateCABACStat(STATS__CABAC_TRM_BITS, m_uiRange+2, m_uiRange, ruiBin);
350#endif
351    if ( scaledRange < ( 256 << 7 ) )
352    {
353      m_uiRange = scaledRange >> 6;
354      m_uiValue += m_uiValue;
355
356      if ( ++m_bitsNeeded == 0 )
357      {
358        m_bitsNeeded = -8;
359        m_uiValue += m_pcTComBitstream->readByte();
360      }
361    }
362  }
363}
364
365/** Read a PCM code.
366 * \param uiLength code bit-depth
367 * \param ruiCode pointer to PCM code value
368 * \returns Void
369 */
370Void  TDecBinCABAC::xReadPCMCode(UInt uiLength, UInt& ruiCode)
371{
372  assert ( uiLength > 0 );
373  m_pcTComBitstream->read (uiLength, ruiCode);
374#if RExt__DECODER_DEBUG_BIT_STATISTICS
375  TComCodingStatistics::IncrementStatisticEP(STATS__CABAC_PCM_CODE_BITS, uiLength, ruiCode);
376#endif
377}
378//! \}
Note: See TracBrowser for help on using the repository browser.