source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibDecoder/AnnexBread.cpp @ 1550

Last change on this file since 1550 was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

  • Property svn:eol-style set to native
File size: 7.6 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-2016, 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/**
35 \file     AnnexBread.cpp
36 \brief    reading functions for Annex B byte streams
37 */
38
39
40#include <stdint.h>
41#include <cassert>
42#include <vector>
43#include "AnnexBread.h"
44#if RExt__DECODER_DEBUG_BIT_STATISTICS
45#include "TLibCommon/TComCodingStatistics.h"
46#endif
47
48using namespace std;
49
50//! \ingroup TLibDecoder
51//! \{
52
53/**
54 * Parse an AVC AnnexB Bytestream bs to extract a single nalUnit
55 * while accumulating bytestream statistics into stats.
56 *
57 * If EOF occurs while trying to extract a NALunit, an exception
58 * of std::ios_base::failure is thrown.  The contsnts of stats will
59 * be correct at this point.
60 */
61static Void
62_byteStreamNALUnit(
63  InputByteStream& bs,
64  vector<uint8_t>& nalUnit,
65  AnnexBStats& stats)
66{
67  /* At the beginning of the decoding process, the decoder initialises its
68   * current position in the byte stream to the beginning of the byte stream.
69   * It then extracts and discards each leading_zero_8bits syntax element (if
70   * present), moving the current position in the byte stream forward one
71   * byte at a time, until the current position in the byte stream is such
72   * that the next four bytes in the bitstream form the four-byte sequence
73   * 0x00000001.
74   */
75#if RExt__DECODER_DEBUG_BIT_STATISTICS
76  TComCodingStatistics::SStat &statBits=TComCodingStatistics::GetStatisticEP(STATS__NAL_UNIT_PACKING);
77#endif
78  while ((bs.eofBeforeNBytes(24/8) || bs.peekBytes(24/8) != 0x000001)
79  &&     (bs.eofBeforeNBytes(32/8) || bs.peekBytes(32/8) != 0x00000001))
80  {
81    uint8_t leading_zero_8bits = bs.readByte();
82#if RExt__DECODER_DEBUG_BIT_STATISTICS
83    statBits.bits+=8; statBits.count++;
84#endif
85    assert(leading_zero_8bits == 0);
86    stats.m_numLeadingZero8BitsBytes++;
87  }
88
89  /* 1. When the next four bytes in the bitstream form the four-byte sequence
90   * 0x00000001, the next byte in the byte stream (which is a zero_byte
91   * syntax element) is extracted and discarded and the current position in
92   * the byte stream is set equal to the position of the byte following this
93   * discarded byte.
94   */
95  /* NB, the previous step guarantees this will succeed -- if EOF was
96   * encountered, an exception will stop execution getting this far */
97  if (bs.peekBytes(24/8) != 0x000001)
98  {
99    uint8_t zero_byte = bs.readByte();
100#if RExt__DECODER_DEBUG_BIT_STATISTICS
101    statBits.bits+=8; statBits.count++;
102#endif
103    assert(zero_byte == 0);
104    stats.m_numZeroByteBytes++;
105  }
106
107  /* 2. The next three-byte sequence in the byte stream (which is a
108   * start_code_prefix_one_3bytes) is extracted and discarded and the current
109   * position in the byte stream is set equal to the position of the byte
110   * following this three-byte sequence.
111   */
112  /* NB, (1) guarantees that the next three bytes are 0x00 00 01 */
113  uint32_t start_code_prefix_one_3bytes = bs.readBytes(24/8);
114#if RExt__DECODER_DEBUG_BIT_STATISTICS
115  statBits.bits+=24; statBits.count+=3;
116#endif
117  assert(start_code_prefix_one_3bytes == 0x000001);
118  stats.m_numStartCodePrefixBytes += 3;
119
120  /* 3. NumBytesInNALunit is set equal to the number of bytes starting with
121   * the byte at the current position in the byte stream up to and including
122   * the last byte that precedes the location of any of the following
123   * conditions:
124   *   a. A subsequent byte-aligned three-byte sequence equal to 0x000000, or
125   *   b. A subsequent byte-aligned three-byte sequence equal to 0x000001, or
126   *   c. The end of the byte stream, as determined by unspecified means.
127   */
128  /* 4. NumBytesInNALunit bytes are removed from the bitstream and the
129   * current position in the byte stream is advanced by NumBytesInNALunit
130   * bytes. This sequence of bytes is nal_unit( NumBytesInNALunit ) and is
131   * decoded using the NAL unit decoding process
132   */
133  /* NB, (unsigned)x > 2 implies n!=0 && n!=1 */
134#if RExt__DECODER_DEBUG_BIT_STATISTICS
135  TComCodingStatistics::SStat &bodyStats=TComCodingStatistics::GetStatisticEP(STATS__NAL_UNIT_TOTAL_BODY);
136#endif
137  while (bs.eofBeforeNBytes(24/8) || bs.peekBytes(24/8) > 2)
138  {
139#if RExt__DECODER_DEBUG_BIT_STATISTICS
140    uint8_t thebyte=bs.readByte();bodyStats.bits+=8;bodyStats.count++;
141    nalUnit.push_back(thebyte);
142#else
143    nalUnit.push_back(bs.readByte());
144#endif
145  }
146
147  /* 5. When the current position in the byte stream is:
148   *  - not at the end of the byte stream (as determined by unspecified means)
149   *  - and the next bytes in the byte stream do not start with a three-byte
150   *    sequence equal to 0x000001
151   *  - and the next bytes in the byte stream do not start with a four byte
152   *    sequence equal to 0x00000001,
153   * the decoder extracts and discards each trailing_zero_8bits syntax
154   * element, moving the current position in the byte stream forward one byte
155   * at a time, until the current position in the byte stream is such that:
156   *  - the next bytes in the byte stream form the four-byte sequence
157   *    0x00000001 or
158   *  - the end of the byte stream has been encountered (as determined by
159   *    unspecified means).
160   */
161  /* NB, (3) guarantees there are at least three bytes available or none */
162  while ((bs.eofBeforeNBytes(24/8) || bs.peekBytes(24/8) != 0x000001)
163  &&     (bs.eofBeforeNBytes(32/8) || bs.peekBytes(32/8) != 0x00000001))
164  {
165    uint8_t trailing_zero_8bits = bs.readByte();
166#if RExt__DECODER_DEBUG_BIT_STATISTICS
167    statBits.bits+=8; statBits.count++;
168#endif
169    assert(trailing_zero_8bits == 0);
170    stats.m_numTrailingZero8BitsBytes++;
171  }
172}
173
174/**
175 * Parse an AVC AnnexB Bytestream bs to extract a single nalUnit
176 * while accumulating bytestream statistics into stats.
177 *
178 * Returns false if EOF was reached (NB, nalunit data may be valid),
179 *         otherwise true.
180 */
181Bool
182byteStreamNALUnit(
183  InputByteStream& bs,
184  vector<uint8_t>& nalUnit,
185  AnnexBStats& stats)
186{
187  Bool eof = false;
188  try
189  {
190    _byteStreamNALUnit(bs, nalUnit, stats);
191  }
192  catch (...)
193  {
194    eof = true;
195  }
196  stats.m_numBytesInNALUnit = UInt(nalUnit.size());
197  return eof;
198}
199//! \}
Note: See TracBrowser for help on using the repository browser.