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

Last change on this file since 847 was 595, checked in by seregin, 11 years ago

merge with SHM-5.0-dev branch

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