source: 3DVCSoftware/trunk/source/Lib/TLibDecoder/TDecBinCoderCABAC.cpp

Last change on this file was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • 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-2017, 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#if 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#if DEBUG_CABAC_BINS
164  if ((g_debugCounter + debugCabacBinWindow) >= debugCabacBinTargetLine)
165  {
166    std::cout << g_debugCounter << ": coding bin value " << ruiBin << ", range = [" << startingRange << "->" << m_uiRange << "]\n";
167  }
168
169  if (g_debugCounter >= debugCabacBinTargetLine)
170  {
171    UChar breakPointThis;
172    breakPointThis = 7;
173  }
174  if (g_debugCounter >= (debugCabacBinTargetLine + debugCabacBinWindow))
175  {
176    exit(0);
177  }
178  g_debugCounter++;
179#endif
180}
181
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
188{
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
199  m_uiValue += m_uiValue;
200
201  if ( ++m_bitsNeeded >= 0 )
202  {
203    m_bitsNeeded = -8;
204    m_uiValue += m_pcTComBitstream->readByte();
205  }
206
207  ruiBin = 0;
208  UInt scaledRange = m_uiRange << 7;
209  if ( m_uiValue >= scaledRange )
210  {
211    ruiBin = 1;
212    m_uiValue -= scaledRange;
213  }
214#if RExt__DECODER_DEBUG_BIT_STATISTICS
215  TComCodingStatistics::IncrementStatisticEP(whichStat, 1, Int(ruiBin));
216#endif
217}
218
219#if RExt__DECODER_DEBUG_BIT_STATISTICS
220Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins, const TComCodingStatisticsClassType &whichStat )
221#else
222Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins )
223#endif
224{
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
235  UInt bins = 0;
236#if RExt__DECODER_DEBUG_BIT_STATISTICS
237  Int origNumBins=numBins;
238#endif
239  while ( numBins > 8 )
240  {
241    m_uiValue = ( m_uiValue << 8 ) + ( m_pcTComBitstream->readByte() << ( 8 + m_bitsNeeded ) );
242
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  }
256
257  m_bitsNeeded += numBins;
258  m_uiValue <<= numBins;
259
260  if ( m_bitsNeeded >= 0 )
261  {
262    m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
263    m_bitsNeeded -= 8;
264  }
265
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  }
277
278  ruiBin = bins;
279#if RExt__DECODER_DEBUG_BIT_STATISTICS
280  TComCodingStatistics::IncrementStatisticEP(whichStat, origNumBins, Int(ruiBin));
281#endif
282}
283
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
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;
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
349  }
350  else
351  {
352    ruiBin = 0;
353#if RExt__DECODER_DEBUG_BIT_STATISTICS
354    TComCodingStatistics::UpdateCABACStat(STATS__CABAC_TRM_BITS, m_uiRange+2, m_uiRange, ruiBin);
355#endif
356    if ( scaledRange < ( 256 << 7 ) )
357    {
358      m_uiRange = scaledRange >> 6;
359      m_uiValue += m_uiValue;
360
361      if ( ++m_bitsNeeded == 0 )
362      {
363        m_bitsNeeded = -8;
364        m_uiValue += m_pcTComBitstream->readByte();
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);
379#if RExt__DECODER_DEBUG_BIT_STATISTICS
380  TComCodingStatistics::IncrementStatisticEP(STATS__CABAC_PCM_CODE_BITS, uiLength, ruiCode);
381#endif
382}
383//! \}
Note: See TracBrowser for help on using the repository browser.