source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComBitStream.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: 10.8 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     TComBitStream.cpp
35    \brief    class for handling bitstream
36*/
37
38#include <stdint.h>
39#include <vector>
40#include "TComBitStream.h"
41#include <string.h>
42#include <memory.h>
43
44using namespace std;
45
46//! \ingroup TLibCommon
47//! \{
48
49// ====================================================================================================================
50// Constructor / destructor / create / destroy
51// ====================================================================================================================
52
53TComOutputBitstream::TComOutputBitstream()
54{
55  m_fifo = new vector<uint8_t>;
56  clear();
57  m_puiTileMarkerLocation     = new UInt[MAX_MARKER_PER_NALU];
58  m_uiTileMarkerLocationCount = 0;
59}
60
61TComOutputBitstream::~TComOutputBitstream()
62{
63  delete m_fifo;
64  delete [] m_puiTileMarkerLocation;
65}
66
67TComInputBitstream::TComInputBitstream(std::vector<uint8_t>* buf)
68{
69  m_fifo = buf;
70  m_fifo_idx = 0;
71  m_held_bits = 0;
72  m_num_held_bits = 0;
73  m_puiTileMarkerLocation     = new UInt[MAX_MARKER_PER_NALU];
74  m_uiTileMarkerLocationCount = 0;
75#if TILES_WPP_ENTRY_POINT_SIGNALLING
76  m_numBitsRead = 0;
77#endif
78}
79
80TComInputBitstream::~TComInputBitstream()
81{
82  delete [] m_puiTileMarkerLocation;
83}
84
85// ====================================================================================================================
86// Public member functions
87// ====================================================================================================================
88
89char* TComOutputBitstream::getByteStream() const
90{
91  return (char*) &m_fifo->front();
92}
93
94unsigned int TComOutputBitstream::getByteStreamLength()
95{
96  return unsigned(m_fifo->size());
97}
98
99void TComOutputBitstream::clear()
100{
101  m_fifo->clear();
102  m_held_bits = 0;
103  m_num_held_bits = 0;
104  m_uiTileMarkerLocationCount = 0;
105}
106
107Void TComOutputBitstream::write   ( UInt uiBits, UInt uiNumberOfBits )
108{
109  assert( uiNumberOfBits <= 32 );
110
111  /* any modulo 8 remainder of num_total_bits cannot be written this time,
112   * and will be held until next time. */
113  unsigned num_total_bits = uiNumberOfBits + m_num_held_bits;
114  unsigned next_num_held_bits = num_total_bits % 8;
115
116  /* form a byte aligned word (write_bits), by concatenating any held bits
117   * with the new bits, discarding the bits that will form the next_held_bits.
118   * eg: H = held bits, V = n new bits        /---- next_held_bits
119   * len(H)=7, len(V)=1: ... ---- HHHH HHHV . 0000 0000, next_num_held_bits=0
120   * len(H)=7, len(V)=2: ... ---- HHHH HHHV . V000 0000, next_num_held_bits=1
121   * if total_bits < 8, the value of v_ is not used */
122  unsigned char next_held_bits = uiBits << (8 - next_num_held_bits);
123
124  if (!(num_total_bits >> 3))
125  {
126    /* insufficient bits accumulated to write out, append new_held_bits to
127     * current held_bits */
128    /* NB, this requires that v only contains 0 in bit positions {31..n} */
129    m_held_bits |= next_held_bits;
130    m_num_held_bits = next_num_held_bits;
131    return;
132  }
133
134  /* topword serves to justify held_bits to align with the msb of uiBits */
135  unsigned topword = (uiNumberOfBits - next_num_held_bits) & ~((1 << 3) -1);
136  unsigned int write_bits = (m_held_bits << topword) | (uiBits >> next_num_held_bits);
137
138  switch (num_total_bits >> 3)
139  {
140  case 4: m_fifo->push_back(write_bits >> 24);
141  case 3: m_fifo->push_back(write_bits >> 16);
142  case 2: m_fifo->push_back(write_bits >> 8);
143  case 1: m_fifo->push_back(write_bits);
144  }
145
146  m_held_bits = next_held_bits;
147  m_num_held_bits = next_num_held_bits;
148}
149
150Void TComOutputBitstream::writeAlignOne()
151{
152  unsigned int num_bits = getNumBitsUntilByteAligned();
153  write((1 << num_bits) - 1, num_bits);
154  return;
155}
156
157Void TComOutputBitstream::writeAlignZero()
158{
159  if (0 == m_num_held_bits)
160    return;
161  m_fifo->push_back(m_held_bits);
162  m_held_bits = 0;
163  m_num_held_bits = 0;
164}
165
166/**
167 - add substream to the end of the current bitstream
168 .
169 \param  pcSubstream  substream to be added
170 */
171Void   TComOutputBitstream::addSubstream( TComOutputBitstream* pcSubstream )
172{
173  UInt uiNumBits = pcSubstream->getNumberOfWrittenBits();
174
175  const vector<uint8_t>& rbsp = pcSubstream->getFIFO();
176  for (vector<uint8_t>::const_iterator it = rbsp.begin(); it != rbsp.end();)
177  {
178    write(*it++, 8);
179  }
180  if (uiNumBits&0x7)
181  {
182    write(pcSubstream->getHeldBits()>>(8-(uiNumBits&0x7)), uiNumBits&0x7);
183  }
184}
185
186/**
187 * read #uiNumberOfBits# from bitstream without updating the bitstream
188 * state, storing the result in #ruiBits#.
189 *
190 * If reading #uiNumberOfBits# would overrun the bitstream buffer,
191 * the bitsream is effectively padded with sufficient zero-bits to
192 * avoid the overrun.
193 */
194Void TComInputBitstream::pseudoRead ( UInt uiNumberOfBits, UInt& ruiBits )
195{
196  unsigned int saved_num_held_bits = m_num_held_bits;
197  unsigned char saved_held_bits = m_held_bits;
198  unsigned int saved_fifo_idx = m_fifo_idx;
199
200  unsigned num_bits_to_read = min(uiNumberOfBits, getNumBitsLeft());
201  read(num_bits_to_read, ruiBits);
202  ruiBits <<= (uiNumberOfBits - num_bits_to_read);
203
204  m_fifo_idx = saved_fifo_idx;
205  m_held_bits = saved_held_bits;
206  m_num_held_bits = saved_num_held_bits;
207}
208
209
210Void TComInputBitstream::read (UInt uiNumberOfBits, UInt& ruiBits)
211{
212  assert( uiNumberOfBits <= 32 );
213 
214#if TILES_WPP_ENTRY_POINT_SIGNALLING
215  m_numBitsRead += uiNumberOfBits;
216#endif
217
218  /* NB, bits are extracted from the MSB of each byte. */
219  unsigned retval = 0;
220  if (uiNumberOfBits <= m_num_held_bits)
221  {
222    /* n=1, len(H)=7:   -VHH HHHH, shift_down=6, mask=0xfe
223     * n=3, len(H)=7:   -VVV HHHH, shift_down=4, mask=0xf8
224     */
225    retval = m_held_bits >> (m_num_held_bits - uiNumberOfBits);
226    retval &= ~(0xff << uiNumberOfBits);
227    m_num_held_bits -= uiNumberOfBits;
228    ruiBits = retval;
229    return;
230  }
231
232  /* all num_held_bits will go into retval
233   *   => need to mask leftover bits from previous extractions
234   *   => align retval with top of extracted word */
235  /* n=5, len(H)=3: ---- -VVV, mask=0x07, shift_up=5-3=2,
236   * n=9, len(H)=3: ---- -VVV, mask=0x07, shift_up=9-3=6 */
237  uiNumberOfBits -= m_num_held_bits;
238  retval = m_held_bits & ~(0xff << m_num_held_bits);
239  retval <<= uiNumberOfBits;
240
241  /* number of whole bytes that need to be loaded to form retval */
242  /* n=32, len(H)=0, load 4bytes, shift_down=0
243   * n=32, len(H)=1, load 4bytes, shift_down=1
244   * n=31, len(H)=1, load 4bytes, shift_down=1+1
245   * n=8,  len(H)=0, load 1byte,  shift_down=0
246   * n=8,  len(H)=3, load 1byte,  shift_down=3
247   * n=5,  len(H)=1, load 1byte,  shift_down=1+3
248   */
249  unsigned aligned_word = 0;
250  unsigned num_bytes_to_load = (uiNumberOfBits - 1) >> 3;
251  assert(m_fifo_idx + num_bytes_to_load < m_fifo->size());
252
253  switch (num_bytes_to_load)
254  {
255  case 3: aligned_word  = (*m_fifo)[m_fifo_idx++] << 24;
256  case 2: aligned_word |= (*m_fifo)[m_fifo_idx++] << 16;
257  case 1: aligned_word |= (*m_fifo)[m_fifo_idx++] <<  8;
258  case 0: aligned_word |= (*m_fifo)[m_fifo_idx++];
259  }
260
261  /* resolve remainder bits */
262  unsigned next_num_held_bits = (32 - uiNumberOfBits) % 8;
263
264  /* copy required part of aligned_word into retval */
265  retval |= aligned_word >> next_num_held_bits;
266
267  /* store held bits */
268  m_num_held_bits = next_num_held_bits;
269  m_held_bits = aligned_word;
270
271  ruiBits = retval;
272}
273
274/**
275 * insert the contents of the bytealigned (and flushed) bitstream src
276 * into this at byte position pos.
277 */
278void TComOutputBitstream::insertAt(const TComOutputBitstream& src, unsigned pos)
279{
280  unsigned src_bits = src.getNumberOfWrittenBits();
281  assert(0 == src_bits % 8);
282
283  vector<uint8_t>::iterator at = this->m_fifo->begin() + pos;
284  this->m_fifo->insert(at, src.m_fifo->begin(), src.m_fifo->end());
285}
286
287Void TComInputBitstream::readOutTrailingBits ()
288{
289  UInt uiBits = 0;
290
291  while ( ( getNumBitsLeft() > 0 ) && (getNumBitsUntilByteAligned()!=0) )
292  {
293    read ( 1, uiBits );
294  }
295}
296
297TComOutputBitstream& TComOutputBitstream::operator= (const TComOutputBitstream& src)
298{
299  vector<uint8_t>::iterator at = this->m_fifo->begin();
300  this->m_fifo->insert(at, src.m_fifo->begin(), src.m_fifo->end());
301
302  this->m_num_held_bits             = src.m_num_held_bits;
303  this->m_held_bits                 = src.m_held_bits;
304  this->m_uiTileMarkerLocationCount = src.m_uiTileMarkerLocationCount;
305  for (Int uiIdx=0; uiIdx<m_uiTileMarkerLocationCount; uiIdx++)
306  {
307    this->m_puiTileMarkerLocation[uiIdx] = src.m_puiTileMarkerLocation[uiIdx];
308  }
309
310  return *this;
311}
312
313/**
314 - extract substream from the current bitstream
315 .
316 \param  pcBitstream  bitstream which contains substreams
317 \param  uiNumBits    number of bits to transfer
318 */
319TComInputBitstream *TComInputBitstream::extractSubstream( UInt uiNumBits )
320{
321  UInt uiNumBytes = uiNumBits/8;
322  std::vector<uint8_t>* buf = new std::vector<uint8_t>;
323  UInt uiByte;
324  for (UInt ui = 0; ui < uiNumBytes; ui++)
325  {
326    read(8, uiByte);
327    buf->push_back(uiByte);
328  }
329  if (uiNumBits&0x7)
330  {
331    uiByte = 0;
332    read(uiNumBits&0x7, uiByte);
333    uiByte <<= 8-(uiNumBits&0x7);
334    buf->push_back(uiByte);
335  }
336#if OL_FLUSH && !OL_FLUSH_ALIGN
337  buf->push_back(0); // The final chunk might not start byte aligned.
338#endif
339  return new TComInputBitstream(buf);
340}
341
342/**
343 - delete internal fifo
344 */
345Void TComInputBitstream::deleteFifo()
346{
347  delete m_fifo;
348  m_fifo = NULL;
349}
350
351//! \}
Note: See TracBrowser for help on using the repository browser.