HEVC Test Model (HM)  HM-16.3
AnnexBread.cpp
Go to the documentation of this file.
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-2015, 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 
40 #include <stdint.h>
41 #include <cassert>
42 #include <vector>
43 #include "AnnexBread.h"
44 #if RExt__DECODER_DEBUG_BIT_STATISTICS
46 #endif
47 
48 using namespace std;
49 
52 
61 static Void
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
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);
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
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);
171  }
172 }
173 
181 Bool
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 }
Bool eofBeforeNBytes(UInt n)
Definition: AnnexBread.h:87
void Void
Definition: TypeDef.h:285
UInt m_numZeroByteBytes
Definition: AnnexBread.h:179
unsigned int UInt
Definition: TypeDef.h:297
STL namespace.
static SStat & GetStatisticEP(const TComCodingStatisticsClassType &stat)
bool Bool
Definition: TypeDef.h:286
UInt m_numBytesInNALUnit
Definition: AnnexBread.h:181
reading functions for Annex B byte streams
UInt m_numLeadingZero8BitsBytes
Definition: AnnexBread.h:178
static Void _byteStreamNALUnit(InputByteStream &bs, vector< uint8_t > &nalUnit, AnnexBStats &stats)
Definition: AnnexBread.cpp:62
UInt m_numTrailingZero8BitsBytes
Definition: AnnexBread.h:182
UInt m_numStartCodePrefixBytes
Definition: AnnexBread.h:180
uint32_t readBytes(UInt n)
Definition: AnnexBread.h:153
uint32_t peekBytes(UInt n)
Definition: AnnexBread.h:123
uint8_t readByte()
Definition: AnnexBread.h:135
Bool byteStreamNALUnit(InputByteStream &bs, vector< uint8_t > &nalUnit, AnnexBStats &stats)
Definition: AnnexBread.cpp:182