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

Last change on this file since 381 was 296, checked in by tech, 12 years ago

Reintegrated branch 5.1-dev0 rev. 295.

  • Property svn:eol-style set to native
File size: 8.3 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-2012, 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
40//! \ingroup TLibDecoder
41//! \{
42
43TDecBinCABAC::TDecBinCABAC()
44: m_pcTComBitstream( 0 )
45{
46}
47
48TDecBinCABAC::~TDecBinCABAC()
49{
50}
51
52Void
53TDecBinCABAC::init( TComInputBitstream* pcTComBitstream )
54{
55  m_pcTComBitstream = pcTComBitstream;
56}
57
58Void
59TDecBinCABAC::uninit()
60{
61  m_pcTComBitstream = 0;
62}
63
64Void
65TDecBinCABAC::start()
66{
67#if OL_FLUSH_ALIGN
68  assert( m_pcTComBitstream->getNumBitsUntilByteAligned() == 0 );
69#endif
70 
71  m_uiRange    = 510;
72  m_bitsNeeded = -8;
73  m_uiValue    = m_pcTComBitstream->readByte() << 8;
74#if !OL_FLUSH_ALIGN
75  m_uiLastByte = m_pcTComBitstream->readByte();
76  m_uiValue   |= m_uiLastByte;
77#else
78  m_uiValue   |= m_pcTComBitstream->readByte();
79#endif
80}
81
82Void
83TDecBinCABAC::finish()
84{
85}
86
87Void
88TDecBinCABAC::flush()
89{
90#if OL_FLUSH_ALIGN
91  while (m_pcTComBitstream->getNumBitsLeft() > 0 && m_pcTComBitstream->getNumBitsUntilByteAligned() != 0)
92  {
93    UInt uiBits;
94    m_pcTComBitstream->read ( 1, uiBits );
95  }
96  start();
97#else
98  m_uiRange    = 510;
99  Int iExtra = 16+m_bitsNeeded+1; // m_bitsNeeded is -ve: iExtra is many bits to read to make up 16.
100  UInt uiExtraBits;
101  m_pcTComBitstream->read(iExtra, uiExtraBits);
102  m_uiValue = (m_uiLastByte << iExtra) | uiExtraBits;
103  m_uiValue &= 0xffff;
104  m_uiLastByte = m_uiValue;
105  m_uiLastByte &= 0xff;
106  m_bitsNeeded = -8;
107#endif // OL_FLUSH_ALIGN
108}
109
110/**
111 - Copy CABAC state.
112 .
113 \param pcTDecBinIf The source CABAC engine.
114 */
115Void
116TDecBinCABAC::copyState( TDecBinIf* pcTDecBinIf )
117{
118  TDecBinCABAC* pcTDecBinCABAC = pcTDecBinIf->getTDecBinCABAC();
119  m_uiRange   = pcTDecBinCABAC->m_uiRange;
120  m_uiValue   = pcTDecBinCABAC->m_uiValue;
121  m_bitsNeeded= pcTDecBinCABAC->m_bitsNeeded;
122#if !OL_FLUSH_ALIGN
123  m_uiLastByte= pcTDecBinCABAC->m_uiLastByte;
124#endif
125}
126
127
128Void
129TDecBinCABAC::decodeBin( UInt& ruiBin, ContextModel &rcCtxModel )
130{
131  UInt uiLPS = TComCABACTables::sm_aucLPSTable[ rcCtxModel.getState() ][ ( m_uiRange >> 6 ) - 4 ];
132  m_uiRange -= uiLPS;
133  UInt scaledRange = m_uiRange << 7;
134 
135  if( m_uiValue < scaledRange )
136  {
137    // MPS path
138    ruiBin = rcCtxModel.getMps();
139    rcCtxModel.updateMPS();
140   
141    if ( scaledRange >= ( 256 << 7 ) )
142    {
143      return;
144    }
145   
146    m_uiRange = scaledRange >> 6;
147    m_uiValue += m_uiValue;
148   
149    if ( ++m_bitsNeeded == 0 )
150    {
151      m_bitsNeeded = -8;
152#if !OL_FLUSH_ALIGN
153      m_uiLastByte = m_pcTComBitstream->readByte();
154      m_uiValue += m_uiLastByte;   
155#else
156      m_uiValue += m_pcTComBitstream->readByte();     
157#endif
158    }
159  }
160  else
161  {
162    // LPS path
163    Int numBits = TComCABACTables::sm_aucRenormTable[ uiLPS >> 3 ];
164    m_uiValue   = ( m_uiValue - scaledRange ) << numBits;
165    m_uiRange   = uiLPS << numBits;
166    ruiBin      = 1 - rcCtxModel.getMps();
167    rcCtxModel.updateLPS();
168   
169    m_bitsNeeded += numBits;
170   
171    if ( m_bitsNeeded >= 0 )
172    {
173#if !OL_FLUSH_ALIGN
174      m_uiLastByte = m_pcTComBitstream->readByte();
175      m_uiValue += m_uiLastByte << m_bitsNeeded;
176#else
177      m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
178#endif
179      m_bitsNeeded -= 8;
180    }
181  }
182}
183
184Void
185TDecBinCABAC::decodeBinEP( UInt& ruiBin )
186{
187  m_uiValue += m_uiValue;
188 
189  if ( ++m_bitsNeeded >= 0 )
190  {
191    m_bitsNeeded = -8;
192#if !OL_FLUSH_ALIGN
193    m_uiLastByte = m_pcTComBitstream->readByte();
194    m_uiValue += m_uiLastByte;
195#else
196    m_uiValue += m_pcTComBitstream->readByte();
197#endif
198  }
199 
200  ruiBin = 0;
201  UInt scaledRange = m_uiRange << 7;
202  if ( m_uiValue >= scaledRange )
203  {
204    ruiBin = 1;
205    m_uiValue -= scaledRange;
206  }
207}
208
209Void TDecBinCABAC::decodeBinsEP( UInt& ruiBin, Int numBins )
210{
211  UInt bins = 0;
212 
213  while ( numBins > 8 )
214  {
215#if !OL_FLUSH_ALIGN
216    m_uiLastByte = m_pcTComBitstream->readByte();
217    m_uiValue = ( m_uiValue << 8 ) + ( m_uiLastByte << ( 8 + m_bitsNeeded ) );
218#else
219    m_uiValue = ( m_uiValue << 8 ) + ( m_pcTComBitstream->readByte() << ( 8 + m_bitsNeeded ) );
220#endif
221   
222    UInt scaledRange = m_uiRange << 15;
223    for ( Int i = 0; i < 8; i++ )
224    {
225      bins += bins;
226      scaledRange >>= 1;
227      if ( m_uiValue >= scaledRange )
228      {
229        bins++;
230        m_uiValue -= scaledRange;
231      }
232    }
233    numBins -= 8;
234  }
235 
236  m_bitsNeeded += numBins;
237  m_uiValue <<= numBins;
238 
239  if ( m_bitsNeeded >= 0 )
240  {
241#if !OL_FLUSH_ALIGN
242    m_uiLastByte = m_pcTComBitstream->readByte();
243    m_uiValue += m_uiLastByte << m_bitsNeeded;
244#else
245    m_uiValue += m_pcTComBitstream->readByte() << m_bitsNeeded;
246#endif
247    m_bitsNeeded -= 8;
248  }
249 
250  UInt scaledRange = m_uiRange << ( numBins + 7 );
251  for ( Int i = 0; i < numBins; i++ )
252  {
253    bins += bins;
254    scaledRange >>= 1;
255    if ( m_uiValue >= scaledRange )
256    {
257      bins++;
258      m_uiValue -= scaledRange;
259    }
260  }
261 
262  ruiBin = bins;
263}
264
265Void
266TDecBinCABAC::decodeBinTrm( UInt& ruiBin )
267{
268  m_uiRange -= 2;
269  UInt scaledRange = m_uiRange << 7;
270  if( m_uiValue >= scaledRange )
271  {
272    ruiBin = 1;
273  }
274  else
275  {
276    ruiBin = 0;
277    if ( scaledRange < ( 256 << 7 ) )
278    {
279      m_uiRange = scaledRange >> 6;
280      m_uiValue += m_uiValue;
281     
282      if ( ++m_bitsNeeded == 0 )
283      {
284        m_bitsNeeded = -8;
285#if !OL_FLUSH_ALIGN
286        m_uiLastByte = m_pcTComBitstream->readByte();
287        m_uiValue += m_uiLastByte;   
288#else
289        m_uiValue += m_pcTComBitstream->readByte();     
290#endif
291      }
292    }
293  }
294}
295
296/** Reset BAC register values.
297 * \returns Void
298 */
299Void TDecBinCABAC::resetBac()
300{
301  m_uiRange    = 510;
302  m_bitsNeeded = -8;
303  m_uiValue    = m_pcTComBitstream->read( 16 );
304}
305
306/** Decode subsequent_pcm_num.
307 * \param numSubseqIPCM
308 * \returns Void
309 */
310Void TDecBinCABAC::decodeNumSubseqIPCM( Int& numSubseqIPCM )
311{
312  UInt bit = 0;
313
314  numSubseqIPCM = 0;
315
316  do
317  {
318    m_uiValue += m_uiValue;
319    if ( ++m_bitsNeeded >= 0 )
320    {
321      m_bitsNeeded = -8;
322#if !OL_FLUSH_ALIGN
323      m_uiLastByte = m_pcTComBitstream->readByte();
324      m_uiValue += m_uiLastByte;
325#else
326      m_uiValue += m_pcTComBitstream->readByte();
327#endif
328    }
329    bit = ((m_uiValue&128)>>7);
330    numSubseqIPCM++;
331  }
332  while( bit && (numSubseqIPCM < 3 ));
333
334  if( bit && (numSubseqIPCM == 3 ))
335  {
336    numSubseqIPCM++;
337  }
338
339  numSubseqIPCM --;
340}
341
342/** Decode PCM alignment zero bits.
343 * \returns Void
344 */
345Void TDecBinCABAC::decodePCMAlignBits()
346{
347  Int iNum = m_pcTComBitstream->getNumBitsUntilByteAligned();
348 
349  UInt uiBit = 0;
350  m_pcTComBitstream->read( iNum, uiBit );
351}
352
353/** Read a PCM code.
354 * \param uiLength code bit-depth
355 * \param ruiCode pointer to PCM code value
356 * \returns Void
357 */
358Void  TDecBinCABAC::xReadPCMCode(UInt uiLength, UInt& ruiCode)
359{
360  assert ( uiLength > 0 );
361  m_pcTComBitstream->read (uiLength, ruiCode);
362}
363//! \}
Note: See TracBrowser for help on using the repository browser.