HEVC Test Model (HM)  HM-16.3
annexBbytecount.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 
34 #include <stdint.h>
35 #include <cassert>
36 #include <fstream>
37 #include <sstream>
38 #include <iostream>
39 #include <string.h>
40 
41 #include "TLibDecoder/AnnexBread.h"
42 
43 using namespace std;
44 
45 static struct {
47  unsigned data_len;
48  const char data[10];
49 } tests[] = {
50  /* trivial cases: startcode, no payload */
51  {{0, 0, 3, 0, 0}, 3, {0,0,1}},
52  {{0, 1, 3, 0, 0}, 4, {0,0,0,1}},
53  {{2, 1, 3, 0, 0}, 6, {0,0,0,0,0,1}},
54  /* trivial cases: startcode, payload */
55  {{0, 0, 3, 1, 0}, 4, {0,0,1,2}},
56  {{0, 0, 3, 2, 0}, 5, {0,0,1,2,0}},
57  {{0, 0, 3, 3, 0}, 6, {0,0,1,2,0,0}},
58  {{0, 0, 3, 1, 3}, 7, {0,0,1,2,0,0,0}},
59  /* trivial cases: two nal units: extract the first */
60  {{0, 0, 3, 1, 0}, 8, {0,0,1,2,0,0,1,3}},
61  {{0, 0, 3, 1, 0}, 9, {0,0,1,2,0,0,0,1,3}},
62  {{0, 0, 3, 1, 1}, 10, {0,0,1,2,0,0,0,0,1,3}},
63  /* edge cases with EOF near start*/
64  {{0, 0, 0, 0, 0}, 0, {}},
65  {{1, 0, 0, 0, 0}, 1, {0}},
66  {{2, 0, 0, 0, 0}, 2, {0,0}},
67  {{3, 0, 0, 0, 0}, 3, {0,0,0}},
68 };
69 
70 void selftest()
71 {
72  /* test */
73  for (unsigned i = 0; i < sizeof(tests)/sizeof(*tests); i++)
74  {
75  istringstream in(string(tests[i].data, tests[i].data_len));
76  InputByteStream bs(in);
77 
78  AnnexBStats actual = AnnexBStats();
79  vector<uint8_t> nalUnit;
80 
81  byteStreamNALUnit(bs, nalUnit, actual);
82 
83  cout << "Self-Test: " << i << ", {";
84  for (unsigned j = 0; j < tests[i].data_len; j++)
85  {
86  cout << hex << (unsigned int)tests[i].data[j] << dec;
87  if (j < tests[i].data_len-1)
88  {
89  cout << ",";
90  }
91  }
92  cout << "} ";
93 
94  bool ok = true;
95 #define VERIFY(a,b,m) \
96  if (a.m != b.m) { \
97  ok = false; \
98  cout << endl << " MISSMATCH " #m << ", E(" << b.m << ") != " << a.m; \
99  }
100  VERIFY(actual, tests[i].expected, m_numLeadingZero8BitsBytes);
101  VERIFY(actual, tests[i].expected, m_numZeroByteBytes);
102  VERIFY(actual, tests[i].expected, m_numStartCodePrefixBytes);
103  VERIFY(actual, tests[i].expected, m_numBytesInNALUnit);
104  VERIFY(actual, tests[i].expected, m_numTrailingZero8BitsBytes);
105 #undef VERIFY
106  if (ok)
107  {
108  cout << "OK";
109  }
110  cout << endl;
111  }
112 }
113 
114 int main(int argc, char*argv[])
115 {
116  selftest();
117 
118  if (argc != 2)
119  {
120  return 0;
121  }
122 
123  ifstream in(argv[1], ifstream::in | ifstream::binary);
124  InputByteStream bs(in);
125 
126  AnnexBStats annexBStatsTotal = AnnexBStats();
127  AnnexBStats annexBStatsTotal_VCL = AnnexBStats();
128  AnnexBStats annexBStatsTotal_Filler = AnnexBStats();
129  AnnexBStats annexBStatsTotal_Other = AnnexBStats();
130  unsigned numNALUnits = 0;
131 
132  cout << "NALUnits:" << endl;
133  while (!!in)
134  {
135  AnnexBStats annexBStatsSingle = AnnexBStats();
136  vector<uint8_t> nalUnit;
137 
138  byteStreamNALUnit(bs, nalUnit, annexBStatsSingle);
139 
140  int nal_unit_type = -1;
141  if (annexBStatsSingle.m_numBytesInNALUnit)
142  {
143  nal_unit_type = nalUnit[0] & 0x1f;
144  }
145 
146  cout << " - NALU: #" << numNALUnits << " nal_unit_type:" << nal_unit_type << endl
147  << " num_bytes(leading_zero_8bits): " << annexBStatsSingle.m_numLeadingZero8BitsBytes << endl
148  << " num_bytes(zero_byte): " << annexBStatsSingle.m_numZeroByteBytes << endl
149  << " num_bytes(start_code_prefix_one_3bytes): " << annexBStatsSingle.m_numStartCodePrefixBytes << endl
150  << " NumBytesInNALunit: " << annexBStatsSingle.m_numBytesInNALUnit << endl
151  << " num_bytes(trailing_zero_8bits): " << annexBStatsSingle.m_numTrailingZero8BitsBytes << endl
152  ;
153 
154  annexBStatsTotal += annexBStatsSingle;
155  numNALUnits++;
156 
157  if (!annexBStatsSingle.m_numBytesInNALUnit)
158  {
159  continue;
160  }
161 
162  /* identify the NAL unit type and add stats to the correct
163  * accumulators */
164  switch (nalUnit[0] & 0x1f) {
165  case 1: case 2: case 3: case 4: case 5:
166  annexBStatsTotal_VCL += annexBStatsSingle;
167  break;
168  case 12:
169  annexBStatsTotal_Filler += annexBStatsSingle;
170  break;
171  default:
172  annexBStatsTotal_Other += annexBStatsSingle;
173  };
174  }
175 
176  cout << "Summary: " << endl
177  << " num_bytes(leading_zero_8bits): " << annexBStatsTotal.m_numLeadingZero8BitsBytes << endl
178  << " num_bytes(zero_byte): " << annexBStatsTotal.m_numZeroByteBytes << endl
179  << " num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal.m_numStartCodePrefixBytes << endl
180  << " NumBytesInNALunit: " << annexBStatsTotal.m_numBytesInNALUnit << endl
181  << " num_bytes(trailing_zero_8bits): " << annexBStatsTotal.m_numTrailingZero8BitsBytes << endl
182  ;
183 
184  cout << "Summary(VCL): " << endl
185  << " num_bytes(leading_zero_8bits): " << annexBStatsTotal_VCL.m_numLeadingZero8BitsBytes << endl
186  << " num_bytes(zero_byte): " << annexBStatsTotal_VCL.m_numZeroByteBytes << endl
187  << " num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_VCL.m_numStartCodePrefixBytes << endl
188  << " NumBytesInNALunit: " << annexBStatsTotal_VCL.m_numBytesInNALUnit << endl
189  << " num_bytes(trailing_zero_8bits): " << annexBStatsTotal_VCL.m_numTrailingZero8BitsBytes << endl
190  ;
191 
192  cout << "Summary(Filler): " << endl
193  << " num_bytes(leading_zero_8bits): " << annexBStatsTotal_Filler.m_numLeadingZero8BitsBytes << endl
194  << " num_bytes(zero_byte): " << annexBStatsTotal_Filler.m_numZeroByteBytes << endl
195  << " num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_Filler.m_numStartCodePrefixBytes << endl
196  << " NumBytesInNALunit: " << annexBStatsTotal_Filler.m_numBytesInNALUnit << endl
197  << " num_bytes(trailing_zero_8bits): " << annexBStatsTotal_Filler.m_numTrailingZero8BitsBytes << endl
198  ;
199 
200  cout << "Summary(Other): " << endl
201  << " num_bytes(leading_zero_8bits): " << annexBStatsTotal_Other.m_numLeadingZero8BitsBytes << endl
202  << " num_bytes(zero_byte): " << annexBStatsTotal_Other.m_numZeroByteBytes << endl
203  << " num_bytes(start_code_prefix_one_3bytes): " << annexBStatsTotal_Other.m_numStartCodePrefixBytes << endl
204  << " NumBytesInNALunit: " << annexBStatsTotal_Other.m_numBytesInNALUnit << endl
205  << " num_bytes(trailing_zero_8bits): " << annexBStatsTotal_Other.m_numTrailingZero8BitsBytes << endl
206  ;
207 
208  /* The first such type of bitstream, called Type I bitstream, is a
209  * NAL unit stream containing only the VCL NAL units and filler data
210  * NAL units for all access units in the bitstream.
211  */
212  unsigned totalBytes_T1HRD = annexBStatsTotal_VCL.m_numBytesInNALUnit + annexBStatsTotal_Filler.m_numBytesInNALUnit;
213 
214  /*The second type of bitstream, called a Type II bitstream,
215  * contains, in addition to the VCL NAL units and filler data NAL
216  * units for all access units in the bitstream, at least one of
217  * the following:
218  * (a) additional non-VCL NAL units other than filler data NAL
219  * units.
220  */
221  unsigned totalBytes_T2aHRD = annexBStatsTotal.m_numBytesInNALUnit;
222 
223  /* (b) all leading_zero_8bits, zero_byte,
224  * start_code_prefix_one_3bytes, and trailing_zero_8bits syntax
225  * elements that form a byte stream from the NAL unit stream (as
226  * specified in Annex B)
227  */
228  unsigned totalBytes_T2abHRD = 0;
229  totalBytes_T2abHRD += annexBStatsTotal.m_numLeadingZero8BitsBytes;
230  totalBytes_T2abHRD += annexBStatsTotal.m_numZeroByteBytes;
231  totalBytes_T2abHRD += annexBStatsTotal.m_numStartCodePrefixBytes;
232  totalBytes_T2abHRD += annexBStatsTotal.m_numBytesInNALUnit;
233  totalBytes_T2abHRD += annexBStatsTotal.m_numTrailingZero8BitsBytes;
234 
235  cout << "Totals (bytes):" << endl;
236  cout << " Type1 HRD: " << totalBytes_T1HRD << endl;
237  cout << " Type2 HRD: " << totalBytes_T2aHRD << endl;
238  cout << " Type2b HRD: " << totalBytes_T2abHRD << endl;
239 
240  return 0;
241 }
static struct @0 tests[]
unsigned data_len
UInt m_numZeroByteBytes
Definition: AnnexBread.h:179
STL namespace.
void selftest()
UInt m_numBytesInNALUnit
Definition: AnnexBread.h:181
reading functions for Annex B byte streams
#define VERIFY(a, b, m)
UInt m_numLeadingZero8BitsBytes
Definition: AnnexBread.h:178
UInt m_numTrailingZero8BitsBytes
Definition: AnnexBread.h:182
UInt m_numStartCodePrefixBytes
Definition: AnnexBread.h:180
AnnexBStats expected
int main(int argc, char *argv[])
const char data[10]
Bool byteStreamNALUnit(InputByteStream &bs, vector< uint8_t > &nalUnit, AnnexBStats &stats)
Definition: AnnexBread.cpp:182