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

Last change on this file since 56 was 56, checked in by hschwarz, 12 years ago

updated trunk (move to HM6.1)

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